diff --git a/engine/GNU.TXT b/engine/GNU.TXT deleted file mode 100644 index 2f3289a..0000000 --- a/engine/GNU.TXT +++ /dev/null @@ -1,87 +0,0 @@ -GNU GENERAL PUBLIC LICENSE -Version 2, June 1991 - -Copyright (C) 1989, 1991 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. -Preamble -The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. - -When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. - -To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. - -For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. - -We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. - -Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. - -Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. - -The precise terms and conditions for copying, distribution and modification follow. - -TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION -0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". - -Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. - -1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. - -You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. - -2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: - - -a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. - -b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. - -c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) -These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. -Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. - -In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. - -3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: - -a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, - -b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, - -c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) -The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. -If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. - -4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. - -5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. - -6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. - -7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. - -If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. - -It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. - -This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. - -8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. - -9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. - -Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. - -10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. - -NO WARRANTY - -11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - -12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. - - -END OF TERMS AND CONDITIONS diff --git a/engine/LICENSE.txt b/engine/LICENSE.txt new file mode 100644 index 0000000..d159169 --- /dev/null +++ b/engine/LICENSE.txt @@ -0,0 +1,339 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Lesser General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. diff --git a/engine/Quake/anorm_dots.h b/engine/Quake/anorm_dots.h new file mode 100644 index 0000000..21e6853 --- /dev/null +++ b/engine/Quake/anorm_dots.h @@ -0,0 +1,580 @@ +/* + * anorm_dots.h + * + * Copyright (C) 1996-1997 Id Software, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +// 0 + { 1.23, 1.30, 1.47, 1.35, 1.56, 1.71, 1.37, 1.38, + 1.59, 1.60, 1.79, 1.97, 1.88, 1.92, 1.79, 1.02, + 0.93, 1.07, 0.82, 0.87, 0.88, 0.94, 0.96, 1.14, + 1.11, 0.82, 0.83, 0.89, 0.89, 0.86, 0.94, 0.91, + 1.00, 1.21, 0.98, 1.48, 1.30, 1.57, 0.96, 1.07, + 1.14, 1.60, 1.61, 1.40, 1.37, 1.72, 1.78, 1.79, + 1.93, 1.99, 1.90, 1.68, 1.71, 1.86, 1.60, 1.68, + 1.78, 1.86, 1.93, 1.99, 1.97, 1.44, 1.22, 1.49, + 0.93, 0.99, 0.99, 1.23, 1.22, 1.44, 1.49, 0.89, + 0.89, 0.97, 0.91, 0.98, 1.19, 0.82, 0.76, 0.82, + 0.71, 0.72, 0.73, 0.76, 0.79, 0.86, 0.83, 0.72, + 0.76, 0.76, 0.89, 0.82, 0.89, 0.82, 0.89, 0.91, + 0.83, 0.96, 1.14, 0.97, 1.40, 1.19, 0.98, 0.94, + 1.00, 1.07, 1.37, 1.21, 1.48, 1.30, 1.57, 1.61, + 1.37, 0.86, 0.83, 0.91, 0.82, 0.82, 0.88, 0.89, + 0.96, 1.14, 0.98, 0.87, 0.93, 0.94, 1.02, 1.30, + 1.07, 1.35, 1.38, 1.11, 1.56, 1.92, 1.79, 1.79, + 1.59, 1.60, 1.72, 1.90, 1.79, 0.80, 0.85, 0.79, + 0.93, 0.80, 0.85, 0.77, 0.74, 0.72, 0.77, 0.74, + 0.72, 0.70, 0.70, 0.71, 0.76, 0.73, 0.79, 0.79, + 0.73, 0.76, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00 + }, + +// 1 + { 1.26, 1.26, 1.48, 1.23, 1.50, 1.71, 1.14, 1.19, + 1.38, 1.46, 1.64, 1.94, 1.87, 1.84, 1.71, 1.02, + 0.92, 1.00, 0.79, 0.85, 0.84, 0.91, 0.90, 0.98, + 0.99, 0.77, 0.77, 0.83, 0.82, 0.79, 0.86, 0.84, + 0.92, 0.99, 0.91, 1.24, 1.03, 1.33, 0.88, 0.94, + 0.97, 1.41, 1.39, 1.18, 1.11, 1.51, 1.61, 1.59, + 1.80, 1.91, 1.76, 1.54, 1.65, 1.76, 1.70, 1.70, + 1.85, 1.85, 1.97, 1.99, 1.93, 1.28, 1.09, 1.39, + 0.92, 0.97, 0.99, 1.18, 1.26, 1.52, 1.48, 0.83, + 0.85, 0.90, 0.88, 0.93, 1.00, 0.77, 0.73, 0.78, + 0.72, 0.71, 0.74, 0.75, 0.79, 0.86, 0.81, 0.75, + 0.81, 0.79, 0.96, 0.88, 0.94, 0.86, 0.93, 0.92, + 0.85, 1.08, 1.33, 1.05, 1.55, 1.31, 1.01, 1.05, + 1.27, 1.31, 1.60, 1.47, 1.70, 1.54, 1.76, 1.76, + 1.57, 0.93, 0.90, 0.99, 0.88, 0.88, 0.95, 0.97, + 1.11, 1.39, 1.20, 0.92, 0.97, 1.01, 1.10, 1.39, + 1.22, 1.51, 1.58, 1.32, 1.64, 1.97, 1.85, 1.91, + 1.77, 1.74, 1.88, 1.99, 1.91, 0.79, 0.86, 0.80, + 0.94, 0.84, 0.88, 0.74, 0.74, 0.71, 0.82, 0.77, + 0.76, 0.70, 0.73, 0.72, 0.73, 0.70, 0.74, 0.85, + 0.77, 0.82, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00 + }, + +// 2 + { 1.34, 1.27, 1.53, 1.17, 1.46, 1.71, 0.98, 1.05, + 1.20, 1.34, 1.48, 1.86, 1.82, 1.71, 1.62, 1.09, + 0.94, 0.99, 0.79, 0.85, 0.82, 0.90, 0.87, 0.93, + 0.96, 0.76, 0.74, 0.79, 0.76, 0.74, 0.79, 0.78, + 0.85, 0.92, 0.85, 1.00, 0.93, 1.06, 0.81, 0.86, + 0.89, 1.16, 1.12, 0.97, 0.95, 1.28, 1.38, 1.35, + 1.60, 1.77, 1.57, 1.33, 1.50, 1.58, 1.69, 1.63, + 1.82, 1.74, 1.91, 1.92, 1.80, 1.04, 0.97, 1.21, + 0.90, 0.93, 0.97, 1.05, 1.21, 1.48, 1.37, 0.77, + 0.80, 0.84, 0.85, 0.88, 0.92, 0.73, 0.71, 0.74, + 0.74, 0.71, 0.75, 0.73, 0.79, 0.84, 0.78, 0.79, + 0.86, 0.81, 1.05, 0.94, 0.99, 0.90, 0.95, 0.92, + 0.86, 1.24, 1.44, 1.14, 1.59, 1.34, 1.02, 1.27, + 1.50, 1.49, 1.80, 1.69, 1.86, 1.72, 1.87, 1.80, + 1.69, 1.00, 0.98, 1.23, 0.95, 0.96, 1.09, 1.16, + 1.37, 1.63, 1.46, 0.99, 1.10, 1.25, 1.24, 1.51, + 1.41, 1.67, 1.77, 1.55, 1.72, 1.95, 1.89, 1.98, + 1.91, 1.86, 1.97, 1.99, 1.94, 0.81, 0.89, 0.85, + 0.98, 0.90, 0.94, 0.75, 0.78, 0.73, 0.89, 0.83, + 0.82, 0.72, 0.77, 0.76, 0.72, 0.70, 0.71, 0.91, + 0.83, 0.89, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00 + }, + +// 3 + { 1.46, 1.34, 1.60, 1.16, 1.46, 1.71, 0.94, 0.99, + 1.05, 1.26, 1.33, 1.74, 1.76, 1.57, 1.54, 1.23, + 0.98, 1.05, 0.83, 0.89, 0.84, 0.92, 0.87, 0.91, + 0.96, 0.78, 0.74, 0.79, 0.72, 0.72, 0.75, 0.76, + 0.80, 0.88, 0.83, 0.94, 0.87, 0.95, 0.76, 0.80, + 0.82, 0.97, 0.96, 0.89, 0.88, 1.08, 1.11, 1.10, + 1.37, 1.59, 1.37, 1.07, 1.27, 1.34, 1.57, 1.45, + 1.69, 1.55, 1.77, 1.79, 1.60, 0.93, 0.90, 0.99, + 0.86, 0.87, 0.93, 0.96, 1.07, 1.35, 1.18, 0.73, + 0.76, 0.77, 0.81, 0.82, 0.85, 0.70, 0.71, 0.72, + 0.78, 0.73, 0.77, 0.73, 0.79, 0.82, 0.76, 0.83, + 0.90, 0.84, 1.18, 0.98, 1.03, 0.92, 0.95, 0.90, + 0.86, 1.32, 1.45, 1.15, 1.53, 1.27, 0.99, 1.42, + 1.65, 1.58, 1.93, 1.83, 1.94, 1.81, 1.88, 1.74, + 1.70, 1.19, 1.17, 1.44, 1.11, 1.15, 1.36, 1.41, + 1.61, 1.81, 1.67, 1.22, 1.34, 1.50, 1.42, 1.65, + 1.61, 1.82, 1.91, 1.75, 1.80, 1.89, 1.89, 1.98, + 1.99, 1.94, 1.98, 1.92, 1.87, 0.86, 0.95, 0.92, + 1.14, 0.98, 1.03, 0.79, 0.84, 0.77, 0.97, 0.90, + 0.89, 0.76, 0.82, 0.82, 0.74, 0.72, 0.71, 0.98, + 0.89, 0.97, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00 + }, + +// 4 + { 1.60, 1.44, 1.68, 1.22, 1.49, 1.71, 0.93, 0.99, + 0.99, 1.23, 1.22, 1.60, 1.68, 1.44, 1.49, 1.40, + 1.14, 1.19, 0.89, 0.96, 0.89, 0.97, 0.89, 0.91, + 0.98, 0.82, 0.76, 0.82, 0.71, 0.72, 0.73, 0.76, + 0.79, 0.86, 0.83, 0.91, 0.83, 0.89, 0.72, 0.76, + 0.76, 0.89, 0.89, 0.82, 0.82, 0.98, 0.96, 0.97, + 1.14, 1.40, 1.19, 0.94, 1.00, 1.07, 1.37, 1.21, + 1.48, 1.30, 1.57, 1.61, 1.37, 0.86, 0.83, 0.91, + 0.82, 0.82, 0.88, 0.89, 0.96, 1.14, 0.98, 0.70, + 0.72, 0.73, 0.77, 0.76, 0.79, 0.70, 0.72, 0.71, + 0.82, 0.77, 0.80, 0.74, 0.79, 0.80, 0.74, 0.87, + 0.93, 0.85, 1.23, 1.02, 1.02, 0.93, 0.93, 0.87, + 0.85, 1.30, 1.35, 1.07, 1.38, 1.11, 0.94, 1.47, + 1.71, 1.56, 1.97, 1.88, 1.92, 1.79, 1.79, 1.59, + 1.60, 1.30, 1.35, 1.56, 1.37, 1.38, 1.59, 1.60, + 1.79, 1.92, 1.79, 1.48, 1.57, 1.72, 1.61, 1.78, + 1.79, 1.93, 1.99, 1.90, 1.86, 1.78, 1.86, 1.93, + 1.99, 1.97, 1.90, 1.79, 1.72, 0.94, 1.07, 1.00, + 1.37, 1.21, 1.30, 0.86, 0.91, 0.83, 1.14, 0.98, + 0.96, 0.82, 0.88, 0.89, 0.79, 0.76, 0.73, 1.07, + 0.94, 1.11, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00 + }, + +// 5 + { 1.74, 1.57, 1.76, 1.33, 1.54, 1.71, 0.94, 1.05, + 0.99, 1.26, 1.16, 1.46, 1.60, 1.34, 1.46, 1.59, + 1.37, 1.37, 0.97, 1.11, 0.96, 1.10, 0.95, 0.94, + 1.08, 0.89, 0.82, 0.88, 0.72, 0.76, 0.75, 0.80, + 0.80, 0.88, 0.87, 0.91, 0.83, 0.87, 0.72, 0.76, + 0.74, 0.83, 0.84, 0.78, 0.79, 0.96, 0.89, 0.92, + 0.98, 1.23, 1.05, 0.86, 0.92, 0.95, 1.11, 0.98, + 1.22, 1.03, 1.34, 1.42, 1.14, 0.79, 0.77, 0.84, + 0.78, 0.76, 0.82, 0.82, 0.89, 0.97, 0.90, 0.70, + 0.71, 0.71, 0.73, 0.72, 0.74, 0.73, 0.76, 0.72, + 0.86, 0.81, 0.82, 0.76, 0.79, 0.77, 0.73, 0.90, + 0.95, 0.86, 1.18, 1.03, 0.98, 0.92, 0.90, 0.83, + 0.84, 1.19, 1.17, 0.98, 1.15, 0.97, 0.89, 1.42, + 1.65, 1.44, 1.93, 1.83, 1.81, 1.67, 1.61, 1.36, + 1.41, 1.32, 1.45, 1.58, 1.57, 1.53, 1.74, 1.70, + 1.88, 1.94, 1.81, 1.69, 1.77, 1.87, 1.79, 1.89, + 1.92, 1.98, 1.99, 1.98, 1.89, 1.65, 1.80, 1.82, + 1.91, 1.94, 1.75, 1.61, 1.50, 1.07, 1.34, 1.27, + 1.60, 1.45, 1.55, 0.93, 0.99, 0.90, 1.35, 1.18, + 1.07, 0.87, 0.93, 0.96, 0.85, 0.82, 0.77, 1.15, + 0.99, 1.27, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00 + }, + +// 6 + { 1.86, 1.71, 1.82, 1.48, 1.62, 1.71, 0.98, 1.20, + 1.05, 1.34, 1.17, 1.34, 1.53, 1.27, 1.46, 1.77, + 1.60, 1.57, 1.16, 1.38, 1.12, 1.35, 1.06, 1.00, + 1.28, 0.97, 0.89, 0.95, 0.76, 0.81, 0.79, 0.86, + 0.85, 0.92, 0.93, 0.93, 0.85, 0.87, 0.74, 0.78, + 0.74, 0.79, 0.82, 0.76, 0.79, 0.96, 0.85, 0.90, + 0.94, 1.09, 0.99, 0.81, 0.85, 0.89, 0.95, 0.90, + 0.99, 0.94, 1.10, 1.24, 0.98, 0.75, 0.73, 0.78, + 0.74, 0.72, 0.77, 0.76, 0.82, 0.89, 0.83, 0.73, + 0.71, 0.71, 0.71, 0.70, 0.72, 0.77, 0.80, 0.74, + 0.90, 0.85, 0.84, 0.78, 0.79, 0.75, 0.73, 0.92, + 0.95, 0.86, 1.05, 0.99, 0.94, 0.90, 0.86, 0.79, + 0.81, 1.00, 0.98, 0.91, 0.96, 0.89, 0.83, 1.27, + 1.50, 1.23, 1.80, 1.69, 1.63, 1.46, 1.37, 1.09, + 1.16, 1.24, 1.44, 1.49, 1.69, 1.59, 1.80, 1.69, + 1.87, 1.86, 1.72, 1.82, 1.91, 1.94, 1.92, 1.95, + 1.99, 1.98, 1.91, 1.97, 1.89, 1.51, 1.72, 1.67, + 1.77, 1.86, 1.55, 1.41, 1.25, 1.33, 1.58, 1.50, + 1.80, 1.63, 1.74, 1.04, 1.21, 0.97, 1.48, 1.37, + 1.21, 0.93, 0.97, 1.05, 0.92, 0.88, 0.84, 1.14, + 1.02, 1.34, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00 + }, + +// 7 + { 1.94, 1.84, 1.87, 1.64, 1.71, 1.71, 1.14, 1.38, + 1.19, 1.46, 1.23, 1.26, 1.48, 1.26, 1.50, 1.91, + 1.80, 1.76, 1.41, 1.61, 1.39, 1.59, 1.33, 1.24, + 1.51, 1.18, 0.97, 1.11, 0.82, 0.88, 0.86, 0.94, + 0.92, 0.99, 1.03, 0.98, 0.91, 0.90, 0.79, 0.84, + 0.77, 0.79, 0.84, 0.77, 0.83, 0.99, 0.85, 0.91, + 0.92, 1.02, 1.00, 0.79, 0.80, 0.86, 0.88, 0.84, + 0.92, 0.88, 0.97, 1.10, 0.94, 0.74, 0.71, 0.74, + 0.72, 0.70, 0.73, 0.72, 0.76, 0.82, 0.77, 0.77, + 0.73, 0.74, 0.71, 0.70, 0.73, 0.83, 0.85, 0.78, + 0.92, 0.88, 0.86, 0.81, 0.79, 0.74, 0.75, 0.92, + 0.93, 0.85, 0.96, 0.94, 0.88, 0.86, 0.81, 0.75, + 0.79, 0.93, 0.90, 0.85, 0.88, 0.82, 0.77, 1.05, + 1.27, 0.99, 1.60, 1.47, 1.39, 1.20, 1.11, 0.95, + 0.97, 1.08, 1.33, 1.31, 1.70, 1.55, 1.76, 1.57, + 1.76, 1.70, 1.54, 1.85, 1.97, 1.91, 1.99, 1.97, + 1.99, 1.91, 1.77, 1.88, 1.85, 1.39, 1.64, 1.51, + 1.58, 1.74, 1.32, 1.22, 1.01, 1.54, 1.76, 1.65, + 1.93, 1.70, 1.85, 1.28, 1.39, 1.09, 1.52, 1.48, + 1.26, 0.97, 0.99, 1.18, 1.00, 0.93, 0.90, 1.05, + 1.01, 1.31, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00 + }, + +// 8 + { 1.97, 1.92, 1.88, 1.79, 1.79, 1.71, 1.37, 1.59, + 1.38, 1.60, 1.35, 1.23, 1.47, 1.30, 1.56, 1.99, + 1.93, 1.90, 1.60, 1.78, 1.61, 1.79, 1.57, 1.48, + 1.72, 1.40, 1.14, 1.37, 0.89, 0.96, 0.94, 1.07, + 1.00, 1.21, 1.30, 1.14, 0.98, 0.96, 0.86, 0.91, + 0.83, 0.82, 0.88, 0.82, 0.89, 1.11, 0.87, 0.94, + 0.93, 1.02, 1.07, 0.80, 0.79, 0.85, 0.82, 0.80, + 0.87, 0.85, 0.93, 1.02, 0.93, 0.77, 0.72, 0.74, + 0.71, 0.70, 0.70, 0.71, 0.72, 0.77, 0.74, 0.82, + 0.76, 0.79, 0.72, 0.73, 0.76, 0.89, 0.89, 0.82, + 0.93, 0.91, 0.86, 0.83, 0.79, 0.73, 0.76, 0.91, + 0.89, 0.83, 0.89, 0.89, 0.82, 0.82, 0.76, 0.72, + 0.76, 0.86, 0.83, 0.79, 0.82, 0.76, 0.73, 0.94, + 1.00, 0.91, 1.37, 1.21, 1.14, 0.98, 0.96, 0.88, + 0.89, 0.96, 1.14, 1.07, 1.60, 1.40, 1.61, 1.37, + 1.57, 1.48, 1.30, 1.78, 1.93, 1.79, 1.99, 1.92, + 1.90, 1.79, 1.59, 1.72, 1.79, 1.30, 1.56, 1.35, + 1.38, 1.60, 1.11, 1.07, 0.94, 1.68, 1.86, 1.71, + 1.97, 1.68, 1.86, 1.44, 1.49, 1.22, 1.44, 1.49, + 1.22, 0.99, 0.99, 1.23, 1.19, 0.98, 0.97, 0.97, + 0.98, 1.19, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00 + }, + +// 9 + { 1.94, 1.97, 1.87, 1.91, 1.85, 1.71, 1.60, 1.77, + 1.58, 1.74, 1.51, 1.26, 1.48, 1.39, 1.64, 1.99, + 1.97, 1.99, 1.70, 1.85, 1.76, 1.91, 1.76, 1.70, + 1.88, 1.55, 1.33, 1.57, 0.96, 1.08, 1.05, 1.31, + 1.27, 1.47, 1.54, 1.39, 1.20, 1.11, 0.93, 0.99, + 0.90, 0.88, 0.95, 0.88, 0.97, 1.32, 0.92, 1.01, + 0.97, 1.10, 1.22, 0.84, 0.80, 0.88, 0.79, 0.79, + 0.85, 0.86, 0.92, 1.02, 0.94, 0.82, 0.76, 0.77, + 0.72, 0.73, 0.70, 0.72, 0.71, 0.74, 0.74, 0.88, + 0.81, 0.85, 0.75, 0.77, 0.82, 0.94, 0.93, 0.86, + 0.92, 0.92, 0.86, 0.85, 0.79, 0.74, 0.79, 0.88, + 0.85, 0.81, 0.82, 0.83, 0.77, 0.78, 0.73, 0.71, + 0.75, 0.79, 0.77, 0.74, 0.77, 0.73, 0.70, 0.86, + 0.92, 0.84, 1.14, 0.99, 0.98, 0.91, 0.90, 0.84, + 0.83, 0.88, 0.97, 0.94, 1.41, 1.18, 1.39, 1.11, + 1.33, 1.24, 1.03, 1.61, 1.80, 1.59, 1.91, 1.84, + 1.76, 1.64, 1.38, 1.51, 1.71, 1.26, 1.50, 1.23, + 1.19, 1.46, 0.99, 1.00, 0.91, 1.70, 1.85, 1.65, + 1.93, 1.54, 1.76, 1.52, 1.48, 1.26, 1.28, 1.39, + 1.09, 0.99, 0.97, 1.18, 1.31, 1.01, 1.05, 0.90, + 0.93, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00 + }, + +// 10 + { 1.86, 1.95, 1.82, 1.98, 1.89, 1.71, 1.80, 1.91, + 1.77, 1.86, 1.67, 1.34, 1.53, 1.51, 1.72, 1.92, + 1.91, 1.99, 1.69, 1.82, 1.80, 1.94, 1.87, 1.86, + 1.97, 1.59, 1.44, 1.69, 1.05, 1.24, 1.27, 1.49, + 1.50, 1.69, 1.72, 1.63, 1.46, 1.37, 1.00, 1.23, + 0.98, 0.95, 1.09, 0.96, 1.16, 1.55, 0.99, 1.25, + 1.10, 1.24, 1.41, 0.90, 0.85, 0.94, 0.79, 0.81, + 0.85, 0.89, 0.94, 1.09, 0.98, 0.89, 0.82, 0.83, + 0.74, 0.77, 0.72, 0.76, 0.73, 0.75, 0.78, 0.94, + 0.86, 0.91, 0.79, 0.83, 0.89, 0.99, 0.95, 0.90, + 0.90, 0.92, 0.84, 0.86, 0.79, 0.75, 0.81, 0.85, + 0.80, 0.78, 0.76, 0.77, 0.73, 0.74, 0.71, 0.71, + 0.73, 0.74, 0.74, 0.71, 0.76, 0.72, 0.70, 0.79, + 0.85, 0.78, 0.98, 0.92, 0.93, 0.85, 0.87, 0.82, + 0.79, 0.81, 0.89, 0.86, 1.16, 0.97, 1.12, 0.95, + 1.06, 1.00, 0.93, 1.38, 1.60, 1.35, 1.77, 1.71, + 1.57, 1.48, 1.20, 1.28, 1.62, 1.27, 1.46, 1.17, + 1.05, 1.34, 0.96, 0.99, 0.90, 1.63, 1.74, 1.50, + 1.80, 1.33, 1.58, 1.48, 1.37, 1.21, 1.04, 1.21, + 0.97, 0.97, 0.93, 1.05, 1.34, 1.02, 1.14, 0.84, + 0.88, 0.92, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00 + }, + +// 11 + { 1.74, 1.89, 1.76, 1.98, 1.89, 1.71, 1.93, 1.99, + 1.91, 1.94, 1.82, 1.46, 1.60, 1.65, 1.80, 1.79, + 1.77, 1.92, 1.57, 1.69, 1.74, 1.87, 1.88, 1.94, + 1.98, 1.53, 1.45, 1.70, 1.18, 1.32, 1.42, 1.58, + 1.65, 1.83, 1.81, 1.81, 1.67, 1.61, 1.19, 1.44, + 1.17, 1.11, 1.36, 1.15, 1.41, 1.75, 1.22, 1.50, + 1.34, 1.42, 1.61, 0.98, 0.92, 1.03, 0.83, 0.86, + 0.89, 0.95, 0.98, 1.23, 1.14, 0.97, 0.89, 0.90, + 0.78, 0.82, 0.76, 0.82, 0.77, 0.79, 0.84, 0.98, + 0.90, 0.98, 0.83, 0.89, 0.97, 1.03, 0.95, 0.92, + 0.86, 0.90, 0.82, 0.86, 0.79, 0.77, 0.84, 0.81, + 0.76, 0.76, 0.72, 0.73, 0.70, 0.72, 0.71, 0.73, + 0.73, 0.72, 0.74, 0.71, 0.78, 0.74, 0.72, 0.75, + 0.80, 0.76, 0.94, 0.88, 0.91, 0.83, 0.87, 0.84, + 0.79, 0.76, 0.82, 0.80, 0.97, 0.89, 0.96, 0.88, + 0.95, 0.94, 0.87, 1.11, 1.37, 1.10, 1.59, 1.57, + 1.37, 1.33, 1.05, 1.08, 1.54, 1.34, 1.46, 1.16, + 0.99, 1.26, 0.96, 1.05, 0.92, 1.45, 1.55, 1.27, + 1.60, 1.07, 1.34, 1.35, 1.18, 1.07, 0.93, 0.99, + 0.90, 0.93, 0.87, 0.96, 1.27, 0.99, 1.15, 0.77, + 0.82, 0.85, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00 + }, + +// 12 + { 1.60, 1.78, 1.68, 1.93, 1.86, 1.71, 1.97, 1.99, + 1.99, 1.97, 1.93, 1.60, 1.68, 1.78, 1.86, 1.61, + 1.57, 1.79, 1.37, 1.48, 1.59, 1.72, 1.79, 1.92, + 1.90, 1.38, 1.35, 1.60, 1.23, 1.30, 1.47, 1.56, + 1.71, 1.88, 1.79, 1.92, 1.79, 1.79, 1.30, 1.56, + 1.35, 1.37, 1.59, 1.38, 1.60, 1.90, 1.48, 1.72, + 1.57, 1.61, 1.79, 1.21, 1.00, 1.30, 0.89, 0.94, + 0.96, 1.07, 1.14, 1.40, 1.37, 1.14, 0.96, 0.98, + 0.82, 0.88, 0.82, 0.89, 0.83, 0.86, 0.91, 1.02, + 0.93, 1.07, 0.87, 0.94, 1.11, 1.02, 0.93, 0.93, + 0.82, 0.87, 0.80, 0.85, 0.79, 0.80, 0.85, 0.77, + 0.72, 0.74, 0.71, 0.70, 0.70, 0.71, 0.72, 0.77, + 0.74, 0.72, 0.76, 0.73, 0.82, 0.79, 0.76, 0.73, + 0.79, 0.76, 0.93, 0.86, 0.91, 0.83, 0.89, 0.89, + 0.82, 0.72, 0.76, 0.76, 0.89, 0.82, 0.89, 0.82, + 0.89, 0.91, 0.83, 0.96, 1.14, 0.97, 1.40, 1.44, + 1.19, 1.22, 0.99, 0.98, 1.49, 1.44, 1.49, 1.22, + 0.99, 1.23, 0.98, 1.19, 0.97, 1.21, 1.30, 1.00, + 1.37, 0.94, 1.07, 1.14, 0.98, 0.96, 0.86, 0.91, + 0.83, 0.88, 0.82, 0.89, 1.11, 0.94, 1.07, 0.73, + 0.76, 0.79, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00 + }, + +// 13 + { 1.46, 1.65, 1.60, 1.82, 1.80, 1.71, 1.93, 1.91, + 1.99, 1.94, 1.98, 1.74, 1.76, 1.89, 1.89, 1.42, + 1.34, 1.61, 1.11, 1.22, 1.36, 1.50, 1.61, 1.81, + 1.75, 1.15, 1.17, 1.41, 1.18, 1.19, 1.42, 1.44, + 1.65, 1.83, 1.67, 1.94, 1.81, 1.88, 1.32, 1.58, + 1.45, 1.57, 1.74, 1.53, 1.70, 1.98, 1.69, 1.87, + 1.77, 1.79, 1.92, 1.45, 1.27, 1.55, 0.97, 1.07, + 1.11, 1.34, 1.37, 1.59, 1.60, 1.35, 1.07, 1.18, + 0.86, 0.93, 0.87, 0.96, 0.90, 0.93, 0.99, 1.03, + 0.95, 1.15, 0.90, 0.99, 1.27, 0.98, 0.90, 0.92, + 0.78, 0.83, 0.77, 0.84, 0.79, 0.82, 0.86, 0.73, + 0.71, 0.73, 0.72, 0.70, 0.73, 0.72, 0.76, 0.81, + 0.76, 0.76, 0.82, 0.77, 0.89, 0.85, 0.82, 0.75, + 0.80, 0.80, 0.94, 0.88, 0.94, 0.87, 0.95, 0.96, + 0.88, 0.72, 0.74, 0.76, 0.83, 0.78, 0.84, 0.79, + 0.87, 0.91, 0.83, 0.89, 0.98, 0.92, 1.23, 1.34, + 1.05, 1.16, 0.99, 0.96, 1.46, 1.57, 1.54, 1.33, + 1.05, 1.26, 1.08, 1.37, 1.10, 0.98, 1.03, 0.92, + 1.14, 0.86, 0.95, 0.97, 0.90, 0.89, 0.79, 0.84, + 0.77, 0.82, 0.76, 0.82, 0.97, 0.89, 0.98, 0.71, + 0.72, 0.74, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00 + }, + +// 14 + { 1.34, 1.51, 1.53, 1.67, 1.72, 1.71, 1.80, 1.77, + 1.91, 1.86, 1.98, 1.86, 1.82, 1.95, 1.89, 1.24, + 1.10, 1.41, 0.95, 0.99, 1.09, 1.25, 1.37, 1.63, + 1.55, 0.96, 0.98, 1.16, 1.05, 1.00, 1.27, 1.23, + 1.50, 1.69, 1.46, 1.86, 1.72, 1.87, 1.24, 1.49, + 1.44, 1.69, 1.80, 1.59, 1.69, 1.97, 1.82, 1.94, + 1.91, 1.92, 1.99, 1.63, 1.50, 1.74, 1.16, 1.33, + 1.38, 1.58, 1.60, 1.77, 1.80, 1.48, 1.21, 1.37, + 0.90, 0.97, 0.93, 1.05, 0.97, 1.04, 1.21, 0.99, + 0.95, 1.14, 0.92, 1.02, 1.34, 0.94, 0.86, 0.90, + 0.74, 0.79, 0.75, 0.81, 0.79, 0.84, 0.86, 0.71, + 0.71, 0.73, 0.76, 0.73, 0.77, 0.74, 0.80, 0.85, + 0.78, 0.81, 0.89, 0.84, 0.97, 0.92, 0.88, 0.79, + 0.85, 0.86, 0.98, 0.92, 1.00, 0.93, 1.06, 1.12, + 0.95, 0.74, 0.74, 0.78, 0.79, 0.76, 0.82, 0.79, + 0.87, 0.93, 0.85, 0.85, 0.94, 0.90, 1.09, 1.27, + 0.99, 1.17, 1.05, 0.96, 1.46, 1.71, 1.62, 1.48, + 1.20, 1.34, 1.28, 1.57, 1.35, 0.90, 0.94, 0.85, + 0.98, 0.81, 0.89, 0.89, 0.83, 0.82, 0.75, 0.78, + 0.73, 0.77, 0.72, 0.76, 0.89, 0.83, 0.91, 0.71, + 0.70, 0.72, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00 + }, + +// 15 + { 1.26, 1.39, 1.48, 1.51, 1.64, 1.71, 1.60, 1.58, + 1.77, 1.74, 1.91, 1.94, 1.87, 1.97, 1.85, 1.10, + 0.97, 1.22, 0.88, 0.92, 0.95, 1.01, 1.11, 1.39, + 1.32, 0.88, 0.90, 0.97, 0.96, 0.93, 1.05, 0.99, + 1.27, 1.47, 1.20, 1.70, 1.54, 1.76, 1.08, 1.31, + 1.33, 1.70, 1.76, 1.55, 1.57, 1.88, 1.85, 1.91, + 1.97, 1.99, 1.99, 1.70, 1.65, 1.85, 1.41, 1.54, + 1.61, 1.76, 1.80, 1.91, 1.93, 1.52, 1.26, 1.48, + 0.92, 0.99, 0.97, 1.18, 1.09, 1.28, 1.39, 0.94, + 0.93, 1.05, 0.92, 1.01, 1.31, 0.88, 0.81, 0.86, + 0.72, 0.75, 0.74, 0.79, 0.79, 0.86, 0.85, 0.71, + 0.73, 0.75, 0.82, 0.77, 0.83, 0.78, 0.85, 0.88, + 0.81, 0.88, 0.97, 0.90, 1.18, 1.00, 0.93, 0.86, + 0.92, 0.94, 1.14, 0.99, 1.24, 1.03, 1.33, 1.39, + 1.11, 0.79, 0.77, 0.84, 0.79, 0.77, 0.84, 0.83, + 0.90, 0.98, 0.91, 0.85, 0.92, 0.91, 1.02, 1.26, + 1.00, 1.23, 1.19, 0.99, 1.50, 1.84, 1.71, 1.64, + 1.38, 1.46, 1.51, 1.76, 1.59, 0.84, 0.88, 0.80, + 0.94, 0.79, 0.86, 0.82, 0.77, 0.76, 0.74, 0.74, + 0.71, 0.73, 0.70, 0.72, 0.82, 0.77, 0.85, 0.74, + 0.70, 0.73, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, + 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00 + } + diff --git a/engine/Quake/anorms.h b/engine/Quake/anorms.h new file mode 100644 index 0000000..35a903e --- /dev/null +++ b/engine/Quake/anorms.h @@ -0,0 +1,182 @@ +/* + * anorms.h + * + * Copyright (C) 1996-1997 Id Software, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + + { -0.525731, 0.000000, 0.850651 }, + { -0.442863, 0.238856, 0.864188 }, + { -0.295242, 0.000000, 0.955423 }, + { -0.309017, 0.500000, 0.809017 }, + { -0.162460, 0.262866, 0.951056 }, + { 0.000000, 0.000000, 1.000000 }, + { 0.000000, 0.850651, 0.525731 }, + { -0.147621, 0.716567, 0.681718 }, + { 0.147621, 0.716567, 0.681718 }, + { 0.000000, 0.525731, 0.850651 }, + { 0.309017, 0.500000, 0.809017 }, + { 0.525731, 0.000000, 0.850651 }, + { 0.295242, 0.000000, 0.955423 }, + { 0.442863, 0.238856, 0.864188 }, + { 0.162460, 0.262866, 0.951056 }, + { -0.681718, 0.147621, 0.716567 }, + { -0.809017, 0.309017, 0.500000 }, + { -0.587785, 0.425325, 0.688191 }, + { -0.850651, 0.525731, 0.000000 }, + { -0.864188, 0.442863, 0.238856 }, + { -0.716567, 0.681718, 0.147621 }, + { -0.688191, 0.587785, 0.425325 }, + { -0.500000, 0.809017, 0.309017 }, + { -0.238856, 0.864188, 0.442863 }, + { -0.425325, 0.688191, 0.587785 }, + { -0.716567, 0.681718, -0.147621 }, + { -0.500000, 0.809017, -0.309017 }, + { -0.525731, 0.850651, 0.000000 }, + { 0.000000, 0.850651, -0.525731 }, + { -0.238856, 0.864188, -0.442863 }, + { 0.000000, 0.955423, -0.295242 }, + { -0.262866, 0.951056, -0.162460 }, + { 0.000000, 1.000000, 0.000000 }, + { 0.000000, 0.955423, 0.295242 }, + { -0.262866, 0.951056, 0.162460 }, + { 0.238856, 0.864188, 0.442863 }, + { 0.262866, 0.951056, 0.162460 }, + { 0.500000, 0.809017, 0.309017 }, + { 0.238856, 0.864188, -0.442863 }, + { 0.262866, 0.951056, -0.162460 }, + { 0.500000, 0.809017, -0.309017 }, + { 0.850651, 0.525731, 0.000000 }, + { 0.716567, 0.681718, 0.147621 }, + { 0.716567, 0.681718, -0.147621 }, + { 0.525731, 0.850651, 0.000000 }, + { 0.425325, 0.688191, 0.587785 }, + { 0.864188, 0.442863, 0.238856 }, + { 0.688191, 0.587785, 0.425325 }, + { 0.809017, 0.309017, 0.500000 }, + { 0.681718, 0.147621, 0.716567 }, + { 0.587785, 0.425325, 0.688191 }, + { 0.955423, 0.295242, 0.000000 }, + { 1.000000, 0.000000, 0.000000 }, + { 0.951056, 0.162460, 0.262866 }, + { 0.850651, -0.525731, 0.000000 }, + { 0.955423, -0.295242, 0.000000 }, + { 0.864188, -0.442863, 0.238856 }, + { 0.951056, -0.162460, 0.262866 }, + { 0.809017, -0.309017, 0.500000 }, + { 0.681718, -0.147621, 0.716567 }, + { 0.850651, 0.000000, 0.525731 }, + { 0.864188, 0.442863, -0.238856 }, + { 0.809017, 0.309017, -0.500000 }, + { 0.951056, 0.162460, -0.262866 }, + { 0.525731, 0.000000, -0.850651 }, + { 0.681718, 0.147621, -0.716567 }, + { 0.681718, -0.147621, -0.716567 }, + { 0.850651, 0.000000, -0.525731 }, + { 0.809017, -0.309017, -0.500000 }, + { 0.864188, -0.442863, -0.238856 }, + { 0.951056, -0.162460, -0.262866 }, + { 0.147621, 0.716567, -0.681718 }, + { 0.309017, 0.500000, -0.809017 }, + { 0.425325, 0.688191, -0.587785 }, + { 0.442863, 0.238856, -0.864188 }, + { 0.587785, 0.425325, -0.688191 }, + { 0.688191, 0.587785, -0.425325 }, + { -0.147621, 0.716567, -0.681718 }, + { -0.309017, 0.500000, -0.809017 }, + { 0.000000, 0.525731, -0.850651 }, + { -0.525731, 0.000000, -0.850651 }, + { -0.442863, 0.238856, -0.864188 }, + { -0.295242, 0.000000, -0.955423 }, + { -0.162460, 0.262866, -0.951056 }, + { 0.000000, 0.000000, -1.000000 }, + { 0.295242, 0.000000, -0.955423 }, + { 0.162460, 0.262866, -0.951056 }, + { -0.442863, -0.238856, -0.864188 }, + { -0.309017, -0.500000, -0.809017 }, + { -0.162460, -0.262866, -0.951056 }, + { 0.000000, -0.850651, -0.525731 }, + { -0.147621, -0.716567, -0.681718 }, + { 0.147621, -0.716567, -0.681718 }, + { 0.000000, -0.525731, -0.850651 }, + { 0.309017, -0.500000, -0.809017 }, + { 0.442863, -0.238856, -0.864188 }, + { 0.162460, -0.262866, -0.951056 }, + { 0.238856, -0.864188, -0.442863 }, + { 0.500000, -0.809017, -0.309017 }, + { 0.425325, -0.688191, -0.587785 }, + { 0.716567, -0.681718, -0.147621 }, + { 0.688191, -0.587785, -0.425325 }, + { 0.587785, -0.425325, -0.688191 }, + { 0.000000, -0.955423, -0.295242 }, + { 0.000000, -1.000000, 0.000000 }, + { 0.262866, -0.951056, -0.162460 }, + { 0.000000, -0.850651, 0.525731 }, + { 0.000000, -0.955423, 0.295242 }, + { 0.238856, -0.864188, 0.442863 }, + { 0.262866, -0.951056, 0.162460 }, + { 0.500000, -0.809017, 0.309017 }, + { 0.716567, -0.681718, 0.147621 }, + { 0.525731, -0.850651, 0.000000 }, + { -0.238856, -0.864188, -0.442863 }, + { -0.500000, -0.809017, -0.309017 }, + { -0.262866, -0.951056, -0.162460 }, + { -0.850651, -0.525731, 0.000000 }, + { -0.716567, -0.681718, -0.147621 }, + { -0.716567, -0.681718, 0.147621 }, + { -0.525731, -0.850651, 0.000000 }, + { -0.500000, -0.809017, 0.309017 }, + { -0.238856, -0.864188, 0.442863 }, + { -0.262866, -0.951056, 0.162460 }, + { -0.864188, -0.442863, 0.238856 }, + { -0.809017, -0.309017, 0.500000 }, + { -0.688191, -0.587785, 0.425325 }, + { -0.681718, -0.147621, 0.716567 }, + { -0.442863, -0.238856, 0.864188 }, + { -0.587785, -0.425325, 0.688191 }, + { -0.309017, -0.500000, 0.809017 }, + { -0.147621, -0.716567, 0.681718 }, + { -0.425325, -0.688191, 0.587785 }, + { -0.162460, -0.262866, 0.951056 }, + { 0.442863, -0.238856, 0.864188 }, + { 0.162460, -0.262866, 0.951056 }, + { 0.309017, -0.500000, 0.809017 }, + { 0.147621, -0.716567, 0.681718 }, + { 0.000000, -0.525731, 0.850651 }, + { 0.425325, -0.688191, 0.587785 }, + { 0.587785, -0.425325, 0.688191 }, + { 0.688191, -0.587785, 0.425325 }, + { -0.955423, 0.295242, 0.000000 }, + { -0.951056, 0.162460, 0.262866 }, + { -1.000000, 0.000000, 0.000000 }, + { -0.850651, 0.000000, 0.525731 }, + { -0.955423, -0.295242, 0.000000 }, + { -0.951056, -0.162460, 0.262866 }, + { -0.864188, 0.442863, -0.238856 }, + { -0.951056, 0.162460, -0.262866 }, + { -0.809017, 0.309017, -0.500000 }, + { -0.864188, -0.442863, -0.238856 }, + { -0.951056, -0.162460, -0.262866 }, + { -0.809017, -0.309017, -0.500000 }, + { -0.681718, 0.147621, -0.716567 }, + { -0.681718, -0.147621, -0.716567 }, + { -0.850651, 0.000000, -0.525731 }, + { -0.688191, 0.587785, -0.425325 }, + { -0.587785, 0.425325, -0.688191 }, + { -0.425325, 0.688191, -0.587785 }, + { -0.425325, -0.688191, -0.587785 }, + { -0.587785, -0.425325, -0.688191 }, + { -0.688191, -0.587785, -0.425325 }, diff --git a/engine/Quake/arch_def.h b/engine/Quake/arch_def.h new file mode 100644 index 0000000..4a27d9a --- /dev/null +++ b/engine/Quake/arch_def.h @@ -0,0 +1,170 @@ +/* + * arch_def.h + * platform specific definitions + * - standalone header + * - doesn't and must not include any other headers + * - shouldn't depend on compiler.h, q_stdinc.h, or + * any other headers + * + * Copyright (C) 2007-2016 O.Sezer + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef ARCHDEFS_H +#define ARCHDEFS_H + + +#if defined(__DJGPP__) || defined(__MSDOS__) || defined(__DOS__) || defined(_MSDOS) + +# if !defined(PLATFORM_DOS) +# define PLATFORM_DOS 1 +# endif + +#elif defined(__OS2__) || defined(__EMX__) + +# if !defined(PLATFORM_OS2) +# define PLATFORM_OS2 1 +# endif + +#elif defined(_WIN32) || defined(__WIN32__) || defined(_WIN64) || defined(__NT__) || defined(_Windows) + +# if !defined(PLATFORM_WINDOWS) +# define PLATFORM_WINDOWS 1 +# endif + +#elif defined(__APPLE__) && defined(__MACH__) /* Mac OS X */ + +# if !defined(PLATFORM_OSX) +# define PLATFORM_OSX 1 +# endif + +#elif defined(macintosh) /* Mac OS classic */ + +# if !defined(PLATFORM_MAC) +# define PLATFORM_MAC 1 +# endif + +#elif defined(__MORPHOS__) || defined(__AROS__) || defined(AMIGAOS) || \ + defined(__amigaos__) || defined(__amigaos4__) ||defined(__amigados__) || \ + defined(AMIGA) || defined(_AMIGA) || defined(__AMIGA__) + +# if !defined(PLATFORM_AMIGA) +# define PLATFORM_AMIGA 1 +# endif + +#elif defined(__riscos__) + +# if !defined(PLATFORM_RISCOS) +# define PLATFORM_RISCOS 1 +# endif + +#else /* here goes the unix platforms */ + +#if defined(__unix) || defined(__unix__) || defined(unix) || \ + defined(__linux__) || defined(__linux) || \ + defined(__FreeBSD__) || defined(__DragonFly__) || \ + defined(__FreeBSD_kernel__) /* Debian GNU/kFreeBSD */ || \ + defined(__OpenBSD__) || defined(__NetBSD__) || \ + defined(__hpux) || defined(__hpux__) || defined(_hpux) || \ + defined(__sun) || defined(sun) || \ + defined(__sgi) || defined(sgi) || defined(__sgi__) || \ + defined(__GNU__) /* GNU/Hurd */ || \ + defined(__QNX__) || defined(__QNXNTO__) +# if !defined(PLATFORM_UNIX) +# define PLATFORM_UNIX 1 +# endif +#endif + +#endif /* PLATFORM_xxx */ + + +#if defined (PLATFORM_OSX) /* OS X is unix-based */ +# if !defined(PLATFORM_UNIX) +# define PLATFORM_UNIX 2 +# endif +#endif /* OS X -> PLATFORM_UNIX */ + + +#if defined(__FreeBSD__) || defined(__DragonFly__) || \ + defined(__FreeBSD_kernel__) /* Debian GNU/kFreeBSD */ || \ + defined(__OpenBSD__) || defined(__NetBSD__) +# if !defined(PLATFORM_BSD) +# define PLATFORM_BSD 1 +# endif +#endif /* PLATFORM_BSD (for convenience) */ + + +#if defined(PLATFORM_AMIGA) && !defined(PLATFORM_AMIGAOS3) +# if !defined(__MORPHOS__) && !defined(__AROS__) && !defined(__amigaos4__) +# define PLATFORM_AMIGAOS3 1 +# endif +#endif /* PLATFORM_AMIGAOS3 (for convenience) */ + + +#if defined(_WIN64) +# define PLATFORM_STRING "Win64" +#elif defined(PLATFORM_WINDOWS) +# define PLATFORM_STRING "Windows" +#elif defined(PLATFORM_DOS) +# define PLATFORM_STRING "DOS" +#elif defined(PLATFORM_OS2) +# define PLATFORM_STRING "OS/2" +#elif defined(__linux__) || defined(__linux) +# define PLATFORM_STRING "Linux" +#elif defined(__DragonFly__) +# define PLATFORM_STRING "DragonFly" +#elif defined(__FreeBSD__) +# define PLATFORM_STRING "FreeBSD" +#elif defined(__NetBSD__) +# define PLATFORM_STRING "NetBSD" +#elif defined(__OpenBSD__) +# define PLATFORM_STRING "OpenBSD" +#elif defined(__MORPHOS__) +# define PLATFORM_STRING "MorphOS" +#elif defined(__AROS__) +# define PLATFORM_STRING "AROS" +#elif defined(__amigaos4__) +# define PLATFORM_STRING "AmigaOS4" +#elif defined(PLATFORM_AMIGA) +# define PLATFORM_STRING "AmigaOS" +#elif defined(__QNX__) || defined(__QNXNTO__) +# define PLATFORM_STRING "QNX" +#elif defined(PLATFORM_OSX) +# define PLATFORM_STRING "MacOSX" +#elif defined(PLATFORM_MAC) +# define PLATFORM_STRING "MacOS" +#elif defined(__hpux) || defined(__hpux__) || defined(_hpux) +# define PLATFORM_STRING "HP-UX" +#elif (defined(__sun) || defined(sun)) && (defined(__svr4__) || defined(__SVR4)) +# define PLATFORM_STRING "Solaris" +#elif defined(__sun) || defined(sun) +# define PLATFORM_STRING "SunOS" +#elif defined(__sgi) || defined(sgi) || defined(__sgi__) +# define PLATFORM_STRING "Irix" +#elif defined(PLATFORM_RISCOS) +# define PLATFORM_STRING "RiscOS" +#elif defined(__GNU__) +# define PLATFORM_STRING "GNU/Hurd" +#elif defined(PLATFORM_UNIX) +# define PLATFORM_STRING "Unix" +#else +# define PLATFORM_STRING "Unknown" +# warning "Platform is UNKNOWN." +#endif /* PLATFORM_STRING */ + +#endif /* ARCHDEFS_H */ + diff --git a/engine/Quake/bgmusic.c b/engine/Quake/bgmusic.c new file mode 100644 index 0000000..65df3ca --- /dev/null +++ b/engine/Quake/bgmusic.c @@ -0,0 +1,469 @@ +/* + * Background music handling for Quakespasm (adapted from uHexen2) + * Handles streaming music as raw sound samples and runs the midi driver + * + * Copyright (C) 1999-2005 Id Software, Inc. + * Copyright (C) 2010-2018 O.Sezer + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#include "quakedef.h" +#include "snd_codec.h" +#include "bgmusic.h" + +#define MUSIC_DIRNAME "music" + +qboolean bgmloop; +cvar_t bgm_extmusic = {"bgm_extmusic", "1", CVAR_ARCHIVE}; + +static qboolean no_extmusic= false; +static float old_volume = -1.0f; + +typedef enum _bgm_player +{ + BGM_NONE = -1, + BGM_MIDIDRV = 1, + BGM_STREAMER +} bgm_player_t; + +typedef struct music_handler_s +{ + unsigned int type; /* 1U << n (see snd_codec.h) */ + bgm_player_t player; /* Enumerated bgm player type */ + int is_available; /* -1 means not present */ + const char *ext; /* Expected file extension */ + const char *dir; /* Where to look for music file */ + struct music_handler_s *next; +} music_handler_t; + +static music_handler_t wanted_handlers[] = +{ + { CODECTYPE_VORBIS,BGM_STREAMER,-1, "ogg", MUSIC_DIRNAME, NULL }, + { CODECTYPE_OPUS, BGM_STREAMER, -1, "opus", MUSIC_DIRNAME, NULL }, + { CODECTYPE_MP3, BGM_STREAMER, -1, "mp3", MUSIC_DIRNAME, NULL }, + { CODECTYPE_FLAC, BGM_STREAMER, -1, "flac", MUSIC_DIRNAME, NULL }, + { CODECTYPE_WAV, BGM_STREAMER, -1, "wav", MUSIC_DIRNAME, NULL }, + { CODECTYPE_MOD, BGM_STREAMER, -1, "it", MUSIC_DIRNAME, NULL }, + { CODECTYPE_MOD, BGM_STREAMER, -1, "s3m", MUSIC_DIRNAME, NULL }, + { CODECTYPE_MOD, BGM_STREAMER, -1, "xm", MUSIC_DIRNAME, NULL }, + { CODECTYPE_MOD, BGM_STREAMER, -1, "mod", MUSIC_DIRNAME, NULL }, + { CODECTYPE_UMX, BGM_STREAMER, -1, "umx", MUSIC_DIRNAME, NULL }, + { CODECTYPE_NONE, BGM_NONE, -1, NULL, NULL, NULL } +}; + +static music_handler_t *music_handlers = NULL; + +#define ANY_CODECTYPE 0xFFFFFFFF +#define CDRIP_TYPES (CODECTYPE_VORBIS | CODECTYPE_MP3 | CODECTYPE_FLAC | CODECTYPE_WAV | CODECTYPE_OPUS) +#define CDRIPTYPE(x) (((x) & CDRIP_TYPES) != 0) + +static snd_stream_t *bgmstream = NULL; + +static void BGM_Play_f (void) +{ + if (Cmd_Argc() == 2) + { + BGM_Play (Cmd_Argv(1)); + } + else + { + Con_Printf ("music \n"); + return; + } +} + +static void BGM_Pause_f (void) +{ + BGM_Pause (); +} + +static void BGM_Resume_f (void) +{ + BGM_Resume (); +} + +static void BGM_Loop_f (void) +{ + if (Cmd_Argc() == 2) + { + if (q_strcasecmp(Cmd_Argv(1), "0") == 0 || + q_strcasecmp(Cmd_Argv(1),"off") == 0) + bgmloop = false; + else if (q_strcasecmp(Cmd_Argv(1), "1") == 0 || + q_strcasecmp(Cmd_Argv(1),"on") == 0) + bgmloop = true; + else if (q_strcasecmp(Cmd_Argv(1),"toggle") == 0) + bgmloop = !bgmloop; + } + + if (bgmloop) + Con_Printf("Music will be looped\n"); + else + Con_Printf("Music will not be looped\n"); +} + +static void BGM_Stop_f (void) +{ + BGM_Stop(); +} + +qboolean BGM_Init (void) +{ + music_handler_t *handlers = NULL; + int i; + + Cvar_RegisterVariable(&bgm_extmusic); + Cmd_AddCommand("music", BGM_Play_f); + Cmd_AddCommand("music_pause", BGM_Pause_f); + Cmd_AddCommand("music_resume", BGM_Resume_f); + Cmd_AddCommand("music_loop", BGM_Loop_f); + Cmd_AddCommand("music_stop", BGM_Stop_f); + + if (COM_CheckParm("-noextmusic") != 0) + no_extmusic = true; + + bgmloop = true; + + for (i = 0; wanted_handlers[i].type != CODECTYPE_NONE; i++) + { + switch (wanted_handlers[i].player) + { + case BGM_MIDIDRV: + /* not supported in quake */ + break; + case BGM_STREAMER: + wanted_handlers[i].is_available = + S_CodecIsAvailable(wanted_handlers[i].type); + break; + case BGM_NONE: + default: + break; + } + if (wanted_handlers[i].is_available != -1) + { + if (handlers) + { + handlers->next = &wanted_handlers[i]; + handlers = handlers->next; + } + else + { + music_handlers = &wanted_handlers[i]; + handlers = music_handlers; + } + } + } + + return true; +} + +void BGM_Shutdown (void) +{ + BGM_Stop(); +/* sever our connections to + * midi_drv and snd_codec */ + music_handlers = NULL; +} + +static void BGM_Play_noext (const char *filename, unsigned int allowed_types) +{ + char tmp[MAX_QPATH]; + music_handler_t *handler; + + handler = music_handlers; + while (handler) + { + if (! (handler->type & allowed_types)) + { + handler = handler->next; + continue; + } + if (!handler->is_available) + { + handler = handler->next; + continue; + } + q_snprintf(tmp, sizeof(tmp), "%s/%s.%s", + handler->dir, filename, handler->ext); + switch (handler->player) + { + case BGM_MIDIDRV: + /* not supported in quake */ + break; + case BGM_STREAMER: + bgmstream = S_CodecOpenStreamType(tmp, handler->type); + if (bgmstream) + return; /* success */ + break; + case BGM_NONE: + default: + break; + } + handler = handler->next; + } + + Con_Printf("Couldn't handle music file %s\n", filename); +} + +void BGM_Play (const char *filename) +{ + char tmp[MAX_QPATH]; + const char *ext; + music_handler_t *handler; + + BGM_Stop(); + + if (music_handlers == NULL) + return; + + if (!filename || !*filename) + { + Con_DPrintf("null music file name\n"); + return; + } + + ext = COM_FileGetExtension(filename); + if (! *ext) /* try all things */ + { + BGM_Play_noext(filename, ANY_CODECTYPE); + return; + } + + handler = music_handlers; + while (handler) + { + if (handler->is_available && + !q_strcasecmp(ext, handler->ext)) + break; + handler = handler->next; + } + if (!handler) + { + Con_Printf("Unhandled extension for %s\n", filename); + return; + } + q_snprintf(tmp, sizeof(tmp), "%s/%s", handler->dir, filename); + switch (handler->player) + { + case BGM_MIDIDRV: + /* not supported in quake */ + break; + case BGM_STREAMER: + bgmstream = S_CodecOpenStreamType(tmp, handler->type); + if (bgmstream) + return; /* success */ + break; + case BGM_NONE: + default: + break; + } + + Con_Printf("Couldn't handle music file %s\n", filename); +} + +void BGM_PlayCDtrack (byte track, qboolean looping) +{ +/* instead of searching by the order of music_handlers, do so by + * the order of searchpath priority: the file from the searchpath + * with the highest path_id is most likely from our own gamedir + * itself. This way, if a mod has track02 as a *.mp3 file, which + * is below *.ogg in the music_handler order, the mp3 will still + * have priority over track02.ogg from, say, id1. + */ + char tmp[MAX_QPATH]; + const char *ext; + unsigned int path_id, prev_id, type; + music_handler_t *handler; + + BGM_Stop(); + if (CDAudio_Play(track, looping) == 0) + return; /* success */ + + if (music_handlers == NULL) + return; + + if (no_extmusic || !bgm_extmusic.value) + return; + + prev_id = 0; + type = 0; + ext = NULL; + handler = music_handlers; + while (handler) + { + if (! handler->is_available) + goto _next; + if (! CDRIPTYPE(handler->type)) + goto _next; + q_snprintf(tmp, sizeof(tmp), "%s/track%02d.%s", + MUSIC_DIRNAME, (int)track, handler->ext); + if (! COM_FileExists(tmp, &path_id)) + goto _next; + if (path_id > prev_id) + { + prev_id = path_id; + type = handler->type; + ext = handler->ext; + } + _next: + handler = handler->next; + } + if (ext == NULL) + Con_Printf("Couldn't find a cdrip for track %d\n", (int)track); + else + { + q_snprintf(tmp, sizeof(tmp), "%s/track%02d.%s", + MUSIC_DIRNAME, (int)track, ext); + bgmstream = S_CodecOpenStreamType(tmp, type); + if (! bgmstream) + Con_Printf("Couldn't handle music file %s\n", tmp); + } +} + +void BGM_Stop (void) +{ + if (bgmstream) + { + bgmstream->status = STREAM_NONE; + S_CodecCloseStream(bgmstream); + bgmstream = NULL; + s_rawend = 0; + } +} + +void BGM_Pause (void) +{ + if (bgmstream) + { + if (bgmstream->status == STREAM_PLAY) + bgmstream->status = STREAM_PAUSE; + } +} + +void BGM_Resume (void) +{ + if (bgmstream) + { + if (bgmstream->status == STREAM_PAUSE) + bgmstream->status = STREAM_PLAY; + } +} + +static void BGM_UpdateStream (void) +{ + qboolean did_rewind = false; + int res; /* Number of bytes read. */ + int bufferSamples; + int fileSamples; + int fileBytes; + byte raw[16384]; + + if (bgmstream->status != STREAM_PLAY) + return; + + /* don't bother playing anything if musicvolume is 0 */ + if (bgmvolume.value <= 0) + return; + + /* see how many samples should be copied into the raw buffer */ + if (s_rawend < paintedtime) + s_rawend = paintedtime; + + while (s_rawend < paintedtime + MAX_RAW_SAMPLES) + { + bufferSamples = MAX_RAW_SAMPLES - (s_rawend - paintedtime); + + /* decide how much data needs to be read from the file */ + fileSamples = bufferSamples * bgmstream->info.rate / shm->speed; + if (!fileSamples) + return; + + /* our max buffer size */ + fileBytes = fileSamples * (bgmstream->info.width * bgmstream->info.channels); + if (fileBytes > (int) sizeof(raw)) + { + fileBytes = (int) sizeof(raw); + fileSamples = fileBytes / + (bgmstream->info.width * bgmstream->info.channels); + } + + /* Read */ + res = S_CodecReadStream(bgmstream, fileBytes, raw); + if (res < fileBytes) + { + fileBytes = res; + fileSamples = res / (bgmstream->info.width * bgmstream->info.channels); + } + + if (res > 0) /* data: add to raw buffer */ + { + S_RawSamples(fileSamples, bgmstream->info.rate, + bgmstream->info.width, + bgmstream->info.channels, + raw, bgmvolume.value); + did_rewind = false; + } + else if (res == 0) /* EOF */ + { + if (bgmloop) + { + if (did_rewind) + { + Con_Printf("Stream keeps returning EOF.\n"); + BGM_Stop(); + return; + } + + res = S_CodecRewindStream(bgmstream); + if (res != 0) + { + Con_Printf("Stream seek error (%i), stopping.\n", res); + BGM_Stop(); + return; + } + did_rewind = true; + } + else + { + BGM_Stop(); + return; + } + } + else /* res < 0: some read error */ + { + Con_Printf("Stream read error (%i), stopping.\n", res); + BGM_Stop(); + return; + } + } +} + +void BGM_Update (void) +{ + if (old_volume != bgmvolume.value) + { + if (bgmvolume.value < 0) + Cvar_SetQuick (&bgmvolume, "0"); + else if (bgmvolume.value > 1) + Cvar_SetQuick (&bgmvolume, "1"); + old_volume = bgmvolume.value; + } + if (bgmstream) + BGM_UpdateStream (); +} + diff --git a/engine/Quake/bgmusic.h b/engine/Quake/bgmusic.h new file mode 100644 index 0000000..ec30820 --- /dev/null +++ b/engine/Quake/bgmusic.h @@ -0,0 +1,43 @@ +/* + * Background music handling for Quakespasm (adapted from uHexen2) + * Handles streaming music as raw sound samples and runs the midi driver + * + * Copyright (C) 1999-2005 Id Software, Inc. + * Copyright (C) 2010-2012 O.Sezer + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifndef _BGMUSIC_H_ +#define _BGMUSIC_H_ + +extern qboolean bgmloop; +extern cvar_t bgm_extmusic; + +qboolean BGM_Init (void); +void BGM_Shutdown (void); + +void BGM_Play (const char *filename); +void BGM_Stop (void); +void BGM_Update (void); +void BGM_Pause (void); +void BGM_Resume (void); + +void BGM_PlayCDtrack (byte track, qboolean looping); + +#endif /* _BGMUSIC_H_ */ + diff --git a/engine/code/bspfile.h b/engine/Quake/bspfile.h similarity index 69% rename from engine/code/bspfile.h rename to engine/Quake/bspfile.h index 2265079..6da832f 100644 --- a/engine/code/bspfile.h +++ b/engine/Quake/bspfile.h @@ -1,5 +1,7 @@ /* -Copyright (C) 1996-1997 Id Software, Inc. +Copyright (C) 1996-2001 Id Software, Inc. +Copyright (C) 2002-2009 John Fitzgibbons and others +Copyright (C) 2010-2014 QuakeSpasm developers This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -8,7 +10,7 @@ of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. @@ -18,30 +20,32 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#ifndef __BSPFILE_H +#define __BSPFILE_H // upper design bounds #define MAX_MAP_HULLS 4 -#define MAX_MAP_MODELS 1024 // jkrige - design bounds : 256 -#define MAX_MAP_BRUSHES 8192 // jkrige - design bounds : 4096 -#define MAX_MAP_ENTITIES 2048 // jkrige - design bounds : 1024 -#define MAX_MAP_ENTSTRING 0x40000 // jkrige - design bounds : 65536 +#define MAX_MAP_MODELS 256 +#define MAX_MAP_BRUSHES 4096 +#define MAX_MAP_ENTITIES 1024 +#define MAX_MAP_ENTSTRING 65536 -#define MAX_MAP_PLANES 65536 // jkrige - design bounds : 32767 -#define MAX_MAP_NODES 65536 // jkrige - design bounds : 32767 // because negative shorts are contents -#define MAX_MAP_CLIPNODES 65536 // jkrige - design bounds : 32767 // -#define MAX_MAP_LEAFS 16384 // jkrige - design bounds : 8192 +#define MAX_MAP_PLANES 32767 +#define MAX_MAP_NODES 32767 // because negative shorts are contents +#define MAX_MAP_CLIPNODES 32767 +//#define MAX_MAP_LEAFS 80000 //johnfitz -- was 8192 #define MAX_MAP_VERTS 65535 #define MAX_MAP_FACES 65535 #define MAX_MAP_MARKSURFACES 65535 -#define MAX_MAP_TEXINFO 8192 // jkrige - design bounds : 4096 +#define MAX_MAP_TEXINFO 4096 #define MAX_MAP_EDGES 256000 #define MAX_MAP_SURFEDGES 512000 -#define MAX_MAP_TEXTURES 1024 // jkrige - design bounds : 512 -#define MAX_MAP_MIPTEX 0x400000 // jkrige - design bounds : 0x200000 -#define MAX_MAP_LIGHTING 0x200000 // jkrige - design bounds : 0x100000 -#define MAX_MAP_VISIBILITY 0x200000 // jkrige - design bounds : 0x100000 +#define MAX_MAP_TEXTURES 512 +#define MAX_MAP_MIPTEX 0x200000 +#define MAX_MAP_LIGHTING 0x100000 +#define MAX_MAP_VISIBILITY 0x100000 #define MAX_MAP_PORTALS 65536 @@ -54,6 +58,14 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #define BSPVERSION 29 + +/* RMQ support (2PSB). 32bits instead of shorts for all but bbox sizes (which + * still use shorts) */ +#define BSP2VERSION_2PSB (('B' << 24) | ('S' << 16) | ('P' << 8) | '2') + +/* BSP2 support. 32bits instead of shorts for everything (bboxes use floats) */ +#define BSP2VERSION_BSP2 (('B' << 0) | ('S' << 8) | ('P' << 16) | ('2'<<24)) + #define TOOLVERSION 2 typedef struct @@ -90,7 +102,7 @@ typedef struct typedef struct { - int version; + int version; lump_t lumps[HEADER_LUMPS]; } dheader_t; @@ -133,7 +145,6 @@ typedef struct } dplane_t; - #define CONTENTS_EMPTY -1 #define CONTENTS_SOLID -2 #define CONTENTS_WATER -3 @@ -160,13 +171,39 @@ typedef struct short maxs[3]; unsigned short firstface; unsigned short numfaces; // counting both sides -} dnode_t; +} dsnode_t; + +typedef struct +{ + int planenum; + int children[2]; // negative numbers are -(leafs+1), not nodes + short mins[3]; // for sphere culling + short maxs[3]; + unsigned int firstface; + unsigned int numfaces; // counting both sides +} dl1node_t; + +typedef struct +{ + int planenum; + int children[2]; // negative numbers are -(leafs+1), not nodes + float mins[3]; // for sphere culling + float maxs[3]; + unsigned int firstface; + unsigned int numfaces; // counting both sides +} dl2node_t; typedef struct { int planenum; short children[2]; // negative numbers are contents -} dclipnode_t; +} dsclipnode_t; + +typedef struct +{ + int planenum; + int children[2]; // negative numbers are contents +} dlclipnode_t; typedef struct texinfo_s @@ -176,13 +213,19 @@ typedef struct texinfo_s int flags; } texinfo_t; #define TEX_SPECIAL 1 // sky or slime, no lightmap or 256 subdivision +#define TEX_MISSING 2 // johnfitz -- this texinfo does not have a texture // note that edge 0 is never used, because negative edge nums are used for // counterclockwise use of the edge in a face typedef struct { unsigned short v[2]; // vertex numbers -} dedge_t; +} dsedge_t; + +typedef struct +{ + unsigned int v[2]; // vertex numbers +} dledge_t; #define MAXLIGHTMAPS 4 typedef struct @@ -191,15 +234,27 @@ typedef struct short side; int firstedge; // we must support > 64k edges - short numedges; + short numedges; short texinfo; // lighting info byte styles[MAXLIGHTMAPS]; int lightofs; // start of [numstyles*surfsize] samples -} dface_t; +} dsface_t; +typedef struct +{ + int planenum; + int side; + int firstedge; // we must support > 64k edges + int numedges; + int texinfo; + +// lighting info + byte styles[MAXLIGHTMAPS]; + int lightofs; // start of [numstyles*surfsize] samples +} dlface_t; #define AMBIENT_WATER 0 #define AMBIENT_SKY 1 @@ -222,7 +277,35 @@ typedef struct unsigned short nummarksurfaces; byte ambient_level[NUM_AMBIENTS]; -} dleaf_t; +} dsleaf_t; + +typedef struct +{ + int contents; + int visofs; // -1 = no visibility info + + short mins[3]; // for frustum culling + short maxs[3]; + + unsigned int firstmarksurface; + unsigned int nummarksurfaces; + + byte ambient_level[NUM_AMBIENTS]; +} dl1leaf_t; + +typedef struct +{ + int contents; + int visofs; // -1 = no visibility info + + float mins[3]; // for frustum culling + float maxs[3]; + + unsigned int firstmarksurface; + unsigned int nummarksurfaces; + + byte ambient_level[NUM_AMBIENTS]; +} dl2leaf_t; //============================================================================ @@ -250,8 +333,8 @@ extern byte dtexdata[MAX_MAP_MIPTEX]; // (dmiptexlump_t) extern int entdatasize; extern char dentdata[MAX_MAP_ENTSTRING]; -extern int numleafs; -extern dleaf_t dleafs[MAX_MAP_LEAFS]; +//extern int numleafs; +//extern dleaf_t dleafs[MAX_MAP_LEAFS]; extern int numplanes; extern dplane_t dplanes[MAX_MAP_PLANES]; @@ -321,4 +404,7 @@ void GetVectorForKey (entity_t *ent, char *key, vec3_t vec); epair_t *ParseEpair (void); -#endif +#endif /* QUAKE_GAME */ + +#endif /* __BSPFILE_H */ + diff --git a/engine/Quake/cd_null.c b/engine/Quake/cd_null.c new file mode 100644 index 0000000..87afc7b --- /dev/null +++ b/engine/Quake/cd_null.c @@ -0,0 +1,53 @@ +/* + * cd_null.c + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + + +#include "quakedef.h" + +int CDAudio_Play(byte track, qboolean looping) +{ + return -1; +} + +void CDAudio_Stop(void) +{ +} + +void CDAudio_Pause(void) +{ +} + +void CDAudio_Resume(void) +{ +} + +void CDAudio_Update(void) +{ +} + +int CDAudio_Init(void) +{ + Con_Printf("CDAudio disabled at compile time\n"); + return -1; +} + +void CDAudio_Shutdown(void) +{ +} + diff --git a/engine/Quake/cd_sdl.c b/engine/Quake/cd_sdl.c new file mode 100644 index 0000000..69bd3fa --- /dev/null +++ b/engine/Quake/cd_sdl.c @@ -0,0 +1,593 @@ +/* + * cd_sdl.c + * + * Copyright (C) 1996-1997 Id Software, Inc. + * Taken from the Twilight project with modifications + * to make it work with Hexen II: Hammer of Thyrion. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + + +#if defined(SDL_FRAMEWORK) || defined(NO_SDL_CONFIG) +#if defined(USE_SDL2) +#include +#else +#include +#endif +#else +#include "SDL.h" +#endif + +#ifndef SDL_INIT_CDROM + +/* SDL dropped support for + cd audio since v1.3.0 */ +#pragma message("Warning: SDL CDAudio support disabled") +#include "cd_null.c" + +#else /* SDL_INIT_CDROM */ + +#include "quakedef.h" + +static qboolean cdValid = false; +static qboolean playing = false; +static qboolean wasPlaying = false; +static qboolean enabled = true; +static qboolean playLooping = false; +static byte remap[100]; +static byte playTrack; +static double endOfTrack = -1.0, pausetime = -1.0; +static SDL_CD *cd_handle; +static int cd_dev = -1; +static float old_cdvolume; +static qboolean hw_vol_works = true; + + +static void CDAudio_Eject(void) +{ + if (!cd_handle || !enabled) + return; + +#ifdef __linux__ + SDL_CDStop(cd_handle); /* see CDAudio_Stop() */ +#endif + if (SDL_CDEject(cd_handle) < 0) + Con_Printf ("Unable to eject CD-ROM: %s\n", SDL_GetError ()); +} + +static int CDAudio_GetAudioDiskInfo(void) +{ + cdValid = false; + + if (!cd_handle) + return -1; + + if ( ! CD_INDRIVE(SDL_CDStatus(cd_handle)) ) + return -1; + + cdValid = true; + + return 0; +} + +int CDAudio_Play(byte track, qboolean looping) +{ + int len_m, len_s, len_f; + + if (!cd_handle || !enabled) + return -1; + + if (!cdValid) + { + CDAudio_GetAudioDiskInfo(); + if (!cdValid) + return -1; + } + + track = remap[track]; + + if (track < 1 || track > cd_handle->numtracks) + { + Con_Printf ("CDAudio_Play: Bad track number %d.\n", track); + return -1; + } + + if (cd_handle->track[track-1].type == SDL_DATA_TRACK) + { + Con_Printf ("CDAudio_Play: track %d is not audio\n", track); + return -1; + } + + if (playing) + { + if (playTrack == track) + return 0; + CDAudio_Stop(); + } + + if (SDL_CDPlay(cd_handle, cd_handle->track[track-1].offset, cd_handle->track[track-1].length) < 0) + { + Con_Printf ("CDAudio_Play: Unable to play track %d: %s\n", track, SDL_GetError ()); + return -1; + } + + playLooping = looping; + playTrack = track; + playing = true; + + FRAMES_TO_MSF(cd_handle->track[track-1].length, &len_m, &len_s, &len_f); + endOfTrack = realtime + ((double)len_m * 60.0) + (double)len_s + (double)len_f / (double)CD_FPS; + + /* Add the pregap for the next track. This means that disc-at-once CDs + * won't loop smoothly, but they wouldn't anyway so it doesn't really + * matter. SDL doesn't give us pregap information anyway, so you'll + * just have to live with it. */ + endOfTrack += 2.0; + pausetime = -1.0; + + if (bgmvolume.value == 0) /* don't bother advancing */ + CDAudio_Pause (); + + return 0; +} + +void CDAudio_Stop(void) +{ + if (!cd_handle || !enabled) + return; + + if (!playing) + return; + +#ifdef __linux__ + /* Don't really stop, but just pause: On some devices, the CDROMSTOP + * ioctl causes any followup ioctls to fail for a considerable time. + * observed with a TSSTcorp CDW/DVD SH-M522C drive with TS05 and TS08 + * firmware versions running under a 2.6.27.25 kernel, and with a + * Samsung DVD r/w drive running under 2.6.35.6 kernel. + * Therefore, avoid dead stops if playback may be resumed shortly. */ + if (SDL_CDPause(cd_handle) < 0) + Con_Printf ("CDAudio_Stop: Unable to stop CD-ROM (%s)\n", SDL_GetError()); +#else + if (SDL_CDStop(cd_handle) < 0) + Con_Printf ("CDAudio_Stop: Unable to stop CD-ROM (%s)\n", SDL_GetError()); +#endif + + wasPlaying = false; + playing = false; + pausetime = -1.0; + endOfTrack = -1.0; +} + +void CDAudio_Pause(void) +{ + if (!cd_handle || !enabled) + return; + + if (!playing) + return; + + if (SDL_CDPause(cd_handle) < 0) + Con_Printf ("Unable to pause CD-ROM: %s\n", SDL_GetError()); + + wasPlaying = playing; + playing = false; + pausetime = realtime; +} + +void CDAudio_Resume(void) +{ + if (!cd_handle || !enabled) + return; + + if (!cdValid) + return; + + if (!wasPlaying) + return; + + if (SDL_CDResume(cd_handle) < 0) + Con_Printf ("Unable to resume CD-ROM: %s\n", SDL_GetError()); + playing = true; + endOfTrack += realtime - pausetime; + pausetime = -1.0; +} + +static int get_first_audiotrk (void) +{ + int i; + for (i = 0; i < cd_handle->numtracks; ++i) + if (cd_handle->track[i].type != SDL_DATA_TRACK) + return ++i; + return 1; +} + +static void CD_f (void) +{ + const char *command; + int ret, n; + + if (Cmd_Argc() < 2) + { + Con_Printf("commands:"); + Con_Printf("on, off, reset, remap, \n"); + Con_Printf("play, stop, loop, pause, resume\n"); + Con_Printf("eject, info, next, prev\n"); + return; + } + + command = Cmd_Argv (1); + + if (q_strcasecmp(command, "on") == 0) + { + enabled = true; + return; + } + + if (q_strcasecmp(command, "off") == 0) + { + if (playing) + CDAudio_Stop(); + enabled = false; + return; + } + + if (q_strcasecmp(command, "reset") == 0) + { + enabled = true; + if (playing) + CDAudio_Stop(); + for (n = 0; n < 100; n++) + remap[n] = n; + CDAudio_GetAudioDiskInfo(); + return; + } + + if (q_strcasecmp(command, "remap") == 0) + { + ret = Cmd_Argc() - 2; + if (ret <= 0) + { + for (n = 1; n < 100; n++) + if (remap[n] != n) + Con_Printf(" %u -> %u\n", n, remap[n]); + return; + } + for (n = 1; n <= ret; n++) + remap[n] = atoi(Cmd_Argv (n + 1)); + return; + } + + if (!cdValid) + { + CDAudio_GetAudioDiskInfo(); + if (!cdValid) + { + Con_Printf("No CD in player.\n"); + return; + } + } + + if (q_strcasecmp(command, "play") == 0) + { + n = atoi(Cmd_Argv (2)); + if (n == 0) + n = 1; + CDAudio_Play((byte)n, false); + return; + } + + if (q_strcasecmp(command, "loop") == 0) + { + CDAudio_Play((byte)atoi(Cmd_Argv (2)), true); + return; + } + + if (q_strcasecmp(command, "stop") == 0) + { + CDAudio_Stop(); + return; + } + + if (q_strcasecmp(command, "pause") == 0) + { + CDAudio_Pause(); + return; + } + + if (q_strcasecmp(command, "resume") == 0) + { + CDAudio_Resume(); + return; + } + + if (q_strcasecmp(command, "eject") == 0) + { + if (playing) + CDAudio_Stop(); + CDAudio_Eject(); + cdValid = false; + return; + } + + if (q_strcasecmp(command, "info") == 0) + { + int current_min, current_sec, current_frame; + int length_min, length_sec, length_frame; + + Con_Printf ("%u tracks\n", cd_handle->numtracks); + + if (playing) + Con_Printf("Currently %s track %u\n", playLooping ? "looping" : "playing", playTrack); + else if (wasPlaying) + Con_Printf("Paused %s track %u\n", playLooping ? "looping" : "playing", playTrack); + + if (playing || wasPlaying) + { + SDL_CDStatus(cd_handle); + FRAMES_TO_MSF(cd_handle->cur_frame, ¤t_min, ¤t_sec, ¤t_frame); + FRAMES_TO_MSF(cd_handle->track[playTrack-1].length, &length_min, &length_sec, &length_frame); + + Con_Printf ("Current position: %d:%02d.%02d (of %d:%02d.%02d)\n", + current_min, current_sec, current_frame * 60 / CD_FPS, + length_min, length_sec, length_frame * 60 / CD_FPS); + } + Con_Printf("Volume is %f\n", bgmvolume.value); + + return; + } + + if (q_strcasecmp(command, "next") == 0) + { + if (playTrack == cd_handle->numtracks) + playTrack = get_first_audiotrk() - 1; + CDAudio_Play(playTrack + 1, playLooping); + return; + } + + if (q_strcasecmp(command, "prev") == 0) + { + if (playTrack == get_first_audiotrk()) + playTrack = cd_handle->numtracks + 1; + CDAudio_Play(playTrack - 1, playLooping); + return; + } + + Con_Printf ("cd: unknown command \"%s\"\n", command); +} + +static qboolean CD_GetVolume (void *unused) +{ +/* FIXME: write proper code in here when SDL + supports cdrom volume control some day. */ + return false; +} + +static qboolean CD_SetVolume (void *unused) +{ +/* FIXME: write proper code in here when SDL + supports cdrom volume control some day. */ + return false; +} + +static qboolean CDAudio_SetVolume (float value) +{ + if (!cd_handle || !enabled) + return false; + + old_cdvolume = value; + + if (value == 0.0f) + CDAudio_Pause (); + else + CDAudio_Resume(); + + if (!hw_vol_works) + { + return false; + } + else + { +/* FIXME: write proper code in here when SDL + supports cdrom volume control some day. */ + return CD_SetVolume (NULL); + } +} + +void CDAudio_Update(void) +{ + CDstatus curstat; +/* static double lastchk;*/ + + if (!cd_handle || !enabled) + return; + + if (old_cdvolume != bgmvolume.value) + CDAudio_SetVolume (bgmvolume.value); + +/* if (playing && realtime > lastchk)*/ + if (playing && realtime > endOfTrack) + { + /* lastchk = realtime + 2;*/ /* two seconds between chks */ + curstat = SDL_CDStatus(cd_handle); + if (curstat != CD_PLAYING && curstat != CD_PAUSED) + { + playing = false; + endOfTrack = -1.0; + if (playLooping) + CDAudio_Play(playTrack, true); + } + } +} + +static const char *get_cddev_arg (const char *arg) +{ +#if defined(_WIN32) +/* arg should be like "D:\", make sure it is so, + * but tolerate args like "D" or "D:", as well. */ + static char drive[4]; + if (!arg || ! *arg) + return NULL; + if (arg[1] != '\0') + { + if (arg[1] != ':') + return NULL; + if (arg[2] != '\0') + { + if (arg[2] != '\\' && + arg[2] != '/') + return NULL; + if (arg[3] != '\0') + return NULL; + } + } + if (*arg >= 'A' && *arg <= 'Z') + { + drive[0] = *arg; + drive[1] = ':'; + drive[2] = '\\'; + drive[3] = '\0'; + return drive; + } + else if (*arg >= 'a' && *arg <= 'z') + { + /* make it uppercase for SDL */ + drive[0] = *arg - ('a' - 'A'); + drive[1] = ':'; + drive[2] = '\\'; + drive[3] = '\0'; + return drive; + } + return NULL; +#else + if (!arg || ! *arg) + return NULL; + return arg; +#endif +} + +static void export_cddev_arg (void) +{ +/* Bad ugly hack to workaround SDL's cdrom device detection. + * not needed for windows due to the way SDL_cdrom works. */ +#if !defined(_WIN32) + int i = COM_CheckParm("-cddev"); + if (i != 0 && i < com_argc - 1 && com_argv[i+1][0] != '\0') + { + static char arg[64]; + q_snprintf(arg, sizeof(arg), "SDL_CDROM=%s", com_argv[i+1]); + putenv(arg); + } +#endif +} + +int CDAudio_Init(void) +{ + int i, sdl_num_drives; + + if (safemode || COM_CheckParm("-nocdaudio")) + return -1; + + export_cddev_arg(); + + if (SDL_InitSubSystem(SDL_INIT_CDROM) < 0) + { + Con_Printf("Couldn't init SDL cdrom: %s\n", SDL_GetError()); + return -1; + } + + sdl_num_drives = SDL_CDNumDrives (); + Con_Printf ("SDL detected %d CD-ROM drive%c\n", sdl_num_drives, + sdl_num_drives == 1 ? ' ' : 's'); + + if (sdl_num_drives < 1) + return -1; + + if ((i = COM_CheckParm("-cddev")) != 0 && i < com_argc - 1) + { + const char *userdev = get_cddev_arg(com_argv[i+1]); + if (!userdev) + { + Con_Printf("Invalid argument to -cddev\n"); + return -1; + } + for (i = 0; i < sdl_num_drives; i++) + { + if (!q_strcasecmp(SDL_CDName(i), userdev)) + { + cd_dev = i; + break; + } + } + if (cd_dev == -1) + { + Con_Printf("SDL couldn't find cdrom device %s\n", userdev); + return -1; + } + } + + if (cd_dev == -1) + cd_dev = 0; /* default drive */ + + cd_handle = SDL_CDOpen(cd_dev); + if (!cd_handle) + { + Con_Printf ("CDAudio_Init: Unable to open CD-ROM drive %s (%s)\n", + SDL_CDName(cd_dev), SDL_GetError()); + return -1; + } + + for (i = 0; i < 100; i++) + remap[i] = i; + enabled = true; + old_cdvolume = bgmvolume.value; + + Con_Printf("CDAudio initialized (SDL, using %s)\n", SDL_CDName(cd_dev)); + + if (CDAudio_GetAudioDiskInfo()) + { + Con_Printf("CDAudio_Init: No CD in drive\n"); + cdValid = false; + } + + Cmd_AddCommand ("cd", CD_f); + + hw_vol_works = CD_GetVolume (NULL); /* no SDL support at present. */ + if (hw_vol_works) + hw_vol_works = CDAudio_SetVolume (bgmvolume.value); + + return 0; +} + +void CDAudio_Shutdown(void) +{ + if (!cd_handle) + return; + CDAudio_Stop(); + if (hw_vol_works) + CD_SetVolume (NULL); /* no SDL support at present. */ +#ifdef __linux__ + SDL_CDStop(cd_handle); /* see CDAudio_Stop() */ +#endif + SDL_CDClose(cd_handle); + cd_handle = NULL; + cd_dev = -1; + SDL_QuitSubSystem(SDL_INIT_CDROM); +} + +#endif /* SDL_INIT_CDROM */ + diff --git a/engine/code/cdaudio.h b/engine/Quake/cdaudio.h similarity index 57% rename from engine/code/cdaudio.h rename to engine/Quake/cdaudio.h index 3c466c2..7c8477f 100644 --- a/engine/code/cdaudio.h +++ b/engine/Quake/cdaudio.h @@ -1,5 +1,6 @@ /* -Copyright (C) 1996-1997 Id Software, Inc. +Copyright (C) 1996-2001 Id Software, Inc. +Copyright (C) 2010-2014 QuakeSpasm developers This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -8,7 +9,7 @@ of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. @@ -18,16 +19,17 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#ifndef UQE_FMOD_CDAUDIO +#ifndef __CDAUDIO_H +#define __CDAUDIO_H -int CDAudio_Init(void); -void CDAudio_Play(byte track, qboolean looping); -void CDAudio_Stop(void); -void CDAudio_Pause(void); -void CDAudio_Resume(void); -void CDAudio_Shutdown(void); -void CDAudio_Update(void); +int CDAudio_Init (void); +int CDAudio_Play (byte track, qboolean looping); + /* returns 0 for success, -1 for failure. */ +void CDAudio_Stop (void); +void CDAudio_Pause (void); +void CDAudio_Resume (void); +void CDAudio_Shutdown (void); +void CDAudio_Update (void); -void CDAudio_Activate(qboolean active); // jkrige - fmod sound system +#endif /* __CDAUDIO_H */ -#endif \ No newline at end of file diff --git a/engine/Quake/cfgfile.c b/engine/Quake/cfgfile.c new file mode 100644 index 0000000..3373db4 --- /dev/null +++ b/engine/Quake/cfgfile.c @@ -0,0 +1,175 @@ +/* + * cfgfile.c -- misc reads from the config file + * + * Copyright (C) 2008-2012 O.Sezer + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "quakedef.h" + + +static fshandle_t *cfg_file; + +/* +=================== +CFG_ReadCvars + +used for doing early reads from config.cfg searching the list +of given cvar names for the user-set values. a temporary +solution until we merge a better cvar system. +the num_vars argument must be the exact number of strings in the +array, otherwise I have nothing against going out of bounds. +=================== +*/ +void CFG_ReadCvars (const char **vars, int num_vars) +{ + char buff[1024], *tmp; + int i, j; + + if (!cfg_file || num_vars < 1) + return; + + j = 0; + + do { + i = 0; + memset (buff, 0, sizeof(buff)); + // we expect a line in the format that Cvar_WriteVariables + // writes to the config file. although I'm trying to be as + // much cautious as possible, if the user screws it up by + // editing it, it's his fault. + if (FS_fgets(buff, sizeof(buff), cfg_file)) + { + // remove end-of-line characters + while (buff[i]) + { + if (buff[i] == '\r' || buff[i] == '\n') + buff[i] = '\0'; + // while we're here, replace tabs with spaces + if (buff[i] == '\t') + buff[i] = ' '; + i++; + } + // go to the last character + while (buff[i] == 0 && i > 0) + i--; + // remove trailing spaces + while (i > 0) + { + if (buff[i] == ' ') + { + buff[i] = '\0'; + i--; + } + else + break; + } + + // the line must end with a quotation mark + if (buff[i] != '\"') + continue; + buff[i] = '\0'; + + for (i = 0; i < num_vars && vars[i]; i++) + { + // look for the cvar name + one space + tmp = strstr(buff, va("%s ",vars[i])); + if (tmp != buff) + continue; + // locate the first quotation mark + tmp = strchr(buff, '\"'); + if (tmp) + { + Cvar_Set (vars[i], tmp + 1); + j++; + break; + } + } + } + + if (j == num_vars) + break; + + } while (!FS_feof(cfg_file) && !FS_ferror(cfg_file)); + + FS_rewind (cfg_file); +} + +/* +=================== +CFG_ReadCvarOverrides + +convenience function, reading the "+" command line override +values of cvars in the given list. doesn't do anything with +the config file. +=================== +*/ +void CFG_ReadCvarOverrides (const char **vars, int num_vars) +{ + char buff[64]; + int i, j; + + if (num_vars < 1) + return; + + buff[0] = '+'; + + for (i = 0; i < num_vars; i++) + { + q_strlcpy (&buff[1], vars[i], sizeof(buff) - 1); + j = COM_CheckParm(buff); + if (j != 0 && j < com_argc - 1) + { + if (com_argv[j + 1][0] != '-' && com_argv[j + 1][0] != '+') + Cvar_Set(vars[i], com_argv[j + 1]); + } + } +} + +void CFG_CloseConfig (void) +{ + if (cfg_file) + { + FS_fclose(cfg_file); + Z_Free(cfg_file); + cfg_file = NULL; + } +} + +int CFG_OpenConfig (const char *cfg_name) +{ + FILE *f; + long length; + qboolean pak; + + CFG_CloseConfig (); + + length = (long) COM_FOpenFile (cfg_name, &f, NULL); + pak = file_from_pak; + if (length == -1) + return -1; + + cfg_file = (fshandle_t *) Z_Malloc(sizeof(fshandle_t)); + cfg_file->file = f; + cfg_file->start = ftell(f); + cfg_file->pos = 0; + cfg_file->length = length; + cfg_file->pak = pak; + + return 0; +} + diff --git a/engine/Quake/cfgfile.h b/engine/Quake/cfgfile.h new file mode 100644 index 0000000..dbe8f39 --- /dev/null +++ b/engine/Quake/cfgfile.h @@ -0,0 +1,42 @@ +/* + * cfgfile.h -- misc reads from the config file + * + * Copyright (C) 2008-2012 O.Sezer + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef __CFGFILE_H +#define __CFGFILE_H + +int CFG_OpenConfig (const char *cfg_name); +// opens the given config file. only one open config file is +// kept: previosly opened one, if any, will be closed. + +void CFG_CloseConfig (void); +// closes the currently open config file. + +void CFG_ReadCvars (const char **vars, int num_vars); +// reads the values of cvars in the given list from the opened +// config file. + +void CFG_ReadCvarOverrides (const char **vars, int num_vars); +// convenience function, reading the "+" command line override +// values of cvars in the given list. doesn't do anything with +// the config file. call this after CFG_ReadCvars() and before +// locking your cvars. + +#endif /* __CFGFILE_H */ diff --git a/engine/Quake/chase.c b/engine/Quake/chase.c new file mode 100644 index 0000000..6ddd25b --- /dev/null +++ b/engine/Quake/chase.c @@ -0,0 +1,118 @@ +/* +Copyright (C) 1996-2001 Id Software, Inc. +Copyright (C) 2002-2009 John Fitzgibbons and others +Copyright (C) 2010-2014 QuakeSpasm developers + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ +// chase.c -- chase camera code + +#include "quakedef.h" + +cvar_t chase_back = {"chase_back", "100", CVAR_NONE}; +cvar_t chase_up = {"chase_up", "16", CVAR_NONE}; +cvar_t chase_right = {"chase_right", "0", CVAR_NONE}; +cvar_t chase_active = {"chase_active", "0", CVAR_NONE}; + +/* +============== +Chase_Init +============== +*/ +void Chase_Init (void) +{ + Cvar_RegisterVariable (&chase_back); + Cvar_RegisterVariable (&chase_up); + Cvar_RegisterVariable (&chase_right); + Cvar_RegisterVariable (&chase_active); +} + +/* +============== +TraceLine + +TODO: impact on bmodels, monsters +============== +*/ +void TraceLine (vec3_t start, vec3_t end, vec3_t impact) +{ + trace_t trace; + + memset (&trace, 0, sizeof(trace)); + SV_RecursiveHullCheck (cl.worldmodel->hulls, 0, 0, 1, start, end, &trace); + + VectorCopy (trace.endpos, impact); +} + +/* +============== +Chase_UpdateForClient -- johnfitz -- orient client based on camera. called after input +============== +*/ +void Chase_UpdateForClient (void) +{ + //place camera + + //assign client angles to camera + + //see where camera points + + //adjust client angles to point at the same place +} + +/* +============== +Chase_UpdateForDrawing -- johnfitz -- orient camera based on client. called before drawing + +TODO: stay at least 8 units away from all walls in this leaf +============== +*/ +void Chase_UpdateForDrawing (void) +{ + int i; + vec3_t forward, up, right; + vec3_t ideal, crosshair, temp; + + AngleVectors (cl.viewangles, forward, right, up); + + // calc ideal camera location before checking for walls + for (i=0 ; i<3 ; i++) + ideal[i] = cl.viewent.origin[i] + - forward[i]*chase_back.value + + right[i]*chase_right.value; + //+ up[i]*chase_up.value; + ideal[2] = cl.viewent.origin[2] + chase_up.value; + + // make sure camera is not in or behind a wall + TraceLine(r_refdef.vieworg, ideal, temp); + if (VectorLength(temp) != 0) + VectorCopy(temp, ideal); + + // place camera + VectorCopy (ideal, r_refdef.vieworg); + + // find the spot the player is looking at + VectorMA (cl.viewent.origin, 4096, forward, temp); + TraceLine (cl.viewent.origin, temp, crosshair); + + // calculate camera angles to look at the same spot + VectorSubtract (crosshair, r_refdef.vieworg, temp); + VectorAngles (temp, r_refdef.viewangles); + if (r_refdef.viewangles[PITCH] == 90 || r_refdef.viewangles[PITCH] == -90) + r_refdef.viewangles[YAW] = cl.viewangles[YAW]; +} + diff --git a/engine/Quake/cl_demo.c b/engine/Quake/cl_demo.c new file mode 100644 index 0000000..d1ad2bf --- /dev/null +++ b/engine/Quake/cl_demo.c @@ -0,0 +1,504 @@ +/* +Copyright (C) 1996-2001 Id Software, Inc. +Copyright (C) 2010-2014 QuakeSpasm developers + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#include "quakedef.h" + +static void CL_FinishTimeDemo (void); + +/* +============================================================================== + +DEMO CODE + +When a demo is playing back, all NET_SendMessages are skipped, and +NET_GetMessages are read from the demo file. + +Whenever cl.time gets past the last received message, another message is +read from the demo file. +============================================================================== +*/ + +// from ProQuake: space to fill out the demo header for record at any time +static byte demo_head[3][MAX_MSGLEN]; +static int demo_head_size[2]; + +/* +============== +CL_StopPlayback + +Called when a demo file runs out, or the user starts a game +============== +*/ +void CL_StopPlayback (void) +{ + if (!cls.demoplayback) + return; + + fclose (cls.demofile); + cls.demoplayback = false; + cls.demopaused = false; + cls.demofile = NULL; + cls.state = ca_disconnected; + + if (cls.timedemo) + CL_FinishTimeDemo (); +} + +/* +==================== +CL_WriteDemoMessage + +Dumps the current net message, prefixed by the length and view angles +==================== +*/ +static void CL_WriteDemoMessage (void) +{ + int len; + int i; + float f; + + len = LittleLong (net_message.cursize); + fwrite (&len, 4, 1, cls.demofile); + for (i = 0; i < 3; i++) + { + f = LittleFloat (cl.viewangles[i]); + fwrite (&f, 4, 1, cls.demofile); + } + fwrite (net_message.data, net_message.cursize, 1, cls.demofile); + fflush (cls.demofile); +} + +static int CL_GetDemoMessage (void) +{ + int r, i; + float f; + + if (cls.demopaused) + return 0; + + // decide if it is time to grab the next message + if (cls.signon == SIGNONS) // always grab until fully connected + { + if (cls.timedemo) + { + if (host_framecount == cls.td_lastframe) + return 0; // already read this frame's message + cls.td_lastframe = host_framecount; + // if this is the second frame, grab the real td_starttime + // so the bogus time on the first frame doesn't count + if (host_framecount == cls.td_startframe + 1) + cls.td_starttime = realtime; + } + else if (/* cl.time > 0 && */ cl.time <= cl.mtime[0]) + { + return 0; // don't need another message yet + } + } + +// get the next message + fread (&net_message.cursize, 4, 1, cls.demofile); + VectorCopy (cl.mviewangles[0], cl.mviewangles[1]); + for (i = 0 ; i < 3 ; i++) + { + r = fread (&f, 4, 1, cls.demofile); + cl.mviewangles[0][i] = LittleFloat (f); + } + + net_message.cursize = LittleLong (net_message.cursize); + if (net_message.cursize > MAX_MSGLEN) + Sys_Error ("Demo message > MAX_MSGLEN"); + r = fread (net_message.data, net_message.cursize, 1, cls.demofile); + if (r != 1) + { + CL_StopPlayback (); + return 0; + } + + return 1; +} + +/* +==================== +CL_GetMessage + +Handles recording and playback of demos, on top of NET_ code +==================== +*/ +int CL_GetMessage (void) +{ + int r; + + if (cls.demoplayback) + return CL_GetDemoMessage (); + + while (1) + { + r = NET_GetMessage (cls.netcon); + + if (r != 1 && r != 2) + return r; + + // discard nop keepalive message + if (net_message.cursize == 1 && net_message.data[0] == svc_nop) + Con_Printf ("<-- server to client keepalive\n"); + else + break; + } + + if (cls.demorecording) + CL_WriteDemoMessage (); + + if (cls.signon < 2) + { + // record messages before full connection, so that a + // demo record can happen after connection is done + memcpy(demo_head[cls.signon], net_message.data, net_message.cursize); + demo_head_size[cls.signon] = net_message.cursize; + } + + return r; +} + + +/* +==================== +CL_Stop_f + +stop recording a demo +==================== +*/ +void CL_Stop_f (void) +{ + if (cmd_source != src_command) + return; + + if (!cls.demorecording) + { + Con_Printf ("Not recording a demo.\n"); + return; + } + +// write a disconnect message to the demo file + SZ_Clear (&net_message); + MSG_WriteByte (&net_message, svc_disconnect); + CL_WriteDemoMessage (); + +// finish up + fclose (cls.demofile); + cls.demofile = NULL; + cls.demorecording = false; + Con_Printf ("Completed demo\n"); + +// ericw -- update demo tab-completion list + DemoList_Rebuild (); +} + +/* +==================== +CL_Record_f + +record [cd track] +==================== +*/ +void CL_Record_f (void) +{ + int c; + char name[MAX_OSPATH]; + int track; + + if (cmd_source != src_command) + return; + + if (cls.demoplayback) + { + Con_Printf ("Can't record during demo playback\n"); + return; + } + + if (cls.demorecording) + CL_Stop_f(); + + c = Cmd_Argc(); + if (c != 2 && c != 3 && c != 4) + { + Con_Printf ("record [ [cd track]]\n"); + return; + } + + if (strstr(Cmd_Argv(1), "..")) + { + Con_Printf ("Relative pathnames are not allowed.\n"); + return; + } + + if (c == 2 && cls.state == ca_connected) + { +#if 0 + Con_Printf("Can not record - already connected to server\nClient demo recording must be started before connecting\n"); + return; +#endif + if (cls.signon < 2) + { + Con_Printf("Can't record - try again when connected\n"); + return; + } + } + +// write the forced cd track number, or -1 + if (c == 4) + { + track = atoi(Cmd_Argv(3)); + Con_Printf ("Forcing CD track to %i\n", cls.forcetrack); + } + else + { + track = -1; + } + + q_snprintf (name, sizeof(name), "%s/%s", com_gamedir, Cmd_Argv(1)); + +// start the map up + if (c > 2) + { + Cmd_ExecuteString ( va("map %s", Cmd_Argv(2)), src_command); + if (cls.state != ca_connected) + return; + } + +// open the demo file + COM_AddExtension (name, ".dem", sizeof(name)); + + Con_Printf ("recording to %s.\n", name); + cls.demofile = fopen (name, "wb"); + if (!cls.demofile) + { + Con_Printf ("ERROR: couldn't create %s\n", name); + return; + } + + cls.forcetrack = track; + fprintf (cls.demofile, "%i\n", cls.forcetrack); + + cls.demorecording = true; + + // from ProQuake: initialize the demo file if we're already connected + if (c == 2 && cls.state == ca_connected) + { + byte *data = net_message.data; + int cursize = net_message.cursize; + int i; + + for (i = 0; i < 2; i++) + { + net_message.data = demo_head[i]; + net_message.cursize = demo_head_size[i]; + CL_WriteDemoMessage(); + } + + net_message.data = demo_head[2]; + SZ_Clear (&net_message); + + // current names, colors, and frag counts + for (i = 0; i < cl.maxclients; i++) + { + MSG_WriteByte (&net_message, svc_updatename); + MSG_WriteByte (&net_message, i); + MSG_WriteString (&net_message, cl.scores[i].name); + MSG_WriteByte (&net_message, svc_updatefrags); + MSG_WriteByte (&net_message, i); + MSG_WriteShort (&net_message, cl.scores[i].frags); + MSG_WriteByte (&net_message, svc_updatecolors); + MSG_WriteByte (&net_message, i); + MSG_WriteByte (&net_message, cl.scores[i].colors); + } + + // send all current light styles + for (i = 0; i < MAX_LIGHTSTYLES; i++) + { + MSG_WriteByte (&net_message, svc_lightstyle); + MSG_WriteByte (&net_message, i); + MSG_WriteString (&net_message, cl_lightstyle[i].map); + } + + // what about the CD track or SVC fog... future consideration. + MSG_WriteByte (&net_message, svc_updatestat); + MSG_WriteByte (&net_message, STAT_TOTALSECRETS); + MSG_WriteLong (&net_message, cl.stats[STAT_TOTALSECRETS]); + + MSG_WriteByte (&net_message, svc_updatestat); + MSG_WriteByte (&net_message, STAT_TOTALMONSTERS); + MSG_WriteLong (&net_message, cl.stats[STAT_TOTALMONSTERS]); + + MSG_WriteByte (&net_message, svc_updatestat); + MSG_WriteByte (&net_message, STAT_SECRETS); + MSG_WriteLong (&net_message, cl.stats[STAT_SECRETS]); + + MSG_WriteByte (&net_message, svc_updatestat); + MSG_WriteByte (&net_message, STAT_MONSTERS); + MSG_WriteLong (&net_message, cl.stats[STAT_MONSTERS]); + + // view entity + MSG_WriteByte (&net_message, svc_setview); + MSG_WriteShort (&net_message, cl.viewentity); + + // signon + MSG_WriteByte (&net_message, svc_signonnum); + MSG_WriteByte (&net_message, 3); + + CL_WriteDemoMessage(); + + // restore net_message + net_message.data = data; + net_message.cursize = cursize; + } +} + + +/* +==================== +CL_PlayDemo_f + +play [demoname] +==================== +*/ +void CL_PlayDemo_f (void) +{ + char name[MAX_OSPATH]; + int i, c; + qboolean neg; + + if (cmd_source != src_command) + return; + + if (Cmd_Argc() != 2) + { + Con_Printf ("playdemo : plays a demo\n"); + return; + } + +// disconnect from server + CL_Disconnect (); + +// open the demo file + q_strlcpy (name, Cmd_Argv(1), sizeof(name)); + COM_AddExtension (name, ".dem", sizeof(name)); + + Con_Printf ("Playing demo from %s.\n", name); + + COM_FOpenFile (name, &cls.demofile, NULL); + if (!cls.demofile) + { + Con_Printf ("ERROR: couldn't open %s\n", name); + cls.demonum = -1; // stop demo loop + return; + } + +// ZOID, fscanf is evil +// O.S.: if a space character e.g. 0x20 (' ') follows '\n', +// fscanf skips that byte too and screws up further reads. +// fscanf (cls.demofile, "%i\n", &cls.forcetrack); + cls.forcetrack = 0; + c = 0; /* silence pesky compiler warnings */ + neg = false; + // read a decimal integer possibly with a leading '-', + // followed by a '\n': + for (i = 0; i < 13; i++) + { + c = getc(cls.demofile); + if (c == '\n') + break; + if (c == '-') { + neg = true; + continue; + } + // check for multiple '-' or legal digits? meh... + cls.forcetrack = cls.forcetrack * 10 + (c - '0'); + } + if (c != '\n') + { + fclose (cls.demofile); + cls.demofile = NULL; + cls.demonum = -1; // stop demo loop + Con_Printf ("ERROR: demo \"%s\" is invalid\n", name); + return; + } + if (neg) + cls.forcetrack = -cls.forcetrack; + + cls.demoplayback = true; + cls.demopaused = false; + cls.state = ca_connected; + +// get rid of the menu and/or console + key_dest = key_game; +} + +/* +==================== +CL_FinishTimeDemo + +==================== +*/ +static void CL_FinishTimeDemo (void) +{ + int frames; + float time; + + cls.timedemo = false; + +// the first frame didn't count + frames = (host_framecount - cls.td_startframe) - 1; + time = realtime - cls.td_starttime; + if (!time) + time = 1; + Con_Printf ("%i frames %5.1f seconds %5.1f fps\n", frames, time, frames/time); +} + +/* +==================== +CL_TimeDemo_f + +timedemo [demoname] +==================== +*/ +void CL_TimeDemo_f (void) +{ + if (cmd_source != src_command) + return; + + if (Cmd_Argc() != 2) + { + Con_Printf ("timedemo : gets demo speeds\n"); + return; + } + + CL_PlayDemo_f (); + if (!cls.demofile) + return; + +// cls.td_starttime will be grabbed at the second frame of the demo, so +// all the loading time doesn't get counted + + cls.timedemo = true; + cls.td_startframe = host_framecount; + cls.td_lastframe = -1; // get a new message this frame +} + diff --git a/engine/code/cl_input.c b/engine/Quake/cl_input.c similarity index 78% rename from engine/code/cl_input.c rename to engine/Quake/cl_input.c index aff2946..6e5fcdb 100644 --- a/engine/code/cl_input.c +++ b/engine/Quake/cl_input.c @@ -1,5 +1,7 @@ /* -Copyright (C) 1996-1997 Id Software, Inc. +Copyright (C) 1996-2001 Id Software, Inc. +Copyright (C) 2002-2009 John Fitzgibbons and others +Copyright (C) 2010-2014 QuakeSpasm developers This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -8,7 +10,7 @@ of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. @@ -24,6 +26,9 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "quakedef.h" +extern cvar_t cl_maxpitch; //johnfitz -- variable pitch clamping +extern cvar_t cl_minpitch; //johnfitz -- variable pitch clamping + /* =============================================================================== @@ -46,7 +51,7 @@ state bit 2 is edge triggered on the down to up transition */ -//kbutton_t /*in_mlook,*/ in_klook; // jkrige - mlook cvar, removed klook command +kbutton_t in_mlook, in_klook; kbutton_t in_left, in_right, in_forward, in_back; kbutton_t in_lookup, in_lookdown, in_moveleft, in_moveright; kbutton_t in_strafe, in_speed, in_use, in_jump, in_attack; @@ -58,7 +63,7 @@ int in_impulse; void KeyDown (kbutton_t *b) { int k; - char *c; + const char *c; c = Cmd_Argv(1); if (c[0]) @@ -68,7 +73,7 @@ void KeyDown (kbutton_t *b) if (k == b->down[0] || k == b->down[1]) return; // repeating key - + if (!b->down[0]) b->down[0] = k; else if (!b->down[1]) @@ -78,7 +83,7 @@ void KeyDown (kbutton_t *b) Con_Printf ("Three keys down for a button!\n"); return; } - + if (b->state & 1) return; // still down b->state |= 1 + 2; // down + impulse down @@ -87,8 +92,8 @@ void KeyDown (kbutton_t *b) void KeyUp (kbutton_t *b) { int k; - char *c; - + const char *c; + c = Cmd_Argv(1); if (c[0]) k = atoi(c); @@ -114,20 +119,14 @@ void KeyUp (kbutton_t *b) b->state |= 4; // impulse up } -// jkrige - removed klook command -//void IN_KLookDown (void) {KeyDown(&in_klook);} -//void IN_KLookUp (void) {KeyUp(&in_klook);} -// jkrige - removed klook command - -// jkrige - mlook cvar -/*void IN_MLookDown (void) {KeyDown(&in_mlook);} +void IN_KLookDown (void) {KeyDown(&in_klook);} +void IN_KLookUp (void) {KeyUp(&in_klook);} +void IN_MLookDown (void) {KeyDown(&in_mlook);} void IN_MLookUp (void) { -KeyUp(&in_mlook); -if ( !(in_mlook.state&1) && lookspring.value) - V_StartPitchDrift(); -}*/ -// jkrige - mlook cvar - + KeyUp(&in_mlook); + if ( !(in_mlook.state&1) && lookspring.value) + V_StartPitchDrift(); +} void IN_UpDown(void) {KeyDown(&in_up);} void IN_UpUp(void) {KeyUp(&in_up);} void IN_DownDown(void) {KeyDown(&in_down);} @@ -178,62 +177,62 @@ float CL_KeyState (kbutton_t *key) { float val; qboolean impulsedown, impulseup, down; - + impulsedown = key->state & 2; impulseup = key->state & 4; down = key->state & 1; val = 0; - + if (impulsedown && !impulseup) + { if (down) val = 0.5; // pressed and held this frame else val = 0; // I_Error (); + } if (impulseup && !impulsedown) + { if (down) val = 0; // I_Error (); else val = 0; // released this frame + } if (!impulsedown && !impulseup) + { if (down) val = 1.0; // held the entire frame else val = 0; // up the entire frame + } if (impulsedown && impulseup) + { if (down) val = 0.75; // released and re-pressed this frame else val = 0.25; // pressed and released this frame + } key->state &= 1; // clear impulses - + return val; } - - //========================================================================== -cvar_t cl_upspeed = {"cl_upspeed","200"}; -cvar_t cl_forwardspeed = {"cl_forwardspeed","200", true}; -cvar_t cl_backspeed = {"cl_backspeed","200", true}; - -// jkrige - reduced strafe speed -//cvar_t cl_sidespeed = {"cl_sidespeed","350"}; -cvar_t cl_sidespeed = {"cl_sidespeed","225"}; -// jkrige - reduced strafe speed +cvar_t cl_upspeed = {"cl_upspeed","200",CVAR_NONE}; +cvar_t cl_forwardspeed = {"cl_forwardspeed","200", CVAR_ARCHIVE}; +cvar_t cl_backspeed = {"cl_backspeed","200", CVAR_ARCHIVE}; +cvar_t cl_sidespeed = {"cl_sidespeed","350",CVAR_NONE}; +cvar_t cl_movespeedkey = {"cl_movespeedkey","2.0",CVAR_NONE}; -cvar_t cl_movespeedkey = {"cl_movespeedkey","2.0"}; +cvar_t cl_yawspeed = {"cl_yawspeed","140",CVAR_NONE}; +cvar_t cl_pitchspeed = {"cl_pitchspeed","150",CVAR_NONE}; -cvar_t cl_yawspeed = {"cl_yawspeed","140"}; -cvar_t cl_pitchspeed = {"cl_pitchspeed","150"}; +cvar_t cl_anglespeedkey = {"cl_anglespeedkey","1.5",CVAR_NONE}; -cvar_t cl_anglespeedkey = {"cl_anglespeedkey","1.5"}; - -cvar_t cl_mlook = {"cl_mlook", "1", true}; // jkrige - mlook cvar -cvar_t cl_slook = {"cl_slook", "0", true}; // jkrige - slook cvar +cvar_t cl_alwaysrun = {"cl_alwaysrun","0",CVAR_ARCHIVE}; // QuakeSpasm -- new always run /* ================ @@ -246,8 +245,8 @@ void CL_AdjustAngles (void) { float speed; float up, down; - - if (in_speed.state & 1) + + if ((in_speed.state & 1) ^ (cl_alwaysrun.value != 0.0)) speed = host_frametime * cl_anglespeedkey.value; else speed = host_frametime; @@ -258,35 +257,33 @@ void CL_AdjustAngles (void) cl.viewangles[YAW] += speed*cl_yawspeed.value*CL_KeyState (&in_left); cl.viewangles[YAW] = anglemod(cl.viewangles[YAW]); } - - // jkrige - removed klook command - /*if (in_klook.state & 1) + if (in_klook.state & 1) { V_StopPitchDrift (); cl.viewangles[PITCH] -= speed*cl_pitchspeed.value * CL_KeyState (&in_forward); cl.viewangles[PITCH] += speed*cl_pitchspeed.value * CL_KeyState (&in_back); - }*/ - // jkrige - removed klook command - + } + up = CL_KeyState (&in_lookup); down = CL_KeyState(&in_lookdown); - + cl.viewangles[PITCH] -= speed*cl_pitchspeed.value * up; cl.viewangles[PITCH] += speed*cl_pitchspeed.value * down; if (up || down) V_StopPitchDrift (); - - if (cl.viewangles[PITCH] > 80) - cl.viewangles[PITCH] = 80; - if (cl.viewangles[PITCH] < -70) - cl.viewangles[PITCH] = -70; + + //johnfitz -- variable pitch clamping + if (cl.viewangles[PITCH] > cl_maxpitch.value) + cl.viewangles[PITCH] = cl_maxpitch.value; + if (cl.viewangles[PITCH] < cl_minpitch.value) + cl.viewangles[PITCH] = cl_minpitch.value; + //johnfitz if (cl.viewangles[ROLL] > 50) cl.viewangles[ROLL] = 50; if (cl.viewangles[ROLL] < -50) cl.viewangles[ROLL] = -50; - } /* @@ -297,14 +294,14 @@ Send the intended movement message to the server ================ */ void CL_BaseMove (usercmd_t *cmd) -{ +{ if (cls.signon != SIGNONS) return; - + CL_AdjustAngles (); - + Q_memset (cmd, 0, sizeof(*cmd)); - + if (in_strafe.state & 1) { cmd->sidemove += cl_sidespeed.value * CL_KeyState (&in_right); @@ -317,90 +314,78 @@ void CL_BaseMove (usercmd_t *cmd) cmd->upmove += cl_upspeed.value * CL_KeyState (&in_up); cmd->upmove -= cl_upspeed.value * CL_KeyState (&in_down); - // jkrige - removed klook command - //if (! (in_klook.state & 1) ) - //{ + if (! (in_klook.state & 1) ) + { cmd->forwardmove += cl_forwardspeed.value * CL_KeyState (&in_forward); cmd->forwardmove -= cl_backspeed.value * CL_KeyState (&in_back); - //} - // jkrige - removed klook command + } // // adjust for speed key // - // jkrige - speed key now acts as slow key when always run is chosen - //if (in_speed.state & 1) - if ( ( (cl_forwardspeed.value <= 200 && in_speed.state & 1) || (cl_forwardspeed.value > 200 && !(in_speed.state & 1)) ) ) + if ((in_speed.state & 1) ^ (cl_alwaysrun.value != 0.0)) { cmd->forwardmove *= cl_movespeedkey.value; cmd->sidemove *= cl_movespeedkey.value; cmd->upmove *= cl_movespeedkey.value; } - // jkrige - speed key now acts as slow key when always run is chosen - -#ifdef QUAKE2 - cmd->lightlevel = cl.light_level; -#endif } - /* ============== CL_SendMove ============== */ -void CL_SendMove (usercmd_t *cmd) +void CL_SendMove (const usercmd_t *cmd) { int i; int bits; sizebuf_t buf; byte data[128]; - + buf.maxsize = 128; buf.cursize = 0; buf.data = data; - + cl.cmd = *cmd; // // send the movement message // - MSG_WriteByte (&buf, clc_move); + MSG_WriteByte (&buf, clc_move); MSG_WriteFloat (&buf, cl.mtime[0]); // so server can get ping times for (i=0 ; i<3 ; i++) - MSG_WriteAngle (&buf, cl.viewangles[i]); - - MSG_WriteShort (&buf, cmd->forwardmove); - MSG_WriteShort (&buf, cmd->sidemove); - MSG_WriteShort (&buf, cmd->upmove); + //johnfitz -- 16-bit angles for PROTOCOL_FITZQUAKE + if (cl.protocol == PROTOCOL_NETQUAKE) + MSG_WriteAngle (&buf, cl.viewangles[i], cl.protocolflags); + else + MSG_WriteAngle16 (&buf, cl.viewangles[i], cl.protocolflags); + //johnfitz + + MSG_WriteShort (&buf, cmd->forwardmove); + MSG_WriteShort (&buf, cmd->sidemove); + MSG_WriteShort (&buf, cmd->upmove); // // send button bits // bits = 0; - + if ( in_attack.state & 3 ) bits |= 1; in_attack.state &= ~2; - + if (in_jump.state & 3) bits |= 2; in_jump.state &= ~2; - - MSG_WriteByte (&buf, bits); - MSG_WriteByte (&buf, in_impulse); - in_impulse = 0; + MSG_WriteByte (&buf, bits); -#ifdef QUAKE2 -// -// light level -// - MSG_WriteByte (&buf, cmd->lightlevel); -#endif + MSG_WriteByte (&buf, in_impulse); + in_impulse = 0; // // deliver the message @@ -414,7 +399,7 @@ void CL_SendMove (usercmd_t *cmd) // if (++cl.movemessages <= 2) return; - + if (NET_SendUnreliableMessage (cls.netcon, &buf) == -1) { Con_Printf ("CL_SendMove: lost server connection\n"); @@ -460,10 +445,10 @@ void CL_InitInput (void) Cmd_AddCommand ("+jump", IN_JumpDown); Cmd_AddCommand ("-jump", IN_JumpUp); Cmd_AddCommand ("impulse", IN_Impulse); - //Cmd_AddCommand ("+klook", IN_KLookDown); // jkrige - removed klook command - //Cmd_AddCommand ("-klook", IN_KLookUp); // jkrige - removed klook command - //Cmd_AddCommand ("+mlook", IN_MLookDown); // jkrige - removed mlook command - //Cmd_AddCommand ("-mlook", IN_MLookUp); // jkrige - removed mlook command + Cmd_AddCommand ("+klook", IN_KLookDown); + Cmd_AddCommand ("-klook", IN_KLookUp); + Cmd_AddCommand ("+mlook", IN_MLookDown); + Cmd_AddCommand ("-mlook", IN_MLookUp); } diff --git a/engine/code/cl_main.c b/engine/Quake/cl_main.c similarity index 65% rename from engine/code/cl_main.c rename to engine/Quake/cl_main.c index 092868c..5d870bd 100644 --- a/engine/code/cl_main.c +++ b/engine/Quake/cl_main.c @@ -1,5 +1,7 @@ /* -Copyright (C) 1996-1997 Id Software, Inc. +Copyright (C) 1996-2001 Id Software, Inc. +Copyright (C) 2002-2009 John Fitzgibbons and others +Copyright (C) 2010-2014 QuakeSpasm developers This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -8,7 +10,7 @@ of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. @@ -20,47 +22,47 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // cl_main.c -- client main loop #include "quakedef.h" +#include "bgmusic.h" // we need to declare some mouse variables here, because the menu system // references them even when on a unix system. // these two are not intended to be set directly -cvar_t cl_name = {"_cl_name", "player", true}; -cvar_t cl_color = {"_cl_color", "0", true}; +cvar_t cl_name = {"_cl_name", "player", CVAR_ARCHIVE}; +cvar_t cl_color = {"_cl_color", "0", CVAR_ARCHIVE}; -cvar_t cl_shownet = {"cl_shownet","0"}; // can be 0, 1, or 2 -cvar_t cl_nolerp = {"cl_nolerp","0"}; +cvar_t cl_shownet = {"cl_shownet","0",CVAR_NONE}; // can be 0, 1, or 2 +cvar_t cl_nolerp = {"cl_nolerp","0",CVAR_NONE}; -// jkrige - configurable fps caps -cvar_t cl_maxfps = {"cl_maxfps", "110", true}; -// jkrige - configurable fps caps +cvar_t cfg_unbindall = {"cfg_unbindall", "1", CVAR_ARCHIVE}; -cvar_t lookspring = {"lookspring","0", true}; -cvar_t lookstrafe = {"lookstrafe","0", true}; +cvar_t lookspring = {"lookspring","0", CVAR_ARCHIVE}; +cvar_t lookstrafe = {"lookstrafe","0", CVAR_ARCHIVE}; +cvar_t sensitivity = {"sensitivity","3", CVAR_ARCHIVE}; -// jkrige - mouse sensitivity -//cvar_t sensitivity = {"sensitivity","5", true}; -cvar_t sensitivity = {"sensitivity","5.5", true}; -// jkrige - mouse sensitivity - -cvar_t m_pitch = {"m_pitch","0.022", true}; -cvar_t m_yaw = {"m_yaw","0.022", true}; -cvar_t m_forward = {"m_forward","1", true}; -cvar_t m_side = {"m_side","0.8", true}; +cvar_t m_pitch = {"m_pitch","0.022", CVAR_ARCHIVE}; +cvar_t m_yaw = {"m_yaw","0.022", CVAR_ARCHIVE}; +cvar_t m_forward = {"m_forward","1", CVAR_ARCHIVE}; +cvar_t m_side = {"m_side","0.8", CVAR_ARCHIVE}; +cvar_t cl_maxpitch = {"cl_maxpitch", "90", CVAR_ARCHIVE}; //johnfitz -- variable pitch clamping +cvar_t cl_minpitch = {"cl_minpitch", "-90", CVAR_ARCHIVE}; //johnfitz -- variable pitch clamping client_static_t cls; client_state_t cl; // FIXME: put these on hunk? -efrag_t cl_efrags[MAX_EFRAGS]; -entity_t cl_entities[MAX_EDICTS]; entity_t cl_static_entities[MAX_STATIC_ENTITIES]; lightstyle_t cl_lightstyle[MAX_LIGHTSTYLES]; dlight_t cl_dlights[MAX_DLIGHTS]; +entity_t *cl_entities; //johnfitz -- was a static array, now on hunk +int cl_max_edicts; //johnfitz -- only changes when new map loads + int cl_numvisedicts; entity_t *cl_visedicts[MAX_VISEDICTS]; +extern cvar_t r_lerpmodels, r_lerpmove; //johnfitz + /* ===================== CL_ClearState @@ -69,8 +71,6 @@ CL_ClearState */ void CL_ClearState (void) { - int i; - if (!sv.active) Host_ClearMemory (); @@ -79,21 +79,16 @@ void CL_ClearState (void) SZ_Clear (&cls.message); -// clear other arrays - memset (cl_efrags, 0, sizeof(cl_efrags)); - memset (cl_entities, 0, sizeof(cl_entities)); +// clear other arrays memset (cl_dlights, 0, sizeof(cl_dlights)); memset (cl_lightstyle, 0, sizeof(cl_lightstyle)); memset (cl_temp_entities, 0, sizeof(cl_temp_entities)); memset (cl_beams, 0, sizeof(cl_beams)); -// -// allocate the efrags and chain together into a free list -// - cl.free_efrags = cl_efrags; - for (i=0 ; i>4, ((int)cl_color.value)&15)); - + MSG_WriteByte (&cls.message, clc_stringcmd); sprintf (str, "spawn %s", cls.spawnparms); MSG_WriteString (&cls.message, str); break; - - case 3: + + case 3: MSG_WriteByte (&cls.message, clc_stringcmd); MSG_WriteString (&cls.message, "begin"); Cache_Report (); // print remaining memory break; - + case 4: SCR_EndLoadingPlaque (); // allow normal screen updates break; @@ -241,8 +229,6 @@ void CL_NextDemo (void) if (cls.demonum == -1) return; // don't play demos - SCR_BeginLoadingPlaque (); - if (!cls.demos[cls.demonum][0] || cls.demonum == MAX_DEMOS) { cls.demonum = 0; @@ -250,10 +236,13 @@ void CL_NextDemo (void) { Con_Printf ("No demos listed with startdemos\n"); cls.demonum = -1; + CL_Disconnect(); return; } } + SCR_BeginLoadingPlaque (); + sprintf (str,"playdemo %s\n", cls.demos[cls.demonum]); Cbuf_InsertText (str); cls.demonum++; @@ -268,7 +257,10 @@ void CL_PrintEntities_f (void) { entity_t *ent; int i; - + + if (cls.state != ca_connected) + return; + for (i=0,ent=cl_entities ; ikey = key; - - // jkrige - .lit colored lights - dl->color [0] = dl->color[1] = dl->color[2] = 1; - // jkrige - .lit colored lights - + dl->color[0] = dl->color[1] = dl->color[2] = 1; //johnfitz -- lit support via lordhavoc return dl; } } @@ -365,11 +309,7 @@ dlight_t *CL_AllocDlight (int key) { memset (dl, 0, sizeof(*dl)); dl->key = key; - - // jkrige - .lit colored lights - dl->color [0] = dl->color[1] = dl->color[2] = 1; - // jkrige - .lit colored lights - + dl->color[0] = dl->color[1] = dl->color[2] = 1; //johnfitz -- lit support via lordhavoc return dl; } } @@ -377,11 +317,7 @@ dlight_t *CL_AllocDlight (int key) dl = &cl_dlights[0]; memset (dl, 0, sizeof(*dl)); dl->key = key; - - // jkrige - .lit colored lights - dl->color [0] = dl->color[1] = dl->color[2] = 1; - // jkrige - .lit colored lights - + dl->color[0] = dl->color[1] = dl->color[2] = 1; //johnfitz -- lit support via lordhavoc return dl; } @@ -397,7 +333,7 @@ void CL_DecayLights (void) int i; dlight_t *dl; float time; - + time = cl.time - cl.oldtime; dl = cl_dlights; @@ -405,7 +341,7 @@ void CL_DecayLights (void) { if (dl->die < cl.time || !dl->radius) continue; - + dl->radius -= time*dl->decay; if (dl->radius < 0) dl->radius = 0; @@ -426,47 +362,42 @@ float CL_LerpPoint (void) float f, frac; f = cl.mtime[0] - cl.mtime[1]; - - if (!f || cl_nolerp.value || cls.timedemo || sv.active) + + if (!f || cls.timedemo || sv.active) { cl.time = cl.mtime[0]; return 1; } - - if (f > 0.1) - { // dropped packet, or start of demo + + if (f > 0.1) // dropped packet, or start of demo + { cl.mtime[1] = cl.mtime[0] - 0.1; f = 0.1; } + frac = (cl.time - cl.mtime[1]) / f; -//Con_Printf ("frac: %f\n",frac); + if (frac < 0) { if (frac < -0.01) - { -SetPal(1); cl.time = cl.mtime[1]; -// Con_Printf ("low frac\n"); - } frac = 0; } else if (frac > 1) { if (frac > 1.01) - { -SetPal(2); cl.time = cl.mtime[0]; -// Con_Printf ("high frac\n"); - } frac = 1; } - else - SetPal(0); - + + //johnfitz -- better nolerp behavior + if (cl_nolerp.value) + return 1; + //johnfitz + return frac; } - /* =============== CL_RelinkEntities @@ -482,7 +413,7 @@ void CL_RelinkEntities (void) vec3_t oldorg; dlight_t *dl; -// determine partial update time +// determine partial update time frac = CL_LerpPoint (); cl_numvisedicts = 0; @@ -491,12 +422,12 @@ void CL_RelinkEntities (void) // interpolate player info // for (i=0 ; i<3 ; i++) - cl.velocity[i] = cl.mvelocity[1][i] + + cl.velocity[i] = cl.mvelocity[1][i] + frac * (cl.mvelocity[0][i] - cl.mvelocity[1][i]); if (cls.demoplayback) { - // interpolate the angles + // interpolate the angles for (j=0 ; j<3 ; j++) { d = cl.mviewangles[0][j] - cl.mviewangles[1][j]; @@ -507,16 +438,19 @@ void CL_RelinkEntities (void) cl.viewangles[j] = cl.mviewangles[1][j] + frac*d; } } - + bobjrotate = anglemod(100*cl.time); - + // start on the entity after the world for (i=1,ent=cl_entities+1 ; imodel) { // empty slot - if (ent->forcelink) - R_RemoveEfrags (ent); // just became empty + + // ericw -- efrags are only used for static entities in GLQuake + // ent can't be static, so this is a no-op. + //if (ent->forcelink) + // R_RemoveEfrags (ent); // just became empty continue; } @@ -524,6 +458,7 @@ void CL_RelinkEntities (void) if (ent->msgtime != cl.mtime[0]) { ent->model = NULL; + ent->lerpflags |= LERP_RESETMOVE|LERP_RESETANIM; //johnfitz -- next time this entity slot is reused, the lerp will need to be reset continue; } @@ -542,9 +477,17 @@ void CL_RelinkEntities (void) { delta[j] = ent->msg_origins[0][j] - ent->msg_origins[1][j]; if (delta[j] > 100 || delta[j] < -100) + { f = 1; // assume a teleportation, not a motion + ent->lerpflags |= LERP_RESETMOVE; //johnfitz -- don't lerp teleports + } } + //johnfitz -- don't cl_lerp entities that will be r_lerped + if (r_lerpmove.value && (ent->lerpflags & LERP_MOVESTEP)) + f = 1; + //johnfitz + // interpolate the origin and angles for (j=0 ; j<3 ; j++) { @@ -557,7 +500,6 @@ void CL_RelinkEntities (void) d += 360; ent->angles[j] = ent->msg_angles[1][j] + f*d; } - } // rotate binary objects locally @@ -566,10 +508,7 @@ void CL_RelinkEntities (void) if (ent->effects & EF_BRIGHTFIELD) R_EntityParticles (ent); -#ifdef QUAKE2 - if (ent->effects & EF_DARKFIELD) - R_DarkFieldParticles (ent); -#endif + if (ent->effects & EF_MUZZLEFLASH) { vec3_t fv, rv, uv; @@ -578,14 +517,24 @@ void CL_RelinkEntities (void) VectorCopy (ent->origin, dl->origin); dl->origin[2] += 16; AngleVectors (ent->angles, fv, rv, uv); - + VectorMA (dl->origin, 18, fv, dl->origin); dl->radius = 200 + (rand()&31); dl->minlight = 32; dl->die = cl.time + 0.1; + + //johnfitz -- assume muzzle flash accompanied by muzzle flare, which looks bad when lerped + if (r_lerpmodels.value != 2) + { + if (ent == &cl_entities[cl.viewentity]) + cl.viewent.lerpflags |= LERP_RESETANIM|LERP_RESETANIM2; //no lerping for two frames + else + ent->lerpflags |= LERP_RESETANIM|LERP_RESETANIM2; //no lerping for two frames + } + //johnfitz } if (ent->effects & EF_BRIGHTLIGHT) - { + { dl = CL_AllocDlight (i); VectorCopy (ent->origin, dl->origin); dl->origin[2] += 16; @@ -593,29 +542,12 @@ void CL_RelinkEntities (void) dl->die = cl.time + 0.001; } if (ent->effects & EF_DIMLIGHT) - { + { dl = CL_AllocDlight (i); VectorCopy (ent->origin, dl->origin); dl->radius = 200 + (rand()&31); dl->die = cl.time + 0.001; } -#ifdef QUAKE2 - if (ent->effects & EF_DARKLIGHT) - { - dl = CL_AllocDlight (i); - VectorCopy (ent->origin, dl->origin); - dl->radius = 200.0 + (rand()&31); - dl->die = cl.time + 0.001; - dl->dark = true; - } - if (ent->effects & EF_LIGHT) - { - dl = CL_AllocDlight (i); - VectorCopy (ent->origin, dl->origin); - dl->radius = 200; - dl->die = cl.time + 0.001; - } -#endif if (ent->model->flags & EF_GIB) R_RocketTrail (oldorg, ent->origin, 2); @@ -640,22 +572,15 @@ void CL_RelinkEntities (void) ent->forcelink = false; - // jkrige - removed chase - if (i == cl.viewentity) // && !chase_active.value + if (i == cl.viewentity && !chase_active.value) continue; - // jkrige - removed chase -#ifdef QUAKE2 - if ( ent->effects & EF_NODRAW ) - continue; -#endif if (cl_numvisedicts < MAX_VISEDICTS) { cl_visedicts[cl_numvisedicts] = ent; cl_numvisedicts++; } } - } @@ -668,11 +593,18 @@ Read all incoming data from the server */ int CL_ReadFromServer (void) { - int ret; + int ret; + extern int num_temp_entities; //johnfitz + int num_beams = 0; //johnfitz + int num_dlights = 0; //johnfitz + beam_t *b; //johnfitz + dlight_t *l; //johnfitz + int i; //johnfitz + cl.oldtime = cl.time; cl.time += host_frametime; - + do { ret = CL_GetMessage (); @@ -680,17 +612,51 @@ int CL_ReadFromServer (void) Host_Error ("CL_ReadFromServer: lost server connection"); if (!ret) break; - + cl.last_received_message = realtime; CL_ParseServerMessage (); } while (ret && cls.state == ca_connected); - + if (cl_shownet.value) Con_Printf ("\n"); CL_RelinkEntities (); CL_UpdateTEnts (); +//johnfitz -- devstats + + //visedicts + if (cl_numvisedicts > 256 && dev_peakstats.visedicts <= 256) + Con_DWarning ("%i visedicts exceeds standard limit of 256 (max = %d).\n", cl_numvisedicts, MAX_VISEDICTS); + dev_stats.visedicts = cl_numvisedicts; + dev_peakstats.visedicts = q_max(cl_numvisedicts, dev_peakstats.visedicts); + + //temp entities + if (num_temp_entities > 64 && dev_peakstats.tempents <= 64) + Con_DWarning ("%i tempentities exceeds standard limit of 64 (max = %d).\n", num_temp_entities, MAX_TEMP_ENTITIES); + dev_stats.tempents = num_temp_entities; + dev_peakstats.tempents = q_max(num_temp_entities, dev_peakstats.tempents); + + //beams + for (i=0, b=cl_beams ; i< MAX_BEAMS ; i++, b++) + if (b->model && b->endtime >= cl.time) + num_beams++; + if (num_beams > 24 && dev_peakstats.beams <= 24) + Con_DWarning ("%i beams exceeded standard limit of 24 (max = %d).\n", num_beams, MAX_BEAMS); + dev_stats.beams = num_beams; + dev_peakstats.beams = q_max(num_beams, dev_peakstats.beams); + + //dlights + for (i=0, l=cl_dlights ; idie >= cl.time && l->radius) + num_dlights++; + if (num_dlights > 32 && dev_peakstats.dlights <= 32) + Con_DWarning ("%i dlights exceeded standard limit of 32 (max = %d).\n", num_dlights, MAX_DLIGHTS); + dev_stats.dlights = num_dlights; + dev_peakstats.dlights = q_max(num_dlights, dev_peakstats.dlights); + +//johnfitz + // // bring the links up to date // @@ -713,13 +679,12 @@ void CL_SendCmd (void) { // get basic movement from keyboard CL_BaseMove (&cmd); - + // allow mice or other external controllers to add to the move IN_Move (&cmd); - + // send the unreliable message CL_SendMove (&cmd); - } if (cls.demoplayback) @@ -727,38 +692,90 @@ void CL_SendCmd (void) SZ_Clear (&cls.message); return; } - + // send the reliable message if (!cls.message.cursize) return; // no message at all - + if (!NET_CanSendMessage (cls.netcon)) { - Con_DPrintf ("CL_WriteToServer: can't send\n"); + Con_DPrintf ("CL_SendCmd: can't send\n"); return; } if (NET_SendMessage (cls.netcon, &cls.message) == -1) - Host_Error ("CL_WriteToServer: lost server connection"); + Host_Error ("CL_SendCmd: lost server connection"); SZ_Clear (&cls.message); } +/* +============= +CL_Tracepos_f -- johnfitz + +display impact point of trace along VPN +============= +*/ +void CL_Tracepos_f (void) +{ + vec3_t v, w; + + if (cls.state != ca_connected) + return; + + VectorMA(r_refdef.vieworg, 8192.0, vpn, v); + TraceLine(r_refdef.vieworg, v, w); + + if (VectorLength(w) == 0) + Con_Printf ("Tracepos: trace didn't hit anything\n"); + else + Con_Printf ("Tracepos: (%i %i %i)\n", (int)w[0], (int)w[1], (int)w[2]); +} + +/* +============= +CL_Viewpos_f -- johnfitz + +display client's position and angles +============= +*/ +void CL_Viewpos_f (void) +{ + if (cls.state != ca_connected) + return; +#if 0 + //camera position + Con_Printf ("Viewpos: (%i %i %i) %i %i %i\n", + (int)r_refdef.vieworg[0], + (int)r_refdef.vieworg[1], + (int)r_refdef.vieworg[2], + (int)r_refdef.viewangles[PITCH], + (int)r_refdef.viewangles[YAW], + (int)r_refdef.viewangles[ROLL]); +#else + //player position + Con_Printf ("Viewpos: (%i %i %i) %i %i %i\n", + (int)cl_entities[cl.viewentity].origin[0], + (int)cl_entities[cl.viewentity].origin[1], + (int)cl_entities[cl.viewentity].origin[2], + (int)cl.viewangles[PITCH], + (int)cl.viewangles[YAW], + (int)cl.viewangles[ROLL]); +#endif +} + /* ================= CL_Init ================= */ void CL_Init (void) -{ +{ SZ_Alloc (&cls.message, 1024); CL_InitInput (); CL_InitTEnts (); - -// -// register our commands -// + Cvar_RegisterVariable (&cl_name); Cvar_RegisterVariable (&cl_color); Cvar_RegisterVariable (&cl_upspeed); @@ -771,30 +788,30 @@ void CL_Init (void) Cvar_RegisterVariable (&cl_anglespeedkey); Cvar_RegisterVariable (&cl_shownet); Cvar_RegisterVariable (&cl_nolerp); - - // jkrige - configurable fps caps - Cvar_RegisterVariable (&cl_maxfps); - // jkrige - configurable fps caps - Cvar_RegisterVariable (&lookspring); Cvar_RegisterVariable (&lookstrafe); Cvar_RegisterVariable (&sensitivity); - - Cvar_RegisterVariable (&cl_mlook); // jkrige - mlook cvar - Cvar_RegisterVariable (&cl_slook); // jkrige - slook cvar + + Cvar_RegisterVariable (&cl_alwaysrun); Cvar_RegisterVariable (&m_pitch); Cvar_RegisterVariable (&m_yaw); Cvar_RegisterVariable (&m_forward); Cvar_RegisterVariable (&m_side); -// Cvar_RegisterVariable (&cl_autofire); - + Cvar_RegisterVariable (&cfg_unbindall); + + Cvar_RegisterVariable (&cl_maxpitch); //johnfitz -- variable pitch clamping + Cvar_RegisterVariable (&cl_minpitch); //johnfitz -- variable pitch clamping + Cmd_AddCommand ("entities", CL_PrintEntities_f); Cmd_AddCommand ("disconnect", CL_Disconnect_f); Cmd_AddCommand ("record", CL_Record_f); Cmd_AddCommand ("stop", CL_Stop_f); Cmd_AddCommand ("playdemo", CL_PlayDemo_f); Cmd_AddCommand ("timedemo", CL_TimeDemo_f); + + Cmd_AddCommand ("tracepos", CL_Tracepos_f); //johnfitz + Cmd_AddCommand ("viewpos", CL_Viewpos_f); //johnfitz } diff --git a/engine/code/cl_parse.c b/engine/Quake/cl_parse.c similarity index 52% rename from engine/code/cl_parse.c rename to engine/Quake/cl_parse.c index 8e5399b..75bacda 100644 --- a/engine/code/cl_parse.c +++ b/engine/Quake/cl_parse.c @@ -1,5 +1,8 @@ /* -Copyright (C) 1996-1997 Id Software, Inc. +Copyright (C) 1996-2001 Id Software, Inc. +Copyright (C) 2002-2009 John Fitzgibbons and others +Copyright (C) 2007-2008 Kristian Duske +Copyright (C) 2010-2014 QuakeSpasm developers This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -8,7 +11,7 @@ of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. @@ -20,13 +23,9 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // cl_parse.c -- parse a message received from the server #include "quakedef.h" +#include "bgmusic.h" -// jkrige - fix demo playback across maps (music) -// Pa3PyX: new var -extern int stufftext_frame; -// jkrige - fix demo playback across maps - -char *svc_strings[] = +const char *svc_strings[] = { "svc_bad", "svc_nop", @@ -40,7 +39,7 @@ char *svc_strings[] = "svc_stufftext", // [string] stuffed into client's console buffer // the string should be \n terminated "svc_setangle", // [vec3] set the view angle to this absolute value - + "svc_serverinfo", // [long] version // [string] signon string // [string]..[0]model cache [string]...[0]sounds cache @@ -53,11 +52,11 @@ char *svc_strings[] = "svc_updatecolors", // [byte] [byte] "svc_particle", // [vec3] "svc_damage", // [byte] impact [byte] blood [vec3] from - + "svc_spawnstatic", "OBSOLETE svc_spawnbinary", "svc_spawnbaseline", - + "svc_temp_entity", // "svc_setpause", "svc_signonnum", @@ -70,9 +69,30 @@ char *svc_strings[] = "svc_cdtrack", // [byte] track [byte] looptrack "svc_sellscreen", "svc_cutscene", - "svc_skybox" // jkrige - skybox +//johnfitz -- new server messages + "", // 35 + "", // 36 + "svc_skybox", // 37 // [string] skyname + "", // 38 + "", // 39 + "svc_bf", // 40 // no data + "svc_fog", // 41 // [byte] density [byte] red [byte] green [byte] blue [float] time + "svc_spawnbaseline2", //42 // support for large modelindex, large framenum, alpha, using flags + "svc_spawnstatic2", // 43 // support for large modelindex, large framenum, alpha, using flags + "svc_spawnstaticsound2", // 44 // [coord3] [short] samp [byte] vol [byte] aten + "", // 44 + "", // 45 + "", // 46 + "", // 47 + "", // 48 + "", // 49 +//johnfitz }; +qboolean warn_about_nehahra_protocol; //johnfitz + +extern vec3_t v_punchangles[2]; //johnfitz + //============================================================================= /* @@ -84,17 +104,23 @@ This error checks and tracks the total number of entities */ entity_t *CL_EntityNum (int num) { + //johnfitz -- check minimum number too + if (num < 0) + Host_Error ("CL_EntityNum: %i is an invalid number",num); + //john + if (num >= cl.num_entities) { - if (num >= MAX_EDICTS) + if (num >= cl_max_edicts) //johnfitz -- no more MAX_EDICTS Host_Error ("CL_EntityNum: %i is an invalid number",num); while (cl.num_entities<=num) { cl_entities[cl.num_entities].colormap = vid.colormap; + cl_entities[cl.num_entities].lerpflags |= LERP_RESETMOVE|LERP_RESETANIM; //johnfitz cl.num_entities++; } } - + return &cl_entities[num]; } @@ -106,40 +132,58 @@ CL_ParseStartSoundPacket */ void CL_ParseStartSoundPacket(void) { - vec3_t pos; - int channel, ent; - int sound_num; - int volume; - int field_mask; - float attenuation; - int i; - - field_mask = MSG_ReadByte(); - - if (field_mask & SND_VOLUME) + vec3_t pos; + int channel, ent; + int sound_num; + int volume; + int field_mask; + float attenuation; + int i; + + field_mask = MSG_ReadByte(); + + if (field_mask & SND_VOLUME) volume = MSG_ReadByte (); else volume = DEFAULT_SOUND_PACKET_VOLUME; - - if (field_mask & SND_ATTENUATION) + + if (field_mask & SND_ATTENUATION) attenuation = MSG_ReadByte () / 64.0; else attenuation = DEFAULT_SOUND_PACKET_ATTENUATION; - - channel = MSG_ReadShort (); - sound_num = MSG_ReadByte (); - ent = channel >> 3; - channel &= 7; + //johnfitz -- PROTOCOL_FITZQUAKE + if (field_mask & SND_LARGEENTITY) + { + ent = (unsigned short) MSG_ReadShort (); + channel = MSG_ReadByte (); + } + else + { + channel = (unsigned short) MSG_ReadShort (); + ent = channel >> 3; + channel &= 7; + } + + if (field_mask & SND_LARGESOUND) + sound_num = (unsigned short) MSG_ReadShort (); + else + sound_num = MSG_ReadByte (); + //johnfitz + + //johnfitz -- check soundnum + if (sound_num >= MAX_SOUNDS) + Host_Error ("CL_ParseStartSoundPacket: %i > MAX_SOUNDS", sound_num); + //johnfitz - if (ent > MAX_EDICTS) + if (ent > cl_max_edicts) //johnfitz -- no more MAX_EDICTS Host_Error ("CL_ParseStartSoundPacket: ent = %i", ent); - - for (i=0 ; i<3 ; i++) - pos[i] = MSG_ReadCoord (); - - S_StartSound (ent, channel, cl.sound_precache[sound_num], pos, volume/255.0, attenuation); -} + + for (i = 0; i < 3; i++) + pos[i] = MSG_ReadCoord (cl.protocolflags); + + S_StartSound (ent, channel, cl.sound_precache[sound_num], pos, volume/255.0, attenuation); +} /* ================== @@ -149,30 +193,32 @@ When the client is taking a long time to load stuff, send keepalive messages so the server doesn't disconnect. ================== */ +static byte net_olddata[NET_MAXMESSAGE]; void CL_KeepaliveMessage (void) { float time; static float lastmsg; int ret; sizebuf_t old; - byte olddata[8192]; - + byte *olddata; + if (sv.active) return; // no need if server is local if (cls.demoplayback) return; // read messages from server, should just be nops + olddata = net_olddata; old = net_message; memcpy (olddata, net_message.data, net_message.cursize); - + do { ret = CL_GetMessage (); switch (ret) { default: - Host_Error ("CL_KeepaliveMessage: CL_GetMessage failed"); + Host_Error ("CL_KeepaliveMessage: CL_GetMessage failed"); case 0: break; // nothing waiting case 1: @@ -189,7 +235,7 @@ void CL_KeepaliveMessage (void) memcpy (net_message.data, olddata, net_message.cursize); // check time - time = Sys_FloatTime (); + time = Sys_DoubleTime (); if (time - lastmsg < 5) return; lastmsg = time; @@ -209,13 +255,19 @@ CL_ParseServerInfo */ void CL_ParseServerInfo (void) { - char *str; + const char *str; int i; int nummodels, numsounds; char model_precache[MAX_MODELS][MAX_QPATH]; char sound_precache[MAX_SOUNDS][MAX_QPATH]; - + Con_DPrintf ("Serverinfo packet received.\n"); + +// ericw -- bring up loading plaque for map changes within a demo. +// it will be hidden in CL_SignonReply. + if (cls.demoplayback) + SCR_BeginLoadingPlaque(); + // // wipe the client_state_t struct // @@ -223,108 +275,140 @@ void CL_ParseServerInfo (void) // parse protocol version number i = MSG_ReadLong (); - if (i != PROTOCOL_VERSION) - { - Con_Printf ("Server returned version %i, not %i", i, PROTOCOL_VERSION); - return; + //johnfitz -- support multiple protocols + if (i != PROTOCOL_NETQUAKE && i != PROTOCOL_FITZQUAKE && i != PROTOCOL_RMQ) { + Con_Printf ("\n"); //because there's no newline after serverinfo print + Host_Error ("Server returned version %i, not %i or %i or %i", i, PROTOCOL_NETQUAKE, PROTOCOL_FITZQUAKE, PROTOCOL_RMQ); } + cl.protocol = i; + //johnfitz + if (cl.protocol == PROTOCOL_RMQ) + { + const unsigned int supportedflags = (PRFL_SHORTANGLE | PRFL_FLOATANGLE | PRFL_24BITCOORD | PRFL_FLOATCOORD | PRFL_EDICTSCALE | PRFL_INT32COORD); + + // mh - read protocol flags from server so that we know what protocol features to expect + cl.protocolflags = (unsigned int) MSG_ReadLong (); + + if (0 != (cl.protocolflags & (~supportedflags))) + { + Con_Warning("PROTOCOL_RMQ protocolflags %i contains unsupported flags\n", cl.protocolflags); + } + } + else cl.protocolflags = 0; + // parse maxclients cl.maxclients = MSG_ReadByte (); if (cl.maxclients < 1 || cl.maxclients > MAX_SCOREBOARD) { - Con_Printf("Bad maxclients (%u) from server\n", cl.maxclients); - return; + Host_Error ("Bad maxclients (%u) from server", cl.maxclients); } - cl.scores = Hunk_AllocName (cl.maxclients*sizeof(*cl.scores), "scores"); + cl.scores = (scoreboard_t *) Hunk_AllocName (cl.maxclients*sizeof(*cl.scores), "scores"); // parse gametype cl.gametype = MSG_ReadByte (); // parse signon message str = MSG_ReadString (); - strncpy (cl.levelname, str, sizeof(cl.levelname)-1); + q_strlcpy (cl.levelname, str, sizeof(cl.levelname)); // seperate the printfs so the server message can have a color - Con_Printf("\n\n\35\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\37\n\n"); + Con_Printf ("\n%s\n", Con_Quakebar(40)); //johnfitz Con_Printf ("%c%s\n", 2, str); -// +//johnfitz -- tell user which protocol this is + Con_Printf ("Using protocol %i\n", i); + // first we go through and touch all of the precache data that still // happens to be in the cache, so precaching something else doesn't // needlessly purge it -// // precache models memset (cl.model_precache, 0, sizeof(cl.model_precache)); - for (nummodels=1 ; ; nummodels++) + for (nummodels = 1 ; ; nummodels++) { str = MSG_ReadString (); if (!str[0]) break; if (nummodels==MAX_MODELS) { - Con_Printf ("Server sent too many model precaches\n"); - return; + Host_Error ("Server sent too many model precaches"); } - strcpy (model_precache[nummodels], str); + q_strlcpy (model_precache[nummodels], str, MAX_QPATH); Mod_TouchModel (str); } + //johnfitz -- check for excessive models + if (nummodels >= 256) + Con_DWarning ("%i models exceeds standard limit of 256 (max = %d).\n", nummodels, MAX_MODELS); + //johnfitz + // precache sounds memset (cl.sound_precache, 0, sizeof(cl.sound_precache)); - for (numsounds=1 ; ; numsounds++) + for (numsounds = 1 ; ; numsounds++) { str = MSG_ReadString (); if (!str[0]) break; if (numsounds==MAX_SOUNDS) { - Con_Printf ("Server sent too many sound precaches\n"); - return; + Host_Error ("Server sent too many sound precaches"); } - strcpy (sound_precache[numsounds], str); + q_strlcpy (sound_precache[numsounds], str, MAX_QPATH); S_TouchSound (str); } + //johnfitz -- check for excessive sounds + if (numsounds >= 256) + Con_DWarning ("%i sounds exceeds standard limit of 256 (max = %d).\n", numsounds, MAX_SOUNDS); + //johnfitz + // // now we try to load everything else until a cache allocation fails // - for (i=1 ; imsgtime != cl.mtime[1]) forcelink = true; // no previous frame to lerp from else forcelink = false; + //johnfitz -- lerping + if (ent->msgtime + 0.2 < cl.mtime[0]) //more than 0.2 seconds since the last message (most entities think every 0.1 sec) + ent->lerpflags |= LERP_RESETANIM; //if we missed a think, we'd be lerping from the wrong frame + //johnfitz + ent->msgtime = cl.mtime[0]; - + if (bits & U_MODEL) { modnum = MSG_ReadByte (); @@ -385,28 +478,7 @@ if (bits&(1<baseline.modelindex; - - model = cl.model_precache[modnum]; - if (model != ent->model) - { - ent->model = model; - // automatic animation (torches, etc) can be either all together - // or randomized - if (model) - { - if (model->synctype == ST_RAND) - ent->syncbase = (float)(rand()&0x7fff) / 0x7fff; - else - ent->syncbase = 0.0; - } - else - forcelink = true; // hack to make null model players work -#ifdef GLQUAKE - if (num > 0 && num <= cl.maxclients) - R_TranslatePlayerSkin (num - 1); -#endif - } - + if (bits & U_FRAME) ent->frame = MSG_ReadByte (); else @@ -424,26 +496,16 @@ if (bits&(1<= cl.maxclients"); ent->colormap = cl.scores[i-1].translations; } - -#ifdef GLQUAKE if (bits & U_SKIN) skin = MSG_ReadByte(); else skin = ent->baseline.skin; - if (skin != ent->skinnum) { + if (skin != ent->skinnum) + { ent->skinnum = skin; if (num > 0 && num <= cl.maxclients) - R_TranslatePlayerSkin (num - 1); + R_TranslateNewPlayerSkin (num - 1); //johnfitz -- was R_TranslatePlayerSkin } - -#else - - if (bits & U_SKIN) - ent->skinnum = MSG_ReadByte(); - else - ent->skinnum = ent->baseline.skin; -#endif - if (bits & U_EFFECTS) ent->effects = MSG_ReadByte(); else @@ -454,34 +516,109 @@ if (bits&(1<msg_angles[0], ent->msg_angles[1]); if (bits & U_ORIGIN1) - ent->msg_origins[0][0] = MSG_ReadCoord (); + ent->msg_origins[0][0] = MSG_ReadCoord (cl.protocolflags); else ent->msg_origins[0][0] = ent->baseline.origin[0]; if (bits & U_ANGLE1) - ent->msg_angles[0][0] = MSG_ReadAngle(); + ent->msg_angles[0][0] = MSG_ReadAngle(cl.protocolflags); else ent->msg_angles[0][0] = ent->baseline.angles[0]; if (bits & U_ORIGIN2) - ent->msg_origins[0][1] = MSG_ReadCoord (); + ent->msg_origins[0][1] = MSG_ReadCoord (cl.protocolflags); else ent->msg_origins[0][1] = ent->baseline.origin[1]; if (bits & U_ANGLE2) - ent->msg_angles[0][1] = MSG_ReadAngle(); + ent->msg_angles[0][1] = MSG_ReadAngle(cl.protocolflags); else ent->msg_angles[0][1] = ent->baseline.angles[1]; if (bits & U_ORIGIN3) - ent->msg_origins[0][2] = MSG_ReadCoord (); + ent->msg_origins[0][2] = MSG_ReadCoord (cl.protocolflags); else ent->msg_origins[0][2] = ent->baseline.origin[2]; if (bits & U_ANGLE3) - ent->msg_angles[0][2] = MSG_ReadAngle(); + ent->msg_angles[0][2] = MSG_ReadAngle(cl.protocolflags); else ent->msg_angles[0][2] = ent->baseline.angles[2]; - if ( bits & U_NOLERP ) + //johnfitz -- lerping for movetype_step entities + if (bits & U_STEP) + { + ent->lerpflags |= LERP_MOVESTEP; ent->forcelink = true; + } + else + ent->lerpflags &= ~LERP_MOVESTEP; + //johnfitz + + //johnfitz -- PROTOCOL_FITZQUAKE and PROTOCOL_NEHAHRA + if (cl.protocol == PROTOCOL_FITZQUAKE || cl.protocol == PROTOCOL_RMQ) + { + if (bits & U_ALPHA) + ent->alpha = MSG_ReadByte(); + else + ent->alpha = ent->baseline.alpha; + if (bits & U_SCALE) + MSG_ReadByte(); // PROTOCOL_RMQ: currently ignored + if (bits & U_FRAME2) + ent->frame = (ent->frame & 0x00FF) | (MSG_ReadByte() << 8); + if (bits & U_MODEL2) + modnum = (modnum & 0x00FF) | (MSG_ReadByte() << 8); + if (bits & U_LERPFINISH) + { + ent->lerpfinish = ent->msgtime + ((float)(MSG_ReadByte()) / 255); + ent->lerpflags |= LERP_FINISH; + } + else + ent->lerpflags &= ~LERP_FINISH; + } + else if (cl.protocol == PROTOCOL_NETQUAKE) + { + //HACK: if this bit is set, assume this is PROTOCOL_NEHAHRA + if (bits & U_TRANS) + { + float a, b; + + if (warn_about_nehahra_protocol) + { + Con_Warning ("nonstandard update bit, assuming Nehahra protocol\n"); + warn_about_nehahra_protocol = false; + } + + a = MSG_ReadFloat(); + b = MSG_ReadFloat(); //alpha + if (a == 2) + MSG_ReadFloat(); //fullbright (not using this yet) + ent->alpha = ENTALPHA_ENCODE(b); + } + else + ent->alpha = ent->baseline.alpha; + } + //johnfitz + + //johnfitz -- moved here from above + model = cl.model_precache[modnum]; + if (model != ent->model) + { + ent->model = model; + // automatic animation (torches, etc) can be either all together + // or randomized + if (model) + { + if (model->synctype == ST_RAND) + ent->syncbase = (float)(rand()&0x7fff) / 0x7fff; + else + ent->syncbase = 0.0; + } + else + forcelink = true; // hack to make null model players work + if (num > 0 && num <= cl.maxclients) + R_TranslateNewPlayerSkin (num - 1); //johnfitz -- was R_TranslatePlayerSkin + + ent->lerpflags |= LERP_RESETANIM; //johnfitz -- don't lerp animation across model changes + } + //johnfitz if ( forcelink ) { // didn't have an update last message @@ -498,19 +635,26 @@ if (bits&(1<baseline.modelindex = MSG_ReadByte (); - ent->baseline.frame = MSG_ReadByte (); + int i; + int bits; //johnfitz + + //johnfitz -- PROTOCOL_FITZQUAKE + bits = (version == 2) ? MSG_ReadByte() : 0; + ent->baseline.modelindex = (bits & B_LARGEMODEL) ? MSG_ReadShort() : MSG_ReadByte(); + ent->baseline.frame = (bits & B_LARGEFRAME) ? MSG_ReadShort() : MSG_ReadByte(); + //johnfitz + ent->baseline.colormap = MSG_ReadByte(); ent->baseline.skin = MSG_ReadByte(); - for (i=0 ; i<3 ; i++) + for (i = 0; i < 3; i++) { - ent->baseline.origin[i] = MSG_ReadCoord (); - ent->baseline.angles[i] = MSG_ReadAngle (); + ent->baseline.origin[i] = MSG_ReadCoord (cl.protocolflags); + ent->baseline.angles[i] = MSG_ReadAngle (cl.protocolflags); } + + ent->baseline.alpha = (bits & B_ALPHA) ? MSG_ReadByte() : ENTALPHA_DEFAULT; //johnfitz -- PROTOCOL_FITZQUAKE } @@ -521,10 +665,20 @@ CL_ParseClientdata Server information pertaining to this client only ================== */ -void CL_ParseClientdata (int bits) +void CL_ParseClientdata (void) { int i, j; - + int bits; //johnfitz + + bits = (unsigned short)MSG_ReadShort (); //johnfitz -- read bits here isntead of in CL_ParseServerMessage() + + //johnfitz -- PROTOCOL_FITZQUAKE + if (bits & SU_EXTEND1) + bits |= (MSG_ReadByte() << 16); + if (bits & SU_EXTEND2) + bits |= (MSG_ReadByte() << 24); + //johnfitz + if (bits & SU_VIEWHEIGHT) cl.viewheight = MSG_ReadChar (); else @@ -534,32 +688,41 @@ void CL_ParseClientdata (int bits) cl.idealpitch = MSG_ReadChar (); else cl.idealpitch = 0; - + VectorCopy (cl.mvelocity[0], cl.mvelocity[1]); - for (i=0 ; i<3 ; i++) + for (i = 0; i < 3; i++) { if (bits & (SU_PUNCH1< cl.maxclients) Sys_Error ("CL_NewTranslation: slot > cl.maxclients"); dest = cl.scores[slot].translations; @@ -650,23 +844,25 @@ void CL_NewTranslation (int slot) memcpy (dest, vid.colormap, sizeof(cl.scores[slot].translations)); top = cl.scores[slot].colors & 0xf0; bottom = (cl.scores[slot].colors &15)<<4; -#ifdef GLQUAKE R_TranslatePlayerSkin (slot); -#endif - for (i=0 ; i= MAX_STATIC_ENTITIES) Host_Error ("Too many static entities"); + ent = &cl_static_entities[i]; cl.num_statics++; - CL_ParseBaseline (ent); + CL_ParseBaseline (ent, version); //johnfitz -- added second parameter // copy it to the current state + ent->model = cl.model_precache[ent->baseline.modelindex]; + ent->lerpflags |= LERP_RESETANIM; //johnfitz -- lerping ent->frame = ent->baseline.frame; + ent->colormap = vid.colormap; ent->skinnum = ent->baseline.skin; ent->effects = ent->baseline.effects; + ent->alpha = ent->baseline.alpha; //johnfitz -- alpha VectorCopy (ent->baseline.origin, ent->origin); - VectorCopy (ent->baseline.angles, ent->angles); + VectorCopy (ent->baseline.angles, ent->angles); R_AddEfrags (ent); } @@ -704,25 +905,31 @@ void CL_ParseStatic (void) CL_ParseStaticSound =================== */ -void CL_ParseStaticSound (void) +void CL_ParseStaticSound (int version) //johnfitz -- added argument { vec3_t org; int sound_num, vol, atten; int i; - - for (i=0 ; i<3 ; i++) - org[i] = MSG_ReadCoord (); - sound_num = MSG_ReadByte (); + + for (i = 0; i < 3; i++) + org[i] = MSG_ReadCoord (cl.protocolflags); + + //johnfitz -- PROTOCOL_FITZQUAKE + if (version == 2) + sound_num = MSG_ReadShort (); + else + sound_num = MSG_ReadByte (); + //johnfitz + vol = MSG_ReadByte (); atten = MSG_ReadByte (); - + S_StaticSound (cl.sound_precache[sound_num], org, vol, atten); } #define SHOWNET(x) if(cl_shownet.value==2)Con_Printf ("%3i:%s\n", msg_readcount-1, x); - /* ===================== CL_ParseServerMessage @@ -732,6 +939,8 @@ void CL_ParseServerMessage (void) { int cmd; int i; + const char *str; //johnfitz + int total, j, lastcmd; //johnfitz // // if recording demos, copy the message out @@ -740,13 +949,14 @@ void CL_ParseServerMessage (void) Con_Printf ("%i ",net_message.cursize); else if (cl_shownet.value == 2) Con_Printf ("------------------\n"); - - cl.onground = false; // unless the server says otherwise + + cl.onground = false; // unless the server says otherwise // // parse the message // MSG_BeginReading (); - + + lastcmd = 0; while (1) { if (msg_badread) @@ -761,7 +971,7 @@ void CL_ParseServerMessage (void) } // if the high bit of the command byte is set, it is a fast update - if (cmd & 128) + if (cmd & U_SIGNAL) //johnfitz -- was 128, changed for clarity { SHOWNET("fast update"); CL_ParseUpdate (cmd&127); @@ -769,114 +979,130 @@ void CL_ParseServerMessage (void) } SHOWNET(svc_strings[cmd]); - + // other commands switch (cmd) { default: - Host_Error ("CL_ParseServerMessage: Illegible server message\n"); + Host_Error ("Illegible server message, previous was %s", svc_strings[lastcmd]); //johnfitz -- added svc_strings[lastcmd] break; - + case svc_nop: -// Con_Printf ("svc_nop\n"); + // Con_Printf ("svc_nop\n"); break; - + case svc_time: cl.mtime[1] = cl.mtime[0]; - cl.mtime[0] = MSG_ReadFloat (); + cl.mtime[0] = MSG_ReadFloat (); break; - + case svc_clientdata: - i = MSG_ReadShort (); - CL_ParseClientdata (i); + CL_ParseClientdata (); //johnfitz -- removed bits parameter, we will read this inside CL_ParseClientdata() break; - + case svc_version: i = MSG_ReadLong (); - if (i != PROTOCOL_VERSION) - Host_Error ("CL_ParseServerMessage: Server is protocol %i instead of %i\n", i, PROTOCOL_VERSION); + //johnfitz -- support multiple protocols + if (i != PROTOCOL_NETQUAKE && i != PROTOCOL_FITZQUAKE && i != PROTOCOL_RMQ) + Host_Error ("Server returned version %i, not %i or %i or %i", i, PROTOCOL_NETQUAKE, PROTOCOL_FITZQUAKE, PROTOCOL_RMQ); + cl.protocol = i; + //johnfitz break; - + case svc_disconnect: Host_EndGame ("Server disconnected\n"); case svc_print: Con_Printf ("%s", MSG_ReadString ()); break; - + case svc_centerprint: - SCR_CenterPrint (MSG_ReadString ()); + //johnfitz -- log centerprints to console + str = MSG_ReadString (); + SCR_CenterPrint (str); + Con_LogCenterPrint (str); + //johnfitz break; - - case svc_stufftext: - // jkrige - fix demo playback across maps - // Pa3PyX: allow full frame update on stuff messages - stufftext_frame = host_framecount; - // jkrige - fix demo playback across maps + case svc_stufftext: Cbuf_AddText (MSG_ReadString ()); break; - + case svc_damage: V_ParseDamage (); break; - + case svc_serverinfo: CL_ParseServerInfo (); vid.recalc_refdef = true; // leave intermission full screen break; - + case svc_setangle: for (i=0 ; i<3 ; i++) - cl.viewangles[i] = MSG_ReadAngle (); + cl.viewangles[i] = MSG_ReadAngle (cl.protocolflags); break; - + case svc_setview: cl.viewentity = MSG_ReadShort (); break; - + case svc_lightstyle: i = MSG_ReadByte (); if (i >= MAX_LIGHTSTYLES) Sys_Error ("svc_lightstyle > MAX_LIGHTSTYLES"); - Q_strcpy (cl_lightstyle[i].map, MSG_ReadString()); + q_strlcpy (cl_lightstyle[i].map, MSG_ReadString(), MAX_STYLESTRING); cl_lightstyle[i].length = Q_strlen(cl_lightstyle[i].map); + //johnfitz -- save extra info + if (cl_lightstyle[i].length) + { + total = 0; + cl_lightstyle[i].peak = 'a'; + for (j=0; j>3, i&7); break; - + case svc_updatename: - //Sbar_Changed (); // jkrige - always draw sbar + Sbar_Changed (); i = MSG_ReadByte (); if (i >= cl.maxclients) Host_Error ("CL_ParseServerMessage: svc_updatename > MAX_SCOREBOARD"); - strcpy (cl.scores[i].name, MSG_ReadString ()); + q_strlcpy (cl.scores[i].name, MSG_ReadString(), MAX_SCOREBOARDNAME); break; - + case svc_updatefrags: - //Sbar_Changed (); // jkrige - always draw sbar + Sbar_Changed (); i = MSG_ReadByte (); if (i >= cl.maxclients) Host_Error ("CL_ParseServerMessage: svc_updatefrags > MAX_SCOREBOARD"); cl.scores[i].frags = MSG_ReadShort (); - break; + break; case svc_updatecolors: - //Sbar_Changed (); // jkrige - always draw sbar + Sbar_Changed (); i = MSG_ReadByte (); if (i >= cl.maxclients) Host_Error ("CL_ParseServerMessage: svc_updatecolors > MAX_SCOREBOARD"); cl.scores[i].colors = MSG_ReadByte (); CL_NewTranslation (i); break; - + case svc_particle: R_ParseParticleEffect (); break; @@ -884,53 +1110,44 @@ void CL_ParseServerMessage (void) case svc_spawnbaseline: i = MSG_ReadShort (); // must use CL_EntityNum() to force cl.num_entities up - CL_ParseBaseline (CL_EntityNum(i)); + CL_ParseBaseline (CL_EntityNum(i), 1); // johnfitz -- added second parameter break; + case svc_spawnstatic: - CL_ParseStatic (); - break; + CL_ParseStatic (1); //johnfitz -- added parameter + break; + case svc_temp_entity: CL_ParseTEnt (); break; case svc_setpause: + cl.paused = MSG_ReadByte (); + if (cl.paused) { - cl.paused = MSG_ReadByte (); - - if (cl.paused) - { - // jkrige - fmod sound system - begin -#ifdef UQE_FMOD - FMOD_MusicPause(); -#else - CDAudio_Pause(); -#endif - // jkrige - fmod sound system - end -#ifdef _WIN32 - VID_HandlePause (true); -#endif - } - else - { - // jkrige - fmod sound system - begin -#ifdef UQE_FMOD - FMOD_MusicResume(); -#else - CDAudio_Resume(); -#endif - // jkrige - fmod sound system - end -#ifdef _WIN32 - VID_HandlePause (false); -#endif - } + CDAudio_Pause (); + BGM_Pause (); + } + else + { + CDAudio_Resume (); + BGM_Resume (); } break; - + case svc_signonnum: i = MSG_ReadByte (); if (i <= cls.signon) Host_Error ("Received signon %i when at %i", i, cls.signon); cls.signon = i; + //johnfitz -- if signonnum==2, signon packet has been fully parsed, so check for excessive static ents and efrags + if (i == 2) + { + if (cl.num_statics > 128) + Con_DWarning ("%i static entities exceeds standard limit of 128 (max = %d).\n", cl.num_statics, MAX_STATIC_ENTITIES); + R_CheckEfrags (); + } + //johnfitz CL_SignonReply (); break; @@ -948,54 +1165,19 @@ void CL_ParseServerMessage (void) Sys_Error ("svc_updatestat: %i is invalid", i); cl.stats[i] = MSG_ReadLong ();; break; - + case svc_spawnstaticsound: - CL_ParseStaticSound (); + CL_ParseStaticSound (1); //johnfitz -- added parameter break; case svc_cdtrack: cl.cdtrack = MSG_ReadByte (); cl.looptrack = MSG_ReadByte (); - byte cdtrack; - - // jkrige - invalid track number (hipnotic demo) - // if the demo playback returns with an invalid track number, set forcetrack to -1 - if (cls.demoplayback && cls.forcetrack < -1) - cls.forcetrack = -1; - // jkrige - invalid track number (hipnotic demo) - - if ((cls.demoplayback || cls.demorecording) && (cls.forcetrack != -1)) - { - if (cls.forcetrack == 1) - cls.forcetrack++; - - cdtrack = (byte)cls.forcetrack; - } + if ( (cls.demoplayback || cls.demorecording) && (cls.forcetrack != -1) ) + BGM_PlayCDtrack ((byte)cls.forcetrack, true); else - { - cdtrack = (byte)cl.cdtrack; - } - - // jkrige - fmod sound system - begin -#ifdef UQE_FMOD - FMOD_MusicStart(va("%i", (int)cdtrack), true, false); -#else - CDAudio_Play(cdtrack, true); -#endif - // jkrige - fmod sound system - end - break; - - // jkrige - skybox - case svc_skybox: - strcpy(cl.skybox, MSG_ReadString()); -#ifdef GLQUAKE - Cvar_Set("gl_skytype", "0"); - if (strcmpi(cl.skybox, "") != 0) - R_LoadSkys (); -#endif - + BGM_PlayCDtrack ((byte)cl.cdtrack, true); break; - // jkrige - skybox case svc_intermission: cl.intermission = 1; @@ -1007,20 +1189,58 @@ void CL_ParseServerMessage (void) cl.intermission = 2; cl.completed_time = cl.time; vid.recalc_refdef = true; // go to full screen - SCR_CenterPrint (MSG_ReadString ()); + //johnfitz -- log centerprints to console + str = MSG_ReadString (); + SCR_CenterPrint (str); + Con_LogCenterPrint (str); + //johnfitz break; case svc_cutscene: cl.intermission = 3; cl.completed_time = cl.time; vid.recalc_refdef = true; // go to full screen - SCR_CenterPrint (MSG_ReadString ()); + //johnfitz -- log centerprints to console + str = MSG_ReadString (); + SCR_CenterPrint (str); + Con_LogCenterPrint (str); + //johnfitz break; case svc_sellscreen: Cmd_ExecuteString ("help", src_command); break; + + //johnfitz -- new svc types + case svc_skybox: + Sky_LoadSkyBox (MSG_ReadString()); + break; + + case svc_bf: + Cmd_ExecuteString ("bf", src_command); + break; + + case svc_fog: + Fog_ParseServerMessage (); + break; + + case svc_spawnbaseline2: //PROTOCOL_FITZQUAKE + i = MSG_ReadShort (); + // must use CL_EntityNum() to force cl.num_entities up + CL_ParseBaseline (CL_EntityNum(i), 2); + break; + + case svc_spawnstatic2: //PROTOCOL_FITZQUAKE + CL_ParseStatic (2); + break; + + case svc_spawnstaticsound2: //PROTOCOL_FITZQUAKE + CL_ParseStaticSound (2); + break; + //johnfitz } + + lastcmd = cmd; //johnfitz } } diff --git a/engine/code/cl_tent.c b/engine/Quake/cl_tent.c similarity index 73% rename from engine/code/cl_tent.c rename to engine/Quake/cl_tent.c index 546e832..b1c9b8c 100644 --- a/engine/code/cl_tent.c +++ b/engine/Quake/cl_tent.c @@ -1,5 +1,7 @@ /* -Copyright (C) 1996-1997 Id Software, Inc. +Copyright (C) 1996-2001 Id Software, Inc. +Copyright (C) 2002-2009 John Fitzgibbons and others +Copyright (C) 2010-2014 QuakeSpasm developers This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -8,7 +10,7 @@ of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. @@ -32,10 +34,6 @@ sfx_t *cl_sfx_ric1; sfx_t *cl_sfx_ric2; sfx_t *cl_sfx_ric3; sfx_t *cl_sfx_r_exp3; -#ifdef QUAKE2 -sfx_t *cl_sfx_imp; -sfx_t *cl_sfx_rail; -#endif /* ================= @@ -51,10 +49,6 @@ void CL_InitTEnts (void) cl_sfx_ric2 = S_PrecacheSound ("weapons/ric2.wav"); cl_sfx_ric3 = S_PrecacheSound ("weapons/ric3.wav"); cl_sfx_r_exp3 = S_PrecacheSound ("weapons/r_exp3.wav"); -#ifdef QUAKE2 - cl_sfx_imp = S_PrecacheSound ("shambler/sattck1.wav"); - cl_sfx_rail = S_PrecacheSound ("weapons/lstart.wav"); -#endif } /* @@ -62,22 +56,22 @@ void CL_InitTEnts (void) CL_ParseBeam ================= */ -void CL_ParseBeam (model_t *m) +void CL_ParseBeam (qmodel_t *m) { int ent; vec3_t start, end; beam_t *b; int i; - + ent = MSG_ReadShort (); - - start[0] = MSG_ReadCoord (); - start[1] = MSG_ReadCoord (); - start[2] = MSG_ReadCoord (); - - end[0] = MSG_ReadCoord (); - end[1] = MSG_ReadCoord (); - end[2] = MSG_ReadCoord (); + + start[0] = MSG_ReadCoord (cl.protocolflags); + start[1] = MSG_ReadCoord (cl.protocolflags); + start[2] = MSG_ReadCoord (cl.protocolflags); + + end[0] = MSG_ReadCoord (cl.protocolflags); + end[1] = MSG_ReadCoord (cl.protocolflags); + end[2] = MSG_ReadCoord (cl.protocolflags); // override any beam with the same entity for (i=0, b=cl_beams ; i< MAX_BEAMS ; i++, b++) @@ -104,7 +98,14 @@ void CL_ParseBeam (model_t *m) return; } } - Con_Printf ("beam list overflow!\n"); + + //johnfitz -- less spammy overflow message + if (!dev_overflows.beams || dev_overflows.beams + CONSOLE_RESPAM_TIME < realtime ) + { + Con_Printf ("Beam list overflow!\n"); + dev_overflows.beams = realtime; + } + //johnfitz } /* @@ -116,9 +117,6 @@ void CL_ParseTEnt (void) { int type; vec3_t pos; -#ifdef QUAKE2 - vec3_t endpos; -#endif dlight_t *dl; int rnd; int colorStart, colorLength; @@ -127,30 +125,26 @@ void CL_ParseTEnt (void) switch (type) { case TE_WIZSPIKE: // spike hitting wall - pos[0] = MSG_ReadCoord (); - pos[1] = MSG_ReadCoord (); - pos[2] = MSG_ReadCoord (); + pos[0] = MSG_ReadCoord (cl.protocolflags); + pos[1] = MSG_ReadCoord (cl.protocolflags); + pos[2] = MSG_ReadCoord (cl.protocolflags); R_RunParticleEffect (pos, vec3_origin, 20, 30); S_StartSound (-1, 0, cl_sfx_wizhit, pos, 1, 1); break; - + case TE_KNIGHTSPIKE: // spike hitting wall - pos[0] = MSG_ReadCoord (); - pos[1] = MSG_ReadCoord (); - pos[2] = MSG_ReadCoord (); + pos[0] = MSG_ReadCoord (cl.protocolflags); + pos[1] = MSG_ReadCoord (cl.protocolflags); + pos[2] = MSG_ReadCoord (cl.protocolflags); R_RunParticleEffect (pos, vec3_origin, 226, 20); S_StartSound (-1, 0, cl_sfx_knighthit, pos, 1, 1); break; - + case TE_SPIKE: // spike hitting wall - pos[0] = MSG_ReadCoord (); - pos[1] = MSG_ReadCoord (); - pos[2] = MSG_ReadCoord (); -#ifdef GLTEST - Test_Spawn (pos); -#else + pos[0] = MSG_ReadCoord (cl.protocolflags); + pos[1] = MSG_ReadCoord (cl.protocolflags); + pos[2] = MSG_ReadCoord (cl.protocolflags); R_RunParticleEffect (pos, vec3_origin, 0, 10); -#endif if ( rand() % 5 ) S_StartSound (-1, 0, cl_sfx_tink1, pos, 1, 1); else @@ -165,9 +159,9 @@ void CL_ParseTEnt (void) } break; case TE_SUPERSPIKE: // super spike hitting wall - pos[0] = MSG_ReadCoord (); - pos[1] = MSG_ReadCoord (); - pos[2] = MSG_ReadCoord (); + pos[0] = MSG_ReadCoord (cl.protocolflags); + pos[1] = MSG_ReadCoord (cl.protocolflags); + pos[2] = MSG_ReadCoord (cl.protocolflags); R_RunParticleEffect (pos, vec3_origin, 0, 20); if ( rand() % 5 ) @@ -183,18 +177,18 @@ void CL_ParseTEnt (void) S_StartSound (-1, 0, cl_sfx_ric3, pos, 1, 1); } break; - + case TE_GUNSHOT: // bullet hitting wall - pos[0] = MSG_ReadCoord (); - pos[1] = MSG_ReadCoord (); - pos[2] = MSG_ReadCoord (); + pos[0] = MSG_ReadCoord (cl.protocolflags); + pos[1] = MSG_ReadCoord (cl.protocolflags); + pos[2] = MSG_ReadCoord (cl.protocolflags); R_RunParticleEffect (pos, vec3_origin, 0, 20); break; - + case TE_EXPLOSION: // rocket explosion - pos[0] = MSG_ReadCoord (); - pos[1] = MSG_ReadCoord (); - pos[2] = MSG_ReadCoord (); + pos[0] = MSG_ReadCoord (cl.protocolflags); + pos[1] = MSG_ReadCoord (cl.protocolflags); + pos[2] = MSG_ReadCoord (cl.protocolflags); R_ParticleExplosion (pos); dl = CL_AllocDlight (0); VectorCopy (pos, dl->origin); @@ -203,11 +197,11 @@ void CL_ParseTEnt (void) dl->decay = 300; S_StartSound (-1, 0, cl_sfx_r_exp3, pos, 1, 1); break; - + case TE_TAREXPLOSION: // tarbaby explosion - pos[0] = MSG_ReadCoord (); - pos[1] = MSG_ReadCoord (); - pos[2] = MSG_ReadCoord (); + pos[0] = MSG_ReadCoord (cl.protocolflags); + pos[1] = MSG_ReadCoord (cl.protocolflags); + pos[2] = MSG_ReadCoord (cl.protocolflags); R_BlobExplosion (pos); S_StartSound (-1, 0, cl_sfx_r_exp3, pos, 1, 1); @@ -216,39 +210,39 @@ void CL_ParseTEnt (void) case TE_LIGHTNING1: // lightning bolts CL_ParseBeam (Mod_ForName("progs/bolt.mdl", true)); break; - + case TE_LIGHTNING2: // lightning bolts CL_ParseBeam (Mod_ForName("progs/bolt2.mdl", true)); break; - + case TE_LIGHTNING3: // lightning bolts CL_ParseBeam (Mod_ForName("progs/bolt3.mdl", true)); break; - -// PGM 01/21/97 + +// PGM 01/21/97 case TE_BEAM: // grappling hook beam CL_ParseBeam (Mod_ForName("progs/beam.mdl", true)); break; // PGM 01/21/97 - case TE_LAVASPLASH: - pos[0] = MSG_ReadCoord (); - pos[1] = MSG_ReadCoord (); - pos[2] = MSG_ReadCoord (); + case TE_LAVASPLASH: + pos[0] = MSG_ReadCoord (cl.protocolflags); + pos[1] = MSG_ReadCoord (cl.protocolflags); + pos[2] = MSG_ReadCoord (cl.protocolflags); R_LavaSplash (pos); break; - + case TE_TELEPORT: - pos[0] = MSG_ReadCoord (); - pos[1] = MSG_ReadCoord (); - pos[2] = MSG_ReadCoord (); + pos[0] = MSG_ReadCoord (cl.protocolflags); + pos[1] = MSG_ReadCoord (cl.protocolflags); + pos[2] = MSG_ReadCoord (cl.protocolflags); R_TeleportSplash (pos); break; - + case TE_EXPLOSION2: // color mapped explosion - pos[0] = MSG_ReadCoord (); - pos[1] = MSG_ReadCoord (); - pos[2] = MSG_ReadCoord (); + pos[0] = MSG_ReadCoord (cl.protocolflags); + pos[1] = MSG_ReadCoord (cl.protocolflags); + pos[2] = MSG_ReadCoord (cl.protocolflags); colorStart = MSG_ReadByte (); colorLength = MSG_ReadByte (); R_ParticleExplosion2 (pos, colorStart, colorLength); @@ -259,33 +253,6 @@ void CL_ParseTEnt (void) dl->decay = 300; S_StartSound (-1, 0, cl_sfx_r_exp3, pos, 1, 1); break; - -#ifdef QUAKE2 - case TE_IMPLOSION: - pos[0] = MSG_ReadCoord (); - pos[1] = MSG_ReadCoord (); - pos[2] = MSG_ReadCoord (); - S_StartSound (-1, 0, cl_sfx_imp, pos, 1, 1); - break; - - case TE_RAILTRAIL: - pos[0] = MSG_ReadCoord (); - pos[1] = MSG_ReadCoord (); - pos[2] = MSG_ReadCoord (); - endpos[0] = MSG_ReadCoord (); - endpos[1] = MSG_ReadCoord (); - endpos[2] = MSG_ReadCoord (); - S_StartSound (-1, 0, cl_sfx_rail, pos, 1, 1); - S_StartSound (-1, 1, cl_sfx_r_exp3, endpos, 1, 1); - R_RocketTrail (pos, endpos, 0+128); - R_ParticleExplosion (endpos); - dl = CL_AllocDlight (-1); - VectorCopy (endpos, dl->origin); - dl->radius = 350; - dl->die = cl.time + 0.5; - dl->decay = 300; - break; -#endif default: Sys_Error ("CL_ParseTEnt: bad type"); @@ -324,7 +291,7 @@ CL_UpdateTEnts */ void CL_UpdateTEnts (void) { - int i; + int i, j; //johnfitz -- use j instead of using i twice, so we don't corrupt memory beam_t *b; vec3_t dist, org; float d; @@ -334,6 +301,8 @@ void CL_UpdateTEnts (void) num_temp_entities = 0; + srand ((int) (cl.time * 1000)); //johnfitz -- freeze beams when paused + // update lightning for (i=0, b=cl_beams ; i< MAX_BEAMS ; i++, b++) { @@ -362,7 +331,7 @@ void CL_UpdateTEnts (void) yaw = (int) (atan2(dist[1], dist[0]) * 180 / M_PI); if (yaw < 0) yaw += 360; - + forward = sqrt (dist[0]*dist[0] + dist[1]*dist[1]); pitch = (int) (atan2(dist[2], forward) * 180 / M_PI); if (pitch < 0) @@ -383,12 +352,10 @@ void CL_UpdateTEnts (void) ent->angles[1] = yaw; ent->angles[2] = rand()%360; - for (i=0 ; i<3 ; i++) - org[i] += dist[i]*30; + //johnfitz -- use j instead of using i twice, so we don't corrupt memory + for (j=0 ; j<3 ; j++) + org[j] += dist[j]*30; d -= 30; } } - } - - diff --git a/engine/code/client.h b/engine/Quake/client.h similarity index 75% rename from engine/code/client.h rename to engine/Quake/client.h index cb83143..1c7db18 100644 --- a/engine/code/client.h +++ b/engine/Quake/client.h @@ -1,5 +1,7 @@ /* -Copyright (C) 1996-1997 Id Software, Inc. +Copyright (C) 1996-2001 Id Software, Inc. +Copyright (C) 2002-2009 John Fitzgibbons and others +Copyright (C) 2010-2014 QuakeSpasm developers This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -8,7 +10,7 @@ of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. @@ -17,27 +19,18 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -// client.h - -typedef struct -{ - vec3_t viewangles; - -// intended velocities - float forwardmove; - float sidemove; - float upmove; -#ifdef QUAKE2 - byte lightlevel; -#endif +#ifndef _CLIENT_H_ +#define _CLIENT_H_ -} usercmd_t; +// client.h typedef struct { int length; char map[MAX_STYLESTRING]; + char average; //johnfitz + char peak; //johnfitz } lightstyle_t; typedef struct @@ -70,12 +63,7 @@ typedef struct #define SIGNONS 4 // signon messages to receive before connected -// jkrige - increase dlights -//#define MAX_DLIGHTS 32 -#define MAX_DLIGHTS 64 -// jkrige - increase dlights - - +#define MAX_DLIGHTS 64 //johnfitz -- was 32 typedef struct { vec3_t origin; @@ -84,28 +72,19 @@ typedef struct float decay; // drop this each second float minlight; // don't add when contributing less int key; -#ifdef QUAKE2 - qboolean dark; // subtracts light instead of adding -#endif - - // jkrige - .lit colored lights - vec3_t color; - // jkrige - .lit colored lights - + vec3_t color; //johnfitz -- lit support via lordhavoc } dlight_t; -#define MAX_BEAMS 24 +#define MAX_BEAMS 32 //johnfitz -- was 24 typedef struct { int entity; - struct model_s *model; + struct qmodel_s *model; float endtime; vec3_t start, end; } beam_t; -#define MAX_EFRAGS 640 - #define MAX_MAPSTRING 2048 #define MAX_DEMOS 8 #define MAX_DEMONAME 16 @@ -124,38 +103,34 @@ typedef struct { cactive_t state; -// personalization data sent to server - char mapstring[MAX_QPATH]; +// personalization data sent to server char spawnparms[MAX_MAPSTRING]; // to restart a level // demo loop control - int demonum; // -1 = don't play demos - char demos[MAX_DEMOS][MAX_DEMONAME]; // when not playing + int demonum; // -1 = don't play demos + char demos[MAX_DEMOS][MAX_DEMONAME]; // when not playing // demo recording info must be here, because record is started before // entering a map (and clearing client_state_t) qboolean demorecording; qboolean demoplayback; - qboolean timedemo; - int forcetrack; // -1 = use normal cd track - FILE *demofile; - // jkrige - pk3 file support - byte *demobuffer; - int demobufferlength; - int demobufferposition; - // jkrige - pk3 file support +// did the user pause demo playback? (separate from cl.paused because we don't +// want a svc_setpause inside the demo to actually pause demo playback). + qboolean demopaused; - int td_lastframe; // to meter out one message a frame - int td_startframe; // host_framecount at start + qboolean timedemo; + int forcetrack; // -1 = use normal cd track + FILE *demofile; + int td_lastframe; // to meter out one message a frame + int td_startframe; // host_framecount at start float td_starttime; // realtime at second frame of timedemo - // connection information - int signon; // 0 to SIGNONS + int signon; // 0 to SIGNONS struct qsocket_s *netcon; sizebuf_t message; // writing buffer to send to server - + } client_static_t; extern client_static_t cls; @@ -168,7 +143,7 @@ typedef struct { int movemessages; // since connecting to this server // throw out the first couple, so the player - // doesn't accidentally do something the + // doesn't accidentally do something the // first frame usercmd_t cmd; // last command sent to the server @@ -188,13 +163,13 @@ typedef struct vec3_t mviewangles[2]; // during demo playback viewangles is lerped // between these vec3_t viewangles; - + vec3_t mvelocity[2]; // update by server, used for lean+bob // (0 is newest) vec3_t velocity; // lerped between mvelocity[0] and [1] vec3_t punchangle; // temporary offset - + // pitch drifting vars float idealpitch; float pitchvel; @@ -209,53 +184,46 @@ typedef struct qboolean onground; qboolean inwater; - int intermission; // don't change view angle, full screen, etc int completed_time; // latched at intermission start - - double mtime[2]; // the timestamp of last two messages + + double mtime[2]; // the timestamp of last two messages double time; // clients view of time, should be between // servertime and oldservertime to generate // a lerp point for other data double oldtime; // previous cl.time, time-oldtime is used // to decay light values and smooth step ups - + float last_received_message; // (realtime) for net trouble icon // // information that is static for the entire time connected to a server // - struct model_s *model_precache[MAX_MODELS]; + struct qmodel_s *model_precache[MAX_MODELS]; struct sfx_s *sound_precache[MAX_SOUNDS]; - char levelname[40]; // for display on solo scoreboard + char mapname[128]; + char levelname[128]; // for display on solo scoreboard //johnfitz -- was 40. int viewentity; // cl_entitites[cl.viewentity] = player int maxclients; int gametype; // refresh related state - struct model_s *worldmodel; // cl_entitites[0].model + struct qmodel_s *worldmodel; // cl_entitites[0].model struct efrag_s *free_efrags; + int num_efrags; int num_entities; // held in cl_entities array int num_statics; // held in cl_staticentities array entity_t viewent; // the gun model int cdtrack, looptrack; // cd audio - // jkrige - skybox - char skybox[128]; - // jkrige - skybox - // frag scoreboard scoreboard_t *scores; // [cl.maxclients] -#ifdef QUAKE2 -// light level at player's position including dlights -// this is sent back to the server each frame -// architectually ugly but it works - int light_level; -#endif + unsigned protocol; //johnfitz + unsigned protocolflags; } client_state_t; @@ -277,44 +245,43 @@ extern cvar_t cl_pitchspeed; extern cvar_t cl_anglespeedkey; +extern cvar_t cl_alwaysrun; // QuakeSpasm + extern cvar_t cl_autofire; extern cvar_t cl_shownet; extern cvar_t cl_nolerp; -// jkrige - configurable fps caps -extern cvar_t cl_maxfps; -// jkrige - configurable fps caps +extern cvar_t cfg_unbindall; extern cvar_t cl_pitchdriftspeed; extern cvar_t lookspring; extern cvar_t lookstrafe; extern cvar_t sensitivity; -extern cvar_t crosshair; // jkrige - crosshair - -extern cvar_t cl_mlook; // jkrige - mlook cvar -extern cvar_t cl_slook; // jkrige - slook cvar - extern cvar_t m_pitch; extern cvar_t m_yaw; extern cvar_t m_forward; extern cvar_t m_side; -#define MAX_TEMP_ENTITIES 64 // lightning bolts, etc -#define MAX_STATIC_ENTITIES 128 // torches, etc +#define MAX_TEMP_ENTITIES 256 //johnfitz -- was 64 +#define MAX_STATIC_ENTITIES 4096 //ericw -- was 512 //johnfitz -- was 128 +#define MAX_VISEDICTS 4096 // larger, now we support BSP2 extern client_state_t cl; // FIXME, allocate dynamically -extern efrag_t cl_efrags[MAX_EFRAGS]; -extern entity_t cl_entities[MAX_EDICTS]; extern entity_t cl_static_entities[MAX_STATIC_ENTITIES]; extern lightstyle_t cl_lightstyle[MAX_LIGHTSTYLES]; extern dlight_t cl_dlights[MAX_DLIGHTS]; extern entity_t cl_temp_entities[MAX_TEMP_ENTITIES]; extern beam_t cl_beams[MAX_BEAMS]; +extern entity_t *cl_visedicts[MAX_VISEDICTS]; +extern int cl_numvisedicts; + +extern entity_t *cl_entities; //johnfitz -- was a static array, now on hunk +extern int cl_max_edicts; //johnfitz -- only changes when new map loads //============================================================================= @@ -326,7 +293,7 @@ void CL_DecayLights (void); void CL_Init (void); -void CL_EstablishConnection (char *host); +void CL_EstablishConnection (const char *host); void CL_Signon1 (void); void CL_Signon2 (void); void CL_Signon3 (void); @@ -336,10 +303,6 @@ void CL_Disconnect (void); void CL_Disconnect_f (void); void CL_NextDemo (void); -#define MAX_VISEDICTS 256 -extern int cl_numvisedicts; -extern entity_t *cl_visedicts[MAX_VISEDICTS]; - // // cl_input // @@ -349,28 +312,21 @@ typedef struct int state; // low bit is down state } kbutton_t; -//extern kbutton_t /*in_mlook,*/ in_klook; // jkrige - mlook cvar, removed klook command +extern kbutton_t in_mlook, in_klook; extern kbutton_t in_strafe; extern kbutton_t in_speed; void CL_InitInput (void); void CL_SendCmd (void); -void CL_SendMove (usercmd_t *cmd); +void CL_SendMove (const usercmd_t *cmd); +int CL_ReadFromServer (void); +void CL_BaseMove (usercmd_t *cmd); void CL_ParseTEnt (void); void CL_UpdateTEnts (void); void CL_ClearState (void); - -int CL_ReadFromServer (void); -void CL_WriteToServer (usercmd_t *cmd); -void CL_BaseMove (usercmd_t *cmd); - - -float CL_KeyState (kbutton_t *key); -char *Key_KeynumToString (int keynum); - // // cl_demo.c // @@ -395,14 +351,26 @@ void V_StartPitchDrift (void); void V_StopPitchDrift (void); void V_RenderView (void); -void V_UpdatePalette (void); +//void V_UpdatePalette (void); //johnfitz void V_Register (void); void V_ParseDamage (void); void V_SetContentsColor (int contents); - // // cl_tent // void CL_InitTEnts (void); void CL_SignonReply (void); + +// +// chase +// +extern cvar_t chase_active; + +void Chase_Init (void); +void TraceLine (vec3_t start, vec3_t end, vec3_t impact); +void Chase_UpdateForClient (void); //johnfitz +void Chase_UpdateForDrawing (void); //johnfitz + +#endif /* _CLIENT_H_ */ + diff --git a/engine/code/cmd.c b/engine/Quake/cmd.c similarity index 56% rename from engine/code/cmd.c rename to engine/Quake/cmd.c index 7ca11ec..783475f 100644 --- a/engine/code/cmd.c +++ b/engine/Quake/cmd.c @@ -1,5 +1,8 @@ /* -Copyright (C) 1996-1997 Id Software, Inc. +Copyright (C) 1996-2001 Id Software, Inc. +Copyright (C) 2002-2009 John Fitzgibbons and others +Copyright (C) 2007-2008 Kristian Duske +Copyright (C) 2010-2014 QuakeSpasm developers This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -8,7 +11,7 @@ of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. @@ -25,6 +28,8 @@ void Cmd_ForwardToServer (void); #define MAX_ALIAS_NAME 32 +#define CMDLINE_LENGTH 256 //johnfitz -- mirrored in common.c + typedef struct cmdalias_s { struct cmdalias_s *next; @@ -34,9 +39,6 @@ typedef struct cmdalias_s cmdalias_t *cmd_alias; -int trashtest; -int *trashspot; - qboolean cmd_wait; //============================================================================= @@ -72,7 +74,7 @@ Cbuf_Init */ void Cbuf_Init (void) { - SZ_Alloc (&cmd_text, 8192); // space for commands and script files + SZ_Alloc (&cmd_text, 1<<18); // space for commands and script files. spike -- was 8192, but modern configs can be _HUGE_, at least if they contain lots of comments/docs for things. } @@ -83,10 +85,10 @@ Cbuf_AddText Adds command text at the end of the buffer ============ */ -void Cbuf_AddText (char *text) +void Cbuf_AddText (const char *text) { int l; - + l = Q_strlen (text); if (cmd_text.cursize + l >= cmd_text.maxsize) @@ -108,7 +110,7 @@ Adds a \n to the text FIXME: actually change the command buffer to do less copying ============ */ -void Cbuf_InsertText (char *text) +void Cbuf_InsertText (const char *text) { char *temp; int templen; @@ -117,16 +119,16 @@ void Cbuf_InsertText (char *text) templen = cmd_text.cursize; if (templen) { - temp = Z_Malloc (templen); + temp = (char *) Z_Malloc (templen); Q_memcpy (temp, cmd_text.data, templen); SZ_Clear (&cmd_text); } else temp = NULL; // shut up compiler - + // add the entire text of the file Cbuf_AddText (text); - + SZ_Write (&cmd_text, "\n", 1); // add the copied off data if (templen) { @@ -146,7 +148,7 @@ void Cbuf_Execute (void) char *text; char line[1024]; int quotes; - + while (cmd_text.cursize) { // find a \n or ; line break @@ -162,11 +164,18 @@ void Cbuf_Execute (void) if (text[i] == '\n') break; } - - - memcpy (line, text, i); - line[i] = 0; - + + if (i > (int)sizeof(line) - 1) + { + memcpy (line, text, sizeof(line) - 1); + line[sizeof(line) - 1] = 0; + } + else + { + memcpy (line, text, i); + line[i] = 0; + } + // delete the text from the command buffer and move remaining commands down // this is necessary because commands (exec, alias) can insert data at the // beginning of the text buffer @@ -177,12 +186,12 @@ void Cbuf_Execute (void) { i++; cmd_text.cursize -= i; - Q_memcpy (text, text+i, cmd_text.cursize); + memmove (text, text + i, cmd_text.cursize); } // execute the command line Cmd_ExecuteString (line, src_command); - + if (cmd_wait) { // skip out while text still remains in buffer, leaving it // for next frame @@ -202,7 +211,7 @@ void Cbuf_Execute (void) /* =============== -Cmd_StuffCmds_f +Cmd_StuffCmds_f -- johnfitz -- rewritten to read the "cmdline" cvar, for use with dynamic mod loading Adds command line parameters as script statements Commands lead with a +, and continue until a - or another + @@ -212,66 +221,32 @@ quake -nosound +cmd amlev1 */ void Cmd_StuffCmds_f (void) { - int i, j; - int s; - char *text, *build, c; - - if (Cmd_Argc () != 1) - { - Con_Printf ("stuffcmds : execute command line parameters\n"); - return; - } + extern cvar_t cmdline; + char cmds[CMDLINE_LENGTH]; + int i, j, plus; -// build the combined string to parse from - s = 0; - for (i=1 ; i 0) + { + cmds[j-1] = ';'; + cmds[j++] = ' '; + } } + else if (cmdline.string[i] == '-' && + (i==0 || cmdline.string[i-1] == ' ')) //johnfitz -- allow hypenated map names with +map + plus = false; + else if (plus) + cmds[j++] = cmdline.string[i]; } - - if (build[0]) - Cbuf_InsertText (build); - - Z_Free (text); - Z_Free (build); + cmds[j] = 0; + + Cbuf_InsertText (cmds); } @@ -292,14 +267,14 @@ void Cmd_Exec_f (void) } mark = Hunk_LowMark (); - f = (char *)COM_LoadHunkFile (Cmd_Argv(1)); + f = (char *)COM_LoadHunkFile (Cmd_Argv(1), NULL); if (!f) { Con_Printf ("couldn't exec %s\n",Cmd_Argv(1)); return; } Con_Printf ("execing %s\n",Cmd_Argv(1)); - + Cbuf_InsertText (f); Hunk_FreeToLowMark (mark); } @@ -315,7 +290,7 @@ Just prints the rest of the line to the console void Cmd_Echo_f (void) { int i; - + for (i=1 ; inext, i++) + Con_SafePrintf (" %s: %s", a->name, a->value); + if (i) + Con_SafePrintf ("%i alias command(s)\n", i); + else + Con_SafePrintf ("no alias commands found\n"); + break; + case 2: //output current alias string for (a = cmd_alias ; a ; a=a->next) - Con_Printf ("%s : %s\n", a->name, a->value); - return; - } + if (!strcmp(Cmd_Argv(1), a->name)) + Con_Printf (" %s: %s", a->name, a->value); + break; + default: //set alias string + s = Cmd_Argv(1); + if (strlen(s) >= MAX_ALIAS_NAME) + { + Con_Printf ("Alias name is too long\n"); + return; + } - s = Cmd_Argv(1); - if (strlen(s) >= MAX_ALIAS_NAME) - { - Con_Printf ("Alias name is too long\n"); - return; - } + // if the alias allready exists, reuse it + for (a = cmd_alias ; a ; a=a->next) + { + if (!strcmp(s, a->name)) + { + Z_Free (a->value); + break; + } + } - // if the alias allready exists, reuse it - for (a = cmd_alias ; a ; a=a->next) - { - if (!strcmp(s, a->name)) + if (!a) { - Z_Free (a->value); - break; + a = (cmdalias_t *) Z_Malloc (sizeof(cmdalias_t)); + a->next = cmd_alias; + cmd_alias = a; + } + strcpy (a->name, s); + + // copy the rest of the command line + cmd[0] = 0; // start out with a null string + c = Cmd_Argc(); + for (i = 2; i < c; i++) + { + q_strlcat (cmd, Cmd_Argv(i), sizeof(cmd)); + if (i != c - 1) + q_strlcat (cmd, " ", sizeof(cmd)); + } + if (q_strlcat(cmd, "\n", sizeof(cmd)) >= sizeof(cmd)) + { + Con_Printf("alias value too long!\n"); + cmd[0] = '\n'; // nullify the string + cmd[1] = 0; } + + a->value = Z_Strdup (cmd); + break; } +} + +/* +=============== +Cmd_Unalias_f -- johnfitz +=============== +*/ +void Cmd_Unalias_f (void) +{ + cmdalias_t *a, *prev; - if (!a) + switch (Cmd_Argc()) { - a = Z_Malloc (sizeof(cmdalias_t)); - a->next = cmd_alias; - cmd_alias = a; + default: + case 1: + Con_Printf("unalias : delete alias\n"); + break; + case 2: + prev = NULL; + for (a = cmd_alias; a; a = a->next) + { + if (!strcmp(Cmd_Argv(1), a->name)) + { + if (prev) + prev->next = a->next; + else + cmd_alias = a->next; + + Z_Free (a->value); + Z_Free (a); + return; + } + prev = a; + } + Con_Printf ("No alias named %s\n", Cmd_Argv(1)); + break; } - strcpy (a->name, s); +} + +/* +=============== +Cmd_Unaliasall_f -- johnfitz +=============== +*/ +void Cmd_Unaliasall_f (void) +{ + cmdalias_t *blah; -// copy the rest of the command line - cmd[0] = 0; // start out with a null string - c = Cmd_Argc(); - for (i=2 ; i< c ; i++) + while (cmd_alias) { - strcat (cmd, Cmd_Argv(i)); - if (i != c) - strcat (cmd, " "); + blah = cmd_alias->next; + Z_Free(cmd_alias->value); + Z_Free(cmd_alias); + cmd_alias = blah; } - strcat (cmd, "\n"); - - a->value = CopyString (cmd); } /* @@ -403,8 +439,8 @@ void Cmd_Alias_f (void) typedef struct cmd_function_s { struct cmd_function_s *next; - char *name; - xcommand_t function; + const char *name; + xcommand_t function; } cmd_function_t; @@ -412,31 +448,31 @@ typedef struct cmd_function_s static int cmd_argc; static char *cmd_argv[MAX_ARGS]; -static char *cmd_null_string = ""; -static char *cmd_args = NULL; +static char cmd_null_string[] = ""; +static const char *cmd_args = NULL; cmd_source_t cmd_source; +//johnfitz -- better tab completion +//static cmd_function_t *cmd_functions; // possible commands to execute +cmd_function_t *cmd_functions; // possible commands to execute +//johnfitz -static cmd_function_t *cmd_functions; // possible commands to execute - -// jkrige - cmdlist /* -======== -Cmd_List -======== +============ +Cmd_List_f -- johnfitz +============ */ void Cmd_List_f (void) { cmd_function_t *cmd; - char *partial; - int len; - int count; + const char *partial; + int len, count; if (Cmd_Argc() > 1) { partial = Cmd_Argv (1); - len = strlen(partial); + len = Q_strlen(partial); } else { @@ -445,26 +481,79 @@ void Cmd_List_f (void) } count=0; - for (cmd=cmd_functions ; cmd ; cmd=cmd->next) { - if (partial && strncmp (partial,cmd->name, len)) + if (partial && Q_strncmp (partial,cmd->name, len)) { continue; } - Con_Printf ("\"%s\"\n", cmd->name); + Con_SafePrintf (" %s\n", cmd->name); count++; } - Con_Printf ("%i command(s)", count); - + Con_SafePrintf ("%i commands", count); if (partial) { - Con_Printf (" beginning with \"%s\"", partial); + Con_SafePrintf (" beginning with \"%s\"", partial); } - Con_Printf ("\n"); + Con_SafePrintf ("\n"); +} + +static char *Cmd_TintSubstring(const char *in, const char *substr, char *out, size_t outsize) +{ + int l; + char *m; + q_strlcpy(out, in, outsize); + while ((m = q_strcasestr(out, substr))) + { + l = strlen(substr); + while (l-->0) + if (*m >= ' ' && *m < 127) + *m++ |= 0x80; + } + return out; +} + +/* +============ +Cmd_Apropos_f + +scans through each command and cvar names+descriptions for the given substring +we don't support descriptions, so this isn't really all that useful, but even without the sake of consistency it still combines cvars+commands under a single command. +============ +*/ +void Cmd_Apropos_f(void) +{ + char tmpbuf[256]; + int hits = 0; + cmd_function_t *cmd; + cvar_t *var; + const char *substr = Cmd_Argv (1); + if (!*substr) + { + Con_SafePrintf ("%s : search through commands and cvars for the given substring\n", Cmd_Argv(0)); + return; + } + for (cmd=cmd_functions ; cmd ; cmd=cmd->next) + { + if (q_strcasestr(cmd->name, substr)) + { + hits++; + Con_SafePrintf ("%s\n", Cmd_TintSubstring(cmd->name, substr, tmpbuf, sizeof(tmpbuf))); + } + } + + for (var=Cvar_FindVarAfter("", 0) ; var ; var=var->next) + { + if (q_strcasestr(var->name, substr)) + { + hits++; + Con_SafePrintf ("%s (current value: \"%s\")\n", Cmd_TintSubstring(var->name, substr, tmpbuf, sizeof(tmpbuf)), var->string); + } + } + if (!hits) + Con_SafePrintf ("no cvars nor commands contain that substring\n"); } -// jkrige - cmdlist /* ============ @@ -473,17 +562,19 @@ Cmd_Init */ void Cmd_Init (void) { -// -// register our commands -// + Cmd_AddCommand ("cmdlist", Cmd_List_f); //johnfitz + Cmd_AddCommand ("unalias", Cmd_Unalias_f); //johnfitz + Cmd_AddCommand ("unaliasall", Cmd_Unaliasall_f); //johnfitz + Cmd_AddCommand ("stuffcmds",Cmd_StuffCmds_f); Cmd_AddCommand ("exec",Cmd_Exec_f); Cmd_AddCommand ("echo",Cmd_Echo_f); Cmd_AddCommand ("alias",Cmd_Alias_f); Cmd_AddCommand ("cmd", Cmd_ForwardToServer); Cmd_AddCommand ("wait", Cmd_Wait_f); - Cmd_AddCommand ("cmdlist", Cmd_List_f); // jkrige - cmdlist - Cmd_AddCommand ("cvarlist", Cvar_List_f); // jkrige - cvarlist + + Cmd_AddCommand ("apropos", Cmd_Apropos_f); + Cmd_AddCommand ("find", Cmd_Apropos_f); } /* @@ -491,7 +582,7 @@ void Cmd_Init (void) Cmd_Argc ============ */ -int Cmd_Argc (void) +int Cmd_Argc (void) { return cmd_argc; } @@ -501,11 +592,11 @@ int Cmd_Argc (void) Cmd_Argv ============ */ -char *Cmd_Argv (int arg) +const char *Cmd_Argv (int arg) { - if ( (unsigned)arg >= cmd_argc ) + if (arg < 0 || arg >= cmd_argc) return cmd_null_string; - return cmd_argv[arg]; + return cmd_argv[arg]; } /* @@ -513,7 +604,7 @@ char *Cmd_Argv (int arg) Cmd_Args ============ */ -char *Cmd_Args (void) +const char *Cmd_Args (void) { return cmd_args; } @@ -526,17 +617,17 @@ Cmd_TokenizeString Parses the given string into command line tokens. ============ */ -void Cmd_TokenizeString (char *text) +void Cmd_TokenizeString (const char *text) { int i; - + // clear the args from the last string for (i=0 ; inext) { @@ -601,11 +691,29 @@ void Cmd_AddCommand (char *cmd_name, xcommand_t function) } } - cmd = Hunk_Alloc (sizeof(cmd_function_t)); + cmd = (cmd_function_t *) Hunk_Alloc (sizeof(cmd_function_t)); cmd->name = cmd_name; cmd->function = function; - cmd->next = cmd_functions; - cmd_functions = cmd; + + //johnfitz -- insert each entry in alphabetical order + if (cmd_functions == NULL || strcmp(cmd->name, cmd_functions->name) < 0) //insert at front + { + cmd->next = cmd_functions; + cmd_functions = cmd; + } + else //insert later + { + prev = cmd_functions; + cursor = cmd_functions->next; + while ((cursor != NULL) && (strcmp(cmd->name, cursor->name) > 0)) + { + prev = cursor; + cursor = cursor->next; + } + cmd->next = prev->next; + prev->next = cmd; + } + //johnfitz } /* @@ -613,7 +721,7 @@ void Cmd_AddCommand (char *cmd_name, xcommand_t function) Cmd_Exists ============ */ -qboolean Cmd_Exists (char *cmd_name) +qboolean Cmd_Exists (const char *cmd_name) { cmd_function_t *cmd; @@ -633,16 +741,16 @@ qboolean Cmd_Exists (char *cmd_name) Cmd_CompleteCommand ============ */ -char *Cmd_CompleteCommand (char *partial) +const char *Cmd_CompleteCommand (const char *partial) { cmd_function_t *cmd; - int len; - + int len; + len = Q_strlen(partial); - + if (!len) return NULL; - + // check functions for (cmd=cmd_functions ; cmd ; cmd=cmd->next) if (!Q_strncmp (partial,cmd->name, len)) @@ -659,14 +767,14 @@ A complete command line has been parsed, so try to execute it FIXME: lookupnoadd the token to speed search? ============ */ -void Cmd_ExecuteString (char *text, cmd_source_t src) -{ +void Cmd_ExecuteString (const char *text, cmd_source_t src) +{ cmd_function_t *cmd; cmdalias_t *a; cmd_source = src; Cmd_TokenizeString (text); - + // execute the command line if (!Cmd_Argc()) return; // no tokens @@ -674,7 +782,7 @@ void Cmd_ExecuteString (char *text, cmd_source_t src) // check functions for (cmd=cmd_functions ; cmd ; cmd=cmd->next) { - if (!Q_strcasecmp (cmd_argv[0],cmd->name)) + if (!q_strcasecmp (cmd_argv[0],cmd->name)) { cmd->function (); return; @@ -684,17 +792,17 @@ void Cmd_ExecuteString (char *text, cmd_source_t src) // check alias for (a=cmd_alias ; a ; a=a->next) { - if (!Q_strcasecmp (cmd_argv[0], a->name)) + if (!q_strcasecmp (cmd_argv[0], a->name)) { Cbuf_InsertText (a->value); return; } } - + // check cvars if (!Cvar_Command ()) Con_Printf ("Unknown command \"%s\"\n", Cmd_Argv(0)); - + } @@ -712,12 +820,12 @@ void Cmd_ForwardToServer (void) Con_Printf ("Can't \"%s\", not connected\n", Cmd_Argv(0)); return; } - + if (cls.demoplayback) return; // not really connected MSG_WriteByte (&cls.message, clc_stringcmd); - if (Q_strcasecmp(Cmd_Argv(0), "cmd") != 0) + if (q_strcasecmp(Cmd_Argv(0), "cmd") != 0) { SZ_Print (&cls.message, Cmd_Argv(0)); SZ_Print (&cls.message, " "); @@ -738,16 +846,17 @@ where the given parameter apears, or 0 if not present ================ */ -int Cmd_CheckParm (char *parm) +int Cmd_CheckParm (const char *parm) { int i; - + if (!parm) Sys_Error ("Cmd_CheckParm: NULL"); for (i = 1; i < Cmd_Argc (); i++) - if (! Q_strcasecmp (parm, Cmd_Argv (i))) + if (! q_strcasecmp (parm, Cmd_Argv (i))) return i; - + return 0; } + diff --git a/engine/code/cmd.h b/engine/Quake/cmd.h similarity index 83% rename from engine/code/cmd.h rename to engine/Quake/cmd.h index f9eab24..9f688e2 100644 --- a/engine/code/cmd.h +++ b/engine/Quake/cmd.h @@ -1,5 +1,7 @@ /* -Copyright (C) 1996-1997 Id Software, Inc. +Copyright (C) 1996-2001 Id Software, Inc. +Copyright (C) 2002-2009 John Fitzgibbons and others +Copyright (C) 2010-2014 QuakeSpasm developers This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -8,7 +10,7 @@ of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. @@ -18,6 +20,9 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#ifndef _QUAKE_CMD_H +#define _QUAKE_CMD_H + // cmd.h -- Command buffer and command execution //=========================================================================== @@ -34,15 +39,14 @@ The game starts with a Cbuf_AddText ("exec quake.rc\n"); Cbuf_Execute (); */ - void Cbuf_Init (void); // allocates an initial text buffer that will grow as needed -void Cbuf_AddText (char *text); +void Cbuf_AddText (const char *text); // as new commands are generated from the console or keybindings, // the text is added to the end of the command buffer. -void Cbuf_InsertText (char *text); +void Cbuf_InsertText (const char *text); // when a command wants to issue other commands immediately, the text is // inserted at the beginning of the buffer, before any remaining unexecuted // commands. @@ -79,34 +83,34 @@ extern cmd_source_t cmd_source; void Cmd_Init (void); -void Cmd_AddCommand (char *cmd_name, xcommand_t function); +void Cmd_AddCommand (const char *cmd_name, xcommand_t function); // called by the init functions of other parts of the program to // register commands and functions to call for them. // The cmd_name is referenced later, so it should not be in temp memory -qboolean Cmd_Exists (char *cmd_name); +qboolean Cmd_Exists (const char *cmd_name); // used by the cvar code to check for cvar / command name overlap -char *Cmd_CompleteCommand (char *partial); +const char *Cmd_CompleteCommand (const char *partial); // attempts to match a partial command for automatic command line completion // returns NULL if nothing fits int Cmd_Argc (void); -char *Cmd_Argv (int arg); -char *Cmd_Args (void); +const char *Cmd_Argv (int arg); +const char *Cmd_Args (void); // The functions that execute commands get their parameters with these // functions. Cmd_Argv () will return an empty string, not a NULL // if arg > argc, so string operations are allways safe. -int Cmd_CheckParm (char *parm); +int Cmd_CheckParm (const char *parm); // Returns the position (1 to argc-1) in the command's argument list // where the given parameter apears, or 0 if not present -void Cmd_TokenizeString (char *text); +void Cmd_TokenizeString (const char *text); // Takes a null terminated string. Does not need to be /n terminated. // breaks the string up into arg tokens. -void Cmd_ExecuteString (char *text, cmd_source_t src); +void Cmd_ExecuteString (const char *text, cmd_source_t src); // Parses a single line of text into arguments and tries to execute it. // The text can come from the command buffer, a remote client, or stdin. @@ -115,7 +119,9 @@ void Cmd_ForwardToServer (void); // things like godmode, noclip, etc, are commands directed to the server, // so when they are typed in at the console, they will need to be forwarded. -void Cmd_Print (char *text); +void Cmd_Print (const char *text); // used by command functions to send output to either the graphics console or // passed as a print message to the client +#endif /* _QUAKE_CMD_H */ + diff --git a/engine/Quake/common.c b/engine/Quake/common.c new file mode 100644 index 0000000..a449001 --- /dev/null +++ b/engine/Quake/common.c @@ -0,0 +1,2463 @@ +/* +Copyright (C) 1996-2001 Id Software, Inc. +Copyright (C) 2002-2009 John Fitzgibbons and others +Copyright (C) 2010-2014 QuakeSpasm developers + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +// common.c -- misc functions used in client and server + +#include "quakedef.h" +#include "q_ctype.h" +#include + +static char *largv[MAX_NUM_ARGVS + 1]; +static char argvdummy[] = " "; + +int safemode; + +cvar_t registered = {"registered","1",CVAR_ROM}; /* set to correct value in COM_CheckRegistered() */ +cvar_t cmdline = {"cmdline","",CVAR_ROM/*|CVAR_SERVERINFO*/}; /* sending cmdline upon CCREQ_RULE_INFO is evil */ + +static qboolean com_modified; // set true if using non-id files + +qboolean fitzmode; + +static void COM_Path_f (void); + +// if a packfile directory differs from this, it is assumed to be hacked +#define PAK0_COUNT 339 /* id1/pak0.pak - v1.0x */ +#define PAK0_CRC_V100 13900 /* id1/pak0.pak - v1.00 */ +#define PAK0_CRC_V101 62751 /* id1/pak0.pak - v1.01 */ +#define PAK0_CRC_V106 32981 /* id1/pak0.pak - v1.06 */ +#define PAK0_CRC (PAK0_CRC_V106) +#define PAK0_COUNT_V091 308 /* id1/pak0.pak - v0.91/0.92, not supported */ +#define PAK0_CRC_V091 28804 /* id1/pak0.pak - v0.91/0.92, not supported */ + +char com_token[1024]; +int com_argc; +char **com_argv; + +#define CMDLINE_LENGTH 256 /* johnfitz -- mirrored in cmd.c */ +char com_cmdline[CMDLINE_LENGTH]; + +qboolean standard_quake = true, rogue, hipnotic; + +// this graphic needs to be in the pak file to use registered features +static unsigned short pop[] = +{ + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, + 0x0000,0x0000,0x6600,0x0000,0x0000,0x0000,0x6600,0x0000, + 0x0000,0x0066,0x0000,0x0000,0x0000,0x0000,0x0067,0x0000, + 0x0000,0x6665,0x0000,0x0000,0x0000,0x0000,0x0065,0x6600, + 0x0063,0x6561,0x0000,0x0000,0x0000,0x0000,0x0061,0x6563, + 0x0064,0x6561,0x0000,0x0000,0x0000,0x0000,0x0061,0x6564, + 0x0064,0x6564,0x0000,0x6469,0x6969,0x6400,0x0064,0x6564, + 0x0063,0x6568,0x6200,0x0064,0x6864,0x0000,0x6268,0x6563, + 0x0000,0x6567,0x6963,0x0064,0x6764,0x0063,0x6967,0x6500, + 0x0000,0x6266,0x6769,0x6a68,0x6768,0x6a69,0x6766,0x6200, + 0x0000,0x0062,0x6566,0x6666,0x6666,0x6666,0x6562,0x0000, + 0x0000,0x0000,0x0062,0x6364,0x6664,0x6362,0x0000,0x0000, + 0x0000,0x0000,0x0000,0x0062,0x6662,0x0000,0x0000,0x0000, + 0x0000,0x0000,0x0000,0x0061,0x6661,0x0000,0x0000,0x0000, + 0x0000,0x0000,0x0000,0x0000,0x6500,0x0000,0x0000,0x0000, + 0x0000,0x0000,0x0000,0x0000,0x6400,0x0000,0x0000,0x0000 +}; + +/* + +All of Quake's data access is through a hierchal file system, but the contents +of the file system can be transparently merged from several sources. + +The "base directory" is the path to the directory holding the quake.exe and all +game directories. The sys_* files pass this to host_init in quakeparms_t->basedir. +This can be overridden with the "-basedir" command line parm to allow code +debugging in a different directory. The base directory is only used during +filesystem initialization. + +The "game directory" is the first tree on the search path and directory that all +generated files (savegames, screenshots, demos, config files) will be saved to. +This can be overridden with the "-game" command line parameter. The game +directory can never be changed while quake is executing. This is a precacution +against having a malicious server instruct clients to write files over areas they +shouldn't. + +The "cache directory" is only used during development to save network bandwidth, +especially over ISDN / T1 lines. If there is a cache directory specified, when +a file is found by the normal search path, it will be mirrored into the cache +directory, then opened there. + +FIXME: +The file "parms.txt" will be read out of the game directory and appended to the +current command line arguments to allow different games to initialize startup +parms differently. This could be used to add a "-sspeed 22050" for the high +quality sound edition. Because they are added at the end, they will not +override an explicit setting on the original command line. + +*/ + +//============================================================================ + + +// ClearLink is used for new headnodes +void ClearLink (link_t *l) +{ + l->prev = l->next = l; +} + +void RemoveLink (link_t *l) +{ + l->next->prev = l->prev; + l->prev->next = l->next; +} + +void InsertLinkBefore (link_t *l, link_t *before) +{ + l->next = before; + l->prev = before->prev; + l->prev->next = l; + l->next->prev = l; +} + +void InsertLinkAfter (link_t *l, link_t *after) +{ + l->next = after->next; + l->prev = after; + l->prev->next = l; + l->next->prev = l; +} + +/* +============================================================================ + + LIBRARY REPLACEMENT FUNCTIONS + +============================================================================ +*/ + +int q_strcasecmp(const char * s1, const char * s2) +{ + const char * p1 = s1; + const char * p2 = s2; + char c1, c2; + + if (p1 == p2) + return 0; + + do + { + c1 = q_tolower (*p1++); + c2 = q_tolower (*p2++); + if (c1 == '\0') + break; + } while (c1 == c2); + + return (int)(c1 - c2); +} + +int q_strncasecmp(const char *s1, const char *s2, size_t n) +{ + const char * p1 = s1; + const char * p2 = s2; + char c1, c2; + + if (p1 == p2 || n == 0) + return 0; + + do + { + c1 = q_tolower (*p1++); + c2 = q_tolower (*p2++); + if (c1 == '\0' || c1 != c2) + break; + } while (--n > 0); + + return (int)(c1 - c2); +} + +//spike -- grabbed this from fte, because its useful to me +char *q_strcasestr(const char *haystack, const char *needle) +{ + int c1, c2, c2f; + int i; + c2f = *needle; + if (c2f >= 'a' && c2f <= 'z') + c2f -= ('a' - 'A'); + if (!c2f) + return (char*)haystack; + while (1) + { + c1 = *haystack; + if (!c1) + return NULL; + if (c1 >= 'a' && c1 <= 'z') + c1 -= ('a' - 'A'); + if (c1 == c2f) + { + for (i = 1; ; i++) + { + c1 = haystack[i]; + c2 = needle[i]; + if (c1 >= 'a' && c1 <= 'z') + c1 -= ('a' - 'A'); + if (c2 >= 'a' && c2 <= 'z') + c2 -= ('a' - 'A'); + if (!c2) + return (char*)haystack; //end of needle means we found a complete match + if (!c1) //end of haystack means we can't possibly find needle in it any more + return NULL; + if (c1 != c2) //mismatch means no match starting at haystack[0] + break; + } + } + haystack++; + } + return NULL; //didn't find it +} + +char *q_strlwr (char *str) +{ + char *c; + c = str; + while (*c) + { + *c = q_tolower(*c); + c++; + } + return str; +} + +char *q_strupr (char *str) +{ + char *c; + c = str; + while (*c) + { + *c = q_toupper(*c); + c++; + } + return str; +} + +/* platform dependant (v)snprintf function names: */ +#if defined(_WIN32) +#define snprintf_func _snprintf +#define vsnprintf_func _vsnprintf +#else +#define snprintf_func snprintf +#define vsnprintf_func vsnprintf +#endif + +int q_vsnprintf(char *str, size_t size, const char *format, va_list args) +{ + int ret; + + ret = vsnprintf_func (str, size, format, args); + + if (ret < 0) + ret = (int)size; + if (size == 0) /* no buffer */ + return ret; + if ((size_t)ret >= size) + str[size - 1] = '\0'; + + return ret; +} + +int q_snprintf (char *str, size_t size, const char *format, ...) +{ + int ret; + va_list argptr; + + va_start (argptr, format); + ret = q_vsnprintf (str, size, format, argptr); + va_end (argptr); + + return ret; +} + +void Q_memset (void *dest, int fill, size_t count) +{ + size_t i; + + if ( (((size_t)dest | count) & 3) == 0) + { + count >>= 2; + fill = fill | (fill<<8) | (fill<<16) | (fill<<24); + for (i = 0; i < count; i++) + ((int *)dest)[i] = fill; + } + else + for (i = 0; i < count; i++) + ((byte *)dest)[i] = fill; +} + +void Q_memcpy (void *dest, const void *src, size_t count) +{ + size_t i; + + if (( ( (size_t)dest | (size_t)src | count) & 3) == 0 ) + { + count >>= 2; + for (i = 0; i < count; i++) + ((int *)dest)[i] = ((int *)src)[i]; + } + else + for (i = 0; i < count; i++) + ((byte *)dest)[i] = ((byte *)src)[i]; +} + +int Q_memcmp (const void *m1, const void *m2, size_t count) +{ + while(count) + { + count--; + if (((byte *)m1)[count] != ((byte *)m2)[count]) + return -1; + } + return 0; +} + +void Q_strcpy (char *dest, const char *src) +{ + while (*src) + { + *dest++ = *src++; + } + *dest++ = 0; +} + +void Q_strncpy (char *dest, const char *src, int count) +{ + while (*src && count--) + { + *dest++ = *src++; + } + if (count) + *dest++ = 0; +} + +int Q_strlen (const char *str) +{ + int count; + + count = 0; + while (str[count]) + count++; + + return count; +} + +char *Q_strrchr(const char *s, char c) +{ + int len = Q_strlen(s); + s += len; + while (len--) + { + if (*--s == c) + return (char *)s; + } + return NULL; +} + +void Q_strcat (char *dest, const char *src) +{ + dest += Q_strlen(dest); + Q_strcpy (dest, src); +} + +int Q_strcmp (const char *s1, const char *s2) +{ + while (1) + { + if (*s1 != *s2) + return -1; // strings not equal + if (!*s1) + return 0; // strings are equal + s1++; + s2++; + } + + return -1; +} + +int Q_strncmp (const char *s1, const char *s2, int count) +{ + while (1) + { + if (!count--) + return 0; + if (*s1 != *s2) + return -1; // strings not equal + if (!*s1) + return 0; // strings are equal + s1++; + s2++; + } + + return -1; +} + +int Q_atoi (const char *str) +{ + int val; + int sign; + int c; + + if (*str == '-') + { + sign = -1; + str++; + } + else + sign = 1; + + val = 0; + +// +// check for hex +// + if (str[0] == '0' && (str[1] == 'x' || str[1] == 'X') ) + { + str += 2; + while (1) + { + c = *str++; + if (c >= '0' && c <= '9') + val = (val<<4) + c - '0'; + else if (c >= 'a' && c <= 'f') + val = (val<<4) + c - 'a' + 10; + else if (c >= 'A' && c <= 'F') + val = (val<<4) + c - 'A' + 10; + else + return val*sign; + } + } + +// +// check for character +// + if (str[0] == '\'') + { + return sign * str[1]; + } + +// +// assume decimal +// + while (1) + { + c = *str++; + if (c <'0' || c > '9') + return val*sign; + val = val*10 + c - '0'; + } + + return 0; +} + + +float Q_atof (const char *str) +{ + double val; + int sign; + int c; + int decimal, total; + + if (*str == '-') + { + sign = -1; + str++; + } + else + sign = 1; + + val = 0; + +// +// check for hex +// + if (str[0] == '0' && (str[1] == 'x' || str[1] == 'X') ) + { + str += 2; + while (1) + { + c = *str++; + if (c >= '0' && c <= '9') + val = (val*16) + c - '0'; + else if (c >= 'a' && c <= 'f') + val = (val*16) + c - 'a' + 10; + else if (c >= 'A' && c <= 'F') + val = (val*16) + c - 'A' + 10; + else + return val*sign; + } + } + +// +// check for character +// + if (str[0] == '\'') + { + return sign * str[1]; + } + +// +// assume decimal +// + decimal = -1; + total = 0; + while (1) + { + c = *str++; + if (c == '.') + { + decimal = total; + continue; + } + if (c <'0' || c > '9') + break; + val = val*10 + c - '0'; + total++; + } + + if (decimal == -1) + return val*sign; + while (total > decimal) + { + val /= 10; + total--; + } + + return val*sign; +} + +/* +============================================================================ + + BYTE ORDER FUNCTIONS + +============================================================================ +*/ + +qboolean host_bigendian; + +short (*BigShort) (short l); +short (*LittleShort) (short l); +int (*BigLong) (int l); +int (*LittleLong) (int l); +float (*BigFloat) (float l); +float (*LittleFloat) (float l); + +short ShortSwap (short l) +{ + byte b1, b2; + + b1 = l&255; + b2 = (l>>8)&255; + + return (b1<<8) + b2; +} + +short ShortNoSwap (short l) +{ + return l; +} + +int LongSwap (int l) +{ + byte b1, b2, b3, b4; + + b1 = l&255; + b2 = (l>>8)&255; + b3 = (l>>16)&255; + b4 = (l>>24)&255; + + return ((int)b1<<24) + ((int)b2<<16) + ((int)b3<<8) + b4; +} + +int LongNoSwap (int l) +{ + return l; +} + +float FloatSwap (float f) +{ + union + { + float f; + byte b[4]; + } dat1, dat2; + + + dat1.f = f; + dat2.b[0] = dat1.b[3]; + dat2.b[1] = dat1.b[2]; + dat2.b[2] = dat1.b[1]; + dat2.b[3] = dat1.b[0]; + return dat2.f; +} + +float FloatNoSwap (float f) +{ + return f; +} + +/* +============================================================================== + + MESSAGE IO FUNCTIONS + +Handles byte ordering and avoids alignment errors +============================================================================== +*/ + +// +// writing functions +// + +void MSG_WriteChar (sizebuf_t *sb, int c) +{ + byte *buf; + +#ifdef PARANOID + if (c < -128 || c > 127) + Sys_Error ("MSG_WriteChar: range error"); +#endif + + buf = (byte *) SZ_GetSpace (sb, 1); + buf[0] = c; +} + +void MSG_WriteByte (sizebuf_t *sb, int c) +{ + byte *buf; + +#ifdef PARANOID + if (c < 0 || c > 255) + Sys_Error ("MSG_WriteByte: range error"); +#endif + + buf = (byte *) SZ_GetSpace (sb, 1); + buf[0] = c; +} + +void MSG_WriteShort (sizebuf_t *sb, int c) +{ + byte *buf; + +#ifdef PARANOID + if (c < ((short)0x8000) || c > (short)0x7fff) + Sys_Error ("MSG_WriteShort: range error"); +#endif + + buf = (byte *) SZ_GetSpace (sb, 2); + buf[0] = c&0xff; + buf[1] = c>>8; +} + +void MSG_WriteLong (sizebuf_t *sb, int c) +{ + byte *buf; + + buf = (byte *) SZ_GetSpace (sb, 4); + buf[0] = c&0xff; + buf[1] = (c>>8)&0xff; + buf[2] = (c>>16)&0xff; + buf[3] = c>>24; +} + +void MSG_WriteFloat (sizebuf_t *sb, float f) +{ + union + { + float f; + int l; + } dat; + + dat.f = f; + dat.l = LittleLong (dat.l); + + SZ_Write (sb, &dat.l, 4); +} + +void MSG_WriteString (sizebuf_t *sb, const char *s) +{ + if (!s) + SZ_Write (sb, "", 1); + else + SZ_Write (sb, s, Q_strlen(s)+1); +} + +//johnfitz -- original behavior, 13.3 fixed point coords, max range +-4096 +void MSG_WriteCoord16 (sizebuf_t *sb, float f) +{ + MSG_WriteShort (sb, Q_rint(f*8)); +} + +//johnfitz -- 16.8 fixed point coords, max range +-32768 +void MSG_WriteCoord24 (sizebuf_t *sb, float f) +{ + MSG_WriteShort (sb, f); + MSG_WriteByte (sb, (int)(f*255)%255); +} + +//johnfitz -- 32-bit float coords +void MSG_WriteCoord32f (sizebuf_t *sb, float f) +{ + MSG_WriteFloat (sb, f); +} + +void MSG_WriteCoord (sizebuf_t *sb, float f, unsigned int flags) +{ + if (flags & PRFL_FLOATCOORD) + MSG_WriteFloat (sb, f); + else if (flags & PRFL_INT32COORD) + MSG_WriteLong (sb, Q_rint (f * 16)); + else if (flags & PRFL_24BITCOORD) + MSG_WriteCoord24 (sb, f); + else MSG_WriteCoord16 (sb, f); +} + +void MSG_WriteAngle (sizebuf_t *sb, float f, unsigned int flags) +{ + if (flags & PRFL_FLOATANGLE) + MSG_WriteFloat (sb, f); + else if (flags & PRFL_SHORTANGLE) + MSG_WriteShort (sb, Q_rint(f * 65536.0 / 360.0) & 65535); + else MSG_WriteByte (sb, Q_rint(f * 256.0 / 360.0) & 255); //johnfitz -- use Q_rint instead of (int) } +} + +//johnfitz -- for PROTOCOL_FITZQUAKE +void MSG_WriteAngle16 (sizebuf_t *sb, float f, unsigned int flags) +{ + if (flags & PRFL_FLOATANGLE) + MSG_WriteFloat (sb, f); + else MSG_WriteShort (sb, Q_rint(f * 65536.0 / 360.0) & 65535); +} +//johnfitz + +// +// reading functions +// +int msg_readcount; +qboolean msg_badread; + +void MSG_BeginReading (void) +{ + msg_readcount = 0; + msg_badread = false; +} + +// returns -1 and sets msg_badread if no more characters are available +int MSG_ReadChar (void) +{ + int c; + + if (msg_readcount+1 > net_message.cursize) + { + msg_badread = true; + return -1; + } + + c = (signed char)net_message.data[msg_readcount]; + msg_readcount++; + + return c; +} + +int MSG_ReadByte (void) +{ + int c; + + if (msg_readcount+1 > net_message.cursize) + { + msg_badread = true; + return -1; + } + + c = (unsigned char)net_message.data[msg_readcount]; + msg_readcount++; + + return c; +} + +int MSG_ReadShort (void) +{ + int c; + + if (msg_readcount+2 > net_message.cursize) + { + msg_badread = true; + return -1; + } + + c = (short)(net_message.data[msg_readcount] + + (net_message.data[msg_readcount+1]<<8)); + + msg_readcount += 2; + + return c; +} + +int MSG_ReadLong (void) +{ + int c; + + if (msg_readcount+4 > net_message.cursize) + { + msg_badread = true; + return -1; + } + + c = net_message.data[msg_readcount] + + (net_message.data[msg_readcount+1]<<8) + + (net_message.data[msg_readcount+2]<<16) + + (net_message.data[msg_readcount+3]<<24); + + msg_readcount += 4; + + return c; +} + +float MSG_ReadFloat (void) +{ + union + { + byte b[4]; + float f; + int l; + } dat; + + dat.b[0] = net_message.data[msg_readcount]; + dat.b[1] = net_message.data[msg_readcount+1]; + dat.b[2] = net_message.data[msg_readcount+2]; + dat.b[3] = net_message.data[msg_readcount+3]; + msg_readcount += 4; + + dat.l = LittleLong (dat.l); + + return dat.f; +} + +const char *MSG_ReadString (void) +{ + static char string[2048]; + int c; + size_t l; + + l = 0; + do + { + c = MSG_ReadByte (); + if (c == -1 || c == 0) + break; + string[l] = c; + l++; + } while (l < sizeof(string) - 1); + + string[l] = 0; + + return string; +} + +//johnfitz -- original behavior, 13.3 fixed point coords, max range +-4096 +float MSG_ReadCoord16 (void) +{ + return MSG_ReadShort() * (1.0/8); +} + +//johnfitz -- 16.8 fixed point coords, max range +-32768 +float MSG_ReadCoord24 (void) +{ + return MSG_ReadShort() + MSG_ReadByte() * (1.0/255); +} + +//johnfitz -- 32-bit float coords +float MSG_ReadCoord32f (void) +{ + return MSG_ReadFloat(); +} + +float MSG_ReadCoord (unsigned int flags) +{ + if (flags & PRFL_FLOATCOORD) + return MSG_ReadFloat (); + else if (flags & PRFL_INT32COORD) + return MSG_ReadLong () * (1.0 / 16.0); + else if (flags & PRFL_24BITCOORD) + return MSG_ReadCoord24 (); + else return MSG_ReadCoord16 (); +} + +float MSG_ReadAngle (unsigned int flags) +{ + if (flags & PRFL_FLOATANGLE) + return MSG_ReadFloat (); + else if (flags & PRFL_SHORTANGLE) + return MSG_ReadShort () * (360.0 / 65536); + else return MSG_ReadChar () * (360.0 / 256); +} + +//johnfitz -- for PROTOCOL_FITZQUAKE +float MSG_ReadAngle16 (unsigned int flags) +{ + if (flags & PRFL_FLOATANGLE) + return MSG_ReadFloat (); // make sure + else return MSG_ReadShort () * (360.0 / 65536); +} +//johnfitz + +//=========================================================================== + +void SZ_Alloc (sizebuf_t *buf, int startsize) +{ + if (startsize < 256) + startsize = 256; + buf->data = (byte *) Hunk_AllocName (startsize, "sizebuf"); + buf->maxsize = startsize; + buf->cursize = 0; +} + + +void SZ_Free (sizebuf_t *buf) +{ +// Z_Free (buf->data); +// buf->data = NULL; +// buf->maxsize = 0; + buf->cursize = 0; +} + +void SZ_Clear (sizebuf_t *buf) +{ + buf->cursize = 0; +} + +void *SZ_GetSpace (sizebuf_t *buf, int length) +{ + void *data; + + if (buf->cursize + length > buf->maxsize) + { + if (!buf->allowoverflow) + Host_Error ("SZ_GetSpace: overflow without allowoverflow set"); // ericw -- made Host_Error to be less annoying + + if (length > buf->maxsize) + Sys_Error ("SZ_GetSpace: %i is > full buffer size", length); + + buf->overflowed = true; + Con_Printf ("SZ_GetSpace: overflow"); + SZ_Clear (buf); + } + + data = buf->data + buf->cursize; + buf->cursize += length; + + return data; +} + +void SZ_Write (sizebuf_t *buf, const void *data, int length) +{ + Q_memcpy (SZ_GetSpace(buf,length),data,length); +} + +void SZ_Print (sizebuf_t *buf, const char *data) +{ + int len = Q_strlen(data) + 1; + + if (buf->data[buf->cursize-1]) + { /* no trailing 0 */ + Q_memcpy ((byte *)SZ_GetSpace(buf, len ) , data, len); + } + else + { /* write over trailing 0 */ + Q_memcpy ((byte *)SZ_GetSpace(buf, len-1)-1, data, len); + } +} + + +//============================================================================ + +/* +============ +COM_SkipPath +============ +*/ +const char *COM_SkipPath (const char *pathname) +{ + const char *last; + + last = pathname; + while (*pathname) + { + if (*pathname == '/') + last = pathname + 1; + pathname++; + } + return last; +} + +/* +============ +COM_StripExtension +============ +*/ +void COM_StripExtension (const char *in, char *out, size_t outsize) +{ + int length; + + if (!*in) + { + *out = '\0'; + return; + } + if (in != out) /* copy when not in-place editing */ + q_strlcpy (out, in, outsize); + length = (int)strlen(out) - 1; + while (length > 0 && out[length] != '.') + { + --length; + if (out[length] == '/' || out[length] == '\\') + return; /* no extension */ + } + if (length > 0) + out[length] = '\0'; +} + +/* +============ +COM_FileGetExtension - doesn't return NULL +============ +*/ +const char *COM_FileGetExtension (const char *in) +{ + const char *src; + size_t len; + + len = strlen(in); + if (len < 2) /* nothing meaningful */ + return ""; + + src = in + len - 1; + while (src != in && src[-1] != '.') + src--; + if (src == in || strchr(src, '/') != NULL || strchr(src, '\\') != NULL) + return ""; /* no extension, or parent directory has a dot */ + + return src; +} + +/* +============ +COM_ExtractExtension +============ +*/ +void COM_ExtractExtension (const char *in, char *out, size_t outsize) +{ + const char *ext = COM_FileGetExtension (in); + if (! *ext) + *out = '\0'; + else + q_strlcpy (out, ext, outsize); +} + +/* +============ +COM_FileBase +take 'somedir/otherdir/filename.ext', +write only 'filename' to the output +============ +*/ +void COM_FileBase (const char *in, char *out, size_t outsize) +{ + const char *dot, *slash, *s; + + s = in; + slash = in; + dot = NULL; + while (*s) + { + if (*s == '/') + slash = s + 1; + if (*s == '.') + dot = s; + s++; + } + if (dot == NULL) + dot = s; + + if (dot - slash < 2) + q_strlcpy (out, "?model?", outsize); + else + { + size_t len = dot - slash; + if (len >= outsize) + len = outsize - 1; + memcpy (out, slash, len); + out[len] = '\0'; + } +} + +/* +================== +COM_DefaultExtension +if path doesn't have a .EXT, append extension +(extension should include the leading ".") +================== +*/ +#if 0 /* can be dangerous */ +void COM_DefaultExtension (char *path, const char *extension, size_t len) +{ + char *src; + + if (!*path) return; + src = path + strlen(path) - 1; + + while (*src != '/' && *src != '\\' && src != path) + { + if (*src == '.') + return; // it has an extension + src--; + } + + q_strlcat(path, extension, len); +} +#endif + +/* +================== +COM_AddExtension +if path extension doesn't match .EXT, append it +(extension should include the leading ".") +================== +*/ +void COM_AddExtension (char *path, const char *extension, size_t len) +{ + if (strcmp(COM_FileGetExtension(path), extension + 1) != 0) + q_strlcat(path, extension, len); +} + + +/* +============== +COM_Parse + +Parse a token out of a string +============== +*/ +const char *COM_Parse (const char *data) +{ + int c; + int len; + + len = 0; + com_token[0] = 0; + + if (!data) + return NULL; + +// skip whitespace +skipwhite: + while ((c = *data) <= ' ') + { + if (c == 0) + return NULL; // end of file + data++; + } + +// skip // comments + if (c == '/' && data[1] == '/') + { + while (*data && *data != '\n') + data++; + goto skipwhite; + } + +// skip /*..*/ comments + if (c == '/' && data[1] == '*') + { + data += 2; + while (*data && !(*data == '*' && data[1] == '/')) + data++; + if (*data) + data += 2; + goto skipwhite; + } + +// handle quoted strings specially + if (c == '\"') + { + data++; + while (1) + { + if ((c = *data) != 0) + ++data; + if (c == '\"' || !c) + { + com_token[len] = 0; + return data; + } + com_token[len] = c; + len++; + } + } + +// parse single characters + if (c == '{' || c == '}'|| c == '('|| c == ')' || c == '\'' || c == ':') + { + com_token[len] = c; + len++; + com_token[len] = 0; + return data+1; + } + +// parse a regular word + do + { + com_token[len] = c; + data++; + len++; + c = *data; + /* commented out the check for ':' so that ip:port works */ + if (c == '{' || c == '}'|| c == '('|| c == ')' || c == '\''/* || c == ':' */) + break; + } while (c > 32); + + com_token[len] = 0; + return data; +} + + +/* +================ +COM_CheckParm + +Returns the position (1 to argc-1) in the program's argument list +where the given parameter apears, or 0 if not present +================ +*/ +int COM_CheckParm (const char *parm) +{ + int i; + + for (i = 1; i < com_argc; i++) + { + if (!com_argv[i]) + continue; // NEXTSTEP sometimes clears appkit vars. + if (!Q_strcmp (parm,com_argv[i])) + return i; + } + + return 0; +} + +/* +================ +COM_CheckRegistered + +Looks for the pop.txt file and verifies it. +Sets the "registered" cvar. +Immediately exits out if an alternate game was attempted to be started without +being registered. +================ +*/ +static void COM_CheckRegistered (void) +{ + int h; + unsigned short check[128]; + int i; + + COM_OpenFile("gfx/pop.lmp", &h, NULL); + + if (h == -1) + { + Cvar_SetROM ("registered", "0"); + Con_Printf ("Playing shareware version.\n"); + if (com_modified) + Sys_Error ("You must have the registered version to use modified games.\n\n" + "Basedir is: %s\n\n" + "Check that this has an " GAMENAME " subdirectory containing pak0.pak and pak1.pak, " + "or use the -basedir command-line option to specify another directory.", + com_basedir); + return; + } + + Sys_FileRead (h, check, sizeof(check)); + COM_CloseFile (h); + + for (i = 0; i < 128; i++) + { + if (pop[i] != (unsigned short)BigShort (check[i])) + Sys_Error ("Corrupted data file."); + } + + for (i = 0; com_cmdline[i]; i++) + { + if (com_cmdline[i]!= ' ') + break; + } + + Cvar_SetROM ("cmdline", &com_cmdline[i]); + Cvar_SetROM ("registered", "1"); + Con_Printf ("Playing registered version.\n"); +} + + +/* +================ +COM_InitArgv +================ +*/ +void COM_InitArgv (int argc, char **argv) +{ + int i, j, n; + +// reconstitute the command line for the cmdline externally visible cvar + n = 0; + + for (j = 0; (j 0 && com_cmdline[n-1] == ' ') + com_cmdline[n-1] = 0; //johnfitz -- kill the trailing space + + Con_Printf("Command line: %s\n", com_cmdline); + + for (com_argc = 0; (com_argc < MAX_NUM_ARGVS) && (com_argc < argc); com_argc++) + { + largv[com_argc] = argv[com_argc]; + if (!Q_strcmp ("-safe", argv[com_argc])) + safemode = 1; + } + + largv[com_argc] = argvdummy; + com_argv = largv; + + if (COM_CheckParm ("-rogue")) + { + rogue = true; + standard_quake = false; + } + + if (COM_CheckParm ("-hipnotic") || COM_CheckParm ("-quoth")) //johnfitz -- "-quoth" support + { + hipnotic = true; + standard_quake = false; + } +} + +/* +================ +Test_f -- johnfitz +================ +*/ +#ifdef _DEBUG +static void FitzTest_f (void) +{ +} +#endif + +/* +================ +COM_Init +================ +*/ +void COM_Init (void) +{ + int i = 0x12345678; + /* U N I X */ + + /* + BE_ORDER: 12 34 56 78 + U N I X + + LE_ORDER: 78 56 34 12 + X I N U + + PDP_ORDER: 34 12 78 56 + N U X I + */ + if ( *(char *)&i == 0x12 ) + host_bigendian = true; + else if ( *(char *)&i == 0x78 ) + host_bigendian = false; + else /* if ( *(char *)&i == 0x34 ) */ + Sys_Error ("Unsupported endianism."); + + if (host_bigendian) + { + BigShort = ShortNoSwap; + LittleShort = ShortSwap; + BigLong = LongNoSwap; + LittleLong = LongSwap; + BigFloat = FloatNoSwap; + LittleFloat = FloatSwap; + } + else /* assumed LITTLE_ENDIAN. */ + { + BigShort = ShortSwap; + LittleShort = ShortNoSwap; + BigLong = LongSwap; + LittleLong = LongNoSwap; + BigFloat = FloatSwap; + LittleFloat = FloatNoSwap; + } + + if (COM_CheckParm("-fitz")) + fitzmode = true; +#ifdef _DEBUG + Cmd_AddCommand ("fitztest", FitzTest_f); //johnfitz +#endif +} + + +/* +============ +va + +does a varargs printf into a temp buffer. cycles between +4 different static buffers. the number of buffers cycled +is defined in VA_NUM_BUFFS. +FIXME: make this buffer size safe someday +============ +*/ +#define VA_NUM_BUFFS 4 +#define VA_BUFFERLEN 1024 + +static char *get_va_buffer(void) +{ + static char va_buffers[VA_NUM_BUFFS][VA_BUFFERLEN]; + static int buffer_idx = 0; + buffer_idx = (buffer_idx + 1) & (VA_NUM_BUFFS - 1); + return va_buffers[buffer_idx]; +} + +char *va (const char *format, ...) +{ + va_list argptr; + char *va_buf; + + va_buf = get_va_buffer (); + va_start (argptr, format); + q_vsnprintf (va_buf, VA_BUFFERLEN, format, argptr); + va_end (argptr); + + return va_buf; +} + +/* +============================================================================= + +QUAKE FILESYSTEM + +============================================================================= +*/ + +int com_filesize; + + +// +// on-disk pakfile +// +typedef struct +{ + char name[56]; + int filepos, filelen; +} dpackfile_t; + +typedef struct +{ + char id[4]; + int dirofs; + int dirlen; +} dpackheader_t; + +#define MAX_FILES_IN_PACK 2048 + +char com_gamedir[MAX_OSPATH]; +char com_basedir[MAX_OSPATH]; +int file_from_pak; // ZOID: global indicating that file came from a pak + +searchpath_t *com_searchpaths; +searchpath_t *com_base_searchpaths; + +/* +============ +COM_Path_f +============ +*/ +static void COM_Path_f (void) +{ + searchpath_t *s; + + Con_Printf ("Current search path:\n"); + for (s = com_searchpaths; s; s = s->next) + { + if (s->pack) + { + Con_Printf ("%s (%i files)\n", s->pack->filename, s->pack->numfiles); + } + else + Con_Printf ("%s\n", s->filename); + } +} + +/* +============ +COM_WriteFile + +The filename will be prefixed by the current game directory +============ +*/ +void COM_WriteFile (const char *filename, const void *data, int len) +{ + int handle; + char name[MAX_OSPATH]; + + Sys_mkdir (com_gamedir); //johnfitz -- if we've switched to a nonexistant gamedir, create it now so we don't crash + + q_snprintf (name, sizeof(name), "%s/%s", com_gamedir, filename); + + handle = Sys_FileOpenWrite (name); + if (handle == -1) + { + Sys_Printf ("COM_WriteFile: failed on %s\n", name); + return; + } + + Sys_Printf ("COM_WriteFile: %s\n", name); + Sys_FileWrite (handle, data, len); + Sys_FileClose (handle); +} + +/* +============ +COM_CreatePath +============ +*/ +void COM_CreatePath (char *path) +{ + char *ofs; + + for (ofs = path + 1; *ofs; ofs++) + { + if (*ofs == '/') + { // create the directory + *ofs = 0; + Sys_mkdir (path); + *ofs = '/'; + } + } +} + +/* +================ +COM_filelength +================ +*/ +long COM_filelength (FILE *f) +{ + long pos, end; + + pos = ftell (f); + fseek (f, 0, SEEK_END); + end = ftell (f); + fseek (f, pos, SEEK_SET); + + return end; +} + +/* +=========== +COM_FindFile + +Finds the file in the search path. +Sets com_filesize and one of handle or file +If neither of file or handle is set, this +can be used for detecting a file's presence. +=========== +*/ +static int COM_FindFile (const char *filename, int *handle, FILE **file, + unsigned int *path_id) +{ + searchpath_t *search; + char netpath[MAX_OSPATH]; + pack_t *pak; + int i, findtime; + + if (file && handle) + Sys_Error ("COM_FindFile: both handle and file set"); + + file_from_pak = 0; + +// +// search through the path, one element at a time +// + for (search = com_searchpaths; search; search = search->next) + { + if (search->pack) /* look through all the pak file elements */ + { + pak = search->pack; + for (i = 0; i < pak->numfiles; i++) + { + if (strcmp(pak->files[i].name, filename) != 0) + continue; + // found it! + com_filesize = pak->files[i].filelen; + file_from_pak = 1; + if (path_id) + *path_id = search->path_id; + if (handle) + { + *handle = pak->handle; + Sys_FileSeek (pak->handle, pak->files[i].filepos); + return com_filesize; + } + else if (file) + { /* open a new file on the pakfile */ + *file = fopen (pak->filename, "rb"); + if (*file) + fseek (*file, pak->files[i].filepos, SEEK_SET); + return com_filesize; + } + else /* for COM_FileExists() */ + { + return com_filesize; + } + } + } + else /* check a file in the directory tree */ + { + if (!registered.value) + { /* if not a registered version, don't ever go beyond base */ + if ( strchr (filename, '/') || strchr (filename,'\\')) + continue; + } + + q_snprintf (netpath, sizeof(netpath), "%s/%s",search->filename, filename); + findtime = Sys_FileTime (netpath); + if (findtime == -1) + continue; + + if (path_id) + *path_id = search->path_id; + if (handle) + { + com_filesize = Sys_FileOpenRead (netpath, &i); + *handle = i; + return com_filesize; + } + else if (file) + { + *file = fopen (netpath, "rb"); + com_filesize = (*file == NULL) ? -1 : COM_filelength (*file); + return com_filesize; + } + else + { + return 0; /* dummy valid value for COM_FileExists() */ + } + } + } + + if (strcmp(COM_FileGetExtension(filename), "pcx") != 0 + && strcmp(COM_FileGetExtension(filename), "tga") != 0 + && strcmp(COM_FileGetExtension(filename), "lit") != 0 + && strcmp(COM_FileGetExtension(filename), "ent") != 0) + Con_DPrintf ("FindFile: can't find %s\n", filename); + else Con_DPrintf2("FindFile: can't find %s\n", filename); + // Log pcx, tga, lit, ent misses only if (developer.value >= 2) + + if (handle) + *handle = -1; + if (file) + *file = NULL; + com_filesize = -1; + return com_filesize; +} + + +/* +=========== +COM_FileExists + +Returns whether the file is found in the quake filesystem. +=========== +*/ +qboolean COM_FileExists (const char *filename, unsigned int *path_id) +{ + int ret = COM_FindFile (filename, NULL, NULL, path_id); + return (ret == -1) ? false : true; +} + +/* +=========== +COM_OpenFile + +filename never has a leading slash, but may contain directory walks +returns a handle and a length +it may actually be inside a pak file +=========== +*/ +int COM_OpenFile (const char *filename, int *handle, unsigned int *path_id) +{ + return COM_FindFile (filename, handle, NULL, path_id); +} + +/* +=========== +COM_FOpenFile + +If the requested file is inside a packfile, a new FILE * will be opened +into the file. +=========== +*/ +int COM_FOpenFile (const char *filename, FILE **file, unsigned int *path_id) +{ + return COM_FindFile (filename, NULL, file, path_id); +} + +/* +============ +COM_CloseFile + +If it is a pak file handle, don't really close it +============ +*/ +void COM_CloseFile (int h) +{ + searchpath_t *s; + + for (s = com_searchpaths; s; s = s->next) + if (s->pack && s->pack->handle == h) + return; + + Sys_FileClose (h); +} + + +/* +============ +COM_LoadFile + +Filename are reletive to the quake directory. +Allways appends a 0 byte. +============ +*/ +#define LOADFILE_ZONE 0 +#define LOADFILE_HUNK 1 +#define LOADFILE_TEMPHUNK 2 +#define LOADFILE_CACHE 3 +#define LOADFILE_STACK 4 +#define LOADFILE_MALLOC 5 + +static byte *loadbuf; +static cache_user_t *loadcache; +static int loadsize; + +byte *COM_LoadFile (const char *path, int usehunk, unsigned int *path_id) +{ + int h; + byte *buf; + char base[32]; + int len; + + buf = NULL; // quiet compiler warning + +// look for it in the filesystem or pack files + len = COM_OpenFile (path, &h, path_id); + if (h == -1) + return NULL; + +// extract the filename base name for hunk tag + COM_FileBase (path, base, sizeof(base)); + + switch (usehunk) + { + case LOADFILE_HUNK: + buf = (byte *) Hunk_AllocName (len+1, base); + break; + case LOADFILE_TEMPHUNK: + buf = (byte *) Hunk_TempAlloc (len+1); + break; + case LOADFILE_ZONE: + buf = (byte *) Z_Malloc (len+1); + break; + case LOADFILE_CACHE: + buf = (byte *) Cache_Alloc (loadcache, len+1, base); + break; + case LOADFILE_STACK: + if (len < loadsize) + buf = loadbuf; + else + buf = (byte *) Hunk_TempAlloc (len+1); + break; + case LOADFILE_MALLOC: + buf = (byte *) malloc (len+1); + break; + default: + Sys_Error ("COM_LoadFile: bad usehunk"); + } + + if (!buf) + Sys_Error ("COM_LoadFile: not enough space for %s", path); + + ((byte *)buf)[len] = 0; + + Sys_FileRead (h, buf, len); + COM_CloseFile (h); + + return buf; +} + +byte *COM_LoadHunkFile (const char *path, unsigned int *path_id) +{ + return COM_LoadFile (path, LOADFILE_HUNK, path_id); +} + +byte *COM_LoadZoneFile (const char *path, unsigned int *path_id) +{ + return COM_LoadFile (path, LOADFILE_ZONE, path_id); +} + +byte *COM_LoadTempFile (const char *path, unsigned int *path_id) +{ + return COM_LoadFile (path, LOADFILE_TEMPHUNK, path_id); +} + +void COM_LoadCacheFile (const char *path, struct cache_user_s *cu, unsigned int *path_id) +{ + loadcache = cu; + COM_LoadFile (path, LOADFILE_CACHE, path_id); +} + +// uses temp hunk if larger than bufsize +byte *COM_LoadStackFile (const char *path, void *buffer, int bufsize, unsigned int *path_id) +{ + byte *buf; + + loadbuf = (byte *)buffer; + loadsize = bufsize; + buf = COM_LoadFile (path, LOADFILE_STACK, path_id); + + return buf; +} + +// returns malloc'd memory +byte *COM_LoadMallocFile (const char *path, unsigned int *path_id) +{ + return COM_LoadFile (path, LOADFILE_MALLOC, path_id); +} + +byte *COM_LoadMallocFile_TextMode_OSPath (const char *path, long *len_out) +{ + FILE *f; + byte *data; + long len, actuallen; + + // ericw -- this is used by Host_Loadgame_f. Translate CRLF to LF on load games, + // othewise multiline messages have a garbage character at the end of each line. + // TODO: could handle in a way that allows loading CRLF savegames on mac/linux + // without the junk characters appearing. + f = fopen (path, "rt"); + if (f == NULL) + return NULL; + + len = COM_filelength (f); + if (len < 0) + return NULL; + + data = (byte *) malloc (len + 1); + if (data == NULL) + return NULL; + + // (actuallen < len) if CRLF to LF translation was performed + actuallen = fread (data, 1, len, f); + if (ferror(f)) + { + free (data); + return NULL; + } + data[actuallen] = '\0'; + + if (len_out != NULL) + *len_out = actuallen; + return data; +} + +const char *COM_ParseIntNewline(const char *buffer, int *value) +{ + int consumed = 0; + sscanf (buffer, "%i\n%n", value, &consumed); + return buffer + consumed; +} + +const char *COM_ParseFloatNewline(const char *buffer, float *value) +{ + int consumed = 0; + sscanf (buffer, "%f\n%n", value, &consumed); + return buffer + consumed; +} + +const char *COM_ParseStringNewline(const char *buffer) +{ + int consumed = 0; + com_token[0] = '\0'; + sscanf (buffer, "%1023s\n%n", com_token, &consumed); + return buffer + consumed; +} + +/* +================= +COM_LoadPackFile -- johnfitz -- modified based on topaz's tutorial + +Takes an explicit (not game tree related) path to a pak file. + +Loads the header and directory, adding the files at the beginning +of the list so they override previous pack files. +================= +*/ +static pack_t *COM_LoadPackFile (const char *packfile) +{ + dpackheader_t header; + int i; + packfile_t *newfiles; + int numpackfiles; + pack_t *pack; + int packhandle; + dpackfile_t info[MAX_FILES_IN_PACK]; + unsigned short crc; + + if (Sys_FileOpenRead (packfile, &packhandle) == -1) + return NULL; + + Sys_FileRead (packhandle, (void *)&header, sizeof(header)); + if (header.id[0] != 'P' || header.id[1] != 'A' || header.id[2] != 'C' || header.id[3] != 'K') + Sys_Error ("%s is not a packfile", packfile); + + header.dirofs = LittleLong (header.dirofs); + header.dirlen = LittleLong (header.dirlen); + + numpackfiles = header.dirlen / sizeof(dpackfile_t); + + if (header.dirlen < 0 || header.dirofs < 0) + { + Sys_Error ("Invalid packfile %s (dirlen: %i, dirofs: %i)", + packfile, header.dirlen, header.dirofs); + } + if (!numpackfiles) + { + Sys_Printf ("WARNING: %s has no files, ignored\n", packfile); + Sys_FileClose (packhandle); + return NULL; + } + if (numpackfiles > MAX_FILES_IN_PACK) + Sys_Error ("%s has %i files", packfile, numpackfiles); + + if (numpackfiles != PAK0_COUNT) + com_modified = true; // not the original file + + newfiles = (packfile_t *) Z_Malloc(numpackfiles * sizeof(packfile_t)); + + Sys_FileSeek (packhandle, header.dirofs); + Sys_FileRead (packhandle, (void *)info, header.dirlen); + + // crc the directory to check for modifications + CRC_Init (&crc); + for (i = 0; i < header.dirlen; i++) + CRC_ProcessByte (&crc, ((byte *)info)[i]); + if (crc != PAK0_CRC_V106 && crc != PAK0_CRC_V101 && crc != PAK0_CRC_V100) + com_modified = true; + + // parse the directory + for (i = 0; i < numpackfiles; i++) + { + q_strlcpy (newfiles[i].name, info[i].name, sizeof(newfiles[i].name)); + newfiles[i].filepos = LittleLong(info[i].filepos); + newfiles[i].filelen = LittleLong(info[i].filelen); + } + + pack = (pack_t *) Z_Malloc (sizeof (pack_t)); + q_strlcpy (pack->filename, packfile, sizeof(pack->filename)); + pack->handle = packhandle; + pack->numfiles = numpackfiles; + pack->files = newfiles; + + //Sys_Printf ("Added packfile %s (%i files)\n", packfile, numpackfiles); + return pack; +} + +/* +================= +COM_AddGameDirectory -- johnfitz -- modified based on topaz's tutorial +================= +*/ +static void COM_AddGameDirectory (const char *base, const char *dir) +{ + int i; + unsigned int path_id; + searchpath_t *search; + pack_t *pak, *qspak; + char pakfile[MAX_OSPATH]; + qboolean been_here = false; + + q_strlcpy (com_gamedir, va("%s/%s", base, dir), sizeof(com_gamedir)); + + // assign a path_id to this game directory + if (com_searchpaths) + path_id = com_searchpaths->path_id << 1; + else path_id = 1U; + +_add_path: + // add the directory to the search path + search = (searchpath_t *) Z_Malloc(sizeof(searchpath_t)); + search->path_id = path_id; + q_strlcpy (search->filename, com_gamedir, sizeof(search->filename)); + search->next = com_searchpaths; + com_searchpaths = search; + + // add any pak files in the format pak0.pak pak1.pak, ... + for (i = 0; ; i++) + { + q_snprintf (pakfile, sizeof(pakfile), "%s/pak%i.pak", com_gamedir, i); + pak = COM_LoadPackFile (pakfile); + if (i != 0 || path_id != 1 || fitzmode) + qspak = NULL; + else { + qboolean old = com_modified; + if (been_here) base = host_parms->userdir; + q_snprintf (pakfile, sizeof(pakfile), "%s/quakespasm.pak", base); + qspak = COM_LoadPackFile (pakfile); + com_modified = old; + } + if (pak) { + search = (searchpath_t *) Z_Malloc(sizeof(searchpath_t)); + search->path_id = path_id; + search->pack = pak; + search->next = com_searchpaths; + com_searchpaths = search; + } + if (qspak) { + search = (searchpath_t *) Z_Malloc(sizeof(searchpath_t)); + search->path_id = path_id; + search->pack = qspak; + search->next = com_searchpaths; + com_searchpaths = search; + } + if (!pak) break; + } + + if (!been_here && host_parms->userdir != host_parms->basedir) + { + been_here = true; + q_strlcpy(com_gamedir, va("%s/%s", host_parms->userdir, dir), sizeof(com_gamedir)); + Sys_mkdir(com_gamedir); + goto _add_path; + } +} + +//============================================================================== +//johnfitz -- dynamic gamedir stuff -- modified by QuakeSpasm team. +//============================================================================== +void ExtraMaps_NewGame (void); +static void COM_Game_f (void) +{ + if (Cmd_Argc() > 1) + { + const char *p = Cmd_Argv(1); + const char *p2 = Cmd_Argv(2); + searchpath_t *search; + + if (!registered.value) //disable shareware quake + { + Con_Printf("You must have the registered version to use modified games\n"); + return; + } + + if (!*p || !strcmp(p, ".") || strstr(p, "..") || strstr(p, "/") || strstr(p, "\\") || strstr(p, ":")) + { + Con_Printf ("gamedir should be a single directory name, not a path\n"); + return; + } + + if (*p2) + { + if (strcmp(p2,"-hipnotic") && strcmp(p2,"-rogue") && strcmp(p2,"-quoth")) { + Con_Printf ("invalid mission pack argument to \"game\"\n"); + return; + } + if (!q_strcasecmp(p, GAMENAME)) { + Con_Printf ("no mission pack arguments to %s game\n", GAMENAME); + return; + } + } + + if (!q_strcasecmp(p, COM_SkipPath(com_gamedir))) //no change + { + if (com_searchpaths->path_id > 1) { //current game not id1 + if (*p2 && com_searchpaths->path_id == 2) { + // rely on QuakeSpasm extension treating '-game missionpack' + // as '-missionpack', otherwise would be a mess + if (!q_strcasecmp(p, &p2[1])) + goto _same; + Con_Printf("reloading game \"%s\" with \"%s\" support\n", p, &p2[1]); + } + else if (!*p2 && com_searchpaths->path_id > 2) + Con_Printf("reloading game \"%s\" without mission pack support\n", p); + else goto _same; + } + else { _same: + Con_Printf("\"game\" is already \"%s\"\n", COM_SkipPath(com_gamedir)); + return; + } + } + + com_modified = true; + + //Kill the server + CL_Disconnect (); + Host_ShutdownServer(true); + + //Write config file + Host_WriteConfiguration (); + + //Kill the extra game if it is loaded + while (com_searchpaths != com_base_searchpaths) + { + if (com_searchpaths->pack) + { + Sys_FileClose (com_searchpaths->pack->handle); + Z_Free (com_searchpaths->pack->files); + Z_Free (com_searchpaths->pack); + } + search = com_searchpaths->next; + Z_Free (com_searchpaths); + com_searchpaths = search; + } + hipnotic = false; + rogue = false; + standard_quake = true; + + if (q_strcasecmp(p, GAMENAME)) //game is not id1 + { + if (*p2) { + COM_AddGameDirectory (com_basedir, &p2[1]); + standard_quake = false; + if (!strcmp(p2,"-hipnotic") || !strcmp(p2,"-quoth")) + hipnotic = true; + else if (!strcmp(p2,"-rogue")) + rogue = true; + if (q_strcasecmp(p, &p2[1])) //don't load twice + COM_AddGameDirectory (com_basedir, p); + } + else { + COM_AddGameDirectory (com_basedir, p); + // QuakeSpasm extension: treat '-game missionpack' as '-missionpack' + if (!q_strcasecmp(p,"hipnotic") || !q_strcasecmp(p,"quoth")) { + hipnotic = true; + standard_quake = false; + } + else if (!q_strcasecmp(p,"rogue")) { + rogue = true; + standard_quake = false; + } + } + } + else // just update com_gamedir + { + q_snprintf (com_gamedir, sizeof(com_gamedir), "%s/%s", + (host_parms->userdir != host_parms->basedir)? + host_parms->userdir : com_basedir, + GAMENAME); + } + + //clear out and reload appropriate data + Cache_Flush (); + Mod_ResetAll(); + if (!isDedicated) + { + TexMgr_NewGame (); + Draw_NewGame (); + R_NewGame (); + } + ExtraMaps_NewGame (); + DemoList_Rebuild (); + + Con_Printf("\"game\" changed to \"%s\"\n", COM_SkipPath(com_gamedir)); + + VID_Lock (); + Cbuf_AddText ("exec quake.rc\n"); + Cbuf_AddText ("vid_unlock\n"); + } + else //Diplay the current gamedir + Con_Printf("\"game\" is \"%s\"\n", COM_SkipPath(com_gamedir)); +} + +/* +================= +COM_InitFilesystem +================= +*/ +void COM_InitFilesystem (void) //johnfitz -- modified based on topaz's tutorial +{ + int i, j; + + Cvar_RegisterVariable (®istered); + Cvar_RegisterVariable (&cmdline); + Cmd_AddCommand ("path", COM_Path_f); + Cmd_AddCommand ("game", COM_Game_f); //johnfitz + + i = COM_CheckParm ("-basedir"); + if (i && i < com_argc-1) + q_strlcpy (com_basedir, com_argv[i + 1], sizeof(com_basedir)); + else + q_strlcpy (com_basedir, host_parms->basedir, sizeof(com_basedir)); + + j = strlen (com_basedir); + if (j < 1) Sys_Error("Bad argument to -basedir"); + if ((com_basedir[j-1] == '\\') || (com_basedir[j-1] == '/')) + com_basedir[j-1] = 0; + + // start up with GAMENAME by default (id1) + COM_AddGameDirectory (com_basedir, GAMENAME); + + /* this is the end of our base searchpath: + * any set gamedirs, such as those from -game command line + * arguments or by the 'game' console command will be freed + * up to here upon a new game command. */ + com_base_searchpaths = com_searchpaths; + + // add mission pack requests (only one should be specified) + if (COM_CheckParm ("-rogue")) + COM_AddGameDirectory (com_basedir, "rogue"); + if (COM_CheckParm ("-hipnotic")) + COM_AddGameDirectory (com_basedir, "hipnotic"); + if (COM_CheckParm ("-quoth")) + COM_AddGameDirectory (com_basedir, "quoth"); + + + i = COM_CheckParm ("-game"); + if (i && i < com_argc-1) + { + const char *p = com_argv[i + 1]; + if (!*p || !strcmp(p, ".") || strstr(p, "..") || strstr(p, "/") || strstr(p, "\\") || strstr(p, ":")) + Sys_Error ("gamedir should be a single directory name, not a path\n"); + com_modified = true; + // don't load mission packs twice + if (COM_CheckParm ("-rogue") && !q_strcasecmp(p, "rogue")) p = NULL; + if (COM_CheckParm ("-hipnotic") && !q_strcasecmp(p, "hipnotic")) p = NULL; + if (COM_CheckParm ("-quoth") && !q_strcasecmp(p, "quoth")) p = NULL; + if (p != NULL) { + COM_AddGameDirectory (com_basedir, p); + // QuakeSpasm extension: treat '-game missionpack' as '-missionpack' + if (!q_strcasecmp(p,"rogue")) { + rogue = true; + standard_quake = false; + } + if (!q_strcasecmp(p,"hipnotic") || !q_strcasecmp(p,"quoth")) { + hipnotic = true; + standard_quake = false; + } + } + } + + COM_CheckRegistered (); +} + + +/* The following FS_*() stdio replacements are necessary if one is + * to perform non-sequential reads on files reopened on pak files + * because we need the bookkeeping about file start/end positions. + * Allocating and filling in the fshandle_t structure is the users' + * responsibility when the file is initially opened. */ + +size_t FS_fread(void *ptr, size_t size, size_t nmemb, fshandle_t *fh) +{ + long byte_size; + long bytes_read; + size_t nmemb_read; + + if (!fh) { + errno = EBADF; + return 0; + } + if (!ptr) { + errno = EFAULT; + return 0; + } + if (!size || !nmemb) { /* no error, just zero bytes wanted */ + errno = 0; + return 0; + } + + byte_size = nmemb * size; + if (byte_size > fh->length - fh->pos) /* just read to end */ + byte_size = fh->length - fh->pos; + bytes_read = fread(ptr, 1, byte_size, fh->file); + fh->pos += bytes_read; + + /* fread() must return the number of elements read, + * not the total number of bytes. */ + nmemb_read = bytes_read / size; + /* even if the last member is only read partially + * it is counted as a whole in the return value. */ + if (bytes_read % size) + nmemb_read++; + + return nmemb_read; +} + +int FS_fseek(fshandle_t *fh, long offset, int whence) +{ +/* I don't care about 64 bit off_t or fseeko() here. + * the quake/hexen2 file system is 32 bits, anyway. */ + int ret; + + if (!fh) { + errno = EBADF; + return -1; + } + + /* the relative file position shouldn't be smaller + * than zero or bigger than the filesize. */ + switch (whence) + { + case SEEK_SET: + break; + case SEEK_CUR: + offset += fh->pos; + break; + case SEEK_END: + offset = fh->length + offset; + break; + default: + errno = EINVAL; + return -1; + } + + if (offset < 0) { + errno = EINVAL; + return -1; + } + + if (offset > fh->length) /* just seek to end */ + offset = fh->length; + + ret = fseek(fh->file, fh->start + offset, SEEK_SET); + if (ret < 0) + return ret; + + fh->pos = offset; + return 0; +} + +int FS_fclose(fshandle_t *fh) +{ + if (!fh) { + errno = EBADF; + return -1; + } + return fclose(fh->file); +} + +long FS_ftell(fshandle_t *fh) +{ + if (!fh) { + errno = EBADF; + return -1; + } + return fh->pos; +} + +void FS_rewind(fshandle_t *fh) +{ + if (!fh) return; + clearerr(fh->file); + fseek(fh->file, fh->start, SEEK_SET); + fh->pos = 0; +} + +int FS_feof(fshandle_t *fh) +{ + if (!fh) { + errno = EBADF; + return -1; + } + if (fh->pos >= fh->length) + return -1; + return 0; +} + +int FS_ferror(fshandle_t *fh) +{ + if (!fh) { + errno = EBADF; + return -1; + } + return ferror(fh->file); +} + +int FS_fgetc(fshandle_t *fh) +{ + if (!fh) { + errno = EBADF; + return EOF; + } + if (fh->pos >= fh->length) + return EOF; + fh->pos += 1; + return fgetc(fh->file); +} + +char *FS_fgets(char *s, int size, fshandle_t *fh) +{ + char *ret; + + if (FS_feof(fh)) + return NULL; + + if (size > (fh->length - fh->pos) + 1) + size = (fh->length - fh->pos) + 1; + + ret = fgets(s, size, fh->file); + fh->pos = ftell(fh->file) - fh->start; + + return ret; +} + +long FS_filelength (fshandle_t *fh) +{ + if (!fh) { + errno = EBADF; + return -1; + } + return fh->length; +} + diff --git a/engine/Quake/common.h b/engine/Quake/common.h new file mode 100644 index 0000000..eff6b64 --- /dev/null +++ b/engine/Quake/common.h @@ -0,0 +1,308 @@ +/* +Copyright (C) 1996-2001 Id Software, Inc. +Copyright (C) 2002-2009 John Fitzgibbons and others +Copyright (C) 2010-2014 QuakeSpasm developers + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#ifndef _Q_COMMON_H +#define _Q_COMMON_H + +// comndef.h -- general definitions + +#if defined(_WIN32) +#ifdef _MSC_VER +# pragma warning(disable:4244) + /* 'argument' : conversion from 'type1' to 'type2', + possible loss of data */ +# pragma warning(disable:4305) + /* 'identifier' : truncation from 'type1' to 'type2' */ + /* in our case, truncation from 'double' to 'float' */ +# pragma warning(disable:4267) + /* 'var' : conversion from 'size_t' to 'type', + possible loss of data (/Wp64 warning) */ +#endif /* _MSC_VER */ +#endif /* _WIN32 */ + +#undef min +#undef max +#define q_min(a, b) (((a) < (b)) ? (a) : (b)) +#define q_max(a, b) (((a) > (b)) ? (a) : (b)) +#define CLAMP(_minval, x, _maxval) \ + ((x) < (_minval) ? (_minval) : \ + (x) > (_maxval) ? (_maxval) : (x)) + +typedef struct sizebuf_s +{ + qboolean allowoverflow; // if false, do a Sys_Error + qboolean overflowed; // set to true if the buffer size failed + byte *data; + int maxsize; + int cursize; +} sizebuf_t; + +void SZ_Alloc (sizebuf_t *buf, int startsize); +void SZ_Free (sizebuf_t *buf); +void SZ_Clear (sizebuf_t *buf); +void *SZ_GetSpace (sizebuf_t *buf, int length); +void SZ_Write (sizebuf_t *buf, const void *data, int length); +void SZ_Print (sizebuf_t *buf, const char *data); // strcats onto the sizebuf + +//============================================================================ + +typedef struct link_s +{ + struct link_s *prev, *next; +} link_t; + + +void ClearLink (link_t *l); +void RemoveLink (link_t *l); +void InsertLinkBefore (link_t *l, link_t *before); +void InsertLinkAfter (link_t *l, link_t *after); + +// (type *)STRUCT_FROM_LINK(link_t *link, type, member) +// ent = STRUCT_FROM_LINK(link,entity_t,order) +// FIXME: remove this mess! +#define STRUCT_FROM_LINK(l,t,m) ((t *)((byte *)l - (intptr_t)&(((t *)0)->m))) + +//============================================================================ + +extern qboolean host_bigendian; + +extern short (*BigShort) (short l); +extern short (*LittleShort) (short l); +extern int (*BigLong) (int l); +extern int (*LittleLong) (int l); +extern float (*BigFloat) (float l); +extern float (*LittleFloat) (float l); + +//============================================================================ + +void MSG_WriteChar (sizebuf_t *sb, int c); +void MSG_WriteByte (sizebuf_t *sb, int c); +void MSG_WriteShort (sizebuf_t *sb, int c); +void MSG_WriteLong (sizebuf_t *sb, int c); +void MSG_WriteFloat (sizebuf_t *sb, float f); +void MSG_WriteString (sizebuf_t *sb, const char *s); +void MSG_WriteCoord (sizebuf_t *sb, float f, unsigned int flags); +void MSG_WriteAngle (sizebuf_t *sb, float f, unsigned int flags); +void MSG_WriteAngle16 (sizebuf_t *sb, float f, unsigned int flags); //johnfitz + +extern int msg_readcount; +extern qboolean msg_badread; // set if a read goes beyond end of message + +void MSG_BeginReading (void); +int MSG_ReadChar (void); +int MSG_ReadByte (void); +int MSG_ReadShort (void); +int MSG_ReadLong (void); +float MSG_ReadFloat (void); +const char *MSG_ReadString (void); + +float MSG_ReadCoord (unsigned int flags); +float MSG_ReadAngle (unsigned int flags); +float MSG_ReadAngle16 (unsigned int flags); //johnfitz + +//============================================================================ + +void Q_memset (void *dest, int fill, size_t count); +void Q_memcpy (void *dest, const void *src, size_t count); +int Q_memcmp (const void *m1, const void *m2, size_t count); +void Q_strcpy (char *dest, const char *src); +void Q_strncpy (char *dest, const char *src, int count); +int Q_strlen (const char *str); +char *Q_strrchr (const char *s, char c); +void Q_strcat (char *dest, const char *src); +int Q_strcmp (const char *s1, const char *s2); +int Q_strncmp (const char *s1, const char *s2, int count); +int Q_atoi (const char *str); +float Q_atof (const char *str); + + +#include "strl_fn.h" + +/* locale-insensitive strcasecmp replacement functions: */ +extern int q_strcasecmp (const char * s1, const char * s2); +extern int q_strncasecmp (const char *s1, const char *s2, size_t n); + +/* locale-insensitive case-insensitive alternative to strstr */ +extern char *q_strcasestr(const char *haystack, const char *needle); + +/* locale-insensitive strlwr/upr replacement functions: */ +extern char *q_strlwr (char *str); +extern char *q_strupr (char *str); + +/* snprintf, vsnprintf : always use our versions. */ +extern int q_snprintf (char *str, size_t size, const char *format, ...) FUNC_PRINTF(3,4); +extern int q_vsnprintf(char *str, size_t size, const char *format, va_list args) FUNC_PRINTF(3,0); + +//============================================================================ + +extern char com_token[1024]; +extern qboolean com_eof; + +const char *COM_Parse (const char *data); + + +extern int com_argc; +extern char **com_argv; + +extern int safemode; +/* safe mode: in true, the engine will behave as if one + of these arguments were actually on the command line: + -nosound, -nocdaudio, -nomidi, -stdvid, -dibonly, + -nomouse, -nojoy, -nolan + */ + +int COM_CheckParm (const char *parm); + +void COM_Init (void); +void COM_InitArgv (int argc, char **argv); +void COM_InitFilesystem (void); + +const char *COM_SkipPath (const char *pathname); +void COM_StripExtension (const char *in, char *out, size_t outsize); +void COM_FileBase (const char *in, char *out, size_t outsize); +void COM_AddExtension (char *path, const char *extension, size_t len); +#if 0 /* COM_DefaultExtension can be dangerous */ +void COM_DefaultExtension (char *path, const char *extension, size_t len); +#endif +const char *COM_FileGetExtension (const char *in); /* doesn't return NULL */ +void COM_ExtractExtension (const char *in, char *out, size_t outsize); +void COM_CreatePath (char *path); + +char *va (const char *format, ...) FUNC_PRINTF(1,2); +// does a varargs printf into a temp buffer + + +//============================================================================ + +// QUAKEFS +typedef struct +{ + char name[MAX_QPATH]; + int filepos, filelen; +} packfile_t; + +typedef struct pack_s +{ + char filename[MAX_OSPATH]; + int handle; + int numfiles; + packfile_t *files; +} pack_t; + +typedef struct searchpath_s +{ + unsigned int path_id; // identifier assigned to the game directory + // Note that /game1 and + // /game1 have the same id. + char filename[MAX_OSPATH]; + pack_t *pack; // only one of filename / pack will be used + struct searchpath_s *next; +} searchpath_t; + +extern searchpath_t *com_searchpaths; +extern searchpath_t *com_base_searchpaths; + +extern int com_filesize; +struct cache_user_s; + +extern char com_basedir[MAX_OSPATH]; +extern char com_gamedir[MAX_OSPATH]; +extern int file_from_pak; // global indicating that file came from a pak + +void COM_WriteFile (const char *filename, const void *data, int len); +int COM_OpenFile (const char *filename, int *handle, unsigned int *path_id); +int COM_FOpenFile (const char *filename, FILE **file, unsigned int *path_id); +qboolean COM_FileExists (const char *filename, unsigned int *path_id); +void COM_CloseFile (int h); + +// these procedures open a file using COM_FindFile and loads it into a proper +// buffer. the buffer is allocated with a total size of com_filesize + 1. the +// procedures differ by their buffer allocation method. +byte *COM_LoadStackFile (const char *path, void *buffer, int bufsize, + unsigned int *path_id); + // uses the specified stack stack buffer with the specified size + // of bufsize. if bufsize is too short, uses temp hunk. the bufsize + // must include the +1 +byte *COM_LoadTempFile (const char *path, unsigned int *path_id); + // allocates the buffer on the temp hunk. +byte *COM_LoadHunkFile (const char *path, unsigned int *path_id); + // allocates the buffer on the hunk. +byte *COM_LoadZoneFile (const char *path, unsigned int *path_id); + // allocates the buffer on the zone. +void COM_LoadCacheFile (const char *path, struct cache_user_s *cu, + unsigned int *path_id); + // uses cache mem for allocating the buffer. +byte *COM_LoadMallocFile (const char *path, unsigned int *path_id); + // allocates the buffer on the system mem (malloc). + +// Opens the given path directly, ignoring search paths. +// Returns NULL on failure, or else a '\0'-terminated malloc'ed buffer. +// Loads in "t" mode so CRLF to LF translation is performed on Windows. +byte *COM_LoadMallocFile_TextMode_OSPath (const char *path, long *len_out); + +// Attempts to parse an int, followed by a newline. +// Returns advanced buffer position. +// Doesn't signal parsing failure, but this is not needed for savegame loading. +const char *COM_ParseIntNewline(const char *buffer, int *value); + +// Attempts to parse a float followed by a newline. +// Returns advanced buffer position. +const char *COM_ParseFloatNewline(const char *buffer, float *value); + +// Parse a string of non-whitespace into com_token, then tries to consume a +// newline. Returns advanced buffer position. +const char *COM_ParseStringNewline(const char *buffer); + +/* The following FS_*() stdio replacements are necessary if one is + * to perform non-sequential reads on files reopened on pak files + * because we need the bookkeeping about file start/end positions. + * Allocating and filling in the fshandle_t structure is the users' + * responsibility when the file is initially opened. */ + +typedef struct _fshandle_t +{ + FILE *file; + qboolean pak; /* is the file read from a pak */ + long start; /* file or data start position */ + long length; /* file or data size */ + long pos; /* current position relative to start */ +} fshandle_t; + +size_t FS_fread(void *ptr, size_t size, size_t nmemb, fshandle_t *fh); +int FS_fseek(fshandle_t *fh, long offset, int whence); +long FS_ftell(fshandle_t *fh); +void FS_rewind(fshandle_t *fh); +int FS_feof(fshandle_t *fh); +int FS_ferror(fshandle_t *fh); +int FS_fclose(fshandle_t *fh); +int FS_fgetc(fshandle_t *fh); +char *FS_fgets(char *s, int size, fshandle_t *fh); +long FS_filelength (fshandle_t *fh); + + +extern struct cvar_s registered; +extern qboolean standard_quake, rogue, hipnotic; +extern qboolean fitzmode; + /* if true, run in fitzquake mode disabling custom quakespasm hacks */ + +#endif /* _Q_COMMON_H */ + diff --git a/engine/Quake/console.c b/engine/Quake/console.c new file mode 100644 index 0000000..5884704 --- /dev/null +++ b/engine/Quake/console.c @@ -0,0 +1,1308 @@ +/* +Copyright (C) 1996-2001 Id Software, Inc. +Copyright (C) 2002-2009 John Fitzgibbons and others +Copyright (C) 2010-2014 QuakeSpasm developers + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ +// console.c + +#include +#include +#include +#include +#ifdef _WIN32 +#include +#else +#include +#endif +#include "quakedef.h" + +int con_linewidth; + +float con_cursorspeed = 4; + +#define CON_TEXTSIZE (1024 * 1024) //ericw -- was 65536. johnfitz -- new default size +#define CON_MINSIZE 16384 //johnfitz -- old default, now the minimum size + +int con_buffersize; //johnfitz -- user can now override default + +qboolean con_forcedup; // because no entities to refresh + +int con_totallines; // total lines in console scrollback +int con_backscroll; // lines up from bottom to display +int con_current; // where next message will be printed +int con_x; // offset in current line for next print +char *con_text = NULL; + +cvar_t con_notifytime = {"con_notifytime","3",CVAR_NONE}; //seconds +cvar_t con_logcenterprint = {"con_logcenterprint", "1", CVAR_NONE}; //johnfitz + +char con_lastcenterstring[1024]; //johnfitz + +#define NUM_CON_TIMES 4 +float con_times[NUM_CON_TIMES]; // realtime time the line was generated + // for transparent notify lines + +int con_vislines; + +qboolean con_debuglog = false; + +qboolean con_initialized; + + +/* +================ +Con_Quakebar -- johnfitz -- returns a bar of the desired length, but never wider than the console + +includes a newline, unless len >= con_linewidth. +================ +*/ +const char *Con_Quakebar (int len) +{ + static char bar[42]; + int i; + + len = q_min(len, (int)sizeof(bar) - 2); + len = q_min(len, con_linewidth); + + bar[0] = '\35'; + for (i = 1; i < len - 1; i++) + bar[i] = '\36'; + bar[len-1] = '\37'; + + if (len < con_linewidth) + { + bar[len] = '\n'; + bar[len+1] = 0; + } + else + bar[len] = 0; + + return bar; +} + +/* +================ +Con_ToggleConsole_f +================ +*/ +extern int history_line; //johnfitz + +void Con_ToggleConsole_f (void) +{ + if (key_dest == key_console/* || (key_dest == key_game && con_forcedup)*/) + { + key_lines[edit_line][1] = 0; // clear any typing + key_linepos = 1; + con_backscroll = 0; //johnfitz -- toggleconsole should return you to the bottom of the scrollback + history_line = edit_line; //johnfitz -- it should also return you to the bottom of the command history + + if (cls.state == ca_connected) + { + IN_Activate(); + key_dest = key_game; + } + else + { + M_Menu_Main_f (); + } + } + else + { + IN_Deactivate(modestate == MS_WINDOWED); + key_dest = key_console; + } + + SCR_EndLoadingPlaque (); + memset (con_times, 0, sizeof(con_times)); +} + +/* +================ +Con_Clear_f +================ +*/ +static void Con_Clear_f (void) +{ + if (con_text) + Q_memset (con_text, ' ', con_buffersize); //johnfitz -- con_buffersize replaces CON_TEXTSIZE + con_backscroll = 0; //johnfitz -- if console is empty, being scrolled up is confusing +} + +/* +================ +Con_Dump_f -- johnfitz -- adapted from quake2 source +================ +*/ +static void Con_Dump_f (void) +{ + int l, x; + const char *line; + FILE *f; + char buffer[1024]; + char name[MAX_OSPATH]; + + q_snprintf (name, sizeof(name), "%s/condump.txt", com_gamedir); + COM_CreatePath (name); + f = fopen (name, "w"); + if (!f) + { + Con_Printf ("ERROR: couldn't open file %s.\n", name); + return; + } + + // skip initial empty lines + for (l = con_current - con_totallines + 1; l <= con_current; l++) + { + line = con_text + (l % con_totallines)*con_linewidth; + for (x = 0; x < con_linewidth; x++) + if (line[x] != ' ') + break; + if (x != con_linewidth) + break; + } + + // write the remaining lines + buffer[con_linewidth] = 0; + for ( ; l <= con_current; l++) + { + line = con_text + (l%con_totallines)*con_linewidth; + strncpy (buffer, line, con_linewidth); + for (x = con_linewidth - 1; x >= 0; x--) + { + if (buffer[x] == ' ') + buffer[x] = 0; + else + break; + } + for (x = 0; buffer[x]; x++) + buffer[x] &= 0x7f; + + fprintf (f, "%s\n", buffer); + } + + fclose (f); + Con_Printf ("Dumped console text to %s.\n", name); +} + +/* +================ +Con_ClearNotify +================ +*/ +void Con_ClearNotify (void) +{ + int i; + + for (i = 0; i < NUM_CON_TIMES; i++) + con_times[i] = 0; +} + + +/* +================ +Con_MessageMode_f +================ +*/ +static void Con_MessageMode_f (void) +{ + if (cls.state != ca_connected || cls.demoplayback) + return; + chat_team = false; + key_dest = key_message; +} + +/* +================ +Con_MessageMode2_f +================ +*/ +static void Con_MessageMode2_f (void) +{ + if (cls.state != ca_connected || cls.demoplayback) + return; + chat_team = true; + key_dest = key_message; +} + + +/* +================ +Con_CheckResize + +If the line width has changed, reformat the buffer. +================ +*/ +void Con_CheckResize (void) +{ + int i, j, width, oldwidth, oldtotallines, numlines, numchars; + char *tbuf; //johnfitz -- tbuf no longer a static array + int mark; //johnfitz + + width = (vid.conwidth >> 3) - 2; //johnfitz -- use vid.conwidth instead of vid.width + + if (width == con_linewidth) + return; + + oldwidth = con_linewidth; + con_linewidth = width; + oldtotallines = con_totallines; + con_totallines = con_buffersize / con_linewidth; //johnfitz -- con_buffersize replaces CON_TEXTSIZE + numlines = oldtotallines; + + if (con_totallines < numlines) + numlines = con_totallines; + + numchars = oldwidth; + + if (con_linewidth < numchars) + numchars = con_linewidth; + + mark = Hunk_LowMark (); //johnfitz + tbuf = (char *) Hunk_Alloc (con_buffersize); //johnfitz + + Q_memcpy (tbuf, con_text, con_buffersize);//johnfitz -- con_buffersize replaces CON_TEXTSIZE + Q_memset (con_text, ' ', con_buffersize);//johnfitz -- con_buffersize replaces CON_TEXTSIZE + + for (i = 0; i < numlines; i++) + { + for (j = 0; j < numchars; j++) + { + con_text[(con_totallines - 1 - i) * con_linewidth + j] = + tbuf[((con_current - i + oldtotallines) % oldtotallines) * oldwidth + j]; + } + } + + Hunk_FreeToLowMark (mark); //johnfitz + + Con_ClearNotify (); + + con_backscroll = 0; + con_current = con_totallines - 1; +} + + +/* +================ +Con_Init +================ +*/ +void Con_Init (void) +{ + int i; + + //johnfitz -- user settable console buffer size + i = COM_CheckParm("-consize"); + if (i && i < com_argc-1) + con_buffersize = q_max(CON_MINSIZE,Q_atoi(com_argv[i+1])*1024); + else + con_buffersize = CON_TEXTSIZE; + //johnfitz + + con_text = (char *) Hunk_AllocName (con_buffersize, "context");//johnfitz -- con_buffersize replaces CON_TEXTSIZE + Q_memset (con_text, ' ', con_buffersize);//johnfitz -- con_buffersize replaces CON_TEXTSIZE + con_linewidth = -1; + + //johnfitz -- no need to run Con_CheckResize here + con_linewidth = 38; + con_totallines = con_buffersize / con_linewidth;//johnfitz -- con_buffersize replaces CON_TEXTSIZE + con_backscroll = 0; + con_current = con_totallines - 1; + //johnfitz + + Con_Printf ("Console initialized.\n"); + + Cvar_RegisterVariable (&con_notifytime); + Cvar_RegisterVariable (&con_logcenterprint); //johnfitz + + Cmd_AddCommand ("toggleconsole", Con_ToggleConsole_f); + Cmd_AddCommand ("messagemode", Con_MessageMode_f); + Cmd_AddCommand ("messagemode2", Con_MessageMode2_f); + Cmd_AddCommand ("clear", Con_Clear_f); + Cmd_AddCommand ("condump", Con_Dump_f); //johnfitz + con_initialized = true; +} + + +/* +=============== +Con_Linefeed +=============== +*/ +static void Con_Linefeed (void) +{ + //johnfitz -- improved scrolling + if (con_backscroll) + con_backscroll++; + if (con_backscroll > con_totallines - (glheight>>3) - 1) + con_backscroll = con_totallines - (glheight>>3) - 1; + //johnfitz + + con_x = 0; + con_current++; + Q_memset (&con_text[(con_current%con_totallines)*con_linewidth], ' ', con_linewidth); +} + +/* +================ +Con_Print + +Handles cursor positioning, line wrapping, etc +All console printing must go through this in order to be logged to disk +If no console is visible, the notify window will pop up. +================ +*/ +static void Con_Print (const char *txt) +{ + int y; + int c, l; + static int cr; + int mask; + qboolean boundary; + + //con_backscroll = 0; //johnfitz -- better console scrolling + + if (txt[0] == 1) + { + mask = 128; // go to colored text + S_LocalSound ("misc/talk.wav"); // play talk wav + txt++; + } + else if (txt[0] == 2) + { + mask = 128; // go to colored text + txt++; + } + else + mask = 0; + + boundary = true; + + while ( (c = *txt) ) + { + if (c <= ' ') + { + boundary = true; + } + else if (boundary) + { + // count word length + for (l = 0; l < con_linewidth; l++) + if (txt[l] <= ' ') + break; + + // word wrap + if (l != con_linewidth && (con_x + l > con_linewidth)) + con_x = 0; + + boundary = false; + } + + txt++; + + if (cr) + { + con_current--; + cr = false; + } + + if (!con_x) + { + Con_Linefeed (); + // mark time for transparent overlay + if (con_current >= 0) + con_times[con_current % NUM_CON_TIMES] = realtime; + } + + switch (c) + { + case '\n': + con_x = 0; + break; + + case '\r': + con_x = 0; + cr = 1; + break; + + default: // display character and advance + y = con_current % con_totallines; + con_text[y*con_linewidth+con_x] = c | mask; + con_x++; + if (con_x >= con_linewidth) + con_x = 0; + break; + } + } +} + + +// borrowed from uhexen2 by S.A. for new procs, LOG_Init, LOG_Close + +static char logfilename[MAX_OSPATH]; // current logfile name +static int log_fd = -1; // log file descriptor + +/* +================ +Con_DebugLog +================ +*/ +void Con_DebugLog(const char *msg) +{ + if (log_fd == -1) + return; + + write(log_fd, msg, strlen(msg)); +} + + +/* +================ +Con_Printf + +Handles cursor positioning, line wrapping, etc +================ +*/ +#define MAXPRINTMSG 4096 +void Con_Printf (const char *fmt, ...) +{ + va_list argptr; + char msg[MAXPRINTMSG]; + static qboolean inupdate; + + va_start (argptr, fmt); + q_vsnprintf (msg, sizeof(msg), fmt, argptr); + va_end (argptr); + +// also echo to debugging console + Sys_Printf ("%s", msg); + +// log all messages to file + if (con_debuglog) + Con_DebugLog(msg); + + if (!con_initialized) + return; + + if (cls.state == ca_dedicated) + return; // no graphics mode + +// write it to the scrollable buffer + Con_Print (msg); + +// update the screen if the console is displayed + if (cls.signon != SIGNONS && !scr_disabled_for_loading ) + { + // protect against infinite loop if something in SCR_UpdateScreen calls + // Con_Printd + if (!inupdate) + { + inupdate = true; + SCR_UpdateScreen (); + inupdate = false; + } + } +} + +/* +================ +Con_DWarning -- ericw + +same as Con_Warning, but only prints if "developer" cvar is set. +use for "exceeds standard limit of" messages, which are only relevant for developers +targetting vanilla engines +================ +*/ +void Con_DWarning (const char *fmt, ...) +{ + va_list argptr; + char msg[MAXPRINTMSG]; + + if (!developer.value) + return; // don't confuse non-developers with techie stuff... + + va_start (argptr, fmt); + q_vsnprintf (msg, sizeof(msg), fmt, argptr); + va_end (argptr); + + Con_SafePrintf ("\x02Warning: "); + Con_Printf ("%s", msg); +} + +/* +================ +Con_Warning -- johnfitz -- prints a warning to the console +================ +*/ +void Con_Warning (const char *fmt, ...) +{ + va_list argptr; + char msg[MAXPRINTMSG]; + + va_start (argptr, fmt); + q_vsnprintf (msg, sizeof(msg), fmt, argptr); + va_end (argptr); + + Con_SafePrintf ("\x02Warning: "); + Con_Printf ("%s", msg); +} + +/* +================ +Con_DPrintf + +A Con_Printf that only shows up if the "developer" cvar is set +================ +*/ +void Con_DPrintf (const char *fmt, ...) +{ + va_list argptr; + char msg[MAXPRINTMSG]; + + if (!developer.value) + return; // don't confuse non-developers with techie stuff... + + va_start (argptr, fmt); + q_vsnprintf (msg, sizeof(msg), fmt, argptr); + va_end (argptr); + + Con_SafePrintf ("%s", msg); //johnfitz -- was Con_Printf +} + +/* +================ +Con_DPrintf2 -- johnfitz -- only prints if "developer" >= 2 + +currently not used +================ +*/ +void Con_DPrintf2 (const char *fmt, ...) +{ + va_list argptr; + char msg[MAXPRINTMSG]; + + if (developer.value >= 2) + { + va_start (argptr, fmt); + q_vsnprintf (msg, sizeof(msg), fmt, argptr); + va_end (argptr); + Con_Printf ("%s", msg); + } +} + + +/* +================== +Con_SafePrintf + +Okay to call even when the screen can't be updated +================== +*/ +void Con_SafePrintf (const char *fmt, ...) +{ + va_list argptr; + char msg[1024]; + int temp; + + va_start (argptr, fmt); + q_vsnprintf (msg, sizeof(msg), fmt, argptr); + va_end (argptr); + + temp = scr_disabled_for_loading; + scr_disabled_for_loading = true; + Con_Printf ("%s", msg); + scr_disabled_for_loading = temp; +} + +/* +================ +Con_CenterPrintf -- johnfitz -- pad each line with spaces to make it appear centered +================ +*/ +void Con_CenterPrintf (int linewidth, const char *fmt, ...) FUNC_PRINTF(2,3); +void Con_CenterPrintf (int linewidth, const char *fmt, ...) +{ + va_list argptr; + char msg[MAXPRINTMSG]; //the original message + char line[MAXPRINTMSG]; //one line from the message + char spaces[21]; //buffer for spaces + char *src, *dst; + int len, s; + + va_start (argptr, fmt); + q_vsnprintf (msg, sizeof(msg), fmt, argptr); + va_end (argptr); + + linewidth = q_min(linewidth, con_linewidth); + for (src = msg; *src; ) + { + dst = line; + while (*src && *src != '\n') + *dst++ = *src++; + *dst = 0; + if (*src == '\n') + src++; + + len = strlen(line); + if (len < linewidth) + { + s = (linewidth-len)/2; + memset (spaces, ' ', s); + spaces[s] = 0; + Con_Printf ("%s%s\n", spaces, line); + } + else + Con_Printf ("%s\n", line); + } +} + +/* +================== +Con_LogCenterPrint -- johnfitz -- echo centerprint message to the console +================== +*/ +void Con_LogCenterPrint (const char *str) +{ + if (!strcmp(str, con_lastcenterstring)) + return; //ignore duplicates + + if (cl.gametype == GAME_DEATHMATCH && con_logcenterprint.value != 2) + return; //don't log in deathmatch + + strcpy(con_lastcenterstring, str); + + if (con_logcenterprint.value) + { + Con_Printf ("%s", Con_Quakebar(40)); + Con_CenterPrintf (40, "%s\n", str); + Con_Printf ("%s", Con_Quakebar(40)); + Con_ClearNotify (); + } +} + +/* +============================================================================== + + TAB COMPLETION + +============================================================================== +*/ + +//johnfitz -- tab completion stuff +//unique defs +char key_tabpartial[MAXCMDLINE]; +typedef struct tab_s +{ + const char *name; + const char *type; + struct tab_s *next; + struct tab_s *prev; +} tab_t; +tab_t *tablist; + +//defs from elsewhere +extern qboolean keydown[256]; +typedef struct cmd_function_s +{ + struct cmd_function_s *next; + const char *name; + xcommand_t function; +} cmd_function_t; +extern cmd_function_t *cmd_functions; +#define MAX_ALIAS_NAME 32 +typedef struct cmdalias_s +{ + struct cmdalias_s *next; + char name[MAX_ALIAS_NAME]; + char *value; +} cmdalias_t; +extern cmdalias_t *cmd_alias; + +/* +============ +AddToTabList -- johnfitz + +tablist is a doubly-linked loop, alphabetized by name +============ +*/ + +// bash_partial is the string that can be expanded, +// aka Linux Bash shell. -- S.A. +static char bash_partial[80]; +static qboolean bash_singlematch; + +void AddToTabList (const char *name, const char *type) +{ + tab_t *t,*insert; + char *i_bash; + const char *i_name; + + if (!*bash_partial) + { + strncpy (bash_partial, name, 79); + bash_partial[79] = '\0'; + } + else + { + bash_singlematch = 0; + // find max common between bash_partial and name + i_bash = bash_partial; + i_name = name; + while (*i_bash && (*i_bash == *i_name)) + { + i_bash++; + i_name++; + } + *i_bash = 0; + } + + t = (tab_t *) Hunk_Alloc(sizeof(tab_t)); + t->name = name; + t->type = type; + + if (!tablist) //create list + { + tablist = t; + t->next = t; + t->prev = t; + } + else if (strcmp(name, tablist->name) < 0) //insert at front + { + t->next = tablist; + t->prev = tablist->prev; + t->next->prev = t; + t->prev->next = t; + tablist = t; + } + else //insert later + { + insert = tablist; + do + { + if (strcmp(name, insert->name) < 0) + break; + insert = insert->next; + } while (insert != tablist); + + t->next = insert; + t->prev = insert->prev; + t->next->prev = t; + t->prev->next = t; + } +} + +typedef struct arg_completion_type_s +{ + const char *command; + filelist_item_t **filelist; +} arg_completion_type_t; + +static const arg_completion_type_t arg_completion_types[] = +{ + { "map ", &extralevels }, + { "changelevel ", &extralevels }, + { "game ", &modlist }, + { "record ", &demolist }, + { "playdemo ", &demolist }, + { "timedemo ", &demolist } +}; + +static const int num_arg_completion_types = + sizeof(arg_completion_types)/sizeof(arg_completion_types[0]); + +/* +============ +FindCompletion -- stevenaaus +============ +*/ +const char *FindCompletion (const char *partial, filelist_item_t *filelist, int *nummatches_out) +{ + static char matched[32]; + char *i_matched, *i_name; + filelist_item_t *file; + int init, match, plen; + + memset(matched, 0, sizeof(matched)); + plen = strlen(partial); + match = 0; + + for (file = filelist, init = 0; file; file = file->next) + { + if (!strncmp(file->name, partial, plen)) + { + if (init == 0) + { + init = 1; + strncpy (matched, file->name, sizeof(matched)-1); + matched[sizeof(matched)-1] = '\0'; + } + else + { // find max common + i_matched = matched; + i_name = file->name; + while (*i_matched && (*i_matched == *i_name)) + { + i_matched++; + i_name++; + } + *i_matched = 0; + } + match++; + } + } + + *nummatches_out = match; + + if (match > 1) + { + for (file = filelist; file; file = file->next) + { + if (!strncmp(file->name, partial, plen)) + Con_SafePrintf (" %s\n", file->name); + } + Con_SafePrintf ("\n"); + } + + return matched; +} + +/* +============ +BuildTabList -- johnfitz +============ +*/ +void BuildTabList (const char *partial) +{ + cmdalias_t *alias; + cvar_t *cvar; + cmd_function_t *cmd; + int len; + + tablist = NULL; + len = strlen(partial); + + bash_partial[0] = 0; + bash_singlematch = 1; + + cvar = Cvar_FindVarAfter ("", CVAR_NONE); + for ( ; cvar ; cvar=cvar->next) + if (!Q_strncmp (partial, cvar->name, len)) + AddToTabList (cvar->name, "cvar"); + + for (cmd=cmd_functions ; cmd ; cmd=cmd->next) + if (!Q_strncmp (partial,cmd->name, len)) + AddToTabList (cmd->name, "command"); + + for (alias=cmd_alias ; alias ; alias=alias->next) + if (!Q_strncmp (partial, alias->name, len)) + AddToTabList (alias->name, "alias"); +} + +/* +============ +Con_TabComplete -- johnfitz +============ +*/ +void Con_TabComplete (void) +{ + char partial[MAXCMDLINE]; + const char *match; + static char *c; + tab_t *t; + int mark, i, j; + +// if editline is empty, return + if (key_lines[edit_line][1] == 0) + return; + +// get partial string (space -> cursor) + if (!key_tabpartial[0]) //first time through, find new insert point. (Otherwise, use previous.) + { + //work back from cursor until you find a space, quote, semicolon, or prompt + c = key_lines[edit_line] + key_linepos - 1; //start one space left of cursor + while (*c!=' ' && *c!='\"' && *c!=';' && c!=key_lines[edit_line]) + c--; + c++; //start 1 char after the separator we just found + } + for (i = 0; c + i < key_lines[edit_line] + key_linepos; i++) + partial[i] = c[i]; + partial[i] = 0; + +// Map autocomplete function -- S.A +// Since we don't have argument completion, this hack will do for now... + for (j=0; j= MAXCMDLINE) + key_linepos = MAXCMDLINE - 1; + // if only one match, append a space + if (key_linepos < MAXCMDLINE - 1 && + key_lines[edit_line][key_linepos] == 0 && (nummatches == 1)) + { + key_lines[edit_line][key_linepos] = ' '; + key_linepos++; + key_lines[edit_line][key_linepos] = 0; + } + c = key_lines[edit_line] + key_linepos; + return; + } + } + +//if partial is empty, return + if (partial[0] == 0) + return; + +//trim trailing space becuase it screws up string comparisons + if (i > 0 && partial[i-1] == ' ') + partial[i-1] = 0; + +// find a match + mark = Hunk_LowMark(); + if (!key_tabpartial[0]) //first time through + { + q_strlcpy (key_tabpartial, partial, MAXCMDLINE); + BuildTabList (key_tabpartial); + + if (!tablist) + return; + + // print list if length > 1 + if (tablist->next != tablist) + { + t = tablist; + Con_SafePrintf("\n"); + do + { + Con_SafePrintf(" %s (%s)\n", t->name, t->type); + t = t->next; + } while (t != tablist); + Con_SafePrintf("\n"); + } + + // match = tablist->name; + // First time, just show maximum matching chars -- S.A. + match = bash_partial; + } + else + { + BuildTabList (key_tabpartial); + + if (!tablist) + return; + + //find current match -- can't save a pointer because the list will be rebuilt each time + t = tablist; + match = keydown[K_SHIFT] ? t->prev->name : t->name; + do + { + if (!Q_strcmp(t->name, partial)) + { + match = keydown[K_SHIFT] ? t->prev->name : t->next->name; + break; + } + t = t->next; + } while (t != tablist); + } + Hunk_FreeToLowMark(mark); //it's okay to free it here because match is a pointer to persistent data + +// insert new match into edit line + q_strlcpy (partial, match, MAXCMDLINE); //first copy match string + q_strlcat (partial, key_lines[edit_line] + key_linepos, MAXCMDLINE); //then add chars after cursor + *c = '\0'; //now copy all of this into edit line + q_strlcat (key_lines[edit_line], partial, MAXCMDLINE); + key_linepos = c - key_lines[edit_line] + Q_strlen(match); //set new cursor position + if (key_linepos >= MAXCMDLINE) + key_linepos = MAXCMDLINE - 1; + +// if cursor is at end of string, let's append a space to make life easier + if (key_linepos < MAXCMDLINE - 1 && + key_lines[edit_line][key_linepos] == 0 && bash_singlematch) + { + key_lines[edit_line][key_linepos] = ' '; + key_linepos++; + key_lines[edit_line][key_linepos] = 0; + // S.A.: the map argument completion (may be in combination with the bash-style + // display behavior changes, causes weirdness when completing the arguments for + // the changelevel command. the line below "fixes" it, although I'm not sure about + // the reason, yet, neither do I know any possible side effects of it: + c = key_lines[edit_line] + key_linepos; + } +} + +/* +============================================================================== + +DRAWING + +============================================================================== +*/ + +/* +================ +Con_DrawNotify + +Draws the last few lines of output transparently over the game top +================ +*/ +void Con_DrawNotify (void) +{ + int i, x, v; + const char *text; + float time; + + GL_SetCanvas (CANVAS_CONSOLE); //johnfitz + v = vid.conheight; //johnfitz + + for (i = con_current-NUM_CON_TIMES+1; i <= con_current; i++) + { + if (i < 0) + continue; + time = con_times[i % NUM_CON_TIMES]; + if (time == 0) + continue; + time = realtime - time; + if (time > con_notifytime.value) + continue; + text = con_text + (i % con_totallines)*con_linewidth; + + clearnotify = 0; + + for (x = 0; x < con_linewidth; x++) + Draw_Character ((x+1)<<3, v, text[x]); + + v += 8; + + scr_tileclear_updates = 0; //johnfitz + } + + if (key_dest == key_message) + { + clearnotify = 0; + + if (chat_team) + { + Draw_String (8, v, "say_team:"); + x = 11; + } + else + { + Draw_String (8, v, "say:"); + x = 6; + } + + text = Key_GetChatBuffer(); + i = Key_GetChatMsgLen(); + if (i > con_linewidth - x - 1) + text += i - con_linewidth + x + 1; + + while (*text) + { + Draw_Character (x<<3, v, *text); + x++; + text++; + } + + Draw_Character (x<<3, v, 10 + ((int)(realtime*con_cursorspeed)&1)); + v += 8; + + scr_tileclear_updates = 0; //johnfitz + } +} + +/* +================ +Con_DrawInput -- johnfitz -- modified to allow insert editing + +The input line scrolls horizontally if typing goes beyond the right edge +================ +*/ +extern qpic_t *pic_ovr, *pic_ins; //johnfitz -- new cursor handling + +void Con_DrawInput (void) +{ + int i, ofs; + + if (key_dest != key_console && !con_forcedup) + return; // don't draw anything + +// prestep if horizontally scrolling + if (key_linepos >= con_linewidth) + ofs = 1 + key_linepos - con_linewidth; + else + ofs = 0; + +// draw input string + for (i = 0; key_lines[edit_line][i+ofs] && i < con_linewidth; i++) + Draw_Character ((i+1)<<3, vid.conheight - 16, key_lines[edit_line][i+ofs]); + +// johnfitz -- new cursor handling + if (!((int)((realtime-key_blinktime)*con_cursorspeed) & 1)) + { + i = key_linepos - ofs; + Draw_Pic ((i+1)<<3, vid.conheight - 16, key_insert ? pic_ins : pic_ovr); + } +} + +/* +================ +Con_DrawConsole -- johnfitz -- heavy revision + +Draws the console with the solid background +The typing input line at the bottom should only be drawn if typing is allowed +================ +*/ +void Con_DrawConsole (int lines, qboolean drawinput) +{ + int i, x, y, j, sb, rows; + const char *text; + char ver[32]; + + if (lines <= 0) + return; + + con_vislines = lines * vid.conheight / glheight; + GL_SetCanvas (CANVAS_CONSOLE); + +// draw the background + Draw_ConsoleBackground (); + +// draw the buffer text + rows = (con_vislines +7)/8; + y = vid.conheight - rows*8; + rows -= 2; //for input and version lines + sb = (con_backscroll) ? 2 : 0; + + for (i = con_current - rows + 1; i <= con_current - sb; i++, y += 8) + { + j = i - con_backscroll; + if (j < 0) + j = 0; + text = con_text + (j % con_totallines)*con_linewidth; + + for (x = 0; x < con_linewidth; x++) + Draw_Character ( (x + 1)<<3, y, text[x]); + } + +// draw scrollback arrows + if (con_backscroll) + { + y += 8; // blank line + for (x = 0; x < con_linewidth; x += 4) + Draw_Character ((x + 1)<<3, y, '^'); + y += 8; + } + +// draw the input prompt, user text, and cursor + if (drawinput) + Con_DrawInput (); + +//draw version number in bottom right + y += 8; + q_snprintf (ver, sizeof(ver), "QuakeSpasm " QUAKESPASM_VER_STRING); + for (x = 0; x < (int)strlen(ver); x++) + Draw_Character ((con_linewidth - strlen(ver) + x + 2)<<3, y, ver[x] /*+ 128*/); +} + + +/* +================== +Con_NotifyBox +================== +*/ +void Con_NotifyBox (const char *text) +{ + double t1, t2; + int lastkey, lastchar; + +// during startup for sound / cd warnings + Con_Printf ("\n\n%s", Con_Quakebar(40)); //johnfitz + Con_Printf ("%s", text); + Con_Printf ("Press a key.\n"); + Con_Printf ("%s", Con_Quakebar(40)); //johnfitz + + IN_Deactivate(modestate == MS_WINDOWED); + key_dest = key_console; + + Key_BeginInputGrab (); + do + { + t1 = Sys_DoubleTime (); + SCR_UpdateScreen (); + Sys_SendKeyEvents (); + Key_GetGrabbedInput (&lastkey, &lastchar); + Sys_Sleep (16); + t2 = Sys_DoubleTime (); + realtime += t2-t1; // make the cursor blink + } while (lastkey == -1 && lastchar == -1); + Key_EndInputGrab (); + + Con_Printf ("\n"); + IN_Activate(); + key_dest = key_game; + realtime = 0; // put the cursor back to invisible +} + + +void LOG_Init (quakeparms_t *parms) +{ + time_t inittime; + char session[24]; + + if (!COM_CheckParm("-condebug")) + return; + + inittime = time (NULL); + strftime (session, sizeof(session), "%m/%d/%Y %H:%M:%S", localtime(&inittime)); + q_snprintf (logfilename, sizeof(logfilename), "%s/qconsole.log", parms->basedir); + +// unlink (logfilename); + + log_fd = open (logfilename, O_WRONLY | O_CREAT | O_TRUNC, 0666); + if (log_fd == -1) + { + fprintf (stderr, "Error: Unable to create log file %s\n", logfilename); + return; + } + + con_debuglog = true; + Con_DebugLog (va("LOG started on: %s \n", session)); + +} + +void LOG_Close (void) +{ + if (log_fd == -1) + return; + close (log_fd); + log_fd = -1; +} + diff --git a/engine/code/console.h b/engine/Quake/console.h similarity index 50% rename from engine/code/console.h rename to engine/Quake/console.h index ef01f00..0fa4a8c 100644 --- a/engine/code/console.h +++ b/engine/Quake/console.h @@ -1,5 +1,7 @@ /* -Copyright (C) 1996-1997 Id Software, Inc. +Copyright (C) 1996-2001 Id Software, Inc. +Copyright (C) 2002-2009 John Fitzgibbons and others +Copyright (C) 2010-2014 QuakeSpasm developers This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -8,7 +10,7 @@ of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. @@ -18,6 +20,9 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#ifndef __CONSOLE_H +#define __CONSOLE_H + // // console // @@ -26,21 +31,39 @@ extern int con_backscroll; extern qboolean con_forcedup; // because no entities to refresh extern qboolean con_initialized; extern byte *con_chars; -extern int con_notifylines; // scan lines to clear for notify lines + +extern char con_lastcenterstring[]; //johnfitz void Con_DrawCharacter (int cx, int line, int num); void Con_CheckResize (void); void Con_Init (void); void Con_DrawConsole (int lines, qboolean drawinput); -void Con_Print (char *txt); -void Con_Printf (char *fmt, ...); -void Con_DPrintf (char *fmt, ...); -void Con_SafePrintf (char *fmt, ...); -void Con_Clear_f (void); +void Con_Printf (const char *fmt, ...) FUNC_PRINTF(1,2); +void Con_DWarning (const char *fmt, ...) FUNC_PRINTF(1,2); //ericw +void Con_Warning (const char *fmt, ...) FUNC_PRINTF(1,2); //johnfitz +void Con_DPrintf (const char *fmt, ...) FUNC_PRINTF(1,2); +void Con_DPrintf2 (const char *fmt, ...) FUNC_PRINTF(1,2); //johnfitz +void Con_SafePrintf (const char *fmt, ...) FUNC_PRINTF(1,2); void Con_DrawNotify (void); void Con_ClearNotify (void); void Con_ToggleConsole_f (void); -void Con_NotifyBox (char *text); // during startup for sound / cd warnings +void Con_NotifyBox (const char *text); // during startup for sound / cd warnings + +void Con_Show (void); +void Con_Hide (void); + +const char *Con_Quakebar (int len); +void Con_TabComplete (void); +void Con_LogCenterPrint (const char *str); + +// +// debuglog +// +void LOG_Init (quakeparms_t *parms); +void LOG_Close (void); +void Con_DebugLog (const char *msg); + +#endif /* __CONSOLE_H */ diff --git a/engine/code/crc.c b/engine/Quake/crc.c similarity index 90% rename from engine/code/crc.c rename to engine/Quake/crc.c index ed4880c..37696d5 100644 --- a/engine/code/crc.c +++ b/engine/Quake/crc.c @@ -1,5 +1,6 @@ /* -Copyright (C) 1996-1997 Id Software, Inc. +Copyright (C) 1996-2001 Id Software, Inc. +Copyright (C) 2002-2009 John Fitzgibbons and others This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -8,7 +9,7 @@ of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. @@ -78,4 +79,16 @@ void CRC_ProcessByte(unsigned short *crcvalue, byte data) unsigned short CRC_Value(unsigned short crcvalue) { return crcvalue ^ CRC_XOR_VALUE; -} \ No newline at end of file +} + +//johnfitz -- texture crc +unsigned short CRC_Block (const byte *start, int count) +{ + unsigned short crc; + + CRC_Init (&crc); + while (count--) + crc = (crc << 8) ^ crctable[(crc >> 8) ^ *start++]; + + return crc; +} diff --git a/engine/code/crc.h b/engine/Quake/crc.h similarity index 72% rename from engine/code/crc.h rename to engine/Quake/crc.h index cad9772..421f522 100644 --- a/engine/code/crc.h +++ b/engine/Quake/crc.h @@ -1,5 +1,6 @@ /* -Copyright (C) 1996-1997 Id Software, Inc. +Copyright (C) 1996-2001 Id Software, Inc. +Copyright (C) 2002-2009 John Fitzgibbons and others This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -8,7 +9,7 @@ of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. @@ -17,8 +18,16 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +#ifndef _QUAKE_CRC_H +#define _QUAKE_CRC_H + /* crc.h */ void CRC_Init(unsigned short *crcvalue); void CRC_ProcessByte(unsigned short *crcvalue, byte data); unsigned short CRC_Value(unsigned short crcvalue); +unsigned short CRC_Block (const byte *start, int count); //johnfitz -- texture crc + +#endif /* _QUAKE_CRC_H */ + diff --git a/engine/Quake/cvar.c b/engine/Quake/cvar.c new file mode 100644 index 0000000..aaa8089 --- /dev/null +++ b/engine/Quake/cvar.c @@ -0,0 +1,652 @@ +/* +Copyright (C) 1996-2001 Id Software, Inc. +Copyright (C) 2002-2009 John Fitzgibbons and others +Copyright (C) 2010-2014 QuakeSpasm developers + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ +// cvar.c -- dynamic variable tracking + +#include "quakedef.h" + +static cvar_t *cvar_vars; +static char cvar_null_string[] = ""; + +//============================================================================== +// +// USER COMMANDS +// +//============================================================================== + +void Cvar_Reset (const char *name); //johnfitz + +/* +============ +Cvar_List_f -- johnfitz +============ +*/ +void Cvar_List_f (void) +{ + cvar_t *cvar; + const char *partial; + int len, count; + + if (Cmd_Argc() > 1) + { + partial = Cmd_Argv (1); + len = Q_strlen(partial); + } + else + { + partial = NULL; + len = 0; + } + + count = 0; + for (cvar = cvar_vars ; cvar ; cvar = cvar->next) + { + if (partial && Q_strncmp(partial, cvar->name, len)) + { + continue; + } + Con_SafePrintf ("%s%s %s \"%s\"\n", + (cvar->flags & CVAR_ARCHIVE) ? "*" : " ", + (cvar->flags & CVAR_NOTIFY) ? "s" : " ", + cvar->name, + cvar->string); + count++; + } + + Con_SafePrintf ("%i cvars", count); + if (partial) + { + Con_SafePrintf (" beginning with \"%s\"", partial); + } + Con_SafePrintf ("\n"); +} + +/* +============ +Cvar_Inc_f -- johnfitz +============ +*/ +void Cvar_Inc_f (void) +{ + switch (Cmd_Argc()) + { + default: + case 1: + Con_Printf("inc [amount] : increment cvar\n"); + break; + case 2: + Cvar_SetValue (Cmd_Argv(1), Cvar_VariableValue(Cmd_Argv(1)) + 1); + break; + case 3: + Cvar_SetValue (Cmd_Argv(1), Cvar_VariableValue(Cmd_Argv(1)) + Q_atof(Cmd_Argv(2))); + break; + } +} + +/* +============ +Cvar_Toggle_f -- johnfitz +============ +*/ +void Cvar_Toggle_f (void) +{ + switch (Cmd_Argc()) + { + default: + case 1: + Con_Printf("toggle : toggle cvar\n"); + break; + case 2: + if (Cvar_VariableValue(Cmd_Argv(1))) + Cvar_Set (Cmd_Argv(1), "0"); + else + Cvar_Set (Cmd_Argv(1), "1"); + break; + } +} + +/* +============ +Cvar_Cycle_f -- johnfitz +============ +*/ +void Cvar_Cycle_f (void) +{ + int i; + + if (Cmd_Argc() < 3) + { + Con_Printf("cycle : cycle cvar through a list of values\n"); + return; + } + + //loop through the args until you find one that matches the current cvar value. + //yes, this will get stuck on a list that contains the same value twice. + //it's not worth dealing with, and i'm not even sure it can be dealt with. + for (i = 2; i < Cmd_Argc(); i++) + { + //zero is assumed to be a string, even though it could actually be zero. The worst case + //is that the first time you call this command, it won't match on zero when it should, but after that, + //it will be comparing strings that all had the same source (the user) so it will work. + if (Q_atof(Cmd_Argv(i)) == 0) + { + if (!strcmp(Cmd_Argv(i), Cvar_VariableString(Cmd_Argv(1)))) + break; + } + else + { + if (Q_atof(Cmd_Argv(i)) == Cvar_VariableValue(Cmd_Argv(1))) + break; + } + } + + if (i == Cmd_Argc()) + Cvar_Set (Cmd_Argv(1), Cmd_Argv(2)); // no match + else if (i + 1 == Cmd_Argc()) + Cvar_Set (Cmd_Argv(1), Cmd_Argv(2)); // matched last value in list + else + Cvar_Set (Cmd_Argv(1), Cmd_Argv(i+1)); // matched earlier in list +} + +/* +============ +Cvar_Reset_f -- johnfitz +============ +*/ +void Cvar_Reset_f (void) +{ + switch (Cmd_Argc()) + { + default: + case 1: + Con_Printf ("reset : reset cvar to default\n"); + break; + case 2: + Cvar_Reset (Cmd_Argv(1)); + break; + } +} + +/* +============ +Cvar_ResetAll_f -- johnfitz +============ +*/ +void Cvar_ResetAll_f (void) +{ + cvar_t *var; + + for (var = cvar_vars ; var ; var = var->next) + Cvar_Reset (var->name); +} + +/* +============ +Cvar_ResetCfg_f -- QuakeSpasm +============ +*/ +void Cvar_ResetCfg_f (void) +{ + cvar_t *var; + + for (var = cvar_vars ; var ; var = var->next) + if (var->flags & CVAR_ARCHIVE) Cvar_Reset (var->name); +} + +//============================================================================== +// +// INIT +// +//============================================================================== + +/* +============ +Cvar_Init -- johnfitz +============ +*/ + +void Cvar_Init (void) +{ + Cmd_AddCommand ("cvarlist", Cvar_List_f); + Cmd_AddCommand ("toggle", Cvar_Toggle_f); + Cmd_AddCommand ("cycle", Cvar_Cycle_f); + Cmd_AddCommand ("inc", Cvar_Inc_f); + Cmd_AddCommand ("reset", Cvar_Reset_f); + Cmd_AddCommand ("resetall", Cvar_ResetAll_f); + Cmd_AddCommand ("resetcfg", Cvar_ResetCfg_f); +} + +//============================================================================== +// +// CVAR FUNCTIONS +// +//============================================================================== + +/* +============ +Cvar_FindVar +============ +*/ +cvar_t *Cvar_FindVar (const char *var_name) +{ + cvar_t *var; + + for (var = cvar_vars ; var ; var = var->next) + { + if (!Q_strcmp(var_name, var->name)) + return var; + } + + return NULL; +} + +cvar_t *Cvar_FindVarAfter (const char *prev_name, unsigned int with_flags) +{ + cvar_t *var; + + if (*prev_name) + { + var = Cvar_FindVar (prev_name); + if (!var) + return NULL; + var = var->next; + } + else + var = cvar_vars; + + // search for the next cvar matching the needed flags + while (var) + { + if ((var->flags & with_flags) || !with_flags) + break; + var = var->next; + } + return var; +} + +/* +============ +Cvar_LockVar +============ +*/ +void Cvar_LockVar (const char *var_name) +{ + cvar_t *var = Cvar_FindVar (var_name); + if (var) + var->flags |= CVAR_LOCKED; +} + +void Cvar_UnlockVar (const char *var_name) +{ + cvar_t *var = Cvar_FindVar (var_name); + if (var) + var->flags &= ~CVAR_LOCKED; +} + +void Cvar_UnlockAll (void) +{ + cvar_t *var; + + for (var = cvar_vars ; var ; var = var->next) + { + var->flags &= ~CVAR_LOCKED; + } +} + +/* +============ +Cvar_VariableValue +============ +*/ +float Cvar_VariableValue (const char *var_name) +{ + cvar_t *var; + + var = Cvar_FindVar (var_name); + if (!var) + return 0; + return Q_atof (var->string); +} + + +/* +============ +Cvar_VariableString +============ +*/ +const char *Cvar_VariableString (const char *var_name) +{ + cvar_t *var; + + var = Cvar_FindVar (var_name); + if (!var) + return cvar_null_string; + return var->string; +} + + +/* +============ +Cvar_CompleteVariable +============ +*/ +const char *Cvar_CompleteVariable (const char *partial) +{ + cvar_t *cvar; + int len; + + len = Q_strlen(partial); + if (!len) + return NULL; + +// check functions + for (cvar = cvar_vars ; cvar ; cvar = cvar->next) + { + if (!Q_strncmp(partial, cvar->name, len)) + return cvar->name; + } + + return NULL; +} + +/* +============ +Cvar_Reset -- johnfitz +============ +*/ +void Cvar_Reset (const char *name) +{ + cvar_t *var; + + var = Cvar_FindVar (name); + if (!var) + Con_Printf ("variable \"%s\" not found\n", name); + else + Cvar_SetQuick (var, var->default_string); +} + +void Cvar_SetQuick (cvar_t *var, const char *value) +{ + if (var->flags & (CVAR_ROM|CVAR_LOCKED)) + return; + if (!(var->flags & CVAR_REGISTERED)) + return; + + if (!var->string) + var->string = Z_Strdup (value); + else + { + int len; + + if (!strcmp(var->string, value)) + return; // no change + + var->flags |= CVAR_CHANGED; + len = Q_strlen (value); + if (len != Q_strlen(var->string)) + { + Z_Free ((void *)var->string); + var->string = (char *) Z_Malloc (len + 1); + } + memcpy ((char *)var->string, value, len + 1); + } + + var->value = Q_atof (var->string); + + //johnfitz -- save initial value for "reset" command + if (!var->default_string) + var->default_string = Z_Strdup (var->string); + //johnfitz -- during initialization, update default too + else if (!host_initialized) + { + // Sys_Printf("changing default of %s: %s -> %s\n", + // var->name, var->default_string, var->string); + Z_Free ((void *)var->default_string); + var->default_string = Z_Strdup (var->string); + } + //johnfitz + + if (var->callback) + var->callback (var); +} + +void Cvar_SetValueQuick (cvar_t *var, const float value) +{ + char val[32], *ptr = val; + + if (value == (float)((int)value)) + q_snprintf (val, sizeof(val), "%i", (int)value); + else + { + q_snprintf (val, sizeof(val), "%f", value); + // kill trailing zeroes + while (*ptr) + ptr++; + while (--ptr > val && *ptr == '0' && ptr[-1] != '.') + *ptr = '\0'; + } + + Cvar_SetQuick (var, val); +} + +/* +============ +Cvar_Set +============ +*/ +void Cvar_Set (const char *var_name, const char *value) +{ + cvar_t *var; + + var = Cvar_FindVar (var_name); + if (!var) + { // there is an error in C code if this happens + Con_Printf ("Cvar_Set: variable %s not found\n", var_name); + return; + } + + Cvar_SetQuick (var, value); +} + +/* +============ +Cvar_SetValue +============ +*/ +void Cvar_SetValue (const char *var_name, const float value) +{ + char val[32], *ptr = val; + + if (value == (float)((int)value)) + q_snprintf (val, sizeof(val), "%i", (int)value); + else + { + q_snprintf (val, sizeof(val), "%f", value); + // kill trailing zeroes + while (*ptr) + ptr++; + while (--ptr > val && *ptr == '0' && ptr[-1] != '.') + *ptr = '\0'; + } + + Cvar_Set (var_name, val); +} + +/* +============ +Cvar_SetROM +============ +*/ +void Cvar_SetROM (const char *var_name, const char *value) +{ + cvar_t *var = Cvar_FindVar (var_name); + if (var) + { + var->flags &= ~CVAR_ROM; + Cvar_SetQuick (var, value); + var->flags |= CVAR_ROM; + } +} + +/* +============ +Cvar_SetValueROM +============ +*/ +void Cvar_SetValueROM (const char *var_name, const float value) +{ + cvar_t *var = Cvar_FindVar (var_name); + if (var) + { + var->flags &= ~CVAR_ROM; + Cvar_SetValueQuick (var, value); + var->flags |= CVAR_ROM; + } +} + +/* +============ +Cvar_RegisterVariable + +Adds a freestanding variable to the variable list. +============ +*/ +void Cvar_RegisterVariable (cvar_t *variable) +{ + char value[512]; + qboolean set_rom; + cvar_t *cursor,*prev; //johnfitz -- sorted list insert + +// first check to see if it has already been defined + if (Cvar_FindVar (variable->name)) + { + Con_Printf ("Can't register variable %s, already defined\n", variable->name); + return; + } + +// check for overlap with a command + if (Cmd_Exists (variable->name)) + { + Con_Printf ("Cvar_RegisterVariable: %s is a command\n", variable->name); + return; + } + +// link the variable in + //johnfitz -- insert each entry in alphabetical order + if (cvar_vars == NULL || + strcmp(variable->name, cvar_vars->name) < 0) // insert at front + { + variable->next = cvar_vars; + cvar_vars = variable; + } + else //insert later + { + prev = cvar_vars; + cursor = cvar_vars->next; + while (cursor && (strcmp(variable->name, cursor->name) > 0)) + { + prev = cursor; + cursor = cursor->next; + } + variable->next = prev->next; + prev->next = variable; + } + //johnfitz + variable->flags |= CVAR_REGISTERED; + +// copy the value off, because future sets will Z_Free it + q_strlcpy (value, variable->string, sizeof(value)); + variable->string = NULL; + variable->default_string = NULL; + + if (!(variable->flags & CVAR_CALLBACK)) + variable->callback = NULL; + +// set it through the function to be consistent + set_rom = (variable->flags & CVAR_ROM); + variable->flags &= ~CVAR_ROM; + Cvar_SetQuick (variable, value); + if (set_rom) + variable->flags |= CVAR_ROM; +} + +/* +============ +Cvar_SetCallback + +Set a callback function to the var +============ +*/ +void Cvar_SetCallback (cvar_t *var, cvarcallback_t func) +{ + var->callback = func; + if (func) + var->flags |= CVAR_CALLBACK; + else var->flags &= ~CVAR_CALLBACK; +} + +/* +============ +Cvar_Command + +Handles variable inspection and changing from the console +============ +*/ +qboolean Cvar_Command (void) +{ + cvar_t *v; + +// check variables + v = Cvar_FindVar (Cmd_Argv(0)); + if (!v) + return false; + +// perform a variable print or set + if (Cmd_Argc() == 1) + { + Con_Printf ("\"%s\" is \"%s\"\n", v->name, v->string); + return true; + } + + Cvar_Set (v->name, Cmd_Argv(1)); + return true; +} + + +/* +============ +Cvar_WriteVariables + +Writes lines containing "set variable value" for all variables +with the archive flag set to true. +============ +*/ +void Cvar_WriteVariables (FILE *f) +{ + cvar_t *var; + + for (var = cvar_vars ; var ; var = var->next) + { + if (var->flags & CVAR_ARCHIVE) + fprintf (f, "%s \"%s\"\n", var->name, var->string); + } +} + diff --git a/engine/Quake/cvar.h b/engine/Quake/cvar.h new file mode 100644 index 0000000..495be2e --- /dev/null +++ b/engine/Quake/cvar.h @@ -0,0 +1,143 @@ +/* +Copyright (C) 1996-2001 Id Software, Inc. +Copyright (C) 2002-2009 John Fitzgibbons and others +Copyright (C) 2010-2014 QuakeSpasm developers + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#ifndef __CVAR_H__ +#define __CVAR_H__ + +/* +cvar_t variables are used to hold scalar or string variables that can +be changed or displayed at the console or prog code as well as accessed +directly in C code. + +it is sufficient to initialize a cvar_t with just the first two fields, +or you can add a ,true flag for variables that you want saved to the +configuration file when the game is quit: + +cvar_t r_draworder = {"r_draworder","1"}; +cvar_t scr_screensize = {"screensize","1",true}; + +Cvars must be registered before use, or they will have a 0 value instead +of the float interpretation of the string. +Generally, all cvar_t declarations should be registered in the apropriate +init function before any console commands are executed: + +Cvar_RegisterVariable (&host_framerate); + + +C code usually just references a cvar in place: +if ( r_draworder.value ) + +It could optionally ask for the value to be looked up for a string name: +if (Cvar_VariableValue ("r_draworder")) + +Interpreted prog code can access cvars with the cvar(name) or +cvar_set (name, value) internal functions: +teamplay = cvar("teamplay"); +cvar_set ("registered", "1"); + +The user can access cvars from the console in two ways: +r_draworder prints the current value +r_draworder 0 sets the current value to 0 + +Cvars are restricted from having the same names as commands to keep this +interface from being ambiguous. + +*/ + +#define CVAR_NONE 0 +#define CVAR_ARCHIVE (1U << 0) // if set, causes it to be saved to config +#define CVAR_NOTIFY (1U << 1) // changes will be broadcasted to all players (q1) +#define CVAR_SERVERINFO (1U << 2) // added to serverinfo will be sent to clients (q1/net_dgrm.c and qwsv) +#define CVAR_USERINFO (1U << 3) // added to userinfo, will be sent to server (qwcl) +#define CVAR_CHANGED (1U << 4) +#define CVAR_ROM (1U << 6) +#define CVAR_LOCKED (1U << 8) // locked temporarily +#define CVAR_REGISTERED (1U << 10) // the var is added to the list of variables +#define CVAR_CALLBACK (1U << 16) // var has a callback + + +typedef void (*cvarcallback_t) (struct cvar_s *); + +typedef struct cvar_s +{ + const char *name; + const char *string; + unsigned int flags; + float value; + const char *default_string; //johnfitz -- remember defaults for reset function + cvarcallback_t callback; + struct cvar_s *next; +} cvar_t; + +void Cvar_RegisterVariable (cvar_t *variable); +// registers a cvar that already has the name, string, and optionally +// the archive elements set. + +void Cvar_SetCallback (cvar_t *var, cvarcallback_t func); +// set a callback function to the var + +void Cvar_Set (const char *var_name, const char *value); +// equivelant to " " typed at the console + +void Cvar_SetValue (const char *var_name, const float value); +// expands value to a string and calls Cvar_Set + +void Cvar_SetROM (const char *var_name, const char *value); +void Cvar_SetValueROM (const char *var_name, const float value); +// sets a CVAR_ROM variable from within the engine + +void Cvar_SetQuick (cvar_t *var, const char *value); +void Cvar_SetValueQuick (cvar_t *var, const float value); +// these two accept a cvar pointer instead of a var name, +// but are otherwise identical to the "non-Quick" versions. +// the cvar MUST be registered. + +float Cvar_VariableValue (const char *var_name); +// returns 0 if not defined or non numeric + +const char *Cvar_VariableString (const char *var_name); +// returns an empty string if not defined + +qboolean Cvar_Command (void); +// called by Cmd_ExecuteString when Cmd_Argv(0) doesn't match a known +// command. Returns true if the command was a variable reference that +// was handled. (print or change) + +void Cvar_WriteVariables (FILE *f); +// Writes lines containing "set variable value" for all variables +// with the CVAR_ARCHIVE flag set + +cvar_t *Cvar_FindVar (const char *var_name); +cvar_t *Cvar_FindVarAfter (const char *prev_name, unsigned int with_flags); + +void Cvar_LockVar (const char *var_name); +void Cvar_UnlockVar (const char *var_name); +void Cvar_UnlockAll (void); + +void Cvar_Init (void); + +const char *Cvar_CompleteVariable (const char *partial); +// attempts to match a partial variable name for command line completion +// returns NULL if nothing fits + +#endif /* __CVAR_H__ */ + diff --git a/engine/code/draw.h b/engine/Quake/draw.h similarity index 52% rename from engine/code/draw.h rename to engine/Quake/draw.h index 41454ff..396f57e 100644 --- a/engine/code/draw.h +++ b/engine/Quake/draw.h @@ -1,5 +1,7 @@ /* -Copyright (C) 1996-1997 Id Software, Inc. +Copyright (C) 1996-2001 Id Software, Inc. +Copyright (C) 2002-2009 John Fitzgibbons and others +Copyright (C) 2010-2014 QuakeSpasm developers This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -8,7 +10,7 @@ of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. @@ -18,38 +20,29 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#ifndef _QUAKE_DRAW_H +#define _QUAKE_DRAW_H + // draw.h -- these are the only functions outside the refresh allowed // to touch the vid buffer extern qpic_t *draw_disc; // also used on sbar -// jkrige - external texture loading -extern int image_width; -extern int image_height; -extern int image_bits; -extern int image_alpha; -// jkrige - external texture loading - -// jkrige - .lit colored lights -extern vec3_t lightcolor; // jkrige - used by model rendering -// jkrige - .lit colored lights - void Draw_Init (void); void Draw_Character (int x, int y, int num); void Draw_DebugChar (char num); void Draw_Pic (int x, int y, qpic_t *pic); -void Draw_TransPic (int x, int y, qpic_t *pic); -void Draw_TransPicTranslate (int x, int y, qpic_t *pic, byte *translation); -void Draw_ConsoleBackground (int lines); -void Draw_BeginDisc (void); -void Draw_EndDisc (void); +void Draw_TransPicTranslate (int x, int y, qpic_t *pic, int top, int bottom); //johnfitz -- more parameters +void Draw_ConsoleBackground (void); //johnfitz -- removed parameter int lines void Draw_TileClear (int x, int y, int w, int h); -void Draw_Fill (int x, int y, int w, int h, int c); +void Draw_Fill (int x, int y, int w, int h, int c, float alpha); //johnfitz -- added alpha void Draw_FadeScreen (void); -void Draw_String (int x, int y, char *str); -qpic_t *Draw_PicFromWad (char *name); -qpic_t *Draw_CachePic (char *path); +void Draw_String (int x, int y, const char *str); +qpic_t *Draw_PicFromWad (const char *name); +qpic_t *Draw_CachePic (const char *path); +void Draw_NewGame (void); + +void GL_SetCanvas (canvastype newcanvas); //johnfitz + +#endif /* _QUAKE_DRAW_H */ -// jkrige - external texture loading -byte* LoadImagePixels (char* filename, qboolean complain); -// jkrige - external texture loading \ No newline at end of file diff --git a/engine/Quake/filenames.h b/engine/Quake/filenames.h new file mode 100644 index 0000000..9e4c78f --- /dev/null +++ b/engine/Quake/filenames.h @@ -0,0 +1,193 @@ +/* Macros for taking apart, interpreting and processing file names. + * + * These are here because some non-Posix (a.k.a. DOSish) systems have + * drive letter brain-damage at the beginning of an absolute file name, + * use forward- and back-slash in path names interchangeably, and + * some of them have case-insensitive file names. + * + * This was based on filenames.h from BFD, the Binary File Descriptor + * library, Copyright (C) 2000-2016 Free Software Foundation, Inc., + * and changed by O. Sezer for our needs. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef FILENAMES_H +#define FILENAMES_H + +#include + +/* ---------------------- Windows, DOS, OS2: ---------------------- */ +#if defined(__MSDOS__) || defined(__DOS__) || defined(__DJGPP__) || \ + defined(_MSDOS) || defined(__OS2__) || defined(__EMX__) || \ + defined(_WIN32) || defined(_Windows) || defined(__WINDOWS__) || \ + defined(__NT__) || defined(__CYGWIN__) + +#define HAVE_DOS_BASED_FILE_SYSTEM 1 +#define HAVE_CASE_INSENSITIVE_FILE_SYSTEM 1 + +#define HAS_DRIVE_SPEC(f) ((f)[0] && ((f)[1] == ':')) +#define STRIP_DRIVE_SPEC(f) ((f) + 2) +#define IS_DIR_SEPARATOR(c) ((c) == '/' || (c) == '\\') +/* both '/' and '\\' work as dir separator. djgpp likes changing + * '\\' into '/', so I define DIR_SEPARATOR_CHAR as '/' for djgpp, + * '\\' otherwise. */ +#ifdef __DJGPP__ +#define DIR_SEPARATOR_CHAR '/' +#define DIR_SEPARATOR_STR "/" +#else +#define DIR_SEPARATOR_CHAR '\\' +#define DIR_SEPARATOR_STR "\\" +#endif +/* Note that IS_ABSOLUTE_PATH accepts d:foo as well, although it is + only semi-absolute. This is because the users of IS_ABSOLUTE_PATH + want to know whether to prepend the current working directory to + a file name, which should not be done with a name like d:foo. */ +#define IS_ABSOLUTE_PATH(f) (IS_DIR_SEPARATOR((f)[0]) || HAS_DRIVE_SPEC((f))) + +#ifdef __cplusplus +static inline char *FIND_FIRST_DIRSEP(char *_the_path) { +/* FIXME: What about C:FOO ? */ + char *p1 = strchr(_the_path, '/'); + char *p2 = strchr(_the_path, '\\'); + if (p1 == NULL) return p2; + if (p2 == NULL) return p1; + return (p1 < p2)? p1 : p2; +} +static inline char *FIND_LAST_DIRSEP (char *_the_path) { +/* FIXME: What about C:FOO ? */ + char *p1 = strrchr(_the_path, '/'); + char *p2 = strrchr(_the_path, '\\'); + if (p1 == NULL) return p2; + if (p2 == NULL) return p1; + return (p1 > p2)? p1 : p2; +} +static inline const char *FIND_FIRST_DIRSEP(const char *_the_path) { +/* FIXME: What about C:FOO ? */ + const char *p1 = strchr(_the_path, '/'); + const char *p2 = strchr(_the_path, '\\'); + if (p1 == NULL) return p2; + if (p2 == NULL) return p1; + return (p1 < p2)? p1 : p2; +} +static inline const char *FIND_LAST_DIRSEP (const char *_the_path) { +/* FIXME: What about C:FOO ? */ + const char *p1 = strrchr(_the_path, '/'); + const char *p2 = strrchr(_the_path, '\\'); + if (p1 == NULL) return p2; + if (p2 == NULL) return p1; + return (p1 > p2)? p1 : p2; +} +#else +static inline char *FIND_FIRST_DIRSEP(const char *_the_path) { +/* FIXME: What about C:FOO ? */ + char *p1 = strchr(_the_path, '/'); + char *p2 = strchr(_the_path, '\\'); + if (p1 == NULL) return p2; + if (p2 == NULL) return p1; + return (p1 < p2)? p1 : p2; +} +static inline char *FIND_LAST_DIRSEP (const char *_the_path) { +/* FIXME: What about C:FOO ? */ + char *p1 = strrchr(_the_path, '/'); + char *p2 = strrchr(_the_path, '\\'); + if (p1 == NULL) return p2; + if (p2 == NULL) return p1; + return (p1 > p2)? p1 : p2; +} +#endif /* C++ */ + +/* ----------------- AmigaOS, MorphOS, AROS, etc: ----------------- */ +#elif defined(__MORPHOS__) || defined(__AROS__) || defined(AMIGAOS) || \ + defined(__amigaos__) || defined(__amigaos4__) ||defined(__amigados__) || \ + defined(AMIGA) || defined(_AMIGA) || defined(__AMIGA__) + +#define HAS_DRIVE_SPEC(f) (0) /* */ +#define STRIP_DRIVE_SPEC(f) (f) /* */ +#define IS_DIR_SEPARATOR(c) ((c) == '/' || (c) == ':') +#define DIR_SEPARATOR_CHAR '/' +#define DIR_SEPARATOR_STR "/" +#define IS_ABSOLUTE_PATH(f) (IS_DIR_SEPARATOR((f)[0]) || (strchr((f), ':'))) +#define HAVE_CASE_INSENSITIVE_FILE_SYSTEM 1 + +#ifdef __cplusplus +static inline char *FIND_FIRST_DIRSEP(char *_the_path) { + char *p = strchr(_the_path, ':'); + if (p != NULL) return p; + return strchr(_the_path, '/'); +} +static inline char *FIND_LAST_DIRSEP (char *_the_path) { + char *p = strrchr(_the_path, '/'); + if (p != NULL) return p; + return strchr(_the_path, ':'); +} +static inline const char *FIND_FIRST_DIRSEP(const char *_the_path) { + const char *p = strchr(_the_path, ':'); + if (p != NULL) return p; + return strchr(_the_path, '/'); +} +static inline const char *FIND_LAST_DIRSEP (const char *_the_path) { + const char *p = strrchr(_the_path, '/'); + if (p != NULL) return p; + return strchr(_the_path, ':'); +} +#else +static inline char *FIND_FIRST_DIRSEP(const char *_the_path) { + char *p = strchr(_the_path, ':'); + if (p != NULL) return p; + return strchr(_the_path, '/'); +} +static inline char *FIND_LAST_DIRSEP (const char *_the_path) { + char *p = strrchr(_the_path, '/'); + if (p != NULL) return p; + return strchr(_the_path, ':'); +} +#endif /* C++ */ + +/* ---------------------- assumed UNIX-ish : ---------------------- */ +#else /* */ + +#define IS_DIR_SEPARATOR(c) ((c) == '/') +#define DIR_SEPARATOR_CHAR '/' +#define DIR_SEPARATOR_STR "/" +#define IS_ABSOLUTE_PATH(f) (IS_DIR_SEPARATOR((f)[0])) +#define HAS_DRIVE_SPEC(f) (0) +#define STRIP_DRIVE_SPEC(f) (f) + +#ifdef __cplusplus +static inline char *FIND_FIRST_DIRSEP(char *_the_path) { + return strchr(_the_path, '/'); +} +static inline char *FIND_LAST_DIRSEP (char *_the_path) { + return strrchr(_the_path, '/'); +} +static inline const char *FIND_FIRST_DIRSEP(const char *_the_path) { + return strchr(_the_path, '/'); +} +static inline const char *FIND_LAST_DIRSEP (const char *_the_path) { + return strrchr(_the_path, '/'); +} +#else +static inline char *FIND_FIRST_DIRSEP(const char *_the_path) { + return strchr(_the_path, '/'); +} +static inline char *FIND_LAST_DIRSEP (const char *_the_path) { + return strrchr(_the_path, '/'); +} +#endif /* C++ */ + +#endif + +#endif /* FILENAMES_H */ diff --git a/engine/Quake/gl_draw.c b/engine/Quake/gl_draw.c new file mode 100644 index 0000000..0f67904 --- /dev/null +++ b/engine/Quake/gl_draw.c @@ -0,0 +1,772 @@ +/* +Copyright (C) 1996-2001 Id Software, Inc. +Copyright (C) 2002-2009 John Fitzgibbons and others +Copyright (C) 2007-2008 Kristian Duske +Copyright (C) 2010-2014 QuakeSpasm developers + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +// draw.c -- 2d drawing + +#include "quakedef.h" + +//extern unsigned char d_15to8table[65536]; //johnfitz -- never used + +cvar_t scr_conalpha = {"scr_conalpha", "0.5", CVAR_ARCHIVE}; //johnfitz + +qpic_t *draw_disc; +qpic_t *draw_backtile; + +gltexture_t *char_texture; //johnfitz +qpic_t *pic_ovr, *pic_ins; //johnfitz -- new cursor handling +qpic_t *pic_nul; //johnfitz -- for missing gfx, don't crash + +//johnfitz -- new pics +byte pic_ovr_data[8][8] = +{ + {255,255,255,255,255,255,255,255}, + {255, 15, 15, 15, 15, 15, 15,255}, + {255, 15, 15, 15, 15, 15, 15, 2}, + {255, 15, 15, 15, 15, 15, 15, 2}, + {255, 15, 15, 15, 15, 15, 15, 2}, + {255, 15, 15, 15, 15, 15, 15, 2}, + {255, 15, 15, 15, 15, 15, 15, 2}, + {255,255, 2, 2, 2, 2, 2, 2}, +}; + +byte pic_ins_data[9][8] = +{ + { 15, 15,255,255,255,255,255,255}, + { 15, 15, 2,255,255,255,255,255}, + { 15, 15, 2,255,255,255,255,255}, + { 15, 15, 2,255,255,255,255,255}, + { 15, 15, 2,255,255,255,255,255}, + { 15, 15, 2,255,255,255,255,255}, + { 15, 15, 2,255,255,255,255,255}, + { 15, 15, 2,255,255,255,255,255}, + {255, 2, 2,255,255,255,255,255}, +}; + +byte pic_nul_data[8][8] = +{ + {252,252,252,252, 0, 0, 0, 0}, + {252,252,252,252, 0, 0, 0, 0}, + {252,252,252,252, 0, 0, 0, 0}, + {252,252,252,252, 0, 0, 0, 0}, + { 0, 0, 0, 0,252,252,252,252}, + { 0, 0, 0, 0,252,252,252,252}, + { 0, 0, 0, 0,252,252,252,252}, + { 0, 0, 0, 0,252,252,252,252}, +}; + +byte pic_stipple_data[8][8] = +{ + {255, 0, 0, 0,255, 0, 0, 0}, + { 0, 0,255, 0, 0, 0,255, 0}, + {255, 0, 0, 0,255, 0, 0, 0}, + { 0, 0,255, 0, 0, 0,255, 0}, + {255, 0, 0, 0,255, 0, 0, 0}, + { 0, 0,255, 0, 0, 0,255, 0}, + {255, 0, 0, 0,255, 0, 0, 0}, + { 0, 0,255, 0, 0, 0,255, 0}, +}; + +byte pic_crosshair_data[8][8] = +{ + {255,255,255,255,255,255,255,255}, + {255,255,255, 8, 9,255,255,255}, + {255,255,255, 6, 8, 2,255,255}, + {255, 6, 8, 8, 6, 8, 8,255}, + {255,255, 2, 8, 8, 2, 2, 2}, + {255,255,255, 7, 8, 2,255,255}, + {255,255,255,255, 2, 2,255,255}, + {255,255,255,255,255,255,255,255}, +}; +//johnfitz + +typedef struct +{ + gltexture_t *gltexture; + float sl, tl, sh, th; +} glpic_t; + +canvastype currentcanvas = CANVAS_NONE; //johnfitz -- for GL_SetCanvas + +//============================================================================== +// +// PIC CACHING +// +//============================================================================== + +typedef struct cachepic_s +{ + char name[MAX_QPATH]; + qpic_t pic; + byte padding[32]; // for appended glpic +} cachepic_t; + +#define MAX_CACHED_PICS 128 +cachepic_t menu_cachepics[MAX_CACHED_PICS]; +int menu_numcachepics; + +byte menuplyr_pixels[4096]; + +// scrap allocation +// Allocate all the little status bar obejcts into a single texture +// to crutch up stupid hardware / drivers + +#define MAX_SCRAPS 2 +#define BLOCK_WIDTH 256 +#define BLOCK_HEIGHT 256 + +int scrap_allocated[MAX_SCRAPS][BLOCK_WIDTH]; +byte scrap_texels[MAX_SCRAPS][BLOCK_WIDTH*BLOCK_HEIGHT]; //johnfitz -- removed *4 after BLOCK_HEIGHT +qboolean scrap_dirty; +gltexture_t *scrap_textures[MAX_SCRAPS]; //johnfitz + + +/* +================ +Scrap_AllocBlock + +returns an index into scrap_texnums[] and the position inside it +================ +*/ +int Scrap_AllocBlock (int w, int h, int *x, int *y) +{ + int i, j; + int best, best2; + int texnum; + + for (texnum=0 ; texnum= best) + break; + if (scrap_allocated[texnum][i+j] > best2) + best2 = scrap_allocated[texnum][i+j]; + } + if (j == w) + { // this is a valid spot + *x = i; + *y = best = best2; + } + } + + if (best + h > BLOCK_HEIGHT) + continue; + + for (i=0 ; iwidth < 64 && p->height < 64) + { + int x, y; + int i, j, k; + int texnum; + + texnum = Scrap_AllocBlock (p->width, p->height, &x, &y); + scrap_dirty = true; + k = 0; + for (i=0 ; iheight ; i++) + { + for (j=0 ; jwidth ; j++, k++) + scrap_texels[texnum][(y+i)*BLOCK_WIDTH + x + j] = p->data[k]; + } + gl.gltexture = scrap_textures[texnum]; //johnfitz -- changed to an array + //johnfitz -- no longer go from 0.01 to 0.99 + gl.sl = x/(float)BLOCK_WIDTH; + gl.sh = (x+p->width)/(float)BLOCK_WIDTH; + gl.tl = y/(float)BLOCK_WIDTH; + gl.th = (y+p->height)/(float)BLOCK_WIDTH; + } + else + { + char texturename[64]; //johnfitz + q_snprintf (texturename, sizeof(texturename), "%s:%s", WADFILENAME, name); //johnfitz + + offset = (src_offset_t)p - (src_offset_t)wad_base + sizeof(int)*2; //johnfitz + + gl.gltexture = TexMgr_LoadImage (NULL, texturename, p->width, p->height, SRC_INDEXED, p->data, WADFILENAME, + offset, TEXPREF_ALPHA | TEXPREF_PAD | TEXPREF_NOPICMIP); //johnfitz -- TexMgr + gl.sl = 0; + gl.sh = (float)p->width/(float)TexMgr_PadConditional(p->width); //johnfitz + gl.tl = 0; + gl.th = (float)p->height/(float)TexMgr_PadConditional(p->height); //johnfitz + } + + memcpy (p->data, &gl, sizeof(glpic_t)); + + return p; +} + +/* +================ +Draw_CachePic +================ +*/ +qpic_t *Draw_CachePic (const char *path) +{ + cachepic_t *pic; + int i; + qpic_t *dat; + glpic_t gl; + + for (pic=menu_cachepics, i=0 ; iname)) + return &pic->pic; + } + if (menu_numcachepics == MAX_CACHED_PICS) + Sys_Error ("menu_numcachepics == MAX_CACHED_PICS"); + menu_numcachepics++; + strcpy (pic->name, path); + +// +// load the pic from disk +// + dat = (qpic_t *)COM_LoadTempFile (path, NULL); + if (!dat) + Sys_Error ("Draw_CachePic: failed to load %s", path); + SwapPic (dat); + + // HACK HACK HACK --- we need to keep the bytes for + // the translatable player picture just for the menu + // configuration dialog + if (!strcmp (path, "gfx/menuplyr.lmp")) + memcpy (menuplyr_pixels, dat->data, dat->width*dat->height); + + pic->pic.width = dat->width; + pic->pic.height = dat->height; + + gl.gltexture = TexMgr_LoadImage (NULL, path, dat->width, dat->height, SRC_INDEXED, dat->data, path, + sizeof(int)*2, TEXPREF_ALPHA | TEXPREF_PAD | TEXPREF_NOPICMIP); //johnfitz -- TexMgr + gl.sl = 0; + gl.sh = (float)dat->width/(float)TexMgr_PadConditional(dat->width); //johnfitz + gl.tl = 0; + gl.th = (float)dat->height/(float)TexMgr_PadConditional(dat->height); //johnfitz + memcpy (pic->pic.data, &gl, sizeof(glpic_t)); + + return &pic->pic; +} + +/* +================ +Draw_MakePic -- johnfitz -- generate pics from internal data +================ +*/ +qpic_t *Draw_MakePic (const char *name, int width, int height, byte *data) +{ + int flags = TEXPREF_NEAREST | TEXPREF_ALPHA | TEXPREF_PERSIST | TEXPREF_NOPICMIP | TEXPREF_PAD; + qpic_t *pic; + glpic_t gl; + + pic = (qpic_t *) Hunk_Alloc (sizeof(qpic_t) - 4 + sizeof (glpic_t)); + pic->width = width; + pic->height = height; + + gl.gltexture = TexMgr_LoadImage (NULL, name, width, height, SRC_INDEXED, data, "", (src_offset_t)data, flags); + gl.sl = 0; + gl.sh = (float)width/(float)TexMgr_PadConditional(width); + gl.tl = 0; + gl.th = (float)height/(float)TexMgr_PadConditional(height); + memcpy (pic->data, &gl, sizeof(glpic_t)); + + return pic; +} + +//============================================================================== +// +// INIT +// +//============================================================================== + +/* +=============== +Draw_LoadPics -- johnfitz +=============== +*/ +void Draw_LoadPics (void) +{ + byte *data; + src_offset_t offset; + + data = (byte *) W_GetLumpName ("conchars"); + if (!data) Sys_Error ("Draw_LoadPics: couldn't load conchars"); + offset = (src_offset_t)data - (src_offset_t)wad_base; + char_texture = TexMgr_LoadImage (NULL, WADFILENAME":conchars", 128, 128, SRC_INDEXED, data, + WADFILENAME, offset, TEXPREF_ALPHA | TEXPREF_NEAREST | TEXPREF_NOPICMIP | TEXPREF_CONCHARS); + + draw_disc = Draw_PicFromWad ("disc"); + draw_backtile = Draw_PicFromWad ("backtile"); +} + +/* +=============== +Draw_NewGame -- johnfitz +=============== +*/ +void Draw_NewGame (void) +{ + cachepic_t *pic; + int i; + + // empty scrap and reallocate gltextures + memset(scrap_allocated, 0, sizeof(scrap_allocated)); + memset(scrap_texels, 255, sizeof(scrap_texels)); + + Scrap_Upload (); //creates 2 empty gltextures + + // reload wad pics + W_LoadWadFile (); //johnfitz -- filename is now hard-coded for honesty + Draw_LoadPics (); + SCR_LoadPics (); + Sbar_LoadPics (); + + // empty lmp cache + for (pic = menu_cachepics, i = 0; i < menu_numcachepics; pic++, i++) + pic->name[0] = 0; + menu_numcachepics = 0; +} + +/* +=============== +Draw_Init -- johnfitz -- rewritten +=============== +*/ +void Draw_Init (void) +{ + Cvar_RegisterVariable (&scr_conalpha); + + // clear scrap and allocate gltextures + memset(scrap_allocated, 0, sizeof(scrap_allocated)); + memset(scrap_texels, 255, sizeof(scrap_texels)); + + Scrap_Upload (); //creates 2 empty textures + + // create internal pics + pic_ins = Draw_MakePic ("ins", 8, 9, &pic_ins_data[0][0]); + pic_ovr = Draw_MakePic ("ovr", 8, 8, &pic_ovr_data[0][0]); + pic_nul = Draw_MakePic ("nul", 8, 8, &pic_nul_data[0][0]); + + // load game pics + Draw_LoadPics (); +} + +//============================================================================== +// +// 2D DRAWING +// +//============================================================================== + +/* +================ +Draw_CharacterQuad -- johnfitz -- seperate function to spit out verts +================ +*/ +void Draw_CharacterQuad (int x, int y, char num) +{ + int row, col; + float frow, fcol, size; + + row = num>>4; + col = num&15; + + frow = row*0.0625; + fcol = col*0.0625; + size = 0.0625; + + glTexCoord2f (fcol, frow); + glVertex2f (x, y); + glTexCoord2f (fcol + size, frow); + glVertex2f (x+8, y); + glTexCoord2f (fcol + size, frow + size); + glVertex2f (x+8, y+8); + glTexCoord2f (fcol, frow + size); + glVertex2f (x, y+8); +} + +/* +================ +Draw_Character -- johnfitz -- modified to call Draw_CharacterQuad +================ +*/ +void Draw_Character (int x, int y, int num) +{ + if (y <= -8) + return; // totally off screen + + num &= 255; + + if (num == 32) + return; //don't waste verts on spaces + + GL_Bind (char_texture); + glBegin (GL_QUADS); + + Draw_CharacterQuad (x, y, (char) num); + + glEnd (); +} + +/* +================ +Draw_String -- johnfitz -- modified to call Draw_CharacterQuad +================ +*/ +void Draw_String (int x, int y, const char *str) +{ + if (y <= -8) + return; // totally off screen + + GL_Bind (char_texture); + glBegin (GL_QUADS); + + while (*str) + { + if (*str != 32) //don't waste verts on spaces + Draw_CharacterQuad (x, y, *str); + str++; + x += 8; + } + + glEnd (); +} + +/* +============= +Draw_Pic -- johnfitz -- modified +============= +*/ +void Draw_Pic (int x, int y, qpic_t *pic) +{ + glpic_t *gl; + + if (scrap_dirty) + Scrap_Upload (); + gl = (glpic_t *)pic->data; + GL_Bind (gl->gltexture); + glBegin (GL_QUADS); + glTexCoord2f (gl->sl, gl->tl); + glVertex2f (x, y); + glTexCoord2f (gl->sh, gl->tl); + glVertex2f (x+pic->width, y); + glTexCoord2f (gl->sh, gl->th); + glVertex2f (x+pic->width, y+pic->height); + glTexCoord2f (gl->sl, gl->th); + glVertex2f (x, y+pic->height); + glEnd (); +} + +/* +============= +Draw_TransPicTranslate -- johnfitz -- rewritten to use texmgr to do translation + +Only used for the player color selection menu +============= +*/ +void Draw_TransPicTranslate (int x, int y, qpic_t *pic, int top, int bottom) +{ + static int oldtop = -2; + static int oldbottom = -2; + + if (top != oldtop || bottom != oldbottom) + { + glpic_t *p = (glpic_t *)pic->data; + gltexture_t *glt = p->gltexture; + oldtop = top; + oldbottom = bottom; + TexMgr_ReloadImage (glt, top, bottom); + } + Draw_Pic (x, y, pic); +} + +/* +================ +Draw_ConsoleBackground -- johnfitz -- rewritten +================ +*/ +void Draw_ConsoleBackground (void) +{ + qpic_t *pic; + float alpha; + + pic = Draw_CachePic ("gfx/conback.lmp"); + pic->width = vid.conwidth; + pic->height = vid.conheight; + + alpha = (con_forcedup) ? 1.0 : scr_conalpha.value; + + GL_SetCanvas (CANVAS_CONSOLE); //in case this is called from weird places + + if (alpha > 0.0) + { + if (alpha < 1.0) + { + glEnable (GL_BLEND); + glColor4f (1,1,1,alpha); + glDisable (GL_ALPHA_TEST); + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + } + + Draw_Pic (0, 0, pic); + + if (alpha < 1.0) + { + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); + glEnable (GL_ALPHA_TEST); + glDisable (GL_BLEND); + glColor4f (1,1,1,1); + } + } +} + + +/* +============= +Draw_TileClear + +This repeats a 64*64 tile graphic to fill the screen around a sized down +refresh window. +============= +*/ +void Draw_TileClear (int x, int y, int w, int h) +{ + glpic_t *gl; + + gl = (glpic_t *)draw_backtile->data; + + glColor3f (1,1,1); + GL_Bind (gl->gltexture); + glBegin (GL_QUADS); + glTexCoord2f (x/64.0, y/64.0); + glVertex2f (x, y); + glTexCoord2f ( (x+w)/64.0, y/64.0); + glVertex2f (x+w, y); + glTexCoord2f ( (x+w)/64.0, (y+h)/64.0); + glVertex2f (x+w, y+h); + glTexCoord2f ( x/64.0, (y+h)/64.0 ); + glVertex2f (x, y+h); + glEnd (); +} + +/* +============= +Draw_Fill + +Fills a box of pixels with a single color +============= +*/ +void Draw_Fill (int x, int y, int w, int h, int c, float alpha) //johnfitz -- added alpha +{ + byte *pal = (byte *)d_8to24table; //johnfitz -- use d_8to24table instead of host_basepal + + glDisable (GL_TEXTURE_2D); + glEnable (GL_BLEND); //johnfitz -- for alpha + glDisable (GL_ALPHA_TEST); //johnfitz -- for alpha + glColor4f (pal[c*4]/255.0, pal[c*4+1]/255.0, pal[c*4+2]/255.0, alpha); //johnfitz -- added alpha + + glBegin (GL_QUADS); + glVertex2f (x,y); + glVertex2f (x+w, y); + glVertex2f (x+w, y+h); + glVertex2f (x, y+h); + glEnd (); + + glColor3f (1,1,1); + glDisable (GL_BLEND); //johnfitz -- for alpha + glEnable (GL_ALPHA_TEST); //johnfitz -- for alpha + glEnable (GL_TEXTURE_2D); +} + +/* +================ +Draw_FadeScreen -- johnfitz -- revised +================ +*/ +void Draw_FadeScreen (void) +{ + GL_SetCanvas (CANVAS_DEFAULT); + + glEnable (GL_BLEND); + glDisable (GL_ALPHA_TEST); + glDisable (GL_TEXTURE_2D); + glColor4f (0, 0, 0, 0.5); + glBegin (GL_QUADS); + + glVertex2f (0,0); + glVertex2f (glwidth, 0); + glVertex2f (glwidth, glheight); + glVertex2f (0, glheight); + + glEnd (); + glColor4f (1,1,1,1); + glEnable (GL_TEXTURE_2D); + glEnable (GL_ALPHA_TEST); + glDisable (GL_BLEND); + + Sbar_Changed(); +} + +/* +================ +GL_SetCanvas -- johnfitz -- support various canvas types +================ +*/ +void GL_SetCanvas (canvastype newcanvas) +{ + extern vrect_t scr_vrect; + float s; + int lines; + + if (newcanvas == currentcanvas) + return; + + currentcanvas = newcanvas; + + glMatrixMode(GL_PROJECTION); + glLoadIdentity (); + + switch(newcanvas) + { + case CANVAS_DEFAULT: + glOrtho (0, glwidth, glheight, 0, -99999, 99999); + glViewport (glx, gly, glwidth, glheight); + break; + case CANVAS_CONSOLE: + lines = vid.conheight - (scr_con_current * vid.conheight / glheight); + glOrtho (0, vid.conwidth, vid.conheight + lines, lines, -99999, 99999); + glViewport (glx, gly, glwidth, glheight); + break; + case CANVAS_MENU: + s = q_min((float)glwidth / 320.0, (float)glheight / 200.0); + s = CLAMP (1.0, scr_menuscale.value, s); + // ericw -- doubled width to 640 to accommodate long keybindings + glOrtho (0, 640, 200, 0, -99999, 99999); + glViewport (glx + (glwidth - 320*s) / 2, gly + (glheight - 200*s) / 2, 640*s, 200*s); + break; + case CANVAS_SBAR: + s = CLAMP (1.0, scr_sbarscale.value, (float)glwidth / 320.0); + if (cl.gametype == GAME_DEATHMATCH) + { + glOrtho (0, glwidth / s, 48, 0, -99999, 99999); + glViewport (glx, gly, glwidth, 48*s); + } + else + { + glOrtho (0, 320, 48, 0, -99999, 99999); + glViewport (glx + (glwidth - 320*s) / 2, gly, 320*s, 48*s); + } + break; + case CANVAS_WARPIMAGE: + glOrtho (0, 128, 0, 128, -99999, 99999); + glViewport (glx, gly+glheight-gl_warpimagesize, gl_warpimagesize, gl_warpimagesize); + break; + case CANVAS_CROSSHAIR: //0,0 is center of viewport + s = CLAMP (1.0, scr_crosshairscale.value, 10.0); + glOrtho (scr_vrect.width/-2/s, scr_vrect.width/2/s, scr_vrect.height/2/s, scr_vrect.height/-2/s, -99999, 99999); + glViewport (scr_vrect.x, glheight - scr_vrect.y - scr_vrect.height, scr_vrect.width & ~1, scr_vrect.height & ~1); + break; + case CANVAS_BOTTOMLEFT: //used by devstats + s = (float)glwidth/vid.conwidth; //use console scale + glOrtho (0, 320, 200, 0, -99999, 99999); + glViewport (glx, gly, 320*s, 200*s); + break; + case CANVAS_BOTTOMRIGHT: //used by fps/clock + s = (float)glwidth/vid.conwidth; //use console scale + glOrtho (0, 320, 200, 0, -99999, 99999); + glViewport (glx+glwidth-320*s, gly, 320*s, 200*s); + break; + case CANVAS_TOPRIGHT: //used by disc + s = 1; + glOrtho (0, 320, 200, 0, -99999, 99999); + glViewport (glx+glwidth-320*s, gly+glheight-200*s, 320*s, 200*s); + break; + default: + Sys_Error ("GL_SetCanvas: bad canvas type"); + } + + glMatrixMode(GL_MODELVIEW); + glLoadIdentity (); +} + +/* +================ +GL_Set2D -- johnfitz -- rewritten +================ +*/ +void GL_Set2D (void) +{ + currentcanvas = CANVAS_INVALID; + GL_SetCanvas (CANVAS_DEFAULT); + + glDisable (GL_DEPTH_TEST); + glDisable (GL_CULL_FACE); + glDisable (GL_BLEND); + glEnable (GL_ALPHA_TEST); + glColor4f (1,1,1,1); +} diff --git a/engine/Quake/gl_fog.c b/engine/Quake/gl_fog.c new file mode 100644 index 0000000..8629a22 --- /dev/null +++ b/engine/Quake/gl_fog.c @@ -0,0 +1,410 @@ +/* +Copyright (C) 1996-2001 Id Software, Inc. +Copyright (C) 2002-2009 John Fitzgibbons and others +Copyright (C) 2007-2008 Kristian Duske +Copyright (C) 2010-2014 QuakeSpasm developers + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +//gl_fog.c -- global and volumetric fog + +#include "quakedef.h" + +//============================================================================== +// +// GLOBAL FOG +// +//============================================================================== + +#define DEFAULT_DENSITY 0.0 +#define DEFAULT_GRAY 0.3 + +float fog_density; +float fog_red; +float fog_green; +float fog_blue; + +float old_density; +float old_red; +float old_green; +float old_blue; + +float fade_time; //duration of fade +float fade_done; //time when fade will be done + +/* +============= +Fog_Update + +update internal variables +============= +*/ +void Fog_Update (float density, float red, float green, float blue, float time) +{ + //save previous settings for fade + if (time > 0) + { + //check for a fade in progress + if (fade_done > cl.time) + { + float f; + + f = (fade_done - cl.time) / fade_time; + old_density = f * old_density + (1.0 - f) * fog_density; + old_red = f * old_red + (1.0 - f) * fog_red; + old_green = f * old_green + (1.0 - f) * fog_green; + old_blue = f * old_blue + (1.0 - f) * fog_blue; + } + else + { + old_density = fog_density; + old_red = fog_red; + old_green = fog_green; + old_blue = fog_blue; + } + } + + fog_density = density; + fog_red = red; + fog_green = green; + fog_blue = blue; + fade_time = time; + fade_done = cl.time + time; +} + +/* +============= +Fog_ParseServerMessage + +handle an SVC_FOG message from server +============= +*/ +void Fog_ParseServerMessage (void) +{ + float density, red, green, blue, time; + + density = MSG_ReadByte() / 255.0; + red = MSG_ReadByte() / 255.0; + green = MSG_ReadByte() / 255.0; + blue = MSG_ReadByte() / 255.0; + time = q_max(0.0, MSG_ReadShort() / 100.0); + + Fog_Update (density, red, green, blue, time); +} + +/* +============= +Fog_FogCommand_f + +handle the 'fog' console command +============= +*/ +void Fog_FogCommand_f (void) +{ + switch (Cmd_Argc()) + { + default: + case 1: + Con_Printf("usage:\n"); + Con_Printf(" fog \n"); + Con_Printf(" fog \n"); + Con_Printf(" fog \n"); + Con_Printf("current values:\n"); + Con_Printf(" \"density\" is \"%f\"\n", fog_density); + Con_Printf(" \"red\" is \"%f\"\n", fog_red); + Con_Printf(" \"green\" is \"%f\"\n", fog_green); + Con_Printf(" \"blue\" is \"%f\"\n", fog_blue); + break; + case 2: + Fog_Update(q_max(0.0, atof(Cmd_Argv(1))), + fog_red, + fog_green, + fog_blue, + 0.0); + break; + case 3: //TEST + Fog_Update(q_max(0.0, atof(Cmd_Argv(1))), + fog_red, + fog_green, + fog_blue, + atof(Cmd_Argv(2))); + break; + case 4: + Fog_Update(fog_density, + CLAMP(0.0, atof(Cmd_Argv(1)), 1.0), + CLAMP(0.0, atof(Cmd_Argv(2)), 1.0), + CLAMP(0.0, atof(Cmd_Argv(3)), 1.0), + 0.0); + break; + case 5: + Fog_Update(q_max(0.0, atof(Cmd_Argv(1))), + CLAMP(0.0, atof(Cmd_Argv(2)), 1.0), + CLAMP(0.0, atof(Cmd_Argv(3)), 1.0), + CLAMP(0.0, atof(Cmd_Argv(4)), 1.0), + 0.0); + break; + case 6: //TEST + Fog_Update(q_max(0.0, atof(Cmd_Argv(1))), + CLAMP(0.0, atof(Cmd_Argv(2)), 1.0), + CLAMP(0.0, atof(Cmd_Argv(3)), 1.0), + CLAMP(0.0, atof(Cmd_Argv(4)), 1.0), + atof(Cmd_Argv(5))); + break; + } +} + +/* +============= +Fog_ParseWorldspawn + +called at map load +============= +*/ +void Fog_ParseWorldspawn (void) +{ + char key[128], value[4096]; + const char *data; + + //initially no fog + fog_density = DEFAULT_DENSITY; + fog_red = DEFAULT_GRAY; + fog_green = DEFAULT_GRAY; + fog_blue = DEFAULT_GRAY; + + old_density = DEFAULT_DENSITY; + old_red = DEFAULT_GRAY; + old_green = DEFAULT_GRAY; + old_blue = DEFAULT_GRAY; + + fade_time = 0.0; + fade_done = 0.0; + + data = COM_Parse(cl.worldmodel->entities); + if (!data) + return; // error + if (com_token[0] != '{') + return; // error + while (1) + { + data = COM_Parse(data); + if (!data) + return; // error + if (com_token[0] == '}') + break; // end of worldspawn + if (com_token[0] == '_') + q_strlcpy(key, com_token + 1, sizeof(key)); + else + q_strlcpy(key, com_token, sizeof(key)); + while (key[0] && key[strlen(key)-1] == ' ') // remove trailing spaces + key[strlen(key)-1] = 0; + data = COM_Parse(data); + if (!data) + return; // error + q_strlcpy(value, com_token, sizeof(value)); + + if (!strcmp("fog", key)) + { + sscanf(value, "%f %f %f %f", &fog_density, &fog_red, &fog_green, &fog_blue); + } + } +} + +/* +============= +Fog_GetColor + +calculates fog color for this frame, taking into account fade times +============= +*/ +float *Fog_GetColor (void) +{ + static float c[4]; + float f; + int i; + + if (fade_done > cl.time) + { + f = (fade_done - cl.time) / fade_time; + c[0] = f * old_red + (1.0 - f) * fog_red; + c[1] = f * old_green + (1.0 - f) * fog_green; + c[2] = f * old_blue + (1.0 - f) * fog_blue; + c[3] = 1.0; + } + else + { + c[0] = fog_red; + c[1] = fog_green; + c[2] = fog_blue; + c[3] = 1.0; + } + + //find closest 24-bit RGB value, so solid-colored sky can match the fog perfectly + for (i=0;i<3;i++) + c[i] = (float)(Q_rint(c[i] * 255)) / 255.0f; + + return c; +} + +/* +============= +Fog_GetDensity + +returns current density of fog +============= +*/ +float Fog_GetDensity (void) +{ + float f; + + if (fade_done > cl.time) + { + f = (fade_done - cl.time) / fade_time; + return f * old_density + (1.0 - f) * fog_density; + } + else + return fog_density; +} + +/* +============= +Fog_SetupFrame + +called at the beginning of each frame +============= +*/ +void Fog_SetupFrame (void) +{ + glFogfv(GL_FOG_COLOR, Fog_GetColor()); + glFogf(GL_FOG_DENSITY, Fog_GetDensity() / 64.0); +} + +/* +============= +Fog_EnableGFog + +called before drawing stuff that should be fogged +============= +*/ +void Fog_EnableGFog (void) +{ + if (Fog_GetDensity() > 0) + glEnable(GL_FOG); +} + +/* +============= +Fog_DisableGFog + +called after drawing stuff that should be fogged +============= +*/ +void Fog_DisableGFog (void) +{ + if (Fog_GetDensity() > 0) + glDisable(GL_FOG); +} + +/* +============= +Fog_StartAdditive + +called before drawing stuff that is additive blended -- sets fog color to black +============= +*/ +void Fog_StartAdditive (void) +{ + vec3_t color = {0,0,0}; + + if (Fog_GetDensity() > 0) + glFogfv(GL_FOG_COLOR, color); +} + +/* +============= +Fog_StopAdditive + +called after drawing stuff that is additive blended -- restores fog color +============= +*/ +void Fog_StopAdditive (void) +{ + if (Fog_GetDensity() > 0) + glFogfv(GL_FOG_COLOR, Fog_GetColor()); +} + +//============================================================================== +// +// VOLUMETRIC FOG +// +//============================================================================== + +cvar_t r_vfog = {"r_vfog", "1", CVAR_NONE}; + +void Fog_DrawVFog (void){} +void Fog_MarkModels (void){} + +//============================================================================== +// +// INIT +// +//============================================================================== + +/* +============= +Fog_NewMap + +called whenever a map is loaded +============= +*/ +void Fog_NewMap (void) +{ + Fog_ParseWorldspawn (); //for global fog + Fog_MarkModels (); //for volumetric fog +} + +/* +============= +Fog_Init + +called when quake initializes +============= +*/ +void Fog_Init (void) +{ + Cmd_AddCommand ("fog",Fog_FogCommand_f); + + //Cvar_RegisterVariable (&r_vfog); + + //set up global fog + fog_density = DEFAULT_DENSITY; + fog_red = DEFAULT_GRAY; + fog_green = DEFAULT_GRAY; + fog_blue = DEFAULT_GRAY; + + Fog_SetupState (); +} + +/* +============= +Fog_SetupState + +ericw -- moved from Fog_Init, state that needs to be setup when a new context is created +============= +*/ +void Fog_SetupState (void) +{ + glFogi(GL_FOG_MODE, GL_EXP2); +} diff --git a/engine/Quake/gl_mesh.c b/engine/Quake/gl_mesh.c new file mode 100644 index 0000000..c362fce --- /dev/null +++ b/engine/Quake/gl_mesh.c @@ -0,0 +1,614 @@ +/* +Copyright (C) 1996-2001 Id Software, Inc. +Copyright (C) 2002-2009 John Fitzgibbons and others +Copyright (C) 2010-2014 QuakeSpasm developers + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ +// gl_mesh.c: triangle model functions + +#include "quakedef.h" + + +/* +================================================================= + +ALIAS MODEL DISPLAY LIST GENERATION + +================================================================= +*/ + +qmodel_t *aliasmodel; +aliashdr_t *paliashdr; + +int used[8192]; // qboolean + +// the command list holds counts and s/t values that are valid for +// every frame +int commands[8192]; +int numcommands; + +// all frames will have their vertexes rearranged and expanded +// so they are in the order expected by the command list +int vertexorder[8192]; +int numorder; + +int allverts, alltris; + +int stripverts[128]; +int striptris[128]; +int stripcount; + +/* +================ +StripLength +================ +*/ +int StripLength (int starttri, int startv) +{ + int m1, m2; + int j; + mtriangle_t *last, *check; + int k; + + used[starttri] = 2; + + last = &triangles[starttri]; + + stripverts[0] = last->vertindex[(startv)%3]; + stripverts[1] = last->vertindex[(startv+1)%3]; + stripverts[2] = last->vertindex[(startv+2)%3]; + + striptris[0] = starttri; + stripcount = 1; + + m1 = last->vertindex[(startv+2)%3]; + m2 = last->vertindex[(startv+1)%3]; + + // look for a matching triangle +nexttri: + for (j=starttri+1, check=&triangles[starttri+1] ; jnumtris ; j++, check++) + { + if (check->facesfront != last->facesfront) + continue; + for (k=0 ; k<3 ; k++) + { + if (check->vertindex[k] != m1) + continue; + if (check->vertindex[ (k+1)%3 ] != m2) + continue; + + // this is the next part of the fan + + // if we can't use this triangle, this tristrip is done + if (used[j]) + goto done; + + // the new edge + if (stripcount & 1) + m2 = check->vertindex[ (k+2)%3 ]; + else + m1 = check->vertindex[ (k+2)%3 ]; + + stripverts[stripcount+2] = check->vertindex[ (k+2)%3 ]; + striptris[stripcount] = j; + stripcount++; + + used[j] = 2; + goto nexttri; + } + } +done: + + // clear the temp used flags + for (j=starttri+1 ; jnumtris ; j++) + if (used[j] == 2) + used[j] = 0; + + return stripcount; +} + +/* +=========== +FanLength +=========== +*/ +int FanLength (int starttri, int startv) +{ + int m1, m2; + int j; + mtriangle_t *last, *check; + int k; + + used[starttri] = 2; + + last = &triangles[starttri]; + + stripverts[0] = last->vertindex[(startv)%3]; + stripverts[1] = last->vertindex[(startv+1)%3]; + stripverts[2] = last->vertindex[(startv+2)%3]; + + striptris[0] = starttri; + stripcount = 1; + + m1 = last->vertindex[(startv+0)%3]; + m2 = last->vertindex[(startv+2)%3]; + + + // look for a matching triangle +nexttri: + for (j=starttri+1, check=&triangles[starttri+1] ; jnumtris ; j++, check++) + { + if (check->facesfront != last->facesfront) + continue; + for (k=0 ; k<3 ; k++) + { + if (check->vertindex[k] != m1) + continue; + if (check->vertindex[ (k+1)%3 ] != m2) + continue; + + // this is the next part of the fan + + // if we can't use this triangle, this tristrip is done + if (used[j]) + goto done; + + // the new edge + m2 = check->vertindex[ (k+2)%3 ]; + + stripverts[stripcount+2] = m2; + striptris[stripcount] = j; + stripcount++; + + used[j] = 2; + goto nexttri; + } + } +done: + + // clear the temp used flags + for (j=starttri+1 ; jnumtris ; j++) + if (used[j] == 2) + used[j] = 0; + + return stripcount; +} + + +/* +================ +BuildTris + +Generate a list of trifans or strips +for the model, which holds for all frames +================ +*/ +void BuildTris (void) +{ + int i, j, k; + int startv; + float s, t; + int len, bestlen, besttype; + int bestverts[1024]; + int besttris[1024]; + int type; + + // + // build tristrips + // + numorder = 0; + numcommands = 0; + memset (used, 0, sizeof(used)); + for (i = 0; i < pheader->numtris; i++) + { + // pick an unused triangle and start the trifan + if (used[i]) + continue; + + bestlen = 0; + besttype = 0; + for (type = 0 ; type < 2 ; type++) +// type = 1; + { + for (startv = 0; startv < 3; startv++) + { + if (type == 1) + len = StripLength (i, startv); + else + len = FanLength (i, startv); + if (len > bestlen) + { + besttype = type; + bestlen = len; + for (j = 0; j < bestlen+2; j++) + bestverts[j] = stripverts[j]; + for (j = 0; j < bestlen; j++) + besttris[j] = striptris[j]; + } + } + } + + // mark the tris on the best strip as used + for (j = 0; j < bestlen; j++) + used[besttris[j]] = 1; + + if (besttype == 1) + commands[numcommands++] = (bestlen+2); + else + commands[numcommands++] = -(bestlen+2); + + for (j = 0; j < bestlen+2; j++) + { + int tmp; + + // emit a vertex into the reorder buffer + k = bestverts[j]; + vertexorder[numorder++] = k; + + // emit s/t coords into the commands stream + s = stverts[k].s; + t = stverts[k].t; + if (!triangles[besttris[0]].facesfront && stverts[k].onseam) + s += pheader->skinwidth / 2; // on back side + s = (s + 0.5) / pheader->skinwidth; + t = (t + 0.5) / pheader->skinheight; + + // *(float *)&commands[numcommands++] = s; + // *(float *)&commands[numcommands++] = t; + // NOTE: 4 == sizeof(int) + // == sizeof(float) + memcpy (&tmp, &s, 4); + commands[numcommands++] = tmp; + memcpy (&tmp, &t, 4); + commands[numcommands++] = tmp; + } + } + + commands[numcommands++] = 0; // end of list marker + + Con_DPrintf2 ("%3i tri %3i vert %3i cmd\n", pheader->numtris, numorder, numcommands); + + allverts += numorder; + alltris += pheader->numtris; +} + +static void GL_MakeAliasModelDisplayLists_VBO (void); +static void GLMesh_LoadVertexBuffer (qmodel_t *m, const aliashdr_t *hdr); + +/* +================ +GL_MakeAliasModelDisplayLists +================ +*/ +void GL_MakeAliasModelDisplayLists (qmodel_t *m, aliashdr_t *hdr) +{ + int i, j; + int *cmds; + trivertx_t *verts; + float hscale, vscale; //johnfitz -- padded skins + int count; //johnfitz -- precompute texcoords for padded skins + int *loadcmds; //johnfitz + + //johnfitz -- padded skins + hscale = (float)hdr->skinwidth/(float)TexMgr_PadConditional(hdr->skinwidth); + vscale = (float)hdr->skinheight/(float)TexMgr_PadConditional(hdr->skinheight); + //johnfitz + + aliasmodel = m; + paliashdr = hdr; // (aliashdr_t *)Mod_Extradata (m); + +//johnfitz -- generate meshes + Con_DPrintf2 ("meshing %s...\n",m->name); + BuildTris (); + + // save the data out + + paliashdr->poseverts = numorder; + + cmds = (int *) Hunk_Alloc (numcommands * 4); + paliashdr->commands = (byte *)cmds - (byte *)paliashdr; + + //johnfitz -- precompute texcoords for padded skins + loadcmds = commands; + while(1) + { + *cmds++ = count = *loadcmds++; + + if (!count) + break; + + if (count < 0) + count = -count; + + do + { + *(float *)cmds++ = hscale * (*(float *)loadcmds++); + *(float *)cmds++ = vscale * (*(float *)loadcmds++); + } while (--count); + } + //johnfitz + + verts = (trivertx_t *) Hunk_Alloc (paliashdr->numposes * paliashdr->poseverts * sizeof(trivertx_t)); + paliashdr->posedata = (byte *)verts - (byte *)paliashdr; + for (i=0 ; inumposes ; i++) + for (j=0 ; jnumposes * paliashdr->numverts * sizeof(trivertx_t)); + paliashdr->vertexes = (byte *)verts - (byte *)paliashdr; + for (i=0 ; inumposes ; i++) + for (j=0 ; jnumverts ; j++) + verts[i*paliashdr->numverts + j] = poseverts[i][j]; + + // there can never be more than this number of verts and we just put them all on the hunk + maxverts_vbo = pheader->numtris * 3; + desc = (aliasmesh_t *) Hunk_Alloc (sizeof (aliasmesh_t) * maxverts_vbo); + + // there will always be this number of indexes + indexes = (unsigned short *) Hunk_Alloc (sizeof (unsigned short) * maxverts_vbo); + + pheader->indexes = (intptr_t) indexes - (intptr_t) pheader; + pheader->meshdesc = (intptr_t) desc - (intptr_t) pheader; + pheader->numindexes = 0; + pheader->numverts_vbo = 0; + + for (i = 0; i < pheader->numtris; i++) + { + for (j = 0; j < 3; j++) + { + int v; + + // index into hdr->vertexes + unsigned short vertindex = triangles[i].vertindex[j]; + + // basic s/t coords + int s = stverts[vertindex].s; + int t = stverts[vertindex].t; + + // check for back side and adjust texcoord s + if (!triangles[i].facesfront && stverts[vertindex].onseam) s += pheader->skinwidth / 2; + + // see does this vert already exist + for (v = 0; v < pheader->numverts_vbo; v++) + { + // it could use the same xyz but have different s and t + if (desc[v].vertindex == vertindex && (int) desc[v].st[0] == s && (int) desc[v].st[1] == t) + { + // exists; emit an index for it + indexes[pheader->numindexes++] = v; + + // no need to check any more + break; + } + } + + if (v == pheader->numverts_vbo) + { + // doesn't exist; emit a new vert and index + indexes[pheader->numindexes++] = pheader->numverts_vbo; + + desc[pheader->numverts_vbo].vertindex = vertindex; + desc[pheader->numverts_vbo].st[0] = s; + desc[pheader->numverts_vbo++].st[1] = t; + } + } + } + + // upload immediately + GLMesh_LoadVertexBuffer (aliasmodel, pheader); +} + +#define NUMVERTEXNORMALS 162 +extern float r_avertexnormals[NUMVERTEXNORMALS][3]; + +/* +================ +GLMesh_LoadVertexBuffer + +Upload the given alias model's mesh to a VBO + +Original code by MH from RMQEngine +================ +*/ +static void GLMesh_LoadVertexBuffer (qmodel_t *m, const aliashdr_t *hdr) +{ + int totalvbosize = 0; + const aliasmesh_t *desc; + const short *indexes; + const trivertx_t *trivertexes; + byte *vbodata; + int f; + + if (!gl_glsl_alias_able) + return; + +// count the sizes we need + + // ericw -- RMQEngine stored these vbo*ofs values in aliashdr_t, but we must not + // mutate Mod_Extradata since it might be reloaded from disk, so I moved them to qmodel_t + // (test case: roman1.bsp from arwop, 64mb heap) + m->vboindexofs = 0; + + m->vboxyzofs = 0; + totalvbosize += (hdr->numposes * hdr->numverts_vbo * sizeof (meshxyz_t)); // ericw -- what RMQEngine called nummeshframes is called numposes in QuakeSpasm + + m->vbostofs = totalvbosize; + totalvbosize += (hdr->numverts_vbo * sizeof (meshst_t)); + + if (!hdr->numindexes) return; + if (!totalvbosize) return; + +// grab the pointers to data in the extradata + + desc = (aliasmesh_t *) ((byte *) hdr + hdr->meshdesc); + indexes = (short *) ((byte *) hdr + hdr->indexes); + trivertexes = (trivertx_t *) ((byte *)hdr + hdr->vertexes); + +// upload indices buffer + + GL_DeleteBuffersFunc (1, &m->meshindexesvbo); + GL_GenBuffersFunc (1, &m->meshindexesvbo); + GL_BindBufferFunc (GL_ELEMENT_ARRAY_BUFFER, m->meshindexesvbo); + GL_BufferDataFunc (GL_ELEMENT_ARRAY_BUFFER, hdr->numindexes * sizeof (unsigned short), indexes, GL_STATIC_DRAW); + +// create the vertex buffer (empty) + + vbodata = (byte *) malloc(totalvbosize); + memset(vbodata, 0, totalvbosize); + +// fill in the vertices at the start of the buffer + for (f = 0; f < hdr->numposes; f++) // ericw -- what RMQEngine called nummeshframes is called numposes in QuakeSpasm + { + int v; + meshxyz_t *xyz = (meshxyz_t *) (vbodata + (f * hdr->numverts_vbo * sizeof (meshxyz_t))); + const trivertx_t *tv = trivertexes + (hdr->numverts * f); + + for (v = 0; v < hdr->numverts_vbo; v++) + { + trivertx_t trivert = tv[desc[v].vertindex]; + + xyz[v].xyz[0] = trivert.v[0]; + xyz[v].xyz[1] = trivert.v[1]; + xyz[v].xyz[2] = trivert.v[2]; + xyz[v].xyz[3] = 1; // need w 1 for 4 byte vertex compression + + // map the normal coordinates in [-1..1] to [-127..127] and store in an unsigned char. + // this introduces some error (less than 0.004), but the normals were very coarse + // to begin with + xyz[v].normal[0] = 127 * r_avertexnormals[trivert.lightnormalindex][0]; + xyz[v].normal[1] = 127 * r_avertexnormals[trivert.lightnormalindex][1]; + xyz[v].normal[2] = 127 * r_avertexnormals[trivert.lightnormalindex][2]; + xyz[v].normal[3] = 0; // unused; for 4-byte alignment + } + } + +// fill in the ST coords at the end of the buffer + { + meshst_t *st; + float hscale, vscale; + + //johnfitz -- padded skins + hscale = (float)hdr->skinwidth/(float)TexMgr_PadConditional(hdr->skinwidth); + vscale = (float)hdr->skinheight/(float)TexMgr_PadConditional(hdr->skinheight); + //johnfitz + + st = (meshst_t *) (vbodata + m->vbostofs); + for (f = 0; f < hdr->numverts_vbo; f++) + { + st[f].st[0] = hscale * ((float) desc[f].st[0] + 0.5f) / (float) hdr->skinwidth; + st[f].st[1] = vscale * ((float) desc[f].st[1] + 0.5f) / (float) hdr->skinheight; + } + } + +// upload vertexes buffer + GL_DeleteBuffersFunc (1, &m->meshvbo); + GL_GenBuffersFunc (1, &m->meshvbo); + GL_BindBufferFunc (GL_ARRAY_BUFFER, m->meshvbo); + GL_BufferDataFunc (GL_ARRAY_BUFFER, totalvbosize, vbodata, GL_STATIC_DRAW); + + free (vbodata); + +// invalidate the cached bindings + GL_ClearBufferBindings (); +} + +/* +================ +GLMesh_LoadVertexBuffers + +Loop over all precached alias models, and upload each one to a VBO. +================ +*/ +void GLMesh_LoadVertexBuffers (void) +{ + int j; + qmodel_t *m; + const aliashdr_t *hdr; + + if (!gl_glsl_alias_able) + return; + + for (j = 1; j < MAX_MODELS; j++) + { + if (!(m = cl.model_precache[j])) break; + if (m->type != mod_alias) continue; + + hdr = (const aliashdr_t *) Mod_Extradata (m); + + GLMesh_LoadVertexBuffer (m, hdr); + } +} + +/* +================ +GLMesh_DeleteVertexBuffers + +Delete VBOs for all loaded alias models +================ +*/ +void GLMesh_DeleteVertexBuffers (void) +{ + int j; + qmodel_t *m; + + if (!gl_glsl_alias_able) + return; + + for (j = 1; j < MAX_MODELS; j++) + { + if (!(m = cl.model_precache[j])) break; + if (m->type != mod_alias) continue; + + GL_DeleteBuffersFunc (1, &m->meshvbo); + m->meshvbo = 0; + + GL_DeleteBuffersFunc (1, &m->meshindexesvbo); + m->meshindexesvbo = 0; + } + + GL_ClearBufferBindings (); +} diff --git a/engine/Quake/gl_model.c b/engine/Quake/gl_model.c new file mode 100644 index 0000000..36f3318 --- /dev/null +++ b/engine/Quake/gl_model.c @@ -0,0 +1,2870 @@ +/* +Copyright (C) 1996-2001 Id Software, Inc. +Copyright (C) 2002-2009 John Fitzgibbons and others +Copyright (C) 2010-2014 QuakeSpasm developers + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ +// models.c -- model loading and caching + +// models are the only shared resource between a client and server running +// on the same machine. + +#include "quakedef.h" + +qmodel_t *loadmodel; +char loadname[32]; // for hunk tags + +void Mod_LoadSpriteModel (qmodel_t *mod, void *buffer); +void Mod_LoadBrushModel (qmodel_t *mod, void *buffer); +void Mod_LoadAliasModel (qmodel_t *mod, void *buffer); +qmodel_t *Mod_LoadModel (qmodel_t *mod, qboolean crash); + +cvar_t external_ents = {"external_ents", "1", CVAR_ARCHIVE}; + +static byte *mod_novis; +static int mod_novis_capacity; + +static byte *mod_decompressed; +static int mod_decompressed_capacity; + +#define MAX_MOD_KNOWN 2048 /*johnfitz -- was 512 */ +qmodel_t mod_known[MAX_MOD_KNOWN]; +int mod_numknown; + +texture_t *r_notexture_mip; //johnfitz -- moved here from r_main.c +texture_t *r_notexture_mip2; //johnfitz -- used for non-lightmapped surfs with a missing texture + +/* +=============== +Mod_Init +=============== +*/ +void Mod_Init (void) +{ + Cvar_RegisterVariable (&gl_subdivide_size); + Cvar_RegisterVariable (&external_ents); + + //johnfitz -- create notexture miptex + r_notexture_mip = (texture_t *) Hunk_AllocName (sizeof(texture_t), "r_notexture_mip"); + strcpy (r_notexture_mip->name, "notexture"); + r_notexture_mip->height = r_notexture_mip->width = 32; + + r_notexture_mip2 = (texture_t *) Hunk_AllocName (sizeof(texture_t), "r_notexture_mip2"); + strcpy (r_notexture_mip2->name, "notexture2"); + r_notexture_mip2->height = r_notexture_mip2->width = 32; + //johnfitz +} + +/* +=============== +Mod_Extradata + +Caches the data if needed +=============== +*/ +void *Mod_Extradata (qmodel_t *mod) +{ + void *r; + + r = Cache_Check (&mod->cache); + if (r) + return r; + + Mod_LoadModel (mod, true); + + if (!mod->cache.data) + Sys_Error ("Mod_Extradata: caching failed"); + return mod->cache.data; +} + +/* +=============== +Mod_PointInLeaf +=============== +*/ +mleaf_t *Mod_PointInLeaf (vec3_t p, qmodel_t *model) +{ + mnode_t *node; + float d; + mplane_t *plane; + + if (!model || !model->nodes) + Sys_Error ("Mod_PointInLeaf: bad model"); + + node = model->nodes; + while (1) + { + if (node->contents < 0) + return (mleaf_t *)node; + plane = node->plane; + d = DotProduct (p,plane->normal) - plane->dist; + if (d > 0) + node = node->children[0]; + else + node = node->children[1]; + } + + return NULL; // never reached +} + + +/* +=================== +Mod_DecompressVis +=================== +*/ +byte *Mod_DecompressVis (byte *in, qmodel_t *model) +{ + int c; + byte *out; + byte *outend; + int row; + + row = (model->numleafs+7)>>3; + if (mod_decompressed == NULL || row > mod_decompressed_capacity) + { + mod_decompressed_capacity = row; + mod_decompressed = (byte *) realloc (mod_decompressed, mod_decompressed_capacity); + if (!mod_decompressed) + Sys_Error ("Mod_DecompressVis: realloc() failed on %d bytes", mod_decompressed_capacity); + } + out = mod_decompressed; + outend = mod_decompressed + row; + + if (!in) + { // no vis info, so make all visible + while (row) + { + *out++ = 0xff; + row--; + } + return mod_decompressed; + } + + do + { + if (*in) + { + *out++ = *in++; + continue; + } + + c = in[1]; + in += 2; + while (c) + { + if (out == outend) + { + if(!model->viswarn) { + model->viswarn = true; + Con_Warning("Mod_DecompressVis: output overrun on model \"%s\"\n", model->name); + } + return mod_decompressed; + } + *out++ = 0; + c--; + } + } while (out - mod_decompressed < row); + + return mod_decompressed; +} + +byte *Mod_LeafPVS (mleaf_t *leaf, qmodel_t *model) +{ + if (leaf == model->leafs) + return Mod_NoVisPVS (model); + return Mod_DecompressVis (leaf->compressed_vis, model); +} + +byte *Mod_NoVisPVS (qmodel_t *model) +{ + int pvsbytes; + + pvsbytes = (model->numleafs+7)>>3; + if (mod_novis == NULL || pvsbytes > mod_novis_capacity) + { + mod_novis_capacity = pvsbytes; + mod_novis = (byte *) realloc (mod_novis, mod_novis_capacity); + if (!mod_novis) + Sys_Error ("Mod_NoVisPVS: realloc() failed on %d bytes", mod_novis_capacity); + + memset(mod_novis, 0xff, mod_novis_capacity); + } + return mod_novis; +} + +/* +=================== +Mod_ClearAll +=================== +*/ +void Mod_ClearAll (void) +{ + int i; + qmodel_t *mod; + + for (i=0 , mod=mod_known ; itype != mod_alias) + { + mod->needload = true; + TexMgr_FreeTexturesForOwner (mod); //johnfitz + } +} + +void Mod_ResetAll (void) +{ + int i; + qmodel_t *mod; + + //ericw -- free alias model VBOs + GLMesh_DeleteVertexBuffers (); + + for (i=0 , mod=mod_known ; ineedload) //otherwise Mod_ClearAll() did it already + TexMgr_FreeTexturesForOwner (mod); + memset(mod, 0, sizeof(qmodel_t)); + } + mod_numknown = 0; +} + +/* +================== +Mod_FindName + +================== +*/ +qmodel_t *Mod_FindName (const char *name) +{ + int i; + qmodel_t *mod; + + if (!name[0]) + Sys_Error ("Mod_FindName: NULL name"); //johnfitz -- was "Mod_ForName" + +// +// search the currently loaded models +// + for (i=0 , mod=mod_known ; iname, name) ) + break; + + if (i == mod_numknown) + { + if (mod_numknown == MAX_MOD_KNOWN) + Sys_Error ("mod_numknown == MAX_MOD_KNOWN"); + q_strlcpy (mod->name, name, MAX_QPATH); + mod->needload = true; + mod_numknown++; + } + + return mod; +} + +/* +================== +Mod_TouchModel + +================== +*/ +void Mod_TouchModel (const char *name) +{ + qmodel_t *mod; + + mod = Mod_FindName (name); + + if (!mod->needload) + { + if (mod->type == mod_alias) + Cache_Check (&mod->cache); + } +} + +/* +================== +Mod_LoadModel + +Loads a model into the cache +================== +*/ +qmodel_t *Mod_LoadModel (qmodel_t *mod, qboolean crash) +{ + byte *buf; + byte stackbuf[1024]; // avoid dirtying the cache heap + int mod_type; + + if (!mod->needload) + { + if (mod->type == mod_alias) + { + if (Cache_Check (&mod->cache)) + return mod; + } + else + return mod; // not cached at all + } + +// +// because the world is so huge, load it one piece at a time +// + if (!crash) + { + + } + +// +// load the file +// + buf = COM_LoadStackFile (mod->name, stackbuf, sizeof(stackbuf), & mod->path_id); + if (!buf) + { + if (crash) + Host_Error ("Mod_LoadModel: %s not found", mod->name); //johnfitz -- was "Mod_NumForName" + return NULL; + } + +// +// allocate a new model +// + COM_FileBase (mod->name, loadname, sizeof(loadname)); + + loadmodel = mod; + +// +// fill it in +// + +// call the apropriate loader + mod->needload = false; + + mod_type = (buf[0] | (buf[1] << 8) | (buf[2] << 16) | (buf[3] << 24)); + switch (mod_type) + { + case IDPOLYHEADER: + Mod_LoadAliasModel (mod, buf); + break; + + case IDSPRITEHEADER: + Mod_LoadSpriteModel (mod, buf); + break; + + default: + Mod_LoadBrushModel (mod, buf); + break; + } + + return mod; +} + +/* +================== +Mod_ForName + +Loads in a model for the given name +================== +*/ +qmodel_t *Mod_ForName (const char *name, qboolean crash) +{ + qmodel_t *mod; + + mod = Mod_FindName (name); + + return Mod_LoadModel (mod, crash); +} + + +/* +=============================================================================== + + BRUSHMODEL LOADING + +=============================================================================== +*/ + +byte *mod_base; + +/* +================= +Mod_CheckFullbrights -- johnfitz +================= +*/ +qboolean Mod_CheckFullbrights (byte *pixels, int count) +{ + int i; + for (i = 0; i < count; i++) + if (*pixels++ > 223) + return true; + return false; +} + +/* +================= +Mod_LoadTextures +================= +*/ +void Mod_LoadTextures (lump_t *l) +{ + int i, j, pixels, num, maxanim, altmax; + miptex_t *mt; + texture_t *tx, *tx2; + texture_t *anims[10]; + texture_t *altanims[10]; + dmiptexlump_t *m; +//johnfitz -- more variables + char texturename[64]; + int nummiptex; + src_offset_t offset; + int mark, fwidth, fheight; + char filename[MAX_OSPATH], filename2[MAX_OSPATH], mapname[MAX_OSPATH]; + byte *data; + extern byte *hunk_base; +//johnfitz + + //johnfitz -- don't return early if no textures; still need to create dummy texture + if (!l->filelen) + { + Con_Printf ("Mod_LoadTextures: no textures in bsp file\n"); + nummiptex = 0; + m = NULL; // avoid bogus compiler warning + } + else + { + m = (dmiptexlump_t *)(mod_base + l->fileofs); + m->nummiptex = LittleLong (m->nummiptex); + nummiptex = m->nummiptex; + } + //johnfitz + + loadmodel->numtextures = nummiptex + 2; //johnfitz -- need 2 dummy texture chains for missing textures + loadmodel->textures = (texture_t **) Hunk_AllocName (loadmodel->numtextures * sizeof(*loadmodel->textures) , loadname); + + for (i=0 ; idataofs[i] = LittleLong(m->dataofs[i]); + if (m->dataofs[i] == -1) + continue; + mt = (miptex_t *)((byte *)m + m->dataofs[i]); + mt->width = LittleLong (mt->width); + mt->height = LittleLong (mt->height); + for (j=0 ; joffsets[j] = LittleLong (mt->offsets[j]); + + if ( (mt->width & 15) || (mt->height & 15) ) + Sys_Error ("Texture %s is not 16 aligned", mt->name); + pixels = mt->width*mt->height/64*85; + tx = (texture_t *) Hunk_AllocName (sizeof(texture_t) +pixels, loadname ); + loadmodel->textures[i] = tx; + + memcpy (tx->name, mt->name, sizeof(tx->name)); + tx->width = mt->width; + tx->height = mt->height; + for (j=0 ; joffsets[j] = mt->offsets[j] + sizeof(texture_t) - sizeof(miptex_t); + // the pixels immediately follow the structures + + // ericw -- check for pixels extending past the end of the lump. + // appears in the wild; e.g. jam2_tronyn.bsp (func_mapjam2), + // kellbase1.bsp (quoth), and can lead to a segfault if we read past + // the end of the .bsp file buffer + if (((byte*)(mt+1) + pixels) > (mod_base + l->fileofs + l->filelen)) + { + Con_DPrintf("Texture %s extends past end of lump\n", mt->name); + pixels = q_max(0, (mod_base + l->fileofs + l->filelen) - (byte*)(mt+1)); + } + memcpy ( tx+1, mt+1, pixels); + + tx->update_warp = false; //johnfitz + tx->warpimage = NULL; //johnfitz + tx->fullbright = NULL; //johnfitz + + //johnfitz -- lots of changes + if (!isDedicated) //no texture uploading for dedicated server + { + if (!q_strncasecmp(tx->name,"sky",3)) //sky texture //also note -- was Q_strncmp, changed to match qbsp + Sky_LoadTexture (tx); + else if (tx->name[0] == '*') //warping texture + { + //external textures -- first look in "textures/mapname/" then look in "textures/" + mark = Hunk_LowMark(); + COM_StripExtension (loadmodel->name + 5, mapname, sizeof(mapname)); + q_snprintf (filename, sizeof(filename), "textures/%s/#%s", mapname, tx->name+1); //this also replaces the '*' with a '#' + data = Image_LoadImage (filename, &fwidth, &fheight); + if (!data) + { + q_snprintf (filename, sizeof(filename), "textures/#%s", tx->name+1); + data = Image_LoadImage (filename, &fwidth, &fheight); + } + + //now load whatever we found + if (data) //load external image + { + q_strlcpy (texturename, filename, sizeof(texturename)); + tx->gltexture = TexMgr_LoadImage (loadmodel, texturename, fwidth, fheight, + SRC_RGBA, data, filename, 0, TEXPREF_NONE); + } + else //use the texture from the bsp file + { + q_snprintf (texturename, sizeof(texturename), "%s:%s", loadmodel->name, tx->name); + offset = (src_offset_t)(mt+1) - (src_offset_t)mod_base; + tx->gltexture = TexMgr_LoadImage (loadmodel, texturename, tx->width, tx->height, + SRC_INDEXED, (byte *)(tx+1), loadmodel->name, offset, TEXPREF_NONE); + } + + //now create the warpimage, using dummy data from the hunk to create the initial image + Hunk_Alloc (gl_warpimagesize*gl_warpimagesize*4); //make sure hunk is big enough so we don't reach an illegal address + Hunk_FreeToLowMark (mark); + q_snprintf (texturename, sizeof(texturename), "%s_warp", texturename); + tx->warpimage = TexMgr_LoadImage (loadmodel, texturename, gl_warpimagesize, + gl_warpimagesize, SRC_RGBA, hunk_base, "", (src_offset_t)hunk_base, TEXPREF_NOPICMIP | TEXPREF_WARPIMAGE); + tx->update_warp = true; + } + else //regular texture + { + // ericw -- fence textures + int extraflags; + + extraflags = 0; + if (tx->name[0] == '{') + extraflags |= TEXPREF_ALPHA; + // ericw + + //external textures -- first look in "textures/mapname/" then look in "textures/" + mark = Hunk_LowMark (); + COM_StripExtension (loadmodel->name + 5, mapname, sizeof(mapname)); + q_snprintf (filename, sizeof(filename), "textures/%s/%s", mapname, tx->name); + data = Image_LoadImage (filename, &fwidth, &fheight); + if (!data) + { + q_snprintf (filename, sizeof(filename), "textures/%s", tx->name); + data = Image_LoadImage (filename, &fwidth, &fheight); + } + + //now load whatever we found + if (data) //load external image + { + tx->gltexture = TexMgr_LoadImage (loadmodel, filename, fwidth, fheight, + SRC_RGBA, data, filename, 0, TEXPREF_MIPMAP | extraflags ); + + //now try to load glow/luma image from the same place + Hunk_FreeToLowMark (mark); + q_snprintf (filename2, sizeof(filename2), "%s_glow", filename); + data = Image_LoadImage (filename2, &fwidth, &fheight); + if (!data) + { + q_snprintf (filename2, sizeof(filename2), "%s_luma", filename); + data = Image_LoadImage (filename2, &fwidth, &fheight); + } + + if (data) + tx->fullbright = TexMgr_LoadImage (loadmodel, filename2, fwidth, fheight, + SRC_RGBA, data, filename, 0, TEXPREF_MIPMAP | extraflags ); + } + else //use the texture from the bsp file + { + q_snprintf (texturename, sizeof(texturename), "%s:%s", loadmodel->name, tx->name); + offset = (src_offset_t)(mt+1) - (src_offset_t)mod_base; + if (Mod_CheckFullbrights ((byte *)(tx+1), pixels)) + { + tx->gltexture = TexMgr_LoadImage (loadmodel, texturename, tx->width, tx->height, + SRC_INDEXED, (byte *)(tx+1), loadmodel->name, offset, TEXPREF_MIPMAP | TEXPREF_NOBRIGHT | extraflags); + q_snprintf (texturename, sizeof(texturename), "%s:%s_glow", loadmodel->name, tx->name); + tx->fullbright = TexMgr_LoadImage (loadmodel, texturename, tx->width, tx->height, + SRC_INDEXED, (byte *)(tx+1), loadmodel->name, offset, TEXPREF_MIPMAP | TEXPREF_FULLBRIGHT | extraflags); + } + else + { + tx->gltexture = TexMgr_LoadImage (loadmodel, texturename, tx->width, tx->height, + SRC_INDEXED, (byte *)(tx+1), loadmodel->name, offset, TEXPREF_MIPMAP | extraflags); + } + } + Hunk_FreeToLowMark (mark); + } + } + //johnfitz + } + + //johnfitz -- last 2 slots in array should be filled with dummy textures + loadmodel->textures[loadmodel->numtextures-2] = r_notexture_mip; //for lightmapped surfs + loadmodel->textures[loadmodel->numtextures-1] = r_notexture_mip2; //for SURF_DRAWTILED surfs + +// +// sequence the animations +// + for (i=0 ; itextures[i]; + if (!tx || tx->name[0] != '+') + continue; + if (tx->anim_next) + continue; // allready sequenced + + // find the number of frames in the animation + memset (anims, 0, sizeof(anims)); + memset (altanims, 0, sizeof(altanims)); + + maxanim = tx->name[1]; + altmax = 0; + if (maxanim >= 'a' && maxanim <= 'z') + maxanim -= 'a' - 'A'; + if (maxanim >= '0' && maxanim <= '9') + { + maxanim -= '0'; + altmax = 0; + anims[maxanim] = tx; + maxanim++; + } + else if (maxanim >= 'A' && maxanim <= 'J') + { + altmax = maxanim - 'A'; + maxanim = 0; + altanims[altmax] = tx; + altmax++; + } + else + Sys_Error ("Bad animating texture %s", tx->name); + + for (j=i+1 ; jtextures[j]; + if (!tx2 || tx2->name[0] != '+') + continue; + if (strcmp (tx2->name+2, tx->name+2)) + continue; + + num = tx2->name[1]; + if (num >= 'a' && num <= 'z') + num -= 'a' - 'A'; + if (num >= '0' && num <= '9') + { + num -= '0'; + anims[num] = tx2; + if (num+1 > maxanim) + maxanim = num + 1; + } + else if (num >= 'A' && num <= 'J') + { + num = num - 'A'; + altanims[num] = tx2; + if (num+1 > altmax) + altmax = num+1; + } + else + Sys_Error ("Bad animating texture %s", tx->name); + } + +#define ANIM_CYCLE 2 + // link them all together + for (j=0 ; jname); + tx2->anim_total = maxanim * ANIM_CYCLE; + tx2->anim_min = j * ANIM_CYCLE; + tx2->anim_max = (j+1) * ANIM_CYCLE; + tx2->anim_next = anims[ (j+1)%maxanim ]; + if (altmax) + tx2->alternate_anims = altanims[0]; + } + for (j=0 ; jname); + tx2->anim_total = altmax * ANIM_CYCLE; + tx2->anim_min = j * ANIM_CYCLE; + tx2->anim_max = (j+1) * ANIM_CYCLE; + tx2->anim_next = altanims[ (j+1)%altmax ]; + if (maxanim) + tx2->alternate_anims = anims[0]; + } + } +} + +/* +================= +Mod_LoadLighting -- johnfitz -- replaced with lit support code via lordhavoc +================= +*/ +void Mod_LoadLighting (lump_t *l) +{ + int i, mark; + byte *in, *out, *data; + byte d; + char litfilename[MAX_OSPATH]; + unsigned int path_id; + + loadmodel->lightdata = NULL; + // LordHavoc: check for a .lit file + q_strlcpy(litfilename, loadmodel->name, sizeof(litfilename)); + COM_StripExtension(litfilename, litfilename, sizeof(litfilename)); + q_strlcat(litfilename, ".lit", sizeof(litfilename)); + mark = Hunk_LowMark(); + data = (byte*) COM_LoadHunkFile (litfilename, &path_id); + if (data) + { + // use lit file only from the same gamedir as the map + // itself or from a searchpath with higher priority. + if (path_id < loadmodel->path_id) + { + Hunk_FreeToLowMark(mark); + Con_DPrintf("ignored %s from a gamedir with lower priority\n", litfilename); + } + else + if (data[0] == 'Q' && data[1] == 'L' && data[2] == 'I' && data[3] == 'T') + { + i = LittleLong(((int *)data)[1]); + if (i == 1) + { + Con_DPrintf2("%s loaded\n", litfilename); + loadmodel->lightdata = data + 8; + return; + } + else + { + Hunk_FreeToLowMark(mark); + Con_Printf("Unknown .lit file version (%d)\n", i); + } + } + else + { + Hunk_FreeToLowMark(mark); + Con_Printf("Corrupt .lit file (old version?), ignoring\n"); + } + } + // LordHavoc: no .lit found, expand the white lighting data to color + if (!l->filelen) + return; + loadmodel->lightdata = (byte *) Hunk_AllocName ( l->filelen*3, litfilename); + in = loadmodel->lightdata + l->filelen*2; // place the file at the end, so it will not be overwritten until the very last write + out = loadmodel->lightdata; + memcpy (in, mod_base + l->fileofs, l->filelen); + for (i = 0;i < l->filelen;i++) + { + d = *in++; + *out++ = d; + *out++ = d; + *out++ = d; + } +} + + +/* +================= +Mod_LoadVisibility +================= +*/ +void Mod_LoadVisibility (lump_t *l) +{ + loadmodel->viswarn = false; + if (!l->filelen) + { + loadmodel->visdata = NULL; + return; + } + loadmodel->visdata = (byte *) Hunk_AllocName ( l->filelen, loadname); + memcpy (loadmodel->visdata, mod_base + l->fileofs, l->filelen); +} + + +/* +================= +Mod_LoadEntities +================= +*/ +void Mod_LoadEntities (lump_t *l) +{ + char entfilename[MAX_QPATH]; + char *ents; + int mark; + unsigned int path_id; + + if (! external_ents.value) + goto _load_embedded; + + q_strlcpy(entfilename, loadmodel->name, sizeof(entfilename)); + COM_StripExtension(entfilename, entfilename, sizeof(entfilename)); + q_strlcat(entfilename, ".ent", sizeof(entfilename)); + Con_DPrintf2("trying to load %s\n", entfilename); + mark = Hunk_LowMark(); + ents = (char *) COM_LoadHunkFile (entfilename, &path_id); + if (ents) + { + // use ent file only from the same gamedir as the map + // itself or from a searchpath with higher priority. + if (path_id < loadmodel->path_id) + { + Hunk_FreeToLowMark(mark); + Con_DPrintf("ignored %s from a gamedir with lower priority\n", entfilename); + } + else + { + loadmodel->entities = ents; + Con_DPrintf("Loaded external entity file %s\n", entfilename); + return; + } + } + +_load_embedded: + if (!l->filelen) + { + loadmodel->entities = NULL; + return; + } + loadmodel->entities = (char *) Hunk_AllocName ( l->filelen, loadname); + memcpy (loadmodel->entities, mod_base + l->fileofs, l->filelen); +} + + +/* +================= +Mod_LoadVertexes +================= +*/ +void Mod_LoadVertexes (lump_t *l) +{ + dvertex_t *in; + mvertex_t *out; + int i, count; + + in = (dvertex_t *)(mod_base + l->fileofs); + if (l->filelen % sizeof(*in)) + Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name); + count = l->filelen / sizeof(*in); + out = (mvertex_t *) Hunk_AllocName ( count*sizeof(*out), loadname); + + loadmodel->vertexes = out; + loadmodel->numvertexes = count; + + for (i=0 ; iposition[0] = LittleFloat (in->point[0]); + out->position[1] = LittleFloat (in->point[1]); + out->position[2] = LittleFloat (in->point[2]); + } +} + +/* +================= +Mod_LoadEdges +================= +*/ +void Mod_LoadEdges (lump_t *l, int bsp2) +{ + medge_t *out; + int i, count; + + if (bsp2) + { + dledge_t *in = (dledge_t *)(mod_base + l->fileofs); + + if (l->filelen % sizeof(*in)) + Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name); + + count = l->filelen / sizeof(*in); + out = (medge_t *) Hunk_AllocName ( (count + 1) * sizeof(*out), loadname); + + loadmodel->edges = out; + loadmodel->numedges = count; + + for (i=0 ; iv[0] = LittleLong(in->v[0]); + out->v[1] = LittleLong(in->v[1]); + } + } + else + { + dsedge_t *in = (dsedge_t *)(mod_base + l->fileofs); + + if (l->filelen % sizeof(*in)) + Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name); + + count = l->filelen / sizeof(*in); + out = (medge_t *) Hunk_AllocName ( (count + 1) * sizeof(*out), loadname); + + loadmodel->edges = out; + loadmodel->numedges = count; + + for (i=0 ; iv[0] = (unsigned short)LittleShort(in->v[0]); + out->v[1] = (unsigned short)LittleShort(in->v[1]); + } + } +} + +/* +================= +Mod_LoadTexinfo +================= +*/ +void Mod_LoadTexinfo (lump_t *l) +{ + texinfo_t *in; + mtexinfo_t *out; + int i, j, count, miptex; + float len1, len2; + int missing = 0; //johnfitz + + in = (texinfo_t *)(mod_base + l->fileofs); + if (l->filelen % sizeof(*in)) + Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name); + count = l->filelen / sizeof(*in); + out = (mtexinfo_t *) Hunk_AllocName ( count*sizeof(*out), loadname); + + loadmodel->texinfo = out; + loadmodel->numtexinfo = count; + + for (i=0 ; ivecs[0][j] = LittleFloat (in->vecs[0][j]); + out->vecs[1][j] = LittleFloat (in->vecs[1][j]); + } + len1 = VectorLength (out->vecs[0]); + len2 = VectorLength (out->vecs[1]); + len1 = (len1 + len2)/2; + if (len1 < 0.32) + out->mipadjust = 4; + else if (len1 < 0.49) + out->mipadjust = 3; + else if (len1 < 0.99) + out->mipadjust = 2; + else + out->mipadjust = 1; +#if 0 + if (len1 + len2 < 0.001) + out->mipadjust = 1; // don't crash + else + out->mipadjust = 1 / floor((len1+len2)/2 + 0.1); +#endif + + miptex = LittleLong (in->miptex); + out->flags = LittleLong (in->flags); + + //johnfitz -- rewrote this section + if (miptex >= loadmodel->numtextures-1 || !loadmodel->textures[miptex]) + { + if (out->flags & TEX_SPECIAL) + out->texture = loadmodel->textures[loadmodel->numtextures-1]; + else + out->texture = loadmodel->textures[loadmodel->numtextures-2]; + out->flags |= TEX_MISSING; + missing++; + } + else + { + out->texture = loadmodel->textures[miptex]; + } + //johnfitz + } + + //johnfitz: report missing textures + if (missing && loadmodel->numtextures > 1) + Con_Printf ("Mod_LoadTexinfo: %d texture(s) missing from BSP file\n", missing); + //johnfitz +} + +/* +================ +CalcSurfaceExtents + +Fills in s->texturemins[] and s->extents[] +================ +*/ +void CalcSurfaceExtents (msurface_t *s) +{ + float mins[2], maxs[2], val; + int i,j, e; + mvertex_t *v; + mtexinfo_t *tex; + int bmins[2], bmaxs[2]; + + mins[0] = mins[1] = 999999; + maxs[0] = maxs[1] = -999999; // FIXME: change these two to FLT_MAX/-FLT_MAX + + tex = s->texinfo; + + for (i=0 ; inumedges ; i++) + { + e = loadmodel->surfedges[s->firstedge+i]; + if (e >= 0) + v = &loadmodel->vertexes[loadmodel->edges[e].v[0]]; + else + v = &loadmodel->vertexes[loadmodel->edges[-e].v[1]]; + + for (j=0 ; j<2 ; j++) + { + /* The following calculation is sensitive to floating-point + * precision. It needs to produce the same result that the + * light compiler does, because R_BuildLightMap uses surf-> + * extents to know the width/height of a surface's lightmap, + * and incorrect rounding here manifests itself as patches + * of "corrupted" looking lightmaps. + * Most light compilers are win32 executables, so they use + * x87 floating point. This means the multiplies and adds + * are done at 80-bit precision, and the result is rounded + * down to 32-bits and stored in val. + * Adding the casts to double seems to be good enough to fix + * lighting glitches when Quakespasm is compiled as x86_64 + * and using SSE2 floating-point. A potential trouble spot + * is the hallway at the beginning of mfxsp17. -- ericw + */ + val = ((double)v->position[0] * (double)tex->vecs[j][0]) + + ((double)v->position[1] * (double)tex->vecs[j][1]) + + ((double)v->position[2] * (double)tex->vecs[j][2]) + + (double)tex->vecs[j][3]; + + if (val < mins[j]) + mins[j] = val; + if (val > maxs[j]) + maxs[j] = val; + } + } + + for (i=0 ; i<2 ; i++) + { + bmins[i] = floor(mins[i]/16); + bmaxs[i] = ceil(maxs[i]/16); + + s->texturemins[i] = bmins[i] * 16; + s->extents[i] = (bmaxs[i] - bmins[i]) * 16; + + if ( !(tex->flags & TEX_SPECIAL) && s->extents[i] > 2000) //johnfitz -- was 512 in glquake, 256 in winquake + Sys_Error ("Bad surface extents"); + } +} + +/* +================ +Mod_PolyForUnlitSurface -- johnfitz -- creates polys for unlightmapped surfaces (sky and water) + +TODO: merge this into BuildSurfaceDisplayList? +================ +*/ +void Mod_PolyForUnlitSurface (msurface_t *fa) +{ + vec3_t verts[64]; + int numverts, i, lindex; + float *vec; + glpoly_t *poly; + float texscale; + + if (fa->flags & (SURF_DRAWTURB | SURF_DRAWSKY)) + texscale = (1.0/128.0); //warp animation repeats every 128 + else + texscale = (1.0/32.0); //to match r_notexture_mip + + // convert edges back to a normal polygon + numverts = 0; + for (i=0 ; inumedges ; i++) + { + lindex = loadmodel->surfedges[fa->firstedge + i]; + + if (lindex > 0) + vec = loadmodel->vertexes[loadmodel->edges[lindex].v[0]].position; + else + vec = loadmodel->vertexes[loadmodel->edges[-lindex].v[1]].position; + VectorCopy (vec, verts[numverts]); + numverts++; + } + + //create the poly + poly = (glpoly_t *) Hunk_Alloc (sizeof(glpoly_t) + (numverts-4) * VERTEXSIZE*sizeof(float)); + poly->next = NULL; + fa->polys = poly; + poly->numverts = numverts; + for (i=0, vec=(float *)verts; iverts[i]); + poly->verts[i][3] = DotProduct(vec, fa->texinfo->vecs[0]) * texscale; + poly->verts[i][4] = DotProduct(vec, fa->texinfo->vecs[1]) * texscale; + } +} + +/* +================= +Mod_CalcSurfaceBounds -- johnfitz -- calculate bounding box for per-surface frustum culling +================= +*/ +void Mod_CalcSurfaceBounds (msurface_t *s) +{ + int i, e; + mvertex_t *v; + + s->mins[0] = s->mins[1] = s->mins[2] = 9999; + s->maxs[0] = s->maxs[1] = s->maxs[2] = -9999; + + for (i=0 ; inumedges ; i++) + { + e = loadmodel->surfedges[s->firstedge+i]; + if (e >= 0) + v = &loadmodel->vertexes[loadmodel->edges[e].v[0]]; + else + v = &loadmodel->vertexes[loadmodel->edges[-e].v[1]]; + + if (s->mins[0] > v->position[0]) + s->mins[0] = v->position[0]; + if (s->mins[1] > v->position[1]) + s->mins[1] = v->position[1]; + if (s->mins[2] > v->position[2]) + s->mins[2] = v->position[2]; + + if (s->maxs[0] < v->position[0]) + s->maxs[0] = v->position[0]; + if (s->maxs[1] < v->position[1]) + s->maxs[1] = v->position[1]; + if (s->maxs[2] < v->position[2]) + s->maxs[2] = v->position[2]; + } +} + +/* +================= +Mod_LoadFaces +================= +*/ +void Mod_LoadFaces (lump_t *l, qboolean bsp2) +{ + dsface_t *ins; + dlface_t *inl; + msurface_t *out; + int i, count, surfnum, lofs; + int planenum, side, texinfon; + + if (bsp2) + { + ins = NULL; + inl = (dlface_t *)(mod_base + l->fileofs); + if (l->filelen % sizeof(*inl)) + Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name); + count = l->filelen / sizeof(*inl); + } + else + { + ins = (dsface_t *)(mod_base + l->fileofs); + inl = NULL; + if (l->filelen % sizeof(*ins)) + Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name); + count = l->filelen / sizeof(*ins); + } + out = (msurface_t *)Hunk_AllocName ( count*sizeof(*out), loadname); + + //johnfitz -- warn mappers about exceeding old limits + if (count > 32767 && !bsp2) + Con_DWarning ("%i faces exceeds standard limit of 32767.\n", count); + //johnfitz + + loadmodel->surfaces = out; + loadmodel->numsurfaces = count; + + for (surfnum=0 ; surfnumfirstedge = LittleLong(inl->firstedge); + out->numedges = LittleLong(inl->numedges); + planenum = LittleLong(inl->planenum); + side = LittleLong(inl->side); + texinfon = LittleLong (inl->texinfo); + for (i=0 ; istyles[i] = inl->styles[i]; + lofs = LittleLong(inl->lightofs); + inl++; + } + else + { + out->firstedge = LittleLong(ins->firstedge); + out->numedges = LittleShort(ins->numedges); + planenum = LittleShort(ins->planenum); + side = LittleShort(ins->side); + texinfon = LittleShort (ins->texinfo); + for (i=0 ; istyles[i] = ins->styles[i]; + lofs = LittleLong(ins->lightofs); + ins++; + } + + out->flags = 0; + + if (side) + out->flags |= SURF_PLANEBACK; + + out->plane = loadmodel->planes + planenum; + + out->texinfo = loadmodel->texinfo + texinfon; + + CalcSurfaceExtents (out); + + Mod_CalcSurfaceBounds (out); //johnfitz -- for per-surface frustum culling + + // lighting info + if (lofs == -1) + out->samples = NULL; + else + out->samples = loadmodel->lightdata + (lofs * 3); //johnfitz -- lit support via lordhavoc (was "+ i") + + //johnfitz -- this section rewritten + if (!q_strncasecmp(out->texinfo->texture->name,"sky",3)) // sky surface //also note -- was Q_strncmp, changed to match qbsp + { + out->flags |= (SURF_DRAWSKY | SURF_DRAWTILED); + Mod_PolyForUnlitSurface (out); //no more subdivision + } + else if (out->texinfo->texture->name[0] == '*') // warp surface + { + out->flags |= (SURF_DRAWTURB | SURF_DRAWTILED); + + // detect special liquid types + if (!strncmp (out->texinfo->texture->name, "*lava", 5)) + out->flags |= SURF_DRAWLAVA; + else if (!strncmp (out->texinfo->texture->name, "*slime", 6)) + out->flags |= SURF_DRAWSLIME; + else if (!strncmp (out->texinfo->texture->name, "*tele", 5)) + out->flags |= SURF_DRAWTELE; + else out->flags |= SURF_DRAWWATER; + + Mod_PolyForUnlitSurface (out); + GL_SubdivideSurface (out); + } + else if (out->texinfo->texture->name[0] == '{') // ericw -- fence textures + { + out->flags |= SURF_DRAWFENCE; + } + else if (out->texinfo->flags & TEX_MISSING) // texture is missing from bsp + { + if (out->samples) //lightmapped + { + out->flags |= SURF_NOTEXTURE; + } + else // not lightmapped + { + out->flags |= (SURF_NOTEXTURE | SURF_DRAWTILED); + Mod_PolyForUnlitSurface (out); + } + } + //johnfitz + } +} + + +/* +================= +Mod_SetParent +================= +*/ +void Mod_SetParent (mnode_t *node, mnode_t *parent) +{ + node->parent = parent; + if (node->contents < 0) + return; + Mod_SetParent (node->children[0], node); + Mod_SetParent (node->children[1], node); +} + +/* +================= +Mod_LoadNodes +================= +*/ +void Mod_LoadNodes_S (lump_t *l) +{ + int i, j, count, p; + dsnode_t *in; + mnode_t *out; + + in = (dsnode_t *)(mod_base + l->fileofs); + if (l->filelen % sizeof(*in)) + Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name); + count = l->filelen / sizeof(*in); + out = (mnode_t *) Hunk_AllocName ( count*sizeof(*out), loadname); + + //johnfitz -- warn mappers about exceeding old limits + if (count > 32767) + Con_DWarning ("%i nodes exceeds standard limit of 32767.\n", count); + //johnfitz + + loadmodel->nodes = out; + loadmodel->numnodes = count; + + for (i=0 ; iminmaxs[j] = LittleShort (in->mins[j]); + out->minmaxs[3+j] = LittleShort (in->maxs[j]); + } + + p = LittleLong(in->planenum); + out->plane = loadmodel->planes + p; + + out->firstsurface = (unsigned short)LittleShort (in->firstface); //johnfitz -- explicit cast as unsigned short + out->numsurfaces = (unsigned short)LittleShort (in->numfaces); //johnfitz -- explicit cast as unsigned short + + for (j=0 ; j<2 ; j++) + { + //johnfitz -- hack to handle nodes > 32k, adapted from darkplaces + p = (unsigned short)LittleShort(in->children[j]); + if (p < count) + out->children[j] = loadmodel->nodes + p; + else + { + p = 65535 - p; //note this uses 65535 intentionally, -1 is leaf 0 + if (p < loadmodel->numleafs) + out->children[j] = (mnode_t *)(loadmodel->leafs + p); + else + { + Con_Printf("Mod_LoadNodes: invalid leaf index %i (file has only %i leafs)\n", p, loadmodel->numleafs); + out->children[j] = (mnode_t *)(loadmodel->leafs); //map it to the solid leaf + } + } + //johnfitz + } + } +} + +void Mod_LoadNodes_L1 (lump_t *l) +{ + int i, j, count, p; + dl1node_t *in; + mnode_t *out; + + in = (dl1node_t *)(mod_base + l->fileofs); + if (l->filelen % sizeof(*in)) + Sys_Error ("Mod_LoadNodes: funny lump size in %s",loadmodel->name); + + count = l->filelen / sizeof(*in); + out = (mnode_t *)Hunk_AllocName ( count*sizeof(*out), loadname); + + loadmodel->nodes = out; + loadmodel->numnodes = count; + + for (i=0 ; iminmaxs[j] = LittleShort (in->mins[j]); + out->minmaxs[3+j] = LittleShort (in->maxs[j]); + } + + p = LittleLong(in->planenum); + out->plane = loadmodel->planes + p; + + out->firstsurface = LittleLong (in->firstface); //johnfitz -- explicit cast as unsigned short + out->numsurfaces = LittleLong (in->numfaces); //johnfitz -- explicit cast as unsigned short + + for (j=0 ; j<2 ; j++) + { + //johnfitz -- hack to handle nodes > 32k, adapted from darkplaces + p = LittleLong(in->children[j]); + if (p >= 0 && p < count) + out->children[j] = loadmodel->nodes + p; + else + { + p = 0xffffffff - p; //note this uses 65535 intentionally, -1 is leaf 0 + if (p >= 0 && p < loadmodel->numleafs) + out->children[j] = (mnode_t *)(loadmodel->leafs + p); + else + { + Con_Printf("Mod_LoadNodes: invalid leaf index %i (file has only %i leafs)\n", p, loadmodel->numleafs); + out->children[j] = (mnode_t *)(loadmodel->leafs); //map it to the solid leaf + } + } + //johnfitz + } + } +} + +void Mod_LoadNodes_L2 (lump_t *l) +{ + int i, j, count, p; + dl2node_t *in; + mnode_t *out; + + in = (dl2node_t *)(mod_base + l->fileofs); + if (l->filelen % sizeof(*in)) + Sys_Error ("Mod_LoadNodes: funny lump size in %s",loadmodel->name); + + count = l->filelen / sizeof(*in); + out = (mnode_t *)Hunk_AllocName ( count*sizeof(*out), loadname); + + loadmodel->nodes = out; + loadmodel->numnodes = count; + + for (i=0 ; iminmaxs[j] = LittleFloat (in->mins[j]); + out->minmaxs[3+j] = LittleFloat (in->maxs[j]); + } + + p = LittleLong(in->planenum); + out->plane = loadmodel->planes + p; + + out->firstsurface = LittleLong (in->firstface); //johnfitz -- explicit cast as unsigned short + out->numsurfaces = LittleLong (in->numfaces); //johnfitz -- explicit cast as unsigned short + + for (j=0 ; j<2 ; j++) + { + //johnfitz -- hack to handle nodes > 32k, adapted from darkplaces + p = LittleLong(in->children[j]); + if (p > 0 && p < count) + out->children[j] = loadmodel->nodes + p; + else + { + p = 0xffffffff - p; //note this uses 65535 intentionally, -1 is leaf 0 + if (p >= 0 && p < loadmodel->numleafs) + out->children[j] = (mnode_t *)(loadmodel->leafs + p); + else + { + Con_Printf("Mod_LoadNodes: invalid leaf index %i (file has only %i leafs)\n", p, loadmodel->numleafs); + out->children[j] = (mnode_t *)(loadmodel->leafs); //map it to the solid leaf + } + } + //johnfitz + } + } +} + +void Mod_LoadNodes (lump_t *l, int bsp2) +{ + if (bsp2 == 2) + Mod_LoadNodes_L2(l); + else if (bsp2) + Mod_LoadNodes_L1(l); + else + Mod_LoadNodes_S(l); + + Mod_SetParent (loadmodel->nodes, NULL); // sets nodes and leafs +} + +void Mod_ProcessLeafs_S (dsleaf_t *in, int filelen) +{ + mleaf_t *out; + int i, j, count, p; + + if (filelen % sizeof(*in)) + Sys_Error ("Mod_ProcessLeafs: funny lump size in %s", loadmodel->name); + count = filelen / sizeof(*in); + out = (mleaf_t *) Hunk_AllocName ( count*sizeof(*out), loadname); + + //johnfitz + if (count > 32767) + Host_Error ("Mod_LoadLeafs: %i leafs exceeds limit of 32767.\n", count); + //johnfitz + + loadmodel->leafs = out; + loadmodel->numleafs = count; + + for (i=0 ; iminmaxs[j] = LittleShort (in->mins[j]); + out->minmaxs[3+j] = LittleShort (in->maxs[j]); + } + + p = LittleLong(in->contents); + out->contents = p; + + out->firstmarksurface = loadmodel->marksurfaces + (unsigned short)LittleShort(in->firstmarksurface); //johnfitz -- unsigned short + out->nummarksurfaces = (unsigned short)LittleShort(in->nummarksurfaces); //johnfitz -- unsigned short + + p = LittleLong(in->visofs); + if (p == -1) + out->compressed_vis = NULL; + else + out->compressed_vis = loadmodel->visdata + p; + out->efrags = NULL; + + for (j=0 ; j<4 ; j++) + out->ambient_sound_level[j] = in->ambient_level[j]; + + //johnfitz -- removed code to mark surfaces as SURF_UNDERWATER + } +} + +void Mod_ProcessLeafs_L1 (dl1leaf_t *in, int filelen) +{ + mleaf_t *out; + int i, j, count, p; + + if (filelen % sizeof(*in)) + Sys_Error ("Mod_ProcessLeafs: funny lump size in %s", loadmodel->name); + + count = filelen / sizeof(*in); + + out = (mleaf_t *) Hunk_AllocName (count * sizeof(*out), loadname); + + loadmodel->leafs = out; + loadmodel->numleafs = count; + + for (i=0 ; iminmaxs[j] = LittleShort (in->mins[j]); + out->minmaxs[3+j] = LittleShort (in->maxs[j]); + } + + p = LittleLong(in->contents); + out->contents = p; + + out->firstmarksurface = loadmodel->marksurfaces + LittleLong(in->firstmarksurface); //johnfitz -- unsigned short + out->nummarksurfaces = LittleLong(in->nummarksurfaces); //johnfitz -- unsigned short + + p = LittleLong(in->visofs); + if (p == -1) + out->compressed_vis = NULL; + else + out->compressed_vis = loadmodel->visdata + p; + out->efrags = NULL; + + for (j=0 ; j<4 ; j++) + out->ambient_sound_level[j] = in->ambient_level[j]; + + //johnfitz -- removed code to mark surfaces as SURF_UNDERWATER + } +} + +void Mod_ProcessLeafs_L2 (dl2leaf_t *in, int filelen) +{ + mleaf_t *out; + int i, j, count, p; + + if (filelen % sizeof(*in)) + Sys_Error ("Mod_ProcessLeafs: funny lump size in %s", loadmodel->name); + + count = filelen / sizeof(*in); + + out = (mleaf_t *) Hunk_AllocName (count * sizeof(*out), loadname); + + loadmodel->leafs = out; + loadmodel->numleafs = count; + + for (i=0 ; iminmaxs[j] = LittleFloat (in->mins[j]); + out->minmaxs[3+j] = LittleFloat (in->maxs[j]); + } + + p = LittleLong(in->contents); + out->contents = p; + + out->firstmarksurface = loadmodel->marksurfaces + LittleLong(in->firstmarksurface); //johnfitz -- unsigned short + out->nummarksurfaces = LittleLong(in->nummarksurfaces); //johnfitz -- unsigned short + + p = LittleLong(in->visofs); + if (p == -1) + out->compressed_vis = NULL; + else + out->compressed_vis = loadmodel->visdata + p; + out->efrags = NULL; + + for (j=0 ; j<4 ; j++) + out->ambient_sound_level[j] = in->ambient_level[j]; + + //johnfitz -- removed code to mark surfaces as SURF_UNDERWATER + } +} + +/* +================= +Mod_LoadLeafs +================= +*/ +void Mod_LoadLeafs (lump_t *l, int bsp2) +{ + void *in = (void *)(mod_base + l->fileofs); + + if (bsp2 == 2) + Mod_ProcessLeafs_L2 ((dl2leaf_t *)in, l->filelen); + else if (bsp2) + Mod_ProcessLeafs_L1 ((dl1leaf_t *)in, l->filelen); + else + Mod_ProcessLeafs_S ((dsleaf_t *) in, l->filelen); +} + +/* +================= +Mod_LoadClipnodes +================= +*/ +void Mod_LoadClipnodes (lump_t *l, qboolean bsp2) +{ + dsclipnode_t *ins; + dlclipnode_t *inl; + + mclipnode_t *out; //johnfitz -- was dclipnode_t + int i, count; + hull_t *hull; + + if (bsp2) + { + ins = NULL; + inl = (dlclipnode_t *)(mod_base + l->fileofs); + if (l->filelen % sizeof(*inl)) + Sys_Error ("Mod_LoadClipnodes: funny lump size in %s",loadmodel->name); + + count = l->filelen / sizeof(*inl); + } + else + { + ins = (dsclipnode_t *)(mod_base + l->fileofs); + inl = NULL; + if (l->filelen % sizeof(*ins)) + Sys_Error ("Mod_LoadClipnodes: funny lump size in %s",loadmodel->name); + + count = l->filelen / sizeof(*ins); + } + out = (mclipnode_t *) Hunk_AllocName ( count*sizeof(*out), loadname); + + //johnfitz -- warn about exceeding old limits + if (count > 32767 && !bsp2) + Con_DWarning ("%i clipnodes exceeds standard limit of 32767.\n", count); + //johnfitz + + loadmodel->clipnodes = out; + loadmodel->numclipnodes = count; + + hull = &loadmodel->hulls[1]; + hull->clipnodes = out; + hull->firstclipnode = 0; + hull->lastclipnode = count-1; + hull->planes = loadmodel->planes; + hull->clip_mins[0] = -16; + hull->clip_mins[1] = -16; + hull->clip_mins[2] = -24; + hull->clip_maxs[0] = 16; + hull->clip_maxs[1] = 16; + hull->clip_maxs[2] = 32; + + hull = &loadmodel->hulls[2]; + hull->clipnodes = out; + hull->firstclipnode = 0; + hull->lastclipnode = count-1; + hull->planes = loadmodel->planes; + hull->clip_mins[0] = -32; + hull->clip_mins[1] = -32; + hull->clip_mins[2] = -24; + hull->clip_maxs[0] = 32; + hull->clip_maxs[1] = 32; + hull->clip_maxs[2] = 64; + + if (bsp2) + { + for (i=0 ; iplanenum = LittleLong(inl->planenum); + + //johnfitz -- bounds check + if (out->planenum < 0 || out->planenum >= loadmodel->numplanes) + Host_Error ("Mod_LoadClipnodes: planenum out of bounds"); + //johnfitz + + out->children[0] = LittleLong(inl->children[0]); + out->children[1] = LittleLong(inl->children[1]); + //Spike: FIXME: bounds check + } + } + else + { + for (i=0 ; iplanenum = LittleLong(ins->planenum); + + //johnfitz -- bounds check + if (out->planenum < 0 || out->planenum >= loadmodel->numplanes) + Host_Error ("Mod_LoadClipnodes: planenum out of bounds"); + //johnfitz + + //johnfitz -- support clipnodes > 32k + out->children[0] = (unsigned short)LittleShort(ins->children[0]); + out->children[1] = (unsigned short)LittleShort(ins->children[1]); + + if (out->children[0] >= count) + out->children[0] -= 65536; + if (out->children[1] >= count) + out->children[1] -= 65536; + //johnfitz + } + } +} + +/* +================= +Mod_MakeHull0 + +Duplicate the drawing hull structure as a clipping hull +================= +*/ +void Mod_MakeHull0 (void) +{ + mnode_t *in, *child; + mclipnode_t *out; //johnfitz -- was dclipnode_t + int i, j, count; + hull_t *hull; + + hull = &loadmodel->hulls[0]; + + in = loadmodel->nodes; + count = loadmodel->numnodes; + out = (mclipnode_t *) Hunk_AllocName ( count*sizeof(*out), loadname); + + hull->clipnodes = out; + hull->firstclipnode = 0; + hull->lastclipnode = count-1; + hull->planes = loadmodel->planes; + + for (i=0 ; iplanenum = in->plane - loadmodel->planes; + for (j=0 ; j<2 ; j++) + { + child = in->children[j]; + if (child->contents < 0) + out->children[j] = child->contents; + else + out->children[j] = child - loadmodel->nodes; + } + } +} + +/* +================= +Mod_LoadMarksurfaces +================= +*/ +void Mod_LoadMarksurfaces (lump_t *l, int bsp2) +{ + int i, j, count; + msurface_t **out; + if (bsp2) + { + unsigned int *in = (unsigned int *)(mod_base + l->fileofs); + + if (l->filelen % sizeof(*in)) + Host_Error ("Mod_LoadMarksurfaces: funny lump size in %s",loadmodel->name); + + count = l->filelen / sizeof(*in); + out = (msurface_t **)Hunk_AllocName ( count*sizeof(*out), loadname); + + loadmodel->marksurfaces = out; + loadmodel->nummarksurfaces = count; + + for (i=0 ; i= loadmodel->numsurfaces) + Host_Error ("Mod_LoadMarksurfaces: bad surface number"); + out[i] = loadmodel->surfaces + j; + } + } + else + { + short *in = (short *)(mod_base + l->fileofs); + + if (l->filelen % sizeof(*in)) + Host_Error ("Mod_LoadMarksurfaces: funny lump size in %s",loadmodel->name); + + count = l->filelen / sizeof(*in); + out = (msurface_t **)Hunk_AllocName ( count*sizeof(*out), loadname); + + loadmodel->marksurfaces = out; + loadmodel->nummarksurfaces = count; + + //johnfitz -- warn mappers about exceeding old limits + if (count > 32767) + Con_DWarning ("%i marksurfaces exceeds standard limit of 32767.\n", count); + //johnfitz + + for (i=0 ; i= loadmodel->numsurfaces) + Sys_Error ("Mod_LoadMarksurfaces: bad surface number"); + out[i] = loadmodel->surfaces + j; + } + } +} + +/* +================= +Mod_LoadSurfedges +================= +*/ +void Mod_LoadSurfedges (lump_t *l) +{ + int i, count; + int *in, *out; + + in = (int *)(mod_base + l->fileofs); + if (l->filelen % sizeof(*in)) + Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name); + count = l->filelen / sizeof(*in); + out = (int *) Hunk_AllocName ( count*sizeof(*out), loadname); + + loadmodel->surfedges = out; + loadmodel->numsurfedges = count; + + for (i=0 ; ifileofs); + if (l->filelen % sizeof(*in)) + Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name); + count = l->filelen / sizeof(*in); + out = (mplane_t *) Hunk_AllocName ( count*2*sizeof(*out), loadname); + + loadmodel->planes = out; + loadmodel->numplanes = count; + + for (i=0 ; inormal[j] = LittleFloat (in->normal[j]); + if (out->normal[j] < 0) + bits |= 1<dist = LittleFloat (in->dist); + out->type = LittleLong (in->type); + out->signbits = bits; + } +} + +/* +================= +RadiusFromBounds +================= +*/ +float RadiusFromBounds (vec3_t mins, vec3_t maxs) +{ + int i; + vec3_t corner; + + for (i=0 ; i<3 ; i++) + { + corner[i] = fabs(mins[i]) > fabs(maxs[i]) ? fabs(mins[i]) : fabs(maxs[i]); + } + + return VectorLength (corner); +} + +/* +================= +Mod_LoadSubmodels +================= +*/ +void Mod_LoadSubmodels (lump_t *l) +{ + dmodel_t *in; + dmodel_t *out; + int i, j, count; + + in = (dmodel_t *)(mod_base + l->fileofs); + if (l->filelen % sizeof(*in)) + Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name); + count = l->filelen / sizeof(*in); + out = (dmodel_t *) Hunk_AllocName ( count*sizeof(*out), loadname); + + loadmodel->submodels = out; + loadmodel->numsubmodels = count; + + for (i=0 ; imins[j] = LittleFloat (in->mins[j]) - 1; + out->maxs[j] = LittleFloat (in->maxs[j]) + 1; + out->origin[j] = LittleFloat (in->origin[j]); + } + for (j=0 ; jheadnode[j] = LittleLong (in->headnode[j]); + out->visleafs = LittleLong (in->visleafs); + out->firstface = LittleLong (in->firstface); + out->numfaces = LittleLong (in->numfaces); + } + + // johnfitz -- check world visleafs -- adapted from bjp + out = loadmodel->submodels; + + if (out->visleafs > 8192) + Con_DWarning ("%i visleafs exceeds standard limit of 8192.\n", out->visleafs); + //johnfitz +} + +/* +================= +Mod_BoundsFromClipNode -- johnfitz + +update the model's clipmins and clipmaxs based on each node's plane. + +This works because of the way brushes are expanded in hull generation. +Each brush will include all six axial planes, which bound that brush. +Therefore, the bounding box of the hull can be constructed entirely +from axial planes found in the clipnodes for that hull. +================= +*/ +void Mod_BoundsFromClipNode (qmodel_t *mod, int hull, int nodenum) +{ + mplane_t *plane; + mclipnode_t *node; + + if (nodenum < 0) + return; //hit a leafnode + + node = &mod->clipnodes[nodenum]; + plane = mod->hulls[hull].planes + node->planenum; + switch (plane->type) + { + + case PLANE_X: + if (plane->signbits == 1) + mod->clipmins[0] = q_min(mod->clipmins[0], -plane->dist - mod->hulls[hull].clip_mins[0]); + else + mod->clipmaxs[0] = q_max(mod->clipmaxs[0], plane->dist - mod->hulls[hull].clip_maxs[0]); + break; + case PLANE_Y: + if (plane->signbits == 2) + mod->clipmins[1] = q_min(mod->clipmins[1], -plane->dist - mod->hulls[hull].clip_mins[1]); + else + mod->clipmaxs[1] = q_max(mod->clipmaxs[1], plane->dist - mod->hulls[hull].clip_maxs[1]); + break; + case PLANE_Z: + if (plane->signbits == 4) + mod->clipmins[2] = q_min(mod->clipmins[2], -plane->dist - mod->hulls[hull].clip_mins[2]); + else + mod->clipmaxs[2] = q_max(mod->clipmaxs[2], plane->dist - mod->hulls[hull].clip_maxs[2]); + break; + default: + //skip nonaxial planes; don't need them + break; + } + + Mod_BoundsFromClipNode (mod, hull, node->children[0]); + Mod_BoundsFromClipNode (mod, hull, node->children[1]); +} + +/* +================= +Mod_LoadBrushModel +================= +*/ +void Mod_LoadBrushModel (qmodel_t *mod, void *buffer) +{ + int i, j; + int bsp2; + dheader_t *header; + dmodel_t *bm; + float radius; //johnfitz + + loadmodel->type = mod_brush; + + header = (dheader_t *)buffer; + + mod->bspversion = LittleLong (header->version); + + switch(mod->bspversion) + { + case BSPVERSION: + bsp2 = false; + break; + case BSP2VERSION_2PSB: + bsp2 = 1; //first iteration + break; + case BSP2VERSION_BSP2: + bsp2 = 2; //sanitised revision + break; + default: + Sys_Error ("Mod_LoadBrushModel: %s has wrong version number (%i should be %i)", mod->name, mod->bspversion, BSPVERSION); + break; + } + +// swap all the lumps + mod_base = (byte *)header; + + for (i = 0; i < (int) sizeof(dheader_t) / 4; i++) + ((int *)header)[i] = LittleLong ( ((int *)header)[i]); + +// load into heap + + Mod_LoadVertexes (&header->lumps[LUMP_VERTEXES]); + Mod_LoadEdges (&header->lumps[LUMP_EDGES], bsp2); + Mod_LoadSurfedges (&header->lumps[LUMP_SURFEDGES]); + Mod_LoadTextures (&header->lumps[LUMP_TEXTURES]); + Mod_LoadLighting (&header->lumps[LUMP_LIGHTING]); + Mod_LoadPlanes (&header->lumps[LUMP_PLANES]); + Mod_LoadTexinfo (&header->lumps[LUMP_TEXINFO]); + Mod_LoadFaces (&header->lumps[LUMP_FACES], bsp2); + Mod_LoadMarksurfaces (&header->lumps[LUMP_MARKSURFACES], bsp2); + Mod_LoadVisibility (&header->lumps[LUMP_VISIBILITY]); + Mod_LoadLeafs (&header->lumps[LUMP_LEAFS], bsp2); + Mod_LoadNodes (&header->lumps[LUMP_NODES], bsp2); + Mod_LoadClipnodes (&header->lumps[LUMP_CLIPNODES], bsp2); + Mod_LoadEntities (&header->lumps[LUMP_ENTITIES]); + Mod_LoadSubmodels (&header->lumps[LUMP_MODELS]); + + Mod_MakeHull0 (); + + mod->numframes = 2; // regular and alternate animation + +// +// set up the submodels (FIXME: this is confusing) +// + + // johnfitz -- okay, so that i stop getting confused every time i look at this loop, here's how it works: + // we're looping through the submodels starting at 0. Submodel 0 is the main model, so we don't have to + // worry about clobbering data the first time through, since it's the same data. At the end of the loop, + // we create a new copy of the data to use the next time through. + for (i=0 ; inumsubmodels ; i++) + { + bm = &mod->submodels[i]; + + mod->hulls[0].firstclipnode = bm->headnode[0]; + for (j=1 ; jhulls[j].firstclipnode = bm->headnode[j]; + mod->hulls[j].lastclipnode = mod->numclipnodes-1; + } + + mod->firstmodelsurface = bm->firstface; + mod->nummodelsurfaces = bm->numfaces; + + VectorCopy (bm->maxs, mod->maxs); + VectorCopy (bm->mins, mod->mins); + + //johnfitz -- calculate rotate bounds and yaw bounds + radius = RadiusFromBounds (mod->mins, mod->maxs); + mod->rmaxs[0] = mod->rmaxs[1] = mod->rmaxs[2] = mod->ymaxs[0] = mod->ymaxs[1] = mod->ymaxs[2] = radius; + mod->rmins[0] = mod->rmins[1] = mod->rmins[2] = mod->ymins[0] = mod->ymins[1] = mod->ymins[2] = -radius; + //johnfitz + + //johnfitz -- correct physics cullboxes so that outlying clip brushes on doors and stuff are handled right + if (i > 0 || strcmp(mod->name, sv.modelname) != 0) //skip submodel 0 of sv.worldmodel, which is the actual world + { + // start with the hull0 bounds + VectorCopy (mod->maxs, mod->clipmaxs); + VectorCopy (mod->mins, mod->clipmins); + + // process hull1 (we don't need to process hull2 becuase there's + // no such thing as a brush that appears in hull2 but not hull1) + //Mod_BoundsFromClipNode (mod, 1, mod->hulls[1].firstclipnode); // (disabled for now becuase it fucks up on rotating models) + } + //johnfitz + + mod->numleafs = bm->visleafs; + + if (i < mod->numsubmodels-1) + { // duplicate the basic information + char name[10]; + + sprintf (name, "*%i", i+1); + loadmodel = Mod_FindName (name); + *loadmodel = *mod; + strcpy (loadmodel->name, name); + mod = loadmodel; + } + } +} + +/* +============================================================================== + +ALIAS MODELS + +============================================================================== +*/ + +aliashdr_t *pheader; + +stvert_t stverts[MAXALIASVERTS]; +mtriangle_t triangles[MAXALIASTRIS]; + +// a pose is a single set of vertexes. a frame may be +// an animating sequence of poses +trivertx_t *poseverts[MAXALIASFRAMES]; +int posenum; + +byte **player_8bit_texels_tbl; +byte *player_8bit_texels; + +/* +================= +Mod_LoadAliasFrame +================= +*/ +void * Mod_LoadAliasFrame (void * pin, maliasframedesc_t *frame) +{ + trivertx_t *pinframe; + int i; + daliasframe_t *pdaliasframe; + + pdaliasframe = (daliasframe_t *)pin; + + strcpy (frame->name, pdaliasframe->name); + frame->firstpose = posenum; + frame->numposes = 1; + + for (i=0 ; i<3 ; i++) + { + // these are byte values, so we don't have to worry about + // endianness + frame->bboxmin.v[i] = pdaliasframe->bboxmin.v[i]; + frame->bboxmax.v[i] = pdaliasframe->bboxmax.v[i]; + } + + + pinframe = (trivertx_t *)(pdaliasframe + 1); + + poseverts[posenum] = pinframe; + posenum++; + + pinframe += pheader->numverts; + + return (void *)pinframe; +} + + +/* +================= +Mod_LoadAliasGroup +================= +*/ +void *Mod_LoadAliasGroup (void * pin, maliasframedesc_t *frame) +{ + daliasgroup_t *pingroup; + int i, numframes; + daliasinterval_t *pin_intervals; + void *ptemp; + + pingroup = (daliasgroup_t *)pin; + + numframes = LittleLong (pingroup->numframes); + + frame->firstpose = posenum; + frame->numposes = numframes; + + for (i=0 ; i<3 ; i++) + { + // these are byte values, so we don't have to worry about endianness + frame->bboxmin.v[i] = pingroup->bboxmin.v[i]; + frame->bboxmax.v[i] = pingroup->bboxmax.v[i]; + } + + + pin_intervals = (daliasinterval_t *)(pingroup + 1); + + frame->interval = LittleFloat (pin_intervals->interval); + + pin_intervals += numframes; + + ptemp = (void *)pin_intervals; + + for (i=0 ; inumverts; + } + + return ptemp; +} + +//========================================================= + + +/* +================= +Mod_FloodFillSkin + +Fill background pixels so mipmapping doesn't have haloes - Ed +================= +*/ + +typedef struct +{ + short x, y; +} floodfill_t; + +// must be a power of 2 +#define FLOODFILL_FIFO_SIZE 0x1000 +#define FLOODFILL_FIFO_MASK (FLOODFILL_FIFO_SIZE - 1) + +#define FLOODFILL_STEP( off, dx, dy ) \ +do { \ + if (pos[off] == fillcolor) \ + { \ + pos[off] = 255; \ + fifo[inpt].x = x + (dx), fifo[inpt].y = y + (dy); \ + inpt = (inpt + 1) & FLOODFILL_FIFO_MASK; \ + } \ + else if (pos[off] != 255) fdc = pos[off]; \ +} while (0) + +void Mod_FloodFillSkin( byte *skin, int skinwidth, int skinheight ) +{ + byte fillcolor = *skin; // assume this is the pixel to fill + floodfill_t fifo[FLOODFILL_FIFO_SIZE]; + int inpt = 0, outpt = 0; + int filledcolor = -1; + int i; + + if (filledcolor == -1) + { + filledcolor = 0; + // attempt to find opaque black + for (i = 0; i < 256; ++i) + if (d_8to24table[i] == (255 << 0)) // alpha 1.0 + { + filledcolor = i; + break; + } + } + + // can't fill to filled color or to transparent color (used as visited marker) + if ((fillcolor == filledcolor) || (fillcolor == 255)) + { + //printf( "not filling skin from %d to %d\n", fillcolor, filledcolor ); + return; + } + + fifo[inpt].x = 0, fifo[inpt].y = 0; + inpt = (inpt + 1) & FLOODFILL_FIFO_MASK; + + while (outpt != inpt) + { + int x = fifo[outpt].x, y = fifo[outpt].y; + int fdc = filledcolor; + byte *pos = &skin[x + skinwidth * y]; + + outpt = (outpt + 1) & FLOODFILL_FIFO_MASK; + + if (x > 0) FLOODFILL_STEP( -1, -1, 0 ); + if (x < skinwidth - 1) FLOODFILL_STEP( 1, 1, 0 ); + if (y > 0) FLOODFILL_STEP( -skinwidth, 0, -1 ); + if (y < skinheight - 1) FLOODFILL_STEP( skinwidth, 0, 1 ); + skin[x + skinwidth * y] = fdc; + } +} + +/* +=============== +Mod_LoadAllSkins +=============== +*/ +void *Mod_LoadAllSkins (int numskins, daliasskintype_t *pskintype) +{ + int i, j, k, size, groupskins; + char name[MAX_QPATH]; + byte *skin, *texels; + daliasskingroup_t *pinskingroup; + daliasskininterval_t *pinskinintervals; + char fbr_mask_name[MAX_QPATH]; //johnfitz -- added for fullbright support + src_offset_t offset; //johnfitz + unsigned int texflags = TEXPREF_PAD; + + skin = (byte *)(pskintype + 1); + + if (numskins < 1 || numskins > MAX_SKINS) + Sys_Error ("Mod_LoadAliasModel: Invalid # of skins: %d\n", numskins); + + size = pheader->skinwidth * pheader->skinheight; + + if (loadmodel->flags & MF_HOLEY) + texflags |= TEXPREF_ALPHA; + + for (i=0 ; itype == ALIAS_SKIN_SINGLE) + { + Mod_FloodFillSkin( skin, pheader->skinwidth, pheader->skinheight ); + + // save 8 bit texels for the player model to remap + texels = (byte *) Hunk_AllocName(size, loadname); + pheader->texels[i] = texels - (byte *)pheader; + memcpy (texels, (byte *)(pskintype + 1), size); + + //johnfitz -- rewritten + q_snprintf (name, sizeof(name), "%s:frame%i", loadmodel->name, i); + offset = (src_offset_t)(pskintype+1) - (src_offset_t)mod_base; + if (Mod_CheckFullbrights ((byte *)(pskintype+1), size)) + { + pheader->gltextures[i][0] = TexMgr_LoadImage (loadmodel, name, pheader->skinwidth, pheader->skinheight, + SRC_INDEXED, (byte *)(pskintype+1), loadmodel->name, offset, texflags | TEXPREF_NOBRIGHT); + q_snprintf (fbr_mask_name, sizeof(fbr_mask_name), "%s:frame%i_glow", loadmodel->name, i); + pheader->fbtextures[i][0] = TexMgr_LoadImage (loadmodel, fbr_mask_name, pheader->skinwidth, pheader->skinheight, + SRC_INDEXED, (byte *)(pskintype+1), loadmodel->name, offset, texflags | TEXPREF_FULLBRIGHT); + } + else + { + pheader->gltextures[i][0] = TexMgr_LoadImage (loadmodel, name, pheader->skinwidth, pheader->skinheight, + SRC_INDEXED, (byte *)(pskintype+1), loadmodel->name, offset, texflags); + pheader->fbtextures[i][0] = NULL; + } + + pheader->gltextures[i][3] = pheader->gltextures[i][2] = pheader->gltextures[i][1] = pheader->gltextures[i][0]; + pheader->fbtextures[i][3] = pheader->fbtextures[i][2] = pheader->fbtextures[i][1] = pheader->fbtextures[i][0]; + //johnfitz + + pskintype = (daliasskintype_t *)((byte *)(pskintype+1) + size); + } + else + { + // animating skin group. yuck. + pskintype++; + pinskingroup = (daliasskingroup_t *)pskintype; + groupskins = LittleLong (pinskingroup->numskins); + pinskinintervals = (daliasskininterval_t *)(pinskingroup + 1); + + pskintype = (daliasskintype_t *)(pinskinintervals + groupskins); + + for (j=0 ; jskinwidth, pheader->skinheight ); + if (j == 0) { + texels = (byte *) Hunk_AllocName(size, loadname); + pheader->texels[i] = texels - (byte *)pheader; + memcpy (texels, (byte *)(pskintype), size); + } + + //johnfitz -- rewritten + q_snprintf (name, sizeof(name), "%s:frame%i_%i", loadmodel->name, i,j); + offset = (src_offset_t)(pskintype) - (src_offset_t)mod_base; //johnfitz + if (Mod_CheckFullbrights ((byte *)(pskintype), size)) + { + pheader->gltextures[i][j&3] = TexMgr_LoadImage (loadmodel, name, pheader->skinwidth, pheader->skinheight, + SRC_INDEXED, (byte *)(pskintype), loadmodel->name, offset, texflags | TEXPREF_NOBRIGHT); + q_snprintf (fbr_mask_name, sizeof(fbr_mask_name), "%s:frame%i_%i_glow", loadmodel->name, i,j); + pheader->fbtextures[i][j&3] = TexMgr_LoadImage (loadmodel, fbr_mask_name, pheader->skinwidth, pheader->skinheight, + SRC_INDEXED, (byte *)(pskintype), loadmodel->name, offset, texflags | TEXPREF_FULLBRIGHT); + } + else + { + pheader->gltextures[i][j&3] = TexMgr_LoadImage (loadmodel, name, pheader->skinwidth, pheader->skinheight, + SRC_INDEXED, (byte *)(pskintype), loadmodel->name, offset, texflags); + pheader->fbtextures[i][j&3] = NULL; + } + //johnfitz + + pskintype = (daliasskintype_t *)((byte *)(pskintype) + size); + } + k = j; + for (/**/; j < 4; j++) + pheader->gltextures[i][j&3] = pheader->gltextures[i][j - k]; + } + } + + return (void *)pskintype; +} + +//========================================================================= + +/* +================= +Mod_CalcAliasBounds -- johnfitz -- calculate bounds of alias model for nonrotated, yawrotated, and fullrotated cases +================= +*/ +void Mod_CalcAliasBounds (aliashdr_t *a) +{ + int i,j,k; + float dist, yawradius, radius; + vec3_t v; + + //clear out all data + for (i=0; i<3;i++) + { + loadmodel->mins[i] = loadmodel->ymins[i] = loadmodel->rmins[i] = 999999; + loadmodel->maxs[i] = loadmodel->ymaxs[i] = loadmodel->rmaxs[i] = -999999; + radius = yawradius = 0; + } + + //process verts + for (i=0 ; inumposes; i++) + for (j=0; jnumverts; j++) + { + for (k=0; k<3;k++) + v[k] = poseverts[i][j].v[k] * pheader->scale[k] + pheader->scale_origin[k]; + + for (k=0; k<3;k++) + { + loadmodel->mins[k] = q_min(loadmodel->mins[k], v[k]); + loadmodel->maxs[k] = q_max(loadmodel->maxs[k], v[k]); + } + dist = v[0] * v[0] + v[1] * v[1]; + if (yawradius < dist) + yawradius = dist; + dist += v[2] * v[2]; + if (radius < dist) + radius = dist; + } + + //rbounds will be used when entity has nonzero pitch or roll + radius = sqrt(radius); + loadmodel->rmins[0] = loadmodel->rmins[1] = loadmodel->rmins[2] = -radius; + loadmodel->rmaxs[0] = loadmodel->rmaxs[1] = loadmodel->rmaxs[2] = radius; + + //ybounds will be used when entity has nonzero yaw + yawradius = sqrt(yawradius); + loadmodel->ymins[0] = loadmodel->ymins[1] = -yawradius; + loadmodel->ymaxs[0] = loadmodel->ymaxs[1] = yawradius; + loadmodel->ymins[2] = loadmodel->mins[2]; + loadmodel->ymaxs[2] = loadmodel->maxs[2]; +} + +static qboolean +nameInList(const char *list, const char *name) +{ + const char *s; + char tmp[MAX_QPATH]; + int i; + + s = list; + + while (*s) + { + // make a copy until the next comma or end of string + i = 0; + while (*s && *s != ',') + { + if (i < MAX_QPATH - 1) + tmp[i++] = *s; + s++; + } + tmp[i] = '\0'; + //compare it to the model name + if (!strcmp(name, tmp)) + { + return true; + } + //search forwards to the next comma or end of string + while (*s && *s == ',') + s++; + } + return false; +} + +/* +================= +Mod_SetExtraFlags -- johnfitz -- set up extra flags that aren't in the mdl +================= +*/ +void Mod_SetExtraFlags (qmodel_t *mod) +{ + extern cvar_t r_nolerp_list, r_noshadow_list; + + if (!mod || mod->type != mod_alias) + return; + + mod->flags &= (0xFF | MF_HOLEY); //only preserve first byte, plus MF_HOLEY + + // nolerp flag + if (nameInList(r_nolerp_list.string, mod->name)) + mod->flags |= MOD_NOLERP; + + // noshadow flag + if (nameInList(r_noshadow_list.string, mod->name)) + mod->flags |= MOD_NOSHADOW; + + // fullbright hack (TODO: make this a cvar list) + if (!strcmp (mod->name, "progs/flame2.mdl") || + !strcmp (mod->name, "progs/flame.mdl") || + !strcmp (mod->name, "progs/boss.mdl")) + mod->flags |= MOD_FBRIGHTHACK; +} + +/* +================= +Mod_LoadAliasModel +================= +*/ +void Mod_LoadAliasModel (qmodel_t *mod, void *buffer) +{ + int i, j; + mdl_t *pinmodel; + stvert_t *pinstverts; + dtriangle_t *pintriangles; + int version, numframes; + int size; + daliasframetype_t *pframetype; + daliasskintype_t *pskintype; + int start, end, total; + + start = Hunk_LowMark (); + + pinmodel = (mdl_t *)buffer; + mod_base = (byte *)buffer; //johnfitz + + version = LittleLong (pinmodel->version); + if (version != ALIAS_VERSION) + Sys_Error ("%s has wrong version number (%i should be %i)", + mod->name, version, ALIAS_VERSION); + +// +// allocate space for a working header, plus all the data except the frames, +// skin and group info +// + size = sizeof(aliashdr_t) + + (LittleLong (pinmodel->numframes) - 1) * sizeof (pheader->frames[0]); + pheader = (aliashdr_t *) Hunk_AllocName (size, loadname); + + mod->flags = LittleLong (pinmodel->flags); + +// +// endian-adjust and copy the data, starting with the alias model header +// + pheader->boundingradius = LittleFloat (pinmodel->boundingradius); + pheader->numskins = LittleLong (pinmodel->numskins); + pheader->skinwidth = LittleLong (pinmodel->skinwidth); + pheader->skinheight = LittleLong (pinmodel->skinheight); + + if (pheader->skinheight > MAX_LBM_HEIGHT) + Sys_Error ("model %s has a skin taller than %d", mod->name, + MAX_LBM_HEIGHT); + + pheader->numverts = LittleLong (pinmodel->numverts); + + if (pheader->numverts <= 0) + Sys_Error ("model %s has no vertices", mod->name); + + if (pheader->numverts > MAXALIASVERTS) + Sys_Error ("model %s has too many vertices (%d; max = %d)", mod->name, pheader->numverts, MAXALIASVERTS); + + pheader->numtris = LittleLong (pinmodel->numtris); + + if (pheader->numtris <= 0) + Sys_Error ("model %s has no triangles", mod->name); + + if (pheader->numtris > MAXALIASTRIS) + Sys_Error ("model %s has too many triangles (%d; max = %d)", mod->name, pheader->numtris, MAXALIASTRIS); + + pheader->numframes = LittleLong (pinmodel->numframes); + numframes = pheader->numframes; + if (numframes < 1) + Sys_Error ("Mod_LoadAliasModel: Invalid # of frames: %d\n", numframes); + + pheader->size = LittleFloat (pinmodel->size) * ALIAS_BASE_SIZE_RATIO; + mod->synctype = (synctype_t) LittleLong (pinmodel->synctype); + mod->numframes = pheader->numframes; + + for (i=0 ; i<3 ; i++) + { + pheader->scale[i] = LittleFloat (pinmodel->scale[i]); + pheader->scale_origin[i] = LittleFloat (pinmodel->scale_origin[i]); + pheader->eyeposition[i] = LittleFloat (pinmodel->eyeposition[i]); + } + + +// +// load the skins +// + pskintype = (daliasskintype_t *)&pinmodel[1]; + pskintype = (daliasskintype_t *) Mod_LoadAllSkins (pheader->numskins, pskintype); + +// +// load base s and t vertices +// + pinstverts = (stvert_t *)pskintype; + + for (i=0 ; inumverts ; i++) + { + stverts[i].onseam = LittleLong (pinstverts[i].onseam); + stverts[i].s = LittleLong (pinstverts[i].s); + stverts[i].t = LittleLong (pinstverts[i].t); + } + +// +// load triangle lists +// + pintriangles = (dtriangle_t *)&pinstverts[pheader->numverts]; + + for (i=0 ; inumtris ; i++) + { + triangles[i].facesfront = LittleLong (pintriangles[i].facesfront); + + for (j=0 ; j<3 ; j++) + { + triangles[i].vertindex[j] = + LittleLong (pintriangles[i].vertindex[j]); + } + } + +// +// load the frames +// + posenum = 0; + pframetype = (daliasframetype_t *)&pintriangles[pheader->numtris]; + + for (i=0 ; itype); + if (frametype == ALIAS_SINGLE) + pframetype = (daliasframetype_t *) Mod_LoadAliasFrame (pframetype + 1, &pheader->frames[i]); + else + pframetype = (daliasframetype_t *) Mod_LoadAliasGroup (pframetype + 1, &pheader->frames[i]); + } + + pheader->numposes = posenum; + + mod->type = mod_alias; + + Mod_SetExtraFlags (mod); //johnfitz + + Mod_CalcAliasBounds (pheader); //johnfitz + + // + // build the draw lists + // + GL_MakeAliasModelDisplayLists (mod, pheader); + + UQ_GL_UploadAliasModel(mod->name, pheader, poseverts, triangles, stverts); + +// +// move the complete, relocatable alias model to the cache +// + end = Hunk_LowMark (); + total = end - start; + + Cache_Alloc (&mod->cache, total, loadname); + if (!mod->cache.data) + return; + memcpy (mod->cache.data, pheader, total); + + Hunk_FreeToLowMark (start); +} + +//============================================================================= + +/* +================= +Mod_LoadSpriteFrame +================= +*/ +void * Mod_LoadSpriteFrame (void * pin, mspriteframe_t **ppframe, int framenum) +{ + dspriteframe_t *pinframe; + mspriteframe_t *pspriteframe; + int width, height, size, origin[2]; + char name[64]; + src_offset_t offset; //johnfitz + + pinframe = (dspriteframe_t *)pin; + + width = LittleLong (pinframe->width); + height = LittleLong (pinframe->height); + size = width * height; + + pspriteframe = (mspriteframe_t *) Hunk_AllocName (sizeof (mspriteframe_t),loadname); + *ppframe = pspriteframe; + + pspriteframe->width = width; + pspriteframe->height = height; + origin[0] = LittleLong (pinframe->origin[0]); + origin[1] = LittleLong (pinframe->origin[1]); + + pspriteframe->up = origin[1]; + pspriteframe->down = origin[1] - height; + pspriteframe->left = origin[0]; + pspriteframe->right = width + origin[0]; + + //johnfitz -- image might be padded + pspriteframe->smax = (float)width/(float)TexMgr_PadConditional(width); + pspriteframe->tmax = (float)height/(float)TexMgr_PadConditional(height); + //johnfitz + + q_snprintf (name, sizeof(name), "%s:frame%i", loadmodel->name, framenum); + offset = (src_offset_t)(pinframe+1) - (src_offset_t)mod_base; //johnfitz + pspriteframe->gltexture = + TexMgr_LoadImage (loadmodel, name, width, height, SRC_INDEXED, + (byte *)(pinframe + 1), loadmodel->name, offset, + TEXPREF_PAD | TEXPREF_ALPHA | TEXPREF_NOPICMIP); //johnfitz -- TexMgr + + return (void *)((byte *)pinframe + sizeof (dspriteframe_t) + size); +} + + +/* +================= +Mod_LoadSpriteGroup +================= +*/ +void * Mod_LoadSpriteGroup (void * pin, mspriteframe_t **ppframe, int framenum) +{ + dspritegroup_t *pingroup; + mspritegroup_t *pspritegroup; + int i, numframes; + dspriteinterval_t *pin_intervals; + float *poutintervals; + void *ptemp; + + pingroup = (dspritegroup_t *)pin; + + numframes = LittleLong (pingroup->numframes); + + pspritegroup = (mspritegroup_t *) Hunk_AllocName (sizeof (mspritegroup_t) + + (numframes - 1) * sizeof (pspritegroup->frames[0]), loadname); + + pspritegroup->numframes = numframes; + + *ppframe = (mspriteframe_t *)pspritegroup; + + pin_intervals = (dspriteinterval_t *)(pingroup + 1); + + poutintervals = (float *) Hunk_AllocName (numframes * sizeof (float), loadname); + + pspritegroup->intervals = poutintervals; + + for (i=0 ; iinterval); + if (*poutintervals <= 0.0) + Sys_Error ("Mod_LoadSpriteGroup: interval<=0"); + + poutintervals++; + pin_intervals++; + } + + ptemp = (void *)pin_intervals; + + for (i=0 ; iframes[i], framenum * 100 + i); + } + + return ptemp; +} + + +/* +================= +Mod_LoadSpriteModel +================= +*/ +void Mod_LoadSpriteModel (qmodel_t *mod, void *buffer) +{ + int i; + int version; + dsprite_t *pin; + msprite_t *psprite; + int numframes; + int size; + dspriteframetype_t *pframetype; + + pin = (dsprite_t *)buffer; + mod_base = (byte *)buffer; //johnfitz + + version = LittleLong (pin->version); + if (version != SPRITE_VERSION) + Sys_Error ("%s has wrong version number " + "(%i should be %i)", mod->name, version, SPRITE_VERSION); + + numframes = LittleLong (pin->numframes); + + size = sizeof (msprite_t) + (numframes - 1) * sizeof (psprite->frames); + + psprite = (msprite_t *) Hunk_AllocName (size, loadname); + + mod->cache.data = psprite; + + psprite->type = LittleLong (pin->type); + psprite->maxwidth = LittleLong (pin->width); + psprite->maxheight = LittleLong (pin->height); + psprite->beamlength = LittleFloat (pin->beamlength); + mod->synctype = (synctype_t) LittleLong (pin->synctype); + psprite->numframes = numframes; + + mod->mins[0] = mod->mins[1] = -psprite->maxwidth/2; + mod->maxs[0] = mod->maxs[1] = psprite->maxwidth/2; + mod->mins[2] = -psprite->maxheight/2; + mod->maxs[2] = psprite->maxheight/2; + +// +// load the frames +// + if (numframes < 1) + Sys_Error ("Mod_LoadSpriteModel: Invalid # of frames: %d\n", numframes); + + mod->numframes = numframes; + + pframetype = (dspriteframetype_t *)(pin + 1); + + for (i=0 ; itype); + psprite->frames[i].type = frametype; + + if (frametype == SPR_SINGLE) + { + pframetype = (dspriteframetype_t *) + Mod_LoadSpriteFrame (pframetype + 1, &psprite->frames[i].frameptr, i); + } + else + { + pframetype = (dspriteframetype_t *) + Mod_LoadSpriteGroup (pframetype + 1, &psprite->frames[i].frameptr, i); + } + } + + mod->type = mod_sprite; +} + +//============================================================================= + +/* +================ +Mod_Print +================ +*/ +void Mod_Print (void) +{ + int i; + qmodel_t *mod; + + Con_SafePrintf ("Cached models:\n"); //johnfitz -- safeprint instead of print + for (i=0, mod=mod_known ; i < mod_numknown ; i++, mod++) + { + Con_SafePrintf ("%8p : %s\n", mod->cache.data, mod->name); //johnfitz -- safeprint instead of print + } + Con_Printf ("%i models\n",mod_numknown); //johnfitz -- print the total too +} + diff --git a/engine/code/gl_model.h b/engine/Quake/gl_model.h similarity index 63% rename from engine/code/gl_model.h rename to engine/Quake/gl_model.h index aca5fab..81f8b9b 100644 --- a/engine/code/gl_model.h +++ b/engine/Quake/gl_model.h @@ -1,5 +1,7 @@ /* -Copyright (C) 1996-1997 Id Software, Inc. +Copyright (C) 1996-2001 Id Software, Inc. +Copyright (C) 2002-2009 John Fitzgibbons and others +Copyright (C) 2010-2014 QuakeSpasm developers This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -8,7 +10,7 @@ of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. @@ -73,21 +75,27 @@ typedef struct mplane_s byte pad[2]; } mplane_t; +// ericw -- each texture has two chains, so we can clear the model chains +// without affecting the world +typedef enum { + chain_world = 0, + chain_model = 1 +} texchain_t; + typedef struct texture_s { - char name[16]; - unsigned width, height; - int gl_texturenum; - - qboolean tex_luma; // jkrige - luma textures - qboolean tex_luma8bit; // jkrige - fullbright pixels - - struct msurface_s *texturechain; // for gl_texsort drawing - int anim_total; // total tenths in sequence ( 0 = no) - int anim_min, anim_max; // time for this frame min <=time< max - struct texture_s *anim_next; // in the animation sequence - struct texture_s *alternate_anims; // bmodels in frmae 1 use these - unsigned offsets[MIPLEVELS]; // four mip maps stored + char name[16]; + unsigned width, height; + struct gltexture_s *gltexture; //johnfitz -- pointer to gltexture + struct gltexture_s *fullbright; //johnfitz -- fullbright mask texture + struct gltexture_s *warpimage; //johnfitz -- for water animation + qboolean update_warp; //johnfitz -- update warp this frame + struct msurface_s *texturechains[2]; // for texture chains + int anim_total; // total tenths in sequence ( 0 = no) + int anim_min, anim_max; // time for this frame min <=time< max + struct texture_s *anim_next; // in the animation sequence + struct texture_s *alternate_anims; // bmodels in frmae 1 use these + unsigned offsets[MIPLEVELS]; // four mip maps stored } texture_t; @@ -98,11 +106,17 @@ typedef struct texture_s #define SURF_DRAWTILED 0x20 #define SURF_DRAWBACKGROUND 0x40 #define SURF_UNDERWATER 0x80 +#define SURF_NOTEXTURE 0x100 //johnfitz +#define SURF_DRAWFENCE 0x200 +#define SURF_DRAWLAVA 0x400 +#define SURF_DRAWSLIME 0x800 +#define SURF_DRAWTELE 0x1000 +#define SURF_DRAWWATER 0x2000 // !!! if this is changed, it must be changed in asm_draw.h too !!! typedef struct { - unsigned short v[2]; + unsigned int v[2]; unsigned int cachededgeoffset; } medge_t; @@ -121,20 +135,22 @@ typedef struct glpoly_s struct glpoly_s *next; struct glpoly_s *chain; int numverts; - int flags; // for SURF_UNDERWATER float verts[4][VERTEXSIZE]; // variable sized (xyz s1t1 s2t2) } glpoly_t; typedef struct msurface_s { int visframe; // should be drawn when node is crossed + qboolean culled; // johnfitz -- for frustum culling + float mins[3]; // johnfitz -- for frustum culling + float maxs[3]; // johnfitz -- for frustum culling mplane_t *plane; int flags; int firstedge; // look up in model->surfedges[], negative numbers int numedges; // are backwards edges - + short texturemins[2]; short extents[2]; @@ -145,27 +161,18 @@ typedef struct msurface_s mtexinfo_t *texinfo; - // jkrige - luma textures - qboolean luma_mark; - // jkrige - luma textures - + int vbo_firstvert; // index of this surface's first vert in the VBO + // lighting info int dlightframe; - // jkrige - increase dlights - //int dlightbits; - byte dlightbits[(MAX_DLIGHTS + 7) / 8]; - // jkrige - increase dlights + unsigned int dlightbits[(MAX_DLIGHTS + 31) >> 5]; + // int is 32 bits, need an array for MAX_DLIGHTS > 32 int lightmaptexturenum; byte styles[MAXLIGHTMAPS]; int cached_light[MAXLIGHTMAPS]; // values currently used in lightmap qboolean cached_dlight; // true if dynamic light in cache byte *samples; // [numstyles*surfsize] - - // jkrige - overbrights - qboolean overbright; - // jkrige - overbrights - } msurface_t; typedef struct mnode_s @@ -173,17 +180,17 @@ typedef struct mnode_s // common with leaf int contents; // 0, to differentiate from leafs int visframe; // node needs to be traversed if current - + float minmaxs[6]; // for bounding box culling struct mnode_s *parent; // node specific mplane_t *plane; - struct mnode_s *children[2]; + struct mnode_s *children[2]; - unsigned short firstsurface; - unsigned short numsurfaces; + unsigned int firstsurface; + unsigned int numsurfaces; } mnode_t; @@ -208,10 +215,18 @@ typedef struct mleaf_s byte ambient_sound_level[NUM_AMBIENTS]; } mleaf_t; +//johnfitz -- for clipnodes>32k +typedef struct mclipnode_s +{ + int planenum; + int children[2]; // negative numbers are contents +} mclipnode_t; +//johnfitz + // !!! if this is changed, it must be changed in asm_i386.h too !!! typedef struct { - dclipnode_t *clipnodes; + mclipnode_t *clipnodes; //johnfitz -- was dclipnode_t mplane_t *planes; int firstclipnode; int lastclipnode; @@ -231,10 +246,10 @@ SPRITE MODELS // FIXME: shorten these? typedef struct mspriteframe_s { - int width; - int height; - float up, down, left, right; - int gl_texturenum; + int width, height; + float up, down, left, right; + float smax, tmax; //johnfitz -- image might be padded + struct gltexture_s *gltexture; } mspriteframe_t; typedef struct @@ -271,6 +286,26 @@ Alias models are position independent, so the cache manager can move them. ============================================================================== */ +//-- from RMQEngine +// split out to keep vertex sizes down +typedef struct aliasmesh_s +{ + float st[2]; + unsigned short vertindex; +} aliasmesh_t; + +typedef struct meshxyz_s +{ + byte xyz[4]; + signed char normal[4]; +} meshxyz_t; + +typedef struct meshst_s +{ + float st[2]; +} meshst_t; +//-- + typedef struct { int firstpose; @@ -321,25 +356,27 @@ typedef struct { int flags; float size; + //ericw -- used to populate vbo + int numverts_vbo; // number of verts with unique x,y,z,s,t + intptr_t meshdesc; // offset into extradata: numverts_vbo aliasmesh_t + int numindexes; + intptr_t indexes; // offset into extradata: numindexes unsigned shorts + intptr_t vertexes; // offset into extradata: numposes*vertsperframe trivertx_t + //ericw -- + int numposes; int poseverts; int posedata; // numposes*poseverts trivert_t int commands; // gl command list with embedded s/t - int gl_texturenum[MAX_SKINS][4]; + struct gltexture_s *gltextures[MAX_SKINS][4]; //johnfitz + struct gltexture_s *fbtextures[MAX_SKINS][4]; //johnfitz int texels[MAX_SKINS]; // only for player skins - - // jkrige - fullbright pixels - qboolean skin_luma[MAX_SKINS]; - qboolean skin_luma8bit[MAX_SKINS]; - // jkrige - fullbright pixels - - maliasframedesc_t frames[1]; // variable sized } aliashdr_t; -#define MAXALIASVERTS 1024 +#define MAXALIASVERTS 2000 //johnfitz -- was 1024 #define MAXALIASFRAMES 256 -#define MAXALIASTRIS 2048 +#define MAXALIASTRIS 4096 //ericw -- was 2048 extern aliashdr_t *pheader; extern stvert_t stverts[MAXALIASVERTS]; extern mtriangle_t triangles[MAXALIASTRIS]; @@ -361,27 +398,37 @@ typedef enum {mod_brush, mod_sprite, mod_alias} modtype_t; #define EF_ZOMGIB 32 // small blood trail #define EF_TRACER2 64 // orange split trail + rotate #define EF_TRACER3 128 // purple trail +#define MF_HOLEY (1u<<14) // MarkV/QSS -- make index 255 transparent on mdl's -typedef struct model_s +//johnfitz -- extra flags for rendering +#define MOD_NOLERP 256 //don't lerp when animating +#define MOD_NOSHADOW 512 //don't cast a shadow +#define MOD_FBRIGHTHACK 1024 //when fullbrights are disabled, use a hack to render this model brighter +//johnfitz + +typedef struct qmodel_s { char name[MAX_QPATH]; + unsigned int path_id; // path id of the game directory + // that this model came from qboolean needload; // bmodels and sprites don't cache normally modtype_t type; int numframes; synctype_t synctype; - - int flags; + int flags; // // volume occupied by the model graphics -// +// vec3_t mins, maxs; - float radius; + vec3_t ymins, ymaxs; //johnfitz -- bounds for entities with nonzero yaw + vec3_t rmins, rmaxs; //johnfitz -- bounds for entities with nonzero pitch or roll + //johnfitz -- removed float radius; // -// solid volume for clipping +// solid volume for clipping // qboolean clipbox; vec3_t clipmins, clipmaxs; @@ -419,7 +466,7 @@ typedef struct model_s int *surfedges; int numclipnodes; - dclipnode_t *clipnodes; + mclipnode_t *clipnodes; //johnfitz -- was dclipnode_t int nummarksurfaces; msurface_t **marksurfaces; @@ -433,24 +480,42 @@ typedef struct model_s byte *lightdata; char *entities; + qboolean viswarn; // for Mod_DecompressVis() + + int bspversion; + +// +// alias model +// + + GLuint meshvbo; + GLuint meshindexesvbo; + int vboindexofs; // offset in vbo of the hdr->numindexes unsigned shorts + int vboxyzofs; // offset in vbo of hdr->numposes*hdr->numverts_vbo meshxyz_t + int vbostofs; // offset in vbo of hdr->numverts_vbo meshst_t + // // additional model data // cache_user_t cache; // only access through Mod_Extradata -} model_t; +} qmodel_t; //============================================================================ void Mod_Init (void); void Mod_ClearAll (void); -model_t *Mod_ForName (char *name, qboolean crash); -void *Mod_Extradata (model_t *mod); // handles caching -void Mod_TouchModel (char *name); +void Mod_ResetAll (void); // for gamedir changes (Host_Game_f) +qmodel_t *Mod_ForName (const char *name, qboolean crash); +void *Mod_Extradata (qmodel_t *mod); // handles caching +void Mod_TouchModel (const char *name); + +mleaf_t *Mod_PointInLeaf (float *p, qmodel_t *model); +byte *Mod_LeafPVS (mleaf_t *leaf, qmodel_t *model); +byte *Mod_NoVisPVS (qmodel_t *model); -mleaf_t *Mod_PointInLeaf (float *p, model_t *model); -byte *Mod_LeafPVS (mleaf_t *leaf, model_t *model); +void Mod_SetExtraFlags (qmodel_t *mod); -int UQ_GL_UploadAliasModel(char *name, aliashdr_t *aliashdr, trivertx_t **poseVerts, mtriangle_t *triangles, stvert_t *stVerts); +int UQ_GL_UploadAliasModel(const char *name, aliashdr_t *aliashdr, trivertx_t **poseVerts, mtriangle_t *triangles, stvert_t *stVerts); #endif // __MODEL__ diff --git a/engine/code/gl_refrag.c b/engine/Quake/gl_refrag.c similarity index 55% rename from engine/code/gl_refrag.c rename to engine/Quake/gl_refrag.c index 1b060b3..ee2350c 100644 --- a/engine/code/gl_refrag.c +++ b/engine/Quake/gl_refrag.c @@ -1,5 +1,7 @@ /* -Copyright (C) 1996-1997 Id Software, Inc. +Copyright (C) 1996-2001 Id Software, Inc. +Copyright (C) 2002-2009 John Fitzgibbons and others +Copyright (C) 2010-2014 QuakeSpasm developers This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -8,7 +10,7 @@ of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. @@ -31,55 +33,57 @@ mnode_t *r_pefragtopnode; ENTITY FRAGMENT FUNCTIONS +ericw -- GLQuake only uses efrags for static entities, and they're never +removed, so I trimmed out unused functionality and fields in efrag_t. + +Now, efrags are just a linked list for each leaf of the static +entities that touch that leaf. The efrags are hunk-allocated so there is no +fixed limit. + +This is inspired by MH's tutorial, and code from RMQEngine. +http://forums.insideqc.com/viewtopic.php?t=1930 + =============================================================================== */ -efrag_t **lastlink; - vec3_t r_emins, r_emaxs; entity_t *r_addent; -/* -================ -R_RemoveEfrags +#define EXTRA_EFRAGS 128 -Call when removing an object from the world or moving it to another position -================ -*/ -void R_RemoveEfrags (entity_t *ent) +// based on RMQEngine +static efrag_t *R_GetEfrag (void) { - efrag_t *ef, *old, *walk, **prev; + // we could just Hunk_Alloc a single efrag_t and return it, but since + // the struct is so small (2 pointers) allocate groups of them + // to avoid wasting too much space on the hunk allocation headers. - ef = ent->efrag; - - while (ef) + if (cl.free_efrags) { - prev = &ef->leaf->efrags; - while (1) - { - walk = *prev; - if (!walk) - break; - if (walk == ef) - { // remove this fragment - *prev = ef->leafnext; - break; - } - else - prev = &walk->leafnext; - } - - old = ef; - ef = ef->entnext; + efrag_t *ef = cl.free_efrags; + cl.free_efrags = ef->leafnext; + ef->leafnext = NULL; + + cl.num_efrags++; - // put it on the free list - old->entnext = cl.free_efrags; - cl.free_efrags = old; + return ef; + } + else + { + int i; + + cl.free_efrags = (efrag_t *) Hunk_AllocName (EXTRA_EFRAGS * sizeof (efrag_t), "efrags"); + + for (i = 0; i < EXTRA_EFRAGS - 1; i++) + cl.free_efrags[i].leafnext = &cl.free_efrags[i + 1]; + + cl.free_efrags[i].leafnext = NULL; + + // call recursively to get a newly allocated free efrag + return R_GetEfrag (); } - - ent->efrag = NULL; } /* @@ -93,12 +97,12 @@ void R_SplitEntityOnNode (mnode_t *node) mplane_t *splitplane; mleaf_t *leaf; int sides; - + if (node->contents == CONTENTS_SOLID) { return; } - + // add an efrag if the node is a leaf if ( node->contents < 0) @@ -109,34 +113,21 @@ void R_SplitEntityOnNode (mnode_t *node) leaf = (mleaf_t *)node; // grab an efrag off the free list - ef = cl.free_efrags; - if (!ef) - { - Con_Printf ("Too many efrags!\n"); - return; // no free fragments... - } - cl.free_efrags = cl.free_efrags->entnext; - + ef = R_GetEfrag(); ef->entity = r_addent; - -// add the entity link - *lastlink = ef; - lastlink = &ef->entnext; - ef->entnext = NULL; - + // set the leaf links - ef->leaf = leaf; ef->leafnext = leaf->efrags; leaf->efrags = ef; - + return; } - + // NODE_MIXED splitplane = node->plane; sides = BOX_ON_PLANE_SIDE(r_emins, r_emaxs, splitplane); - + if (sides == 3) { // split on this plane @@ -144,16 +135,31 @@ void R_SplitEntityOnNode (mnode_t *node) if (!r_pefragtopnode) r_pefragtopnode = node; } - + // recurse down the contacted sides if (sides & 1) R_SplitEntityOnNode (node->children[0]); - + if (sides & 2) R_SplitEntityOnNode (node->children[1]); } +/* +=========== +R_CheckEfrags -- johnfitz -- check for excessive efrag count +=========== +*/ +void R_CheckEfrags (void) +{ + if (cls.signon < 2) + return; //don't spam when still parsing signon packet full of static ents + + if (cl.num_efrags > 640 && dev_peakstats.efrags <= 640) + Con_DWarning ("%i efrags exceeds standard limit of 640.\n", cl.num_efrags); + dev_stats.efrags = cl.num_efrags; + dev_peakstats.efrags = q_max(cl.num_efrags, dev_peakstats.efrags); +} /* =========== @@ -162,17 +168,16 @@ R_AddEfrags */ void R_AddEfrags (entity_t *ent) { - model_t *entmodel; + qmodel_t *entmodel; int i; - + if (!ent->model) return; r_addent = ent; - - lastlink = &ent->efrag; + r_pefragtopnode = NULL; - + entmodel = ent->model; for (i=0 ; i<3 ; i++) @@ -184,51 +189,32 @@ void R_AddEfrags (entity_t *ent) R_SplitEntityOnNode (cl.worldmodel->nodes); ent->topnode = r_pefragtopnode; + + R_CheckEfrags (); //johnfitz } /* ================ -R_StoreEfrags - -// FIXME: a lot of this goes away with edge-based +R_StoreEfrags -- johnfitz -- pointless switch statement removed. ================ */ void R_StoreEfrags (efrag_t **ppefrag) { entity_t *pent; - model_t *clmodel; efrag_t *pefrag; - while ((pefrag = *ppefrag) != NULL) { pent = pefrag->entity; - clmodel = pent->model; - switch (clmodel->type) + if ((pent->visframe != r_framecount) && (cl_numvisedicts < MAX_VISEDICTS)) { - case mod_alias: - case mod_brush: - case mod_sprite: - pent = pefrag->entity; - - if ((pent->visframe != r_framecount) && - (cl_numvisedicts < MAX_VISEDICTS)) - { - cl_visedicts[cl_numvisedicts++] = pent; - - // mark that we've recorded this entity for this frame - pent->visframe = r_framecount; - } - - ppefrag = &pefrag->leafnext; - break; - - default: - Sys_Error ("R_StoreEfrags: Bad entity type %d\n", clmodel->type); + cl_visedicts[cl_numvisedicts++] = pent; + pent->visframe = r_framecount; } + + ppefrag = &pefrag->leafnext; } } - diff --git a/engine/code/gl_rlight.c b/engine/Quake/gl_rlight.c similarity index 57% rename from engine/code/gl_rlight.c rename to engine/Quake/gl_rlight.c index c142135..86c73b8 100644 --- a/engine/code/gl_rlight.c +++ b/engine/Quake/gl_rlight.c @@ -1,5 +1,7 @@ /* -Copyright (C) 1996-1997 Id Software, Inc. +Copyright (C) 1996-2001 Id Software, Inc. +Copyright (C) 2002-2009 John Fitzgibbons and others +Copyright (C) 2010-2014 QuakeSpasm developers This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -8,7 +10,7 @@ of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. @@ -23,6 +25,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. int r_dlightframecount; +extern cvar_t r_flatlightstyles; //johnfitz /* ================== @@ -32,7 +35,7 @@ R_AnimateLight void R_AnimateLight (void) { int i,j,k; - + // // light animations // 'm' is normal light, 'a' is no light, 'z' is double bright @@ -44,23 +47,30 @@ void R_AnimateLight (void) d_lightstylevalue[j] = 256; continue; } - k = i % cl_lightstyle[j].length; - k = cl_lightstyle[j].map[k] - 'a'; - k = k*22; - d_lightstylevalue[j] = k; - } + //johnfitz -- r_flatlightstyles + if (r_flatlightstyles.value == 2) + k = cl_lightstyle[j].peak - 'a'; + else if (r_flatlightstyles.value == 1) + k = cl_lightstyle[j].average - 'a'; + else + { + k = i % cl_lightstyle[j].length; + k = cl_lightstyle[j].map[k] - 'a'; + } + d_lightstylevalue[j] = k*22; + //johnfitz + } } /* ============================================================================= -DYNAMIC LIGHTS BLEND RENDERING +DYNAMIC LIGHTS BLEND RENDERING (gl_flashblend 1) ============================================================================= */ -// jkrige - flashblend removal -/*void AddLightBlend (float r, float g, float b, float a2) +void AddLightBlend (float r, float g, float b, float a2) { float a; @@ -71,12 +81,9 @@ DYNAMIC LIGHTS BLEND RENDERING v_blend[0] = v_blend[1]*(1-a2) + r*a2; v_blend[1] = v_blend[1]*(1-a2) + g*a2; v_blend[2] = v_blend[2]*(1-a2) + b*a2; -}*/ -// jkrige - flashblend removal - +} -// jkrige - flashblend removal -/*void R_RenderDlight (dlight_t *light) +void R_RenderDlight (dlight_t *light) { int i, j; float a; @@ -86,7 +93,7 @@ DYNAMIC LIGHTS BLEND RENDERING rad = light->radius * 0.35; VectorSubtract (light->origin, r_origin, v); - if (Length (v) < rad) + if (VectorLength (v) < rad) { // view is inside the dlight AddLightBlend (1, 0.5, 0, light->radius * 0.0003); return; @@ -107,17 +114,14 @@ DYNAMIC LIGHTS BLEND RENDERING glVertex3fv (v); } glEnd (); -}*/ -// jkrige - flashblend removal - +} -// jkrige - flashblend removal /* ============= R_RenderDlights ============= */ -/*void R_RenderDlights (void) +void R_RenderDlights (void) { int i; dlight_t *l; @@ -146,8 +150,8 @@ R_RenderDlights glEnable (GL_TEXTURE_2D); glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glDepthMask (1); -}*/ -// jkrige - flashblend removal +} + /* ============================================================================= @@ -159,143 +163,72 @@ DYNAMIC LIGHTS /* ============= -R_MarkLights +R_MarkLights -- johnfitz -- rewritten to use LordHavoc's lighting speedup ============= */ -void R_MarkLights (dlight_t *light, int lnum, mnode_t *node) +void R_MarkLights (dlight_t *light, int num, mnode_t *node) { mplane_t *splitplane; - float dist; msurface_t *surf; - int i; + vec3_t impact; + float dist, l, maxdist; + int i, j, s, t; - // jkrige - fix dynamic light shine through - int sidebit; - // jkrige - fix dynamic light shine through +start: - // jkrige - speed increase - float l, maxdist; - int j, s, t; - vec3_t impact; -loc0: - // jkrige - speed increase - if (node->contents < 0) return; splitplane = node->plane; - - // jkrige - speed increase if (splitplane->type < 3) dist = light->origin[splitplane->type] - splitplane->dist; else dist = DotProduct (light->origin, splitplane->normal) - splitplane->dist; - //dist = DotProduct (light->origin, splitplane->normal) - splitplane->dist; - // jkrige - speed increase if (dist > light->radius) { - // jkrige - speed increase node = node->children[0]; - goto loc0; - //R_MarkLights (light, lnum, node->children[0]); - //return; - // jkrige - speed increase + goto start; } if (dist < -light->radius) { - // jkrige - speed increase node = node->children[1]; - goto loc0; - //R_MarkLights (light, lnum, node->children[1]); - //return; - // jkrige - speed increase + goto start; } - // jkrige - speed increase maxdist = light->radius*light->radius; - // jkrige - speed increase - // mark the polygons surf = cl.worldmodel->surfaces + node->firstsurface; for (i=0 ; inumsurfaces ; i++, surf++) { - // jkrige - fix dynamic light shine through - if (r_dynamic_sidemark.value) - { - if (dist >= 0) - sidebit = 0; - else - sidebit = SURF_PLANEBACK; - - if ( (surf->flags & SURF_PLANEBACK) != sidebit ) - continue; - } - // jkrige - fix dynamic light shine through - - - // jkrige - speed increase for (j=0 ; j<3 ; j++) - impact[j] = light->origin[j] - surf->plane->normal[j] * dist; - + impact[j] = light->origin[j] - surf->plane->normal[j]*dist; // clamp center of light to corner and check brightness l = DotProduct (impact, surf->texinfo->vecs[0]) + surf->texinfo->vecs[0][3] - surf->texturemins[0]; - s = l + 0.5; - if (s < 0) - s = 0; - else if (s > surf->extents[0]) - s = surf->extents[0]; + s = l+0.5;if (s < 0) s = 0;else if (s > surf->extents[0]) s = surf->extents[0]; s = l - s; l = DotProduct (impact, surf->texinfo->vecs[1]) + surf->texinfo->vecs[1][3] - surf->texturemins[1]; - t = l + 0.5; - if (t < 0) - t = 0; - else if (t > surf->extents[1]) - t = surf->extents[1]; + t = l+0.5;if (t < 0) t = 0;else if (t > surf->extents[1]) t = surf->extents[1]; t = l - t; - // jkrige - speed increase - - - // jkrige - increase dlights - //if (surf->dlightframe != r_dlightframecount) - //{ - // surf->dlightbits = 0; - // surf->dlightframe = r_dlightframecount; - //} - //surf->dlightbits |= lnum; // jkrige - was bit - - - if ((s*s+t*t+dist*dist) < maxdist) // jkrige - speed increase + // compare to minimum light + if ((s*s+t*t+dist*dist) < maxdist) { - if (surf->dlightframe != r_dlightframecount) - { - // init a new dlight on the surf - int j; - - for (j = 0; j < MAX_DLIGHTS; j += 8) - surf->dlightbits[(j >> 3)] = 0; - - surf->dlightframe = r_dlightframecount; + if (surf->dlightframe != r_dlightframecount) // not dynamic until now + { + surf->dlightbits[num >> 5] = 1U << (num & 31); + surf->dlightframe = r_dlightframecount; } - - - // mark it - surf->dlightbits[(lnum >> 3)] |= (1 << (lnum & 7)); + else // already dynamic + surf->dlightbits[num >> 5] |= 1U << (num & 31); } - // jkrige - increase dlights } - // jkrige - speed increase if (node->children[0]->contents >= 0) - R_MarkLights (light, lnum, node->children[0]); + R_MarkLights (light, num, node->children[0]); if (node->children[1]->contents >= 0) - R_MarkLights (light, lnum, node->children[1]); - //R_MarkLights (light, lnum, node->children[0]); - //R_MarkLights (light, lnum, node->children[1]); - // jkrige - speed increase + R_MarkLights (light, num, node->children[1]); } - /* ============= R_PushDlights @@ -306,10 +239,8 @@ void R_PushDlights (void) int i; dlight_t *l; - // jkrige - flashblend removal - //if (gl_flashblend.value) - // return; - // jkrige - flashblend removal + if (gl_flashblend.value) + return; r_dlightframecount = r_framecount + 1; // because the count hasn't // advanced yet for this frame @@ -319,11 +250,7 @@ void R_PushDlights (void) { if (l->die < cl.time || !l->radius) continue; - - // jkrige - increase dlights - //R_MarkLights ( l, 1<nodes ); - R_MarkLights ( l, i, cl.worldmodel->nodes ); - // jkrige - increase dlights + R_MarkLights (l, i, cl.worldmodel->nodes); } } @@ -338,8 +265,13 @@ LIGHT SAMPLING mplane_t *lightplane; vec3_t lightspot; +vec3_t lightcolor; //johnfitz -- lit support via lordhavoc -// jkrige - .lit colored lights +/* +============= +RecursiveLightPoint -- johnfitz -- replaced entire function for lit support via lordhavoc +============= +*/ int RecursiveLightPoint (vec3_t color, mnode_t *node, vec3_t start, vec3_t end) { float front, back, frac; @@ -348,7 +280,7 @@ int RecursiveLightPoint (vec3_t color, mnode_t *node, vec3_t start, vec3_t end) loc0: if (node->contents < 0) return false; // didn't hit anything - + // calculate mid point if (node->plane->type < 3) { @@ -368,12 +300,12 @@ loc0: node = node->children[front < 0]; goto loc0; } - + frac = front / (front-back); mid[0] = start[0] + (end[0] - start[0])*frac; mid[1] = start[1] + (end[1] - start[1])*frac; mid[2] = start[2] + (end[2] - start[2])*frac; - + // go down front side if (RecursiveLightPoint (color, node->children[front < 0], start, mid)) return true; // hit something @@ -391,15 +323,18 @@ loc0: if (surf->flags & SURF_DRAWTILED) continue; // no lightmaps - ds = (int) ((float) DotProduct (mid, surf->texinfo->vecs[0]) + surf->texinfo->vecs[0][3]); - dt = (int) ((float) DotProduct (mid, surf->texinfo->vecs[1]) + surf->texinfo->vecs[1][3]); + // ericw -- added double casts to force 64-bit precision. + // Without them the zombie at the start of jam3_ericw.bsp was + // incorrectly being lit up in SSE builds. + ds = (int) ((double) DoublePrecisionDotProduct (mid, surf->texinfo->vecs[0]) + surf->texinfo->vecs[0][3]); + dt = (int) ((double) DoublePrecisionDotProduct (mid, surf->texinfo->vecs[1]) + surf->texinfo->vecs[1][3]); if (ds < surf->texturemins[0] || dt < surf->texturemins[1]) continue; - + ds -= surf->texturemins[0]; dt -= surf->texturemins[1]; - + if (ds > surf->extents[0] || dt > surf->extents[1]) continue; @@ -435,145 +370,26 @@ loc0: } } -/*int RecursiveLightPoint (mnode_t *node, vec3_t start, vec3_t end) -{ - int r; - float front, back, frac; - int side; - mplane_t *plane; - vec3_t mid; - msurface_t *surf; - int s, t, ds, dt; - int i; - mtexinfo_t *tex; - byte *lightmap; - unsigned scale; - int maps; - - if (node->contents < 0) - return -1; // didn't hit anything - -// calculate mid point - -// FIXME: optimize for axial - plane = node->plane; - front = DotProduct (start, plane->normal) - plane->dist; - back = DotProduct (end, plane->normal) - plane->dist; - side = front < 0; - - if ( (back < 0) == side) - return RecursiveLightPoint (node->children[side], start, end); - - frac = front / (front-back); - mid[0] = start[0] + (end[0] - start[0])*frac; - mid[1] = start[1] + (end[1] - start[1])*frac; - mid[2] = start[2] + (end[2] - start[2])*frac; - -// go down front side - r = RecursiveLightPoint (node->children[side], start, mid); - if (r >= 0) - return r; // hit something - - if ( (back < 0) == side ) - return -1; // didn't hit anuthing - -// check for impact on this node - VectorCopy (mid, lightspot); - lightplane = plane; - - surf = cl.worldmodel->surfaces + node->firstsurface; - for (i=0 ; inumsurfaces ; i++, surf++) - { - if (surf->flags & SURF_DRAWTILED) - continue; // no lightmaps - - tex = surf->texinfo; - - s = DotProduct (mid, tex->vecs[0]) + tex->vecs[0][3]; - t = DotProduct (mid, tex->vecs[1]) + tex->vecs[1][3];; - - if (s < surf->texturemins[0] || - t < surf->texturemins[1]) - continue; - - ds = s - surf->texturemins[0]; - dt = t - surf->texturemins[1]; - - if ( ds > surf->extents[0] || dt > surf->extents[1] ) - continue; - - if (!surf->samples) - return 0; - - ds >>= 4; - dt >>= 4; - - lightmap = surf->samples; - r = 0; - if (lightmap) - { - - lightmap += dt * ((surf->extents[0]>>4)+1) + ds; - - for (maps = 0 ; maps < MAXLIGHTMAPS && surf->styles[maps] != 255 ; - maps++) - { - scale = d_lightstylevalue[surf->styles[maps]]; - r += *lightmap * scale; - lightmap += ((surf->extents[0]>>4)+1) * - ((surf->extents[1]>>4)+1); - } - - r >>= 8; - } - - return r; - } - -// go down back side - return RecursiveLightPoint (node->children[!side], mid, end); -}*/ -// jkrige - .lit colored lights - - -// jkrige - .lit colored lights -vec3_t lightcolor; // jkrige - used by model rendering +/* +============= +R_LightPoint -- johnfitz -- replaced entire function for lit support via lordhavoc +============= +*/ int R_LightPoint (vec3_t p) { vec3_t end; - - if (r_fullbright.value || !cl.worldmodel->lightdata) + + if (!cl.worldmodel->lightdata) { lightcolor[0] = lightcolor[1] = lightcolor[2] = 255; return 255; } - + end[0] = p[0]; end[1] = p[1]; - end[2] = p[2] - 2048; + end[2] = p[2] - 8192; //johnfitz -- was 2048 lightcolor[0] = lightcolor[1] = lightcolor[2] = 0; RecursiveLightPoint (lightcolor, cl.worldmodel->nodes, p, end); return ((lightcolor[0] + lightcolor[1] + lightcolor[2]) * (1.0f / 3.0f)); } - -/*int R_LightPoint (vec3_t p) -{ - vec3_t end; - int r; - - if (!cl.worldmodel->lightdata) - return 255; - - end[0] = p[0]; - end[1] = p[1]; - end[2] = p[2] - 2048; - - r = RecursiveLightPoint (cl.worldmodel->nodes, p, end); - - if (r == -1) - r = 0; - - return r; -}*/ -// jkrige - .lit colored lights \ No newline at end of file diff --git a/engine/Quake/gl_rmain.c b/engine/Quake/gl_rmain.c new file mode 100644 index 0000000..ffad937 --- /dev/null +++ b/engine/Quake/gl_rmain.c @@ -0,0 +1,1148 @@ +/* +Copyright (C) 1996-2001 Id Software, Inc. +Copyright (C) 2002-2009 John Fitzgibbons and others +Copyright (C) 2010-2014 QuakeSpasm developers + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ +// r_main.c + +#include "quakedef.h" + +qboolean r_cache_thrash; // compatability + +vec3_t modelorg, r_entorigin; +entity_t *currententity; + +int r_visframecount; // bumped when going to a new PVS +int r_framecount; // used for dlight push checking + +mplane_t frustum[4]; + +//johnfitz -- rendering statistics +int rs_brushpolys, rs_aliaspolys, rs_skypolys, rs_particles, rs_fogpolys; +int rs_dynamiclightmaps, rs_brushpasses, rs_aliaspasses, rs_skypasses; +float rs_megatexels; + +// +// view origin +// +vec3_t vup; +vec3_t vpn; +vec3_t vright; +vec3_t r_origin; + +float r_fovx, r_fovy; //johnfitz -- rendering fov may be different becuase of r_waterwarp and r_stereo + +// +// screen size info +// +refdef_t r_refdef; + +mleaf_t *r_viewleaf, *r_oldviewleaf; + +int d_lightstylevalue[256]; // 8.8 fraction of base light value + + +cvar_t r_norefresh = {"r_norefresh","0",CVAR_NONE}; +cvar_t r_drawentities = {"r_drawentities","1",CVAR_NONE}; +cvar_t r_drawviewmodel = {"r_drawviewmodel","1",CVAR_NONE}; +cvar_t r_speeds = {"r_speeds","0",CVAR_NONE}; +cvar_t r_pos = {"r_pos","0",CVAR_NONE}; +cvar_t r_fullbright = {"r_fullbright","0",CVAR_NONE}; +cvar_t r_lightmap = {"r_lightmap","0",CVAR_NONE}; +cvar_t r_shadows = {"r_shadows","0",CVAR_ARCHIVE}; +cvar_t r_wateralpha = {"r_wateralpha","1",CVAR_ARCHIVE}; +cvar_t r_dynamic = {"r_dynamic","1",CVAR_ARCHIVE}; +cvar_t r_novis = {"r_novis","0",CVAR_ARCHIVE}; + +cvar_t gl_finish = {"gl_finish","0",CVAR_NONE}; +cvar_t gl_clear = {"gl_clear","1",CVAR_NONE}; +cvar_t gl_cull = {"gl_cull","1",CVAR_NONE}; +cvar_t gl_smoothmodels = {"gl_smoothmodels","1",CVAR_NONE}; +cvar_t gl_affinemodels = {"gl_affinemodels","0",CVAR_NONE}; +cvar_t gl_polyblend = {"gl_polyblend","1",CVAR_NONE}; +cvar_t gl_flashblend = {"gl_flashblend","0",CVAR_ARCHIVE}; +cvar_t gl_playermip = {"gl_playermip","0",CVAR_NONE}; +cvar_t gl_nocolors = {"gl_nocolors","0",CVAR_NONE}; + +//johnfitz -- new cvars +cvar_t r_stereo = {"r_stereo","0",CVAR_NONE}; +cvar_t r_stereodepth = {"r_stereodepth","128",CVAR_NONE}; +cvar_t r_clearcolor = {"r_clearcolor","2",CVAR_ARCHIVE}; +cvar_t r_drawflat = {"r_drawflat","0",CVAR_NONE}; +cvar_t r_flatlightstyles = {"r_flatlightstyles", "0", CVAR_NONE}; +cvar_t gl_fullbrights = {"gl_fullbrights", "1", CVAR_ARCHIVE}; +cvar_t gl_farclip = {"gl_farclip", "16384", CVAR_ARCHIVE}; +cvar_t gl_overbright = {"gl_overbright", "1", CVAR_ARCHIVE}; +cvar_t gl_overbright_models = {"gl_overbright_models", "1", CVAR_ARCHIVE}; +cvar_t r_oldskyleaf = {"r_oldskyleaf", "0", CVAR_NONE}; +cvar_t r_drawworld = {"r_drawworld", "1", CVAR_NONE}; +cvar_t r_showtris = {"r_showtris", "0", CVAR_NONE}; +cvar_t r_showbboxes = {"r_showbboxes", "0", CVAR_NONE}; +cvar_t r_lerpmodels = {"r_lerpmodels", "1", CVAR_NONE}; +cvar_t r_lerpmove = {"r_lerpmove", "1", CVAR_NONE}; +cvar_t r_nolerp_list = {"r_nolerp_list", "progs/flame.mdl,progs/flame2.mdl,progs/braztall.mdl,progs/brazshrt.mdl,progs/longtrch.mdl,progs/flame_pyre.mdl,progs/v_saw.mdl,progs/v_xfist.mdl,progs/h2stuff/newfire.mdl", CVAR_NONE}; +cvar_t r_noshadow_list = {"r_noshadow_list", "progs/flame2.mdl,progs/flame.mdl,progs/bolt1.mdl,progs/bolt2.mdl,progs/bolt3.mdl,progs/laser.mdl", CVAR_NONE}; + +extern cvar_t r_vfog; +//johnfitz + +cvar_t gl_zfix = {"gl_zfix", "0", CVAR_NONE}; // QuakeSpasm z-fighting fix + +cvar_t r_lavaalpha = {"r_lavaalpha","0",CVAR_NONE}; +cvar_t r_telealpha = {"r_telealpha","0",CVAR_NONE}; +cvar_t r_slimealpha = {"r_slimealpha","0",CVAR_NONE}; + +float map_wateralpha, map_lavaalpha, map_telealpha, map_slimealpha; + +qboolean r_drawflat_cheatsafe, r_fullbright_cheatsafe, r_lightmap_cheatsafe, r_drawworld_cheatsafe; //johnfitz + +cvar_t r_scale = {"r_scale", "1", CVAR_ARCHIVE}; + +//============================================================================== +// +// GLSL GAMMA CORRECTION +// +//============================================================================== + +static GLuint r_gamma_texture; +static GLuint r_gamma_program; +static int r_gamma_texture_width, r_gamma_texture_height; + +// uniforms used in gamma shader +static GLuint gammaLoc; +static GLuint contrastLoc; +static GLuint textureLoc; + +/* +============= +GLSLGamma_DeleteTexture +============= +*/ +void GLSLGamma_DeleteTexture (void) +{ + glDeleteTextures (1, &r_gamma_texture); + r_gamma_texture = 0; + r_gamma_program = 0; // deleted in R_DeleteShaders +} + +/* +============= +GLSLGamma_CreateShaders +============= +*/ +static void GLSLGamma_CreateShaders (void) +{ + const GLchar *vertSource = \ + "#version 110\n" + "\n" + "void main(void) {\n" + " gl_Position = vec4(gl_Vertex.xy, 0.0, 1.0);\n" + " gl_TexCoord[0] = gl_MultiTexCoord0;\n" + "}\n"; + + const GLchar *fragSource = \ + "#version 110\n" + "\n" + "uniform sampler2D GammaTexture;\n" + "uniform float GammaValue;\n" + "uniform float ContrastValue;\n" + "\n" + "void main(void) {\n" + " vec4 frag = texture2D(GammaTexture, gl_TexCoord[0].xy);\n" + " frag.rgb = frag.rgb * ContrastValue;\n" + " gl_FragColor = vec4(pow(frag.rgb, vec3(GammaValue)), 1.0);\n" + "}\n"; + + if (!gl_glsl_gamma_able) + return; + + r_gamma_program = GL_CreateProgram (vertSource, fragSource, 0, NULL); + +// get uniform locations + gammaLoc = GL_GetUniformLocation (&r_gamma_program, "GammaValue"); + contrastLoc = GL_GetUniformLocation (&r_gamma_program, "ContrastValue"); + textureLoc = GL_GetUniformLocation (&r_gamma_program, "GammaTexture"); +} + +/* +============= +GLSLGamma_GammaCorrect +============= +*/ +void GLSLGamma_GammaCorrect (void) +{ + float smax, tmax; + + if (!gl_glsl_gamma_able) + return; + + if (vid_gamma.value == 1 && vid_contrast.value == 1) + return; + +// create render-to-texture texture if needed + if (!r_gamma_texture) + { + glGenTextures (1, &r_gamma_texture); + glBindTexture (GL_TEXTURE_2D, r_gamma_texture); + + r_gamma_texture_width = glwidth; + r_gamma_texture_height = glheight; + + if (!gl_texture_NPOT) + { + r_gamma_texture_width = TexMgr_Pad(r_gamma_texture_width); + r_gamma_texture_height = TexMgr_Pad(r_gamma_texture_height); + } + + glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA8, r_gamma_texture_width, r_gamma_texture_height, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL); + glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + } + +// create shader if needed + if (!r_gamma_program) + { + GLSLGamma_CreateShaders (); + if (!r_gamma_program) + { + Sys_Error("GLSLGamma_CreateShaders failed"); + } + } + +// copy the framebuffer to the texture + GL_DisableMultitexture(); + glBindTexture (GL_TEXTURE_2D, r_gamma_texture); + glCopyTexSubImage2D (GL_TEXTURE_2D, 0, 0, 0, glx, gly, glwidth, glheight); + +// draw the texture back to the framebuffer with a fragment shader + GL_UseProgramFunc (r_gamma_program); + GL_Uniform1fFunc (gammaLoc, vid_gamma.value); + GL_Uniform1fFunc (contrastLoc, q_min(2.0, q_max(1.0, vid_contrast.value))); + GL_Uniform1iFunc (textureLoc, 0); // use texture unit 0 + + glDisable (GL_ALPHA_TEST); + glDisable (GL_DEPTH_TEST); + + glViewport (glx, gly, glwidth, glheight); + + smax = glwidth/(float)r_gamma_texture_width; + tmax = glheight/(float)r_gamma_texture_height; + + glBegin (GL_QUADS); + glTexCoord2f (0, 0); + glVertex2f (-1, -1); + glTexCoord2f (smax, 0); + glVertex2f (1, -1); + glTexCoord2f (smax, tmax); + glVertex2f (1, 1); + glTexCoord2f (0, tmax); + glVertex2f (-1, 1); + glEnd (); + + GL_UseProgramFunc (0); + +// clear cached binding + GL_ClearBindings (); +} + +/* +================= +R_CullBox -- johnfitz -- replaced with new function from lordhavoc + +Returns true if the box is completely outside the frustum +================= +*/ +qboolean R_CullBox (vec3_t emins, vec3_t emaxs) +{ + int i; + mplane_t *p; + for (i = 0;i < 4;i++) + { + p = frustum + i; + switch(p->signbits) + { + default: + case 0: + if (p->normal[0]*emaxs[0] + p->normal[1]*emaxs[1] + p->normal[2]*emaxs[2] < p->dist) + return true; + break; + case 1: + if (p->normal[0]*emins[0] + p->normal[1]*emaxs[1] + p->normal[2]*emaxs[2] < p->dist) + return true; + break; + case 2: + if (p->normal[0]*emaxs[0] + p->normal[1]*emins[1] + p->normal[2]*emaxs[2] < p->dist) + return true; + break; + case 3: + if (p->normal[0]*emins[0] + p->normal[1]*emins[1] + p->normal[2]*emaxs[2] < p->dist) + return true; + break; + case 4: + if (p->normal[0]*emaxs[0] + p->normal[1]*emaxs[1] + p->normal[2]*emins[2] < p->dist) + return true; + break; + case 5: + if (p->normal[0]*emins[0] + p->normal[1]*emaxs[1] + p->normal[2]*emins[2] < p->dist) + return true; + break; + case 6: + if (p->normal[0]*emaxs[0] + p->normal[1]*emins[1] + p->normal[2]*emins[2] < p->dist) + return true; + break; + case 7: + if (p->normal[0]*emins[0] + p->normal[1]*emins[1] + p->normal[2]*emins[2] < p->dist) + return true; + break; + } + } + return false; +} +/* +=============== +R_CullModelForEntity -- johnfitz -- uses correct bounds based on rotation +=============== +*/ +qboolean R_CullModelForEntity (entity_t *e) +{ + vec3_t mins, maxs; + + if (e->angles[0] || e->angles[2]) //pitch or roll + { + VectorAdd (e->origin, e->model->rmins, mins); + VectorAdd (e->origin, e->model->rmaxs, maxs); + } + else if (e->angles[1]) //yaw + { + VectorAdd (e->origin, e->model->ymins, mins); + VectorAdd (e->origin, e->model->ymaxs, maxs); + } + else //no rotation + { + VectorAdd (e->origin, e->model->mins, mins); + VectorAdd (e->origin, e->model->maxs, maxs); + } + + return R_CullBox (mins, maxs); +} + +/* +=============== +R_RotateForEntity -- johnfitz -- modified to take origin and angles instead of pointer to entity +=============== +*/ +void R_RotateForEntity (vec3_t origin, vec3_t angles) +{ + glTranslatef (origin[0], origin[1], origin[2]); + glRotatef (angles[1], 0, 0, 1); + glRotatef (-angles[0], 0, 1, 0); + glRotatef (angles[2], 1, 0, 0); +} + +/* +============= +GL_PolygonOffset -- johnfitz + +negative offset moves polygon closer to camera +============= +*/ +void GL_PolygonOffset (int offset) +{ + if (offset > 0) + { + glEnable (GL_POLYGON_OFFSET_FILL); + glEnable (GL_POLYGON_OFFSET_LINE); + glPolygonOffset(1, offset); + } + else if (offset < 0) + { + glEnable (GL_POLYGON_OFFSET_FILL); + glEnable (GL_POLYGON_OFFSET_LINE); + glPolygonOffset(-1, offset); + } + else + { + glDisable (GL_POLYGON_OFFSET_FILL); + glDisable (GL_POLYGON_OFFSET_LINE); + } +} + +//============================================================================== +// +// SETUP FRAME +// +//============================================================================== + +int SignbitsForPlane (mplane_t *out) +{ + int bits, j; + + // for fast box on planeside test + + bits = 0; + for (j=0 ; j<3 ; j++) + { + if (out->normal[j] < 0) + bits |= 1<contents); + V_CalcBlend (); + + r_cache_thrash = false; + + //johnfitz -- calculate r_fovx and r_fovy here + r_fovx = r_refdef.fov_x; + r_fovy = r_refdef.fov_y; + if (r_waterwarp.value) + { + int contents = Mod_PointInLeaf (r_origin, cl.worldmodel)->contents; + if (contents == CONTENTS_WATER || contents == CONTENTS_SLIME || contents == CONTENTS_LAVA) + { + //variance is a percentage of width, where width = 2 * tan(fov / 2) otherwise the effect is too dramatic at high FOV and too subtle at low FOV. what a mess! + r_fovx = atan(tan(DEG2RAD(r_refdef.fov_x) / 2) * (0.97 + sin(cl.time * 1.5) * 0.03)) * 2 / M_PI_DIV_180; + r_fovy = atan(tan(DEG2RAD(r_refdef.fov_y) / 2) * (1.03 - sin(cl.time * 1.5) * 0.03)) * 2 / M_PI_DIV_180; + } + } + //johnfitz + + R_SetFrustum (r_fovx, r_fovy); //johnfitz -- use r_fov* vars + + R_MarkSurfaces (); //johnfitz -- create texture chains from PVS + + R_CullSurfaces (); //johnfitz -- do after R_SetFrustum and R_MarkSurfaces + + R_UpdateWarpTextures (); //johnfitz -- do this before R_Clear + + R_Clear (); + + //johnfitz -- cheat-protect some draw modes + r_drawflat_cheatsafe = r_fullbright_cheatsafe = r_lightmap_cheatsafe = false; + r_drawworld_cheatsafe = true; + if (cl.maxclients == 1) + { + if (!r_drawworld.value) r_drawworld_cheatsafe = false; + + if (r_drawflat.value) r_drawflat_cheatsafe = true; + else if (r_fullbright.value || !cl.worldmodel->lightdata) r_fullbright_cheatsafe = true; + else if (r_lightmap.value) r_lightmap_cheatsafe = true; + } + //johnfitz +} + +//============================================================================== +// +// RENDER VIEW +// +//============================================================================== + +/* +============= +R_DrawEntitiesOnList +============= +*/ +void R_DrawEntitiesOnList (qboolean alphapass) //johnfitz -- added parameter +{ + int i; + + if (!r_drawentities.value) + return; + + //johnfitz -- sprites are not a special case + for (i=0 ; ialpha) < 1 && !alphapass) || + (ENTALPHA_DECODE(currententity->alpha) == 1 && alphapass)) + continue; + + //johnfitz -- chasecam + if (currententity == &cl_entities[cl.viewentity]) + currententity->angles[0] *= 0.3; + //johnfitz + + switch (currententity->model->type) + { + case mod_alias: + R_DrawAliasModel (currententity); + break; + case mod_brush: + R_DrawBrushModel (currententity); + break; + case mod_sprite: + R_DrawSpriteModel (currententity); + break; + } + } +} + +/* +============= +R_DrawViewModel -- johnfitz -- gutted +============= +*/ +void R_DrawViewModel (void) +{ + if (!r_drawviewmodel.value || !r_drawentities.value || chase_active.value) + return; + + if (cl.items & IT_INVISIBILITY || cl.stats[STAT_HEALTH] <= 0) + return; + + currententity = &cl.viewent; + if (!currententity->model) + return; + + //johnfitz -- this fixes a crash + if (currententity->model->type != mod_alias) + return; + //johnfitz + + // hack the depth range to prevent view model from poking into walls + glDepthRange (0, 0.3); + R_DrawAliasModel (currententity); + glDepthRange (0, 1); +} + +/* +================ +R_EmitWirePoint -- johnfitz -- draws a wireframe cross shape for point entities +================ +*/ +void R_EmitWirePoint (vec3_t origin) +{ + int size=8; + + glBegin (GL_LINES); + glVertex3f (origin[0]-size, origin[1], origin[2]); + glVertex3f (origin[0]+size, origin[1], origin[2]); + glVertex3f (origin[0], origin[1]-size, origin[2]); + glVertex3f (origin[0], origin[1]+size, origin[2]); + glVertex3f (origin[0], origin[1], origin[2]-size); + glVertex3f (origin[0], origin[1], origin[2]+size); + glEnd (); +} + +/* +================ +R_EmitWireBox -- johnfitz -- draws one axis aligned bounding box +================ +*/ +void R_EmitWireBox (vec3_t mins, vec3_t maxs) +{ + glBegin (GL_QUAD_STRIP); + glVertex3f (mins[0], mins[1], mins[2]); + glVertex3f (mins[0], mins[1], maxs[2]); + glVertex3f (maxs[0], mins[1], mins[2]); + glVertex3f (maxs[0], mins[1], maxs[2]); + glVertex3f (maxs[0], maxs[1], mins[2]); + glVertex3f (maxs[0], maxs[1], maxs[2]); + glVertex3f (mins[0], maxs[1], mins[2]); + glVertex3f (mins[0], maxs[1], maxs[2]); + glVertex3f (mins[0], mins[1], mins[2]); + glVertex3f (mins[0], mins[1], maxs[2]); + glEnd (); +} + +/* +================ +R_ShowBoundingBoxes -- johnfitz + +draw bounding boxes -- the server-side boxes, not the renderer cullboxes +================ +*/ +void R_ShowBoundingBoxes (void) +{ + extern edict_t *sv_player; + vec3_t mins,maxs; + edict_t *ed; + int i; + + if (!r_showbboxes.value || cl.maxclients > 1 || !r_drawentities.value || !sv.active) + return; + + glDisable (GL_DEPTH_TEST); + glPolygonMode (GL_FRONT_AND_BACK, GL_LINE); + GL_PolygonOffset (OFFSET_SHOWTRIS); + glDisable (GL_TEXTURE_2D); + glDisable (GL_CULL_FACE); + glColor3f (1,1,1); + + for (i=0, ed=NEXT_EDICT(sv.edicts) ; iv.mins[0] == ed->v.maxs[0] && ed->v.mins[1] == ed->v.maxs[1] && ed->v.mins[2] == ed->v.maxs[2]) + { + //point entity + R_EmitWirePoint (ed->v.origin); + } + else + { + //box entity + VectorAdd (ed->v.mins, ed->v.origin, mins); + VectorAdd (ed->v.maxs, ed->v.origin, maxs); + R_EmitWireBox (mins, maxs); + } + } + + glColor3f (1,1,1); + glEnable (GL_TEXTURE_2D); + glEnable (GL_CULL_FACE); + glPolygonMode (GL_FRONT_AND_BACK, GL_FILL); + GL_PolygonOffset (OFFSET_NONE); + glEnable (GL_DEPTH_TEST); + + Sbar_Changed (); //so we don't get dots collecting on the statusbar +} + +/* +================ +R_ShowTris -- johnfitz +================ +*/ +void R_ShowTris (void) +{ + extern cvar_t r_particles; + int i; + + if (r_showtris.value < 1 || r_showtris.value > 2 || cl.maxclients > 1) + return; + + if (r_showtris.value == 1) + glDisable (GL_DEPTH_TEST); + glPolygonMode (GL_FRONT_AND_BACK, GL_LINE); + GL_PolygonOffset (OFFSET_SHOWTRIS); + glDisable (GL_TEXTURE_2D); + glColor3f (1,1,1); +// glEnable (GL_BLEND); +// glBlendFunc (GL_ONE, GL_ONE); + + if (r_drawworld.value) + { + R_DrawWorld_ShowTris (); + } + + if (r_drawentities.value) + { + for (i=0 ; iangles[0] *= 0.3; + + switch (currententity->model->type) + { + case mod_brush: + R_DrawBrushModel_ShowTris (currententity); + break; + case mod_alias: + R_DrawAliasModel_ShowTris (currententity); + break; + case mod_sprite: + R_DrawSpriteModel (currententity); + break; + default: + break; + } + } + + // viewmodel + currententity = &cl.viewent; + if (r_drawviewmodel.value + && !chase_active.value + && cl.stats[STAT_HEALTH] > 0 + && !(cl.items & IT_INVISIBILITY) + && currententity->model + && currententity->model->type == mod_alias) + { + glDepthRange (0, 0.3); + R_DrawAliasModel_ShowTris (currententity); + glDepthRange (0, 1); + } + } + + if (r_particles.value) + { + R_DrawParticles_ShowTris (); + } + +// glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); +// glDisable (GL_BLEND); + glColor3f (1,1,1); + glEnable (GL_TEXTURE_2D); + glPolygonMode (GL_FRONT_AND_BACK, GL_FILL); + GL_PolygonOffset (OFFSET_NONE); + if (r_showtris.value == 1) + glEnable (GL_DEPTH_TEST); + + Sbar_Changed (); //so we don't get dots collecting on the statusbar +} + +/* +================ +R_DrawShadows +================ +*/ +void R_DrawShadows (void) +{ + int i; + + if (!r_shadows.value || !r_drawentities.value || r_drawflat_cheatsafe || r_lightmap_cheatsafe) + return; + + // Use stencil buffer to prevent self-intersecting shadows, from Baker (MarkV) + if (gl_stencilbits) + { + glClear(GL_STENCIL_BUFFER_BIT); + glStencilFunc(GL_EQUAL, 0, ~0); + glStencilOp(GL_KEEP, GL_KEEP, GL_INCR); + glEnable(GL_STENCIL_TEST); + } + + for (i=0 ; imodel->type != mod_alias) + continue; + + if (currententity == &cl.viewent) + return; + + GL_DrawAliasShadow (currententity); + } + + if (gl_stencilbits) + { + glDisable(GL_STENCIL_TEST); + } +} + +/* +================ +R_RenderScene +================ +*/ +void R_RenderScene (void) +{ + R_SetupScene (); //johnfitz -- this does everything that should be done once per call to RenderScene + + Fog_EnableGFog (); //johnfitz + + Sky_DrawSky (); //johnfitz + + R_DrawWorld (); + + S_ExtraUpdate (); // don't let sound get messed up if going slow + + R_DrawShadows (); //johnfitz -- render entity shadows + + R_DrawEntitiesOnList (false); //johnfitz -- false means this is the pass for nonalpha entities + + R_DrawWorld_Water (); //johnfitz -- drawn here since they might have transparency + + R_DrawEntitiesOnList (true); //johnfitz -- true means this is the pass for alpha entities + + R_RenderDlights (); //triangle fan dlights -- johnfitz -- moved after water + + R_DrawParticles (); + + Fog_DisableGFog (); //johnfitz + + R_DrawViewModel (); //johnfitz -- moved here from R_RenderView + + R_ShowTris (); //johnfitz + + R_ShowBoundingBoxes (); //johnfitz +} + +static GLuint r_scaleview_texture; +static int r_scaleview_texture_width, r_scaleview_texture_height; + +/* +============= +R_ScaleView_DeleteTexture +============= +*/ +void R_ScaleView_DeleteTexture (void) +{ + glDeleteTextures (1, &r_scaleview_texture); + r_scaleview_texture = 0; +} + +/* +================ +R_ScaleView + +The r_scale cvar allows rendering the 3D view at 1/2, 1/3, or 1/4 resolution. +This function scales the reduced resolution 3D view back up to fill +r_refdef.vrect. This is for emulating a low-resolution pixellated look, +or possibly as a perforance boost on slow graphics cards. +================ +*/ +void R_ScaleView (void) +{ + float smax, tmax; + int scale; + int srcx, srcy, srcw, srch; + + // copied from R_SetupGL() + scale = CLAMP(1, (int)r_scale.value, 4); + srcx = glx + r_refdef.vrect.x; + srcy = gly + glheight - r_refdef.vrect.y - r_refdef.vrect.height; + srcw = r_refdef.vrect.width / scale; + srch = r_refdef.vrect.height / scale; + + if (scale == 1) + return; + + // make sure texture unit 0 is selected + GL_DisableMultitexture (); + + // create (if needed) and bind the render-to-texture texture + if (!r_scaleview_texture) + { + glGenTextures (1, &r_scaleview_texture); + + r_scaleview_texture_width = 0; + r_scaleview_texture_height = 0; + } + glBindTexture (GL_TEXTURE_2D, r_scaleview_texture); + + // resize render-to-texture texture if needed + if (r_scaleview_texture_width < srcw + || r_scaleview_texture_height < srch) + { + r_scaleview_texture_width = srcw; + r_scaleview_texture_height = srch; + + if (!gl_texture_NPOT) + { + r_scaleview_texture_width = TexMgr_Pad(r_scaleview_texture_width); + r_scaleview_texture_height = TexMgr_Pad(r_scaleview_texture_height); + } + + glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA, r_scaleview_texture_width, r_scaleview_texture_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); + glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + } + + // copy the framebuffer to the texture + glBindTexture (GL_TEXTURE_2D, r_scaleview_texture); + glCopyTexSubImage2D (GL_TEXTURE_2D, 0, 0, 0, srcx, srcy, srcw, srch); + + // draw the texture back to the framebuffer + glDisable (GL_ALPHA_TEST); + glDisable (GL_DEPTH_TEST); + glDisable (GL_CULL_FACE); + glDisable (GL_BLEND); + + glViewport (srcx, srcy, r_refdef.vrect.width, r_refdef.vrect.height); + + glMatrixMode(GL_PROJECTION); + glLoadIdentity (); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity (); + + // correction factor if we lack NPOT textures, normally these are 1.0f + smax = srcw/(float)r_scaleview_texture_width; + tmax = srch/(float)r_scaleview_texture_height; + + glBegin (GL_QUADS); + glTexCoord2f (0, 0); + glVertex2f (-1, -1); + glTexCoord2f (smax, 0); + glVertex2f (1, -1); + glTexCoord2f (smax, tmax); + glVertex2f (1, 1); + glTexCoord2f (0, tmax); + glVertex2f (-1, 1); + glEnd (); + + // clear cached binding + GL_ClearBindings (); +} + +/* +================ +R_RenderView +================ +*/ +void R_RenderView (void) +{ + double time1, time2; + + if (r_norefresh.value) + return; + + if (!cl.worldmodel) + Sys_Error ("R_RenderView: NULL worldmodel"); + + time1 = 0; /* avoid compiler warning */ + if (r_speeds.value) + { + glFinish (); + time1 = Sys_DoubleTime (); + + //johnfitz -- rendering statistics + rs_brushpolys = rs_aliaspolys = rs_skypolys = rs_particles = rs_fogpolys = rs_megatexels = + rs_dynamiclightmaps = rs_aliaspasses = rs_skypasses = rs_brushpasses = 0; + } + else if (gl_finish.value) + glFinish (); + + R_SetupView (); //johnfitz -- this does everything that should be done once per frame + + //johnfitz -- stereo rendering -- full of hacky goodness + if (r_stereo.value) + { + float eyesep = CLAMP(-8.0f, r_stereo.value, 8.0f); + float fdepth = CLAMP(32.0f, r_stereodepth.value, 1024.0f); + + AngleVectors (r_refdef.viewangles, vpn, vright, vup); + + //render left eye (red) + glColorMask(1, 0, 0, 1); + VectorMA (r_refdef.vieworg, -0.5f * eyesep, vright, r_refdef.vieworg); + frustum_skew = 0.5 * eyesep * NEARCLIP / fdepth; + srand((int) (cl.time * 1000)); //sync random stuff between eyes + + R_RenderScene (); + + //render right eye (cyan) + glClear (GL_DEPTH_BUFFER_BIT); + glColorMask(0, 1, 1, 1); + VectorMA (r_refdef.vieworg, 1.0f * eyesep, vright, r_refdef.vieworg); + frustum_skew = -frustum_skew; + srand((int) (cl.time * 1000)); //sync random stuff between eyes + + R_RenderScene (); + + //restore + glColorMask(1, 1, 1, 1); + VectorMA (r_refdef.vieworg, -0.5f * eyesep, vright, r_refdef.vieworg); + frustum_skew = 0.0f; + } + else + { + R_RenderScene (); + } + //johnfitz + + R_ScaleView (); + + //johnfitz -- modified r_speeds output + time2 = Sys_DoubleTime (); + if (r_pos.value) + Con_Printf ("x %i y %i z %i (pitch %i yaw %i roll %i)\n", + (int)cl_entities[cl.viewentity].origin[0], + (int)cl_entities[cl.viewentity].origin[1], + (int)cl_entities[cl.viewentity].origin[2], + (int)cl.viewangles[PITCH], + (int)cl.viewangles[YAW], + (int)cl.viewangles[ROLL]); + else if (r_speeds.value == 2) + Con_Printf ("%3i ms %4i/%4i wpoly %4i/%4i epoly %3i lmap %4i/%4i sky %1.1f mtex\n", + (int)((time2-time1)*1000), + rs_brushpolys, + rs_brushpasses, + rs_aliaspolys, + rs_aliaspasses, + rs_dynamiclightmaps, + rs_skypolys, + rs_skypasses, + TexMgr_FrameUsage ()); + else if (r_speeds.value) + Con_Printf ("%3i ms %4i wpoly %4i epoly %3i lmap\n", + (int)((time2-time1)*1000), + rs_brushpolys, + rs_aliaspolys, + rs_dynamiclightmaps); + //johnfitz +} + diff --git a/engine/Quake/gl_rmisc.c b/engine/Quake/gl_rmisc.c new file mode 100644 index 0000000..4aac822 --- /dev/null +++ b/engine/Quake/gl_rmisc.c @@ -0,0 +1,651 @@ +/* +Copyright (C) 1996-2001 Id Software, Inc. +Copyright (C) 2002-2009 John Fitzgibbons and others +Copyright (C) 2007-2008 Kristian Duske +Copyright (C) 2010-2014 QuakeSpasm developers + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ +// r_misc.c + +#include "quakedef.h" + +//johnfitz -- new cvars +extern cvar_t r_stereo; +extern cvar_t r_stereodepth; +extern cvar_t r_clearcolor; +extern cvar_t r_drawflat; +extern cvar_t r_flatlightstyles; +extern cvar_t gl_fullbrights; +extern cvar_t gl_farclip; +extern cvar_t gl_overbright; +extern cvar_t gl_overbright_models; +extern cvar_t r_waterquality; +extern cvar_t r_oldwater; +extern cvar_t r_waterwarp; +extern cvar_t r_oldskyleaf; +extern cvar_t r_drawworld; +extern cvar_t r_showtris; +extern cvar_t r_showbboxes; +extern cvar_t r_lerpmodels; +extern cvar_t r_lerpmove; +extern cvar_t r_nolerp_list; +extern cvar_t r_noshadow_list; +//johnfitz +extern cvar_t gl_zfix; // QuakeSpasm z-fighting fix + +extern gltexture_t *playertextures[MAX_SCOREBOARD]; //johnfitz + + +/* +==================== +GL_Overbright_f -- johnfitz +==================== +*/ +static void GL_Overbright_f (cvar_t *var) +{ + R_RebuildAllLightmaps (); +} + +/* +==================== +GL_Fullbrights_f -- johnfitz +==================== +*/ +static void GL_Fullbrights_f (cvar_t *var) +{ + TexMgr_ReloadNobrightImages (); +} + +/* +==================== +R_SetClearColor_f -- johnfitz +==================== +*/ +static void R_SetClearColor_f (cvar_t *var) +{ + byte *rgb; + int s; + + s = (int)r_clearcolor.value & 0xFF; + rgb = (byte*)(d_8to24table + s); + glClearColor (rgb[0]/255.0,rgb[1]/255.0,rgb[2]/255.0,0); +} + +/* +==================== +R_Novis_f -- johnfitz +==================== +*/ +static void R_VisChanged (cvar_t *var) +{ + extern int vis_changed; + vis_changed = 1; +} + +/* +=============== +R_Model_ExtraFlags_List_f -- johnfitz -- called when r_nolerp_list or r_noshadow_list cvar changes +=============== +*/ +static void R_Model_ExtraFlags_List_f (cvar_t *var) +{ + int i; + for (i=0; i < MAX_MODELS; i++) + Mod_SetExtraFlags (cl.model_precache[i]); +} + +/* +==================== +R_SetWateralpha_f -- ericw +==================== +*/ +static void R_SetWateralpha_f (cvar_t *var) +{ + map_wateralpha = var->value; +} + +/* +==================== +R_SetLavaalpha_f -- ericw +==================== +*/ +static void R_SetLavaalpha_f (cvar_t *var) +{ + map_lavaalpha = var->value; +} + +/* +==================== +R_SetTelealpha_f -- ericw +==================== +*/ +static void R_SetTelealpha_f (cvar_t *var) +{ + map_telealpha = var->value; +} + +/* +==================== +R_SetSlimealpha_f -- ericw +==================== +*/ +static void R_SetSlimealpha_f (cvar_t *var) +{ + map_slimealpha = var->value; +} + +/* +==================== +GL_WaterAlphaForSurfface -- ericw +==================== +*/ +float GL_WaterAlphaForSurface (msurface_t *fa) +{ + if (fa->flags & SURF_DRAWLAVA) + return map_lavaalpha > 0 ? map_lavaalpha : map_wateralpha; + else if (fa->flags & SURF_DRAWTELE) + return map_telealpha > 0 ? map_telealpha : map_wateralpha; + else if (fa->flags & SURF_DRAWSLIME) + return map_slimealpha > 0 ? map_slimealpha : map_wateralpha; + else + return map_wateralpha; +} + + +/* +=============== +R_Init +=============== +*/ +void R_Init (void) +{ + extern cvar_t gl_finish; + + Cmd_AddCommand ("timerefresh", R_TimeRefresh_f); + Cmd_AddCommand ("pointfile", R_ReadPointFile_f); + + Cvar_RegisterVariable (&r_norefresh); + Cvar_RegisterVariable (&r_lightmap); + Cvar_RegisterVariable (&r_fullbright); + Cvar_RegisterVariable (&r_drawentities); + Cvar_RegisterVariable (&r_drawviewmodel); + Cvar_RegisterVariable (&r_shadows); + Cvar_RegisterVariable (&r_wateralpha); + Cvar_SetCallback (&r_wateralpha, R_SetWateralpha_f); + Cvar_RegisterVariable (&r_dynamic); + Cvar_RegisterVariable (&r_novis); + Cvar_SetCallback (&r_novis, R_VisChanged); + Cvar_RegisterVariable (&r_speeds); + Cvar_RegisterVariable (&r_pos); + + Cvar_RegisterVariable (&gl_finish); + Cvar_RegisterVariable (&gl_clear); + Cvar_RegisterVariable (&gl_cull); + Cvar_RegisterVariable (&gl_smoothmodels); + Cvar_RegisterVariable (&gl_affinemodels); + Cvar_RegisterVariable (&gl_polyblend); + Cvar_RegisterVariable (&gl_flashblend); + Cvar_RegisterVariable (&gl_playermip); + Cvar_RegisterVariable (&gl_nocolors); + + //johnfitz -- new cvars + Cvar_RegisterVariable (&r_stereo); + Cvar_RegisterVariable (&r_stereodepth); + Cvar_RegisterVariable (&r_clearcolor); + Cvar_SetCallback (&r_clearcolor, R_SetClearColor_f); + Cvar_RegisterVariable (&r_waterquality); + Cvar_RegisterVariable (&r_oldwater); + Cvar_RegisterVariable (&r_waterwarp); + Cvar_RegisterVariable (&r_drawflat); + Cvar_RegisterVariable (&r_flatlightstyles); + Cvar_RegisterVariable (&r_oldskyleaf); + Cvar_SetCallback (&r_oldskyleaf, R_VisChanged); + Cvar_RegisterVariable (&r_drawworld); + Cvar_RegisterVariable (&r_showtris); + Cvar_RegisterVariable (&r_showbboxes); + Cvar_RegisterVariable (&gl_farclip); + Cvar_RegisterVariable (&gl_fullbrights); + Cvar_RegisterVariable (&gl_overbright); + Cvar_SetCallback (&gl_fullbrights, GL_Fullbrights_f); + Cvar_SetCallback (&gl_overbright, GL_Overbright_f); + Cvar_RegisterVariable (&gl_overbright_models); + Cvar_RegisterVariable (&r_lerpmodels); + Cvar_RegisterVariable (&r_lerpmove); + Cvar_RegisterVariable (&r_nolerp_list); + Cvar_SetCallback (&r_nolerp_list, R_Model_ExtraFlags_List_f); + Cvar_RegisterVariable (&r_noshadow_list); + Cvar_SetCallback (&r_noshadow_list, R_Model_ExtraFlags_List_f); + //johnfitz + + Cvar_RegisterVariable (&gl_zfix); // QuakeSpasm z-fighting fix + Cvar_RegisterVariable (&r_lavaalpha); + Cvar_RegisterVariable (&r_telealpha); + Cvar_RegisterVariable (&r_slimealpha); + Cvar_RegisterVariable (&r_scale); + Cvar_SetCallback (&r_lavaalpha, R_SetLavaalpha_f); + Cvar_SetCallback (&r_telealpha, R_SetTelealpha_f); + Cvar_SetCallback (&r_slimealpha, R_SetSlimealpha_f); + + R_InitParticles (); + R_SetClearColor_f (&r_clearcolor); //johnfitz + + Sky_Init (); //johnfitz + Fog_Init (); //johnfitz +} + +/* +=============== +R_TranslatePlayerSkin -- johnfitz -- rewritten. also, only handles new colors, not new skins +=============== +*/ +void R_TranslatePlayerSkin (int playernum) +{ + int top, bottom; + + top = (cl.scores[playernum].colors & 0xf0)>>4; + bottom = cl.scores[playernum].colors &15; + + //FIXME: if gl_nocolors is on, then turned off, the textures may be out of sync with the scoreboard colors. + if (!gl_nocolors.value) + if (playertextures[playernum]) + TexMgr_ReloadImage (playertextures[playernum], top, bottom); +} + +/* +=============== +R_TranslateNewPlayerSkin -- johnfitz -- split off of TranslatePlayerSkin -- this is called when +the skin or model actually changes, instead of just new colors +added bug fix from bengt jardup +=============== +*/ +void R_TranslateNewPlayerSkin (int playernum) +{ + char name[64]; + byte *pixels; + aliashdr_t *paliashdr; + int skinnum; + +//get correct texture pixels + currententity = &cl_entities[1+playernum]; + + if (!currententity->model || currententity->model->type != mod_alias) + return; + + paliashdr = (aliashdr_t *)Mod_Extradata (currententity->model); + + skinnum = currententity->skinnum; + + //TODO: move these tests to the place where skinnum gets received from the server + if (skinnum < 0 || skinnum >= paliashdr->numskins) + { + Con_DPrintf("(%d): Invalid player skin #%d\n", playernum, skinnum); + skinnum = 0; + } + + pixels = (byte *)paliashdr + paliashdr->texels[skinnum]; // This is not a persistent place! + +//upload new image + q_snprintf(name, sizeof(name), "player_%i", playernum); + playertextures[playernum] = TexMgr_LoadImage (currententity->model, name, paliashdr->skinwidth, paliashdr->skinheight, + SRC_INDEXED, pixels, paliashdr->gltextures[skinnum][0]->source_file, paliashdr->gltextures[skinnum][0]->source_offset, TEXPREF_PAD | TEXPREF_OVERWRITE); + +//now recolor it + R_TranslatePlayerSkin (playernum); +} + +/* +=============== +R_NewGame -- johnfitz -- handle a game switch +=============== +*/ +void R_NewGame (void) +{ + int i; + + //clear playertexture pointers (the textures themselves were freed by texmgr_newgame) + for (i=0; ientities); + if (!data) + return; // error + if (com_token[0] != '{') + return; // error + while (1) + { + data = COM_Parse(data); + if (!data) + return; // error + if (com_token[0] == '}') + break; // end of worldspawn + if (com_token[0] == '_') + q_strlcpy(key, com_token + 1, sizeof(key)); + else + q_strlcpy(key, com_token, sizeof(key)); + while (key[0] && key[strlen(key)-1] == ' ') // remove trailing spaces + key[strlen(key)-1] = 0; + data = COM_Parse(data); + if (!data) + return; // error + q_strlcpy(value, com_token, sizeof(value)); + + if (!strcmp("wateralpha", key)) + map_wateralpha = atof(value); + + if (!strcmp("lavaalpha", key)) + map_lavaalpha = atof(value); + + if (!strcmp("telealpha", key)) + map_telealpha = atof(value); + + if (!strcmp("slimealpha", key)) + map_slimealpha = atof(value); + } +} + + +/* +=============== +R_NewMap +=============== +*/ +void R_NewMap (void) +{ + int i; + + for (i=0 ; i<256 ; i++) + d_lightstylevalue[i] = 264; // normal light value + +// clear out efrags in case the level hasn't been reloaded +// FIXME: is this one short? + for (i=0 ; inumleafs ; i++) + cl.worldmodel->leafs[i].efrags = NULL; + + r_viewleaf = NULL; + R_ClearParticles (); + + GL_BuildLightmaps (); + GL_BuildBModelVertexBuffer (); + //ericw -- no longer load alias models into a VBO here, it's done in Mod_LoadAliasModel + + r_framecount = 0; //johnfitz -- paranoid? + r_visframecount = 0; //johnfitz -- paranoid? + + Sky_NewMap (); //johnfitz -- skybox in worldspawn + Fog_NewMap (); //johnfitz -- global fog in worldspawn + R_ParseWorldspawn (); //ericw -- wateralpha, lavaalpha, telealpha, slimealpha in worldspawn + + load_subdivide_size = gl_subdivide_size.value; //johnfitz -- is this the right place to set this? +} + +/* +==================== +R_TimeRefresh_f + +For program optimization +==================== +*/ +void R_TimeRefresh_f (void) +{ + int i; + float start, stop, time; + + if (cls.state != ca_connected) + { + Con_Printf("Not connected to a server\n"); + return; + } + + start = Sys_DoubleTime (); + for (i = 0; i < 128; i++) + { + GL_BeginRendering(&glx, &gly, &glwidth, &glheight); + r_refdef.viewangles[1] = i/128.0*360.0; + R_RenderView (); + GL_EndRendering (); + } + + glFinish (); + stop = Sys_DoubleTime (); + time = stop-start; + Con_Printf ("%f seconds (%f fps)\n", time, 128/time); +} + +void D_FlushCaches (void) +{ +} + +static GLuint gl_programs[16]; +static int gl_num_programs; + +static qboolean GL_CheckShader (GLuint shader) +{ + GLint status; + GL_GetShaderivFunc (shader, GL_COMPILE_STATUS, &status); + + if (status != GL_TRUE) + { + char infolog[1024]; + + memset(infolog, 0, sizeof(infolog)); + GL_GetShaderInfoLogFunc (shader, sizeof(infolog), NULL, infolog); + + Con_Warning ("GLSL program failed to compile: %s", infolog); + + return false; + } + return true; +} + +static qboolean GL_CheckProgram (GLuint program) +{ + GLint status; + GL_GetProgramivFunc (program, GL_LINK_STATUS, &status); + + if (status != GL_TRUE) + { + char infolog[1024]; + + memset(infolog, 0, sizeof(infolog)); + GL_GetProgramInfoLogFunc (program, sizeof(infolog), NULL, infolog); + + Con_Warning ("GLSL program failed to link: %s", infolog); + + return false; + } + return true; +} + +/* +============= +GL_GetUniformLocation +============= +*/ +GLint GL_GetUniformLocation (GLuint *programPtr, const char *name) +{ + GLint location; + + if (!programPtr) + return -1; + + location = GL_GetUniformLocationFunc(*programPtr, name); + if (location == -1) + { + Con_Warning("GL_GetUniformLocationFunc %s failed\n", name); + *programPtr = 0; + } + return location; +} + +/* +==================== +GL_CreateProgram + +Compiles and returns GLSL program. +==================== +*/ +GLuint GL_CreateProgram (const GLchar *vertSource, const GLchar *fragSource, int numbindings, const glsl_attrib_binding_t *bindings) +{ + int i; + GLuint program, vertShader, fragShader; + + if (!gl_glsl_able) + return 0; + + vertShader = GL_CreateShaderFunc (GL_VERTEX_SHADER); + GL_ShaderSourceFunc (vertShader, 1, &vertSource, NULL); + GL_CompileShaderFunc (vertShader); + if (!GL_CheckShader (vertShader)) + { + GL_DeleteShaderFunc (vertShader); + return 0; + } + + fragShader = GL_CreateShaderFunc (GL_FRAGMENT_SHADER); + GL_ShaderSourceFunc (fragShader, 1, &fragSource, NULL); + GL_CompileShaderFunc (fragShader); + if (!GL_CheckShader (fragShader)) + { + GL_DeleteShaderFunc (vertShader); + GL_DeleteShaderFunc (fragShader); + return 0; + } + + program = GL_CreateProgramFunc (); + GL_AttachShaderFunc (program, vertShader); + GL_DeleteShaderFunc (vertShader); + GL_AttachShaderFunc (program, fragShader); + GL_DeleteShaderFunc (fragShader); + + for (i = 0; i < numbindings; i++) + { + GL_BindAttribLocationFunc (program, bindings[i].attrib, bindings[i].name); + } + + GL_LinkProgramFunc (program); + + if (!GL_CheckProgram (program)) + { + GL_DeleteProgramFunc (program); + return 0; + } + else + { + if (gl_num_programs == (sizeof(gl_programs)/sizeof(GLuint))) + Host_Error ("gl_programs overflow"); + + gl_programs[gl_num_programs] = program; + gl_num_programs++; + + return program; + } +} + +/* +==================== +R_DeleteShaders + +Deletes any GLSL programs that have been created. +==================== +*/ +void R_DeleteShaders (void) +{ + int i; + + if (!gl_glsl_able) + return; + + for (i = 0; i < gl_num_programs; i++) + { + GL_DeleteProgramFunc (gl_programs[i]); + gl_programs[i] = 0; + } + gl_num_programs = 0; +} +GLuint current_array_buffer, current_element_array_buffer; + +/* +==================== +GL_BindBuffer + +glBindBuffer wrapper +==================== +*/ +void GL_BindBuffer (GLenum target, GLuint buffer) +{ + GLuint *cache; + + if (!gl_vbo_able) + return; + + switch (target) + { + case GL_ARRAY_BUFFER: + cache = ¤t_array_buffer; + break; + case GL_ELEMENT_ARRAY_BUFFER: + cache = ¤t_element_array_buffer; + break; + default: + Host_Error("GL_BindBuffer: unsupported target %d", (int)target); + return; + } + + if (*cache != buffer) + { + *cache = buffer; + GL_BindBufferFunc (target, *cache); + } +} + +/* +==================== +GL_ClearBufferBindings + +This must be called if you do anything that could make the cached bindings +invalid (e.g. manually binding, destroying the context). +==================== +*/ +void GL_ClearBufferBindings () +{ + if (!gl_vbo_able) + return; + + current_array_buffer = 0; + current_element_array_buffer = 0; + GL_BindBufferFunc (GL_ARRAY_BUFFER, 0); + GL_BindBufferFunc (GL_ELEMENT_ARRAY_BUFFER, 0); +} diff --git a/engine/Quake/gl_screen.c b/engine/Quake/gl_screen.c new file mode 100644 index 0000000..c733353 --- /dev/null +++ b/engine/Quake/gl_screen.c @@ -0,0 +1,1133 @@ +/* +Copyright (C) 1996-2001 Id Software, Inc. +Copyright (C) 2002-2009 John Fitzgibbons and others +Copyright (C) 2007-2008 Kristian Duske +Copyright (C) 2010-2014 QuakeSpasm developers + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +// screen.c -- master for refresh, status bar, console, chat, notify, etc + +#include "quakedef.h" + +/* + +background clear +rendering +turtle/net/ram icons +sbar +centerprint / slow centerprint +notify lines +intermission / finale overlay +loading plaque +console +menu + +required background clears +required update regions + + +syncronous draw mode or async +One off screen buffer, with updates either copied or xblited +Need to double buffer? + + +async draw will require the refresh area to be cleared, because it will be +xblited, but sync draw can just ignore it. + +sync +draw + +CenterPrint () +SlowPrint () +Screen_Update (); +Con_Printf (); + +net +turn off messages option + +the refresh is allways rendered, unless the console is full screen + + +console is: + notify lines + half + full + +*/ + + +int glx, gly, glwidth, glheight; + +float scr_con_current; +float scr_conlines; // lines of console to display + +//johnfitz -- new cvars +cvar_t scr_menuscale = {"scr_menuscale", "1", CVAR_ARCHIVE}; +cvar_t scr_sbarscale = {"scr_sbarscale", "1", CVAR_ARCHIVE}; +cvar_t scr_sbaralpha = {"scr_sbaralpha", "0.75", CVAR_ARCHIVE}; +cvar_t scr_conwidth = {"scr_conwidth", "0", CVAR_ARCHIVE}; +cvar_t scr_conscale = {"scr_conscale", "1", CVAR_ARCHIVE}; +cvar_t scr_crosshairscale = {"scr_crosshairscale", "1", CVAR_ARCHIVE}; +cvar_t scr_showfps = {"scr_showfps", "0", CVAR_NONE}; +cvar_t scr_clock = {"scr_clock", "0", CVAR_NONE}; +//johnfitz + +cvar_t scr_viewsize = {"viewsize","100", CVAR_ARCHIVE}; +cvar_t scr_fov = {"fov","90",CVAR_NONE}; // 10 - 170 +cvar_t scr_fov_adapt = {"fov_adapt","1",CVAR_ARCHIVE}; +cvar_t scr_conspeed = {"scr_conspeed","500",CVAR_ARCHIVE}; +cvar_t scr_centertime = {"scr_centertime","2",CVAR_NONE}; +cvar_t scr_showram = {"showram","1",CVAR_NONE}; +cvar_t scr_showturtle = {"showturtle","0",CVAR_NONE}; +cvar_t scr_showpause = {"showpause","1",CVAR_NONE}; +cvar_t scr_printspeed = {"scr_printspeed","8",CVAR_NONE}; +cvar_t gl_triplebuffer = {"gl_triplebuffer", "1", CVAR_ARCHIVE}; + +extern cvar_t crosshair; + +qboolean scr_initialized; // ready to draw + +qpic_t *scr_ram; +qpic_t *scr_net; +qpic_t *scr_turtle; + +int clearconsole; +int clearnotify; + +vrect_t scr_vrect; + +qboolean scr_disabled_for_loading; +qboolean scr_drawloading; +float scr_disabled_time; + +int scr_tileclear_updates = 0; //johnfitz + +void SCR_ScreenShot_f (void); + +/* +=============================================================================== + +CENTER PRINTING + +=============================================================================== +*/ + +char scr_centerstring[1024]; +float scr_centertime_start; // for slow victory printing +float scr_centertime_off; +int scr_center_lines; +int scr_erase_lines; +int scr_erase_center; + +/* +============== +SCR_CenterPrint + +Called for important messages that should stay in the center of the screen +for a few moments +============== +*/ +void SCR_CenterPrint (const char *str) //update centerprint data +{ + strncpy (scr_centerstring, str, sizeof(scr_centerstring)-1); + scr_centertime_off = scr_centertime.value; + scr_centertime_start = cl.time; + +// count the number of lines for centering + scr_center_lines = 1; + str = scr_centerstring; + while (*str) + { + if (*str == '\n') + scr_center_lines++; + str++; + } +} + +void SCR_DrawCenterString (void) //actually do the drawing +{ + char *start; + int l; + int j; + int x, y; + int remaining; + + GL_SetCanvas (CANVAS_MENU); //johnfitz + +// the finale prints the characters one at a time + if (cl.intermission) + remaining = scr_printspeed.value * (cl.time - scr_centertime_start); + else + remaining = 9999; + + scr_erase_center = 0; + start = scr_centerstring; + + if (scr_center_lines <= 4) + y = 200*0.35; //johnfitz -- 320x200 coordinate system + else + y = 48; + if (crosshair.value) + y -= 8; + + do + { + // scan the width of the line + for (l=0 ; l<40 ; l++) + if (start[l] == '\n' || !start[l]) + break; + x = (320 - l*8)/2; //johnfitz -- 320x200 coordinate system + for (j=0 ; j scr_erase_lines) + scr_erase_lines = scr_center_lines; + + scr_centertime_off -= host_frametime; + + if (scr_centertime_off <= 0 && !cl.intermission) + return; + if (key_dest != key_game) + return; + if (cl.paused) //johnfitz -- don't show centerprint during a pause + return; + + SCR_DrawCenterString (); +} + +//============================================================================= + +/* +==================== +AdaptFovx +Adapt a 4:3 horizontal FOV to the current screen size using the "Hor+" scaling: +2.0 * atan(width / height * 3.0 / 4.0 * tan(fov_x / 2.0)) +==================== +*/ +float AdaptFovx (float fov_x, float width, float height) +{ + float a, x; + + if (fov_x < 1 || fov_x > 179) + Sys_Error ("Bad fov: %f", fov_x); + + if (!scr_fov_adapt.value) + return fov_x; + if ((x = height / width) == 0.75) + return fov_x; + a = atan(0.75 / x * tan(fov_x / 360 * M_PI)); + a = a * 360 / M_PI; + return a; +} + +/* +==================== +CalcFovy +==================== +*/ +float CalcFovy (float fov_x, float width, float height) +{ + float a, x; + + if (fov_x < 1 || fov_x > 179) + Sys_Error ("Bad fov: %f", fov_x); + + x = width / tan(fov_x / 360 * M_PI); + a = atan(height / x); + a = a * 360 / M_PI; + return a; +} + +/* +================= +SCR_CalcRefdef + +Must be called whenever vid changes +Internal use only +================= +*/ +static void SCR_CalcRefdef (void) +{ + float size, scale; //johnfitz -- scale + +// force the status bar to redraw + Sbar_Changed (); + + scr_tileclear_updates = 0; //johnfitz + +// bound viewsize + if (scr_viewsize.value < 30) + Cvar_SetQuick (&scr_viewsize, "30"); + if (scr_viewsize.value > 120) + Cvar_SetQuick (&scr_viewsize, "120"); + +// bound fov + if (scr_fov.value < 10) + Cvar_SetQuick (&scr_fov, "10"); + if (scr_fov.value > 170) + Cvar_SetQuick (&scr_fov, "170"); + + vid.recalc_refdef = 0; + + //johnfitz -- rewrote this section + size = scr_viewsize.value; + scale = CLAMP (1.0, scr_sbarscale.value, (float)glwidth / 320.0); + + if (size >= 120 || cl.intermission || scr_sbaralpha.value < 1) //johnfitz -- scr_sbaralpha.value + sb_lines = 0; + else if (size >= 110) + sb_lines = 24 * scale; + else + sb_lines = 48 * scale; + + size = q_min(scr_viewsize.value, 100) / 100; + //johnfitz + + //johnfitz -- rewrote this section + r_refdef.vrect.width = q_max(glwidth * size, 96); //no smaller than 96, for icons + r_refdef.vrect.height = q_min(glheight * size, glheight - sb_lines); //make room for sbar + r_refdef.vrect.x = (glwidth - r_refdef.vrect.width)/2; + r_refdef.vrect.y = (glheight - sb_lines - r_refdef.vrect.height)/2; + //johnfitz + + r_refdef.fov_x = AdaptFovx(scr_fov.value, vid.width, vid.height); + r_refdef.fov_y = CalcFovy (r_refdef.fov_x, r_refdef.vrect.width, r_refdef.vrect.height); + + scr_vrect = r_refdef.vrect; +} + + +/* +================= +SCR_SizeUp_f + +Keybinding command +================= +*/ +void SCR_SizeUp_f (void) +{ + Cvar_SetValueQuick (&scr_viewsize, scr_viewsize.value+10); +} + + +/* +================= +SCR_SizeDown_f + +Keybinding command +================= +*/ +void SCR_SizeDown_f (void) +{ + Cvar_SetValueQuick (&scr_viewsize, scr_viewsize.value-10); +} + +static void SCR_Callback_refdef (cvar_t *var) +{ + vid.recalc_refdef = 1; +} + +/* +================== +SCR_Conwidth_f -- johnfitz -- called when scr_conwidth or scr_conscale changes +================== +*/ +void SCR_Conwidth_f (cvar_t *var) +{ + vid.recalc_refdef = 1; + vid.conwidth = (scr_conwidth.value > 0) ? (int)scr_conwidth.value : (scr_conscale.value > 0) ? (int)(vid.width/scr_conscale.value) : vid.width; + vid.conwidth = CLAMP (320, vid.conwidth, vid.width); + vid.conwidth &= 0xFFFFFFF8; + vid.conheight = vid.conwidth * vid.height / vid.width; +} + +//============================================================================ + +/* +================== +SCR_LoadPics -- johnfitz +================== +*/ +void SCR_LoadPics (void) +{ + scr_ram = Draw_PicFromWad ("ram"); + scr_net = Draw_PicFromWad ("net"); + scr_turtle = Draw_PicFromWad ("turtle"); +} + +/* +================== +SCR_Init +================== +*/ +void SCR_Init (void) +{ + //johnfitz -- new cvars + Cvar_RegisterVariable (&scr_menuscale); + Cvar_RegisterVariable (&scr_sbarscale); + Cvar_SetCallback (&scr_sbaralpha, SCR_Callback_refdef); + Cvar_RegisterVariable (&scr_sbaralpha); + Cvar_SetCallback (&scr_conwidth, &SCR_Conwidth_f); + Cvar_SetCallback (&scr_conscale, &SCR_Conwidth_f); + Cvar_RegisterVariable (&scr_conwidth); + Cvar_RegisterVariable (&scr_conscale); + Cvar_RegisterVariable (&scr_crosshairscale); + Cvar_RegisterVariable (&scr_showfps); + Cvar_RegisterVariable (&scr_clock); + //johnfitz + Cvar_SetCallback (&scr_fov, SCR_Callback_refdef); + Cvar_SetCallback (&scr_fov_adapt, SCR_Callback_refdef); + Cvar_SetCallback (&scr_viewsize, SCR_Callback_refdef); + Cvar_RegisterVariable (&scr_fov); + Cvar_RegisterVariable (&scr_fov_adapt); + Cvar_RegisterVariable (&scr_viewsize); + Cvar_RegisterVariable (&scr_conspeed); + Cvar_RegisterVariable (&scr_showram); + Cvar_RegisterVariable (&scr_showturtle); + Cvar_RegisterVariable (&scr_showpause); + Cvar_RegisterVariable (&scr_centertime); + Cvar_RegisterVariable (&scr_printspeed); + Cvar_RegisterVariable (&gl_triplebuffer); + + Cmd_AddCommand ("screenshot",SCR_ScreenShot_f); + Cmd_AddCommand ("sizeup",SCR_SizeUp_f); + Cmd_AddCommand ("sizedown",SCR_SizeDown_f); + + SCR_LoadPics (); //johnfitz + + scr_initialized = true; +} + +//============================================================================ + +/* +============== +SCR_DrawFPS -- johnfitz +============== +*/ +void SCR_DrawFPS (void) +{ + static double oldtime = 0; + static double lastfps = 0; + static int oldframecount = 0; + double elapsed_time; + int frames; + + elapsed_time = realtime - oldtime; + frames = r_framecount - oldframecount; + + if (elapsed_time < 0 || frames < 0) + { + oldtime = realtime; + oldframecount = r_framecount; + return; + } + // update value every 3/4 second + if (elapsed_time > 0.75) + { + lastfps = frames / elapsed_time; + oldtime = realtime; + oldframecount = r_framecount; + } + + if (scr_showfps.value) + { + char st[16]; + int x, y; + sprintf (st, "%4.0f fps", lastfps); + x = 320 - (strlen(st)<<3); + y = 200 - 8; + if (scr_clock.value) y -= 8; //make room for clock + GL_SetCanvas (CANVAS_BOTTOMRIGHT); + Draw_String (x, y, st); + scr_tileclear_updates = 0; + } +} + +/* +============== +SCR_DrawClock -- johnfitz +============== +*/ +void SCR_DrawClock (void) +{ + char str[12]; + + if (scr_clock.value == 1) + { + int minutes, seconds; + + minutes = cl.time / 60; + seconds = ((int)cl.time)%60; + + sprintf (str,"%i:%i%i", minutes, seconds/10, seconds%10); + } + else + return; + + //draw it + GL_SetCanvas (CANVAS_BOTTOMRIGHT); + Draw_String (320 - (strlen(str)<<3), 200 - 8, str); + + scr_tileclear_updates = 0; +} + +/* +============== +SCR_DrawDevStats +============== +*/ +void SCR_DrawDevStats (void) +{ + char str[40]; + int y = 25-9; //9=number of lines to print + int x = 0; //margin + + if (!devstats.value) + return; + + GL_SetCanvas (CANVAS_BOTTOMLEFT); + + Draw_Fill (x, y*8, 19*8, 9*8, 0, 0.5); //dark rectangle + + sprintf (str, "devstats |Curr Peak"); + Draw_String (x, (y++)*8-x, str); + + sprintf (str, "---------+---------"); + Draw_String (x, (y++)*8-x, str); + + sprintf (str, "Edicts |%4i %4i", dev_stats.edicts, dev_peakstats.edicts); + Draw_String (x, (y++)*8-x, str); + + sprintf (str, "Packet |%4i %4i", dev_stats.packetsize, dev_peakstats.packetsize); + Draw_String (x, (y++)*8-x, str); + + sprintf (str, "Visedicts|%4i %4i", dev_stats.visedicts, dev_peakstats.visedicts); + Draw_String (x, (y++)*8-x, str); + + sprintf (str, "Efrags |%4i %4i", dev_stats.efrags, dev_peakstats.efrags); + Draw_String (x, (y++)*8-x, str); + + sprintf (str, "Dlights |%4i %4i", dev_stats.dlights, dev_peakstats.dlights); + Draw_String (x, (y++)*8-x, str); + + sprintf (str, "Beams |%4i %4i", dev_stats.beams, dev_peakstats.beams); + Draw_String (x, (y++)*8-x, str); + + sprintf (str, "Tempents |%4i %4i", dev_stats.tempents, dev_peakstats.tempents); + Draw_String (x, (y++)*8-x, str); +} + +/* +============== +SCR_DrawRam +============== +*/ +void SCR_DrawRam (void) +{ + if (!scr_showram.value) + return; + + if (!r_cache_thrash) + return; + + GL_SetCanvas (CANVAS_DEFAULT); //johnfitz + + Draw_Pic (scr_vrect.x+32, scr_vrect.y, scr_ram); +} + +/* +============== +SCR_DrawTurtle +============== +*/ +void SCR_DrawTurtle (void) +{ + static int count; + + if (!scr_showturtle.value) + return; + + if (host_frametime < 0.1) + { + count = 0; + return; + } + + count++; + if (count < 3) + return; + + GL_SetCanvas (CANVAS_DEFAULT); //johnfitz + + Draw_Pic (scr_vrect.x, scr_vrect.y, scr_turtle); +} + +/* +============== +SCR_DrawNet +============== +*/ +void SCR_DrawNet (void) +{ + if (realtime - cl.last_received_message < 0.3) + return; + if (cls.demoplayback) + return; + + GL_SetCanvas (CANVAS_DEFAULT); //johnfitz + + Draw_Pic (scr_vrect.x+64, scr_vrect.y, scr_net); +} + +/* +============== +DrawPause +============== +*/ +void SCR_DrawPause (void) +{ + qpic_t *pic; + + if (!cl.paused) + return; + + if (!scr_showpause.value) // turn off for screenshots + return; + + GL_SetCanvas (CANVAS_MENU); //johnfitz + + pic = Draw_CachePic ("gfx/pause.lmp"); + Draw_Pic ( (320 - pic->width)/2, (240 - 48 - pic->height)/2, pic); //johnfitz -- stretched menus + + scr_tileclear_updates = 0; //johnfitz +} + +/* +============== +SCR_DrawLoading +============== +*/ +void SCR_DrawLoading (void) +{ + qpic_t *pic; + + if (!scr_drawloading) + return; + + GL_SetCanvas (CANVAS_MENU); //johnfitz + + pic = Draw_CachePic ("gfx/loading.lmp"); + Draw_Pic ( (320 - pic->width)/2, (240 - 48 - pic->height)/2, pic); //johnfitz -- stretched menus + + scr_tileclear_updates = 0; //johnfitz +} + +/* +============== +SCR_DrawCrosshair -- johnfitz +============== +*/ +void SCR_DrawCrosshair (void) +{ + if (!crosshair.value) + return; + + GL_SetCanvas (CANVAS_CROSSHAIR); + Draw_Character (-4, -4, '+'); //0,0 is center of viewport +} + + + +//============================================================================= + + +/* +================== +SCR_SetUpToDrawConsole +================== +*/ +void SCR_SetUpToDrawConsole (void) +{ + //johnfitz -- let's hack away the problem of slow console when host_timescale is <0 + extern cvar_t host_timescale; + float timescale; + //johnfitz + + Con_CheckResize (); + + if (scr_drawloading) + return; // never a console with loading plaque + +// decide on the height of the console + con_forcedup = !cl.worldmodel || cls.signon != SIGNONS; + + if (con_forcedup) + { + scr_conlines = glheight; //full screen //johnfitz -- glheight instead of vid.height + scr_con_current = scr_conlines; + } + else if (key_dest == key_console) + scr_conlines = glheight/2; //half screen //johnfitz -- glheight instead of vid.height + else + scr_conlines = 0; //none visible + + timescale = (host_timescale.value > 0) ? host_timescale.value : 1; //johnfitz -- timescale + + if (scr_conlines < scr_con_current) + { + // ericw -- (glheight/600.0) factor makes conspeed resolution independent, using 800x600 as a baseline + scr_con_current -= scr_conspeed.value*(glheight/600.0)*host_frametime/timescale; //johnfitz -- timescale + if (scr_conlines > scr_con_current) + scr_con_current = scr_conlines; + } + else if (scr_conlines > scr_con_current) + { + // ericw -- (glheight/600.0) + scr_con_current += scr_conspeed.value*(glheight/600.0)*host_frametime/timescale; //johnfitz -- timescale + if (scr_conlines < scr_con_current) + scr_con_current = scr_conlines; + } + + if (clearconsole++ < vid.numpages) + Sbar_Changed (); + + if (!con_forcedup && scr_con_current) + scr_tileclear_updates = 0; //johnfitz +} + +/* +================== +SCR_DrawConsole +================== +*/ +void SCR_DrawConsole (void) +{ + if (scr_con_current) + { + Con_DrawConsole (scr_con_current, true); + clearconsole = 0; + } + else + { + if (key_dest == key_game || key_dest == key_message) + Con_DrawNotify (); // only draw notify in game + } +} + + +/* +============================================================================== + +SCREEN SHOTS + +============================================================================== +*/ + +static void SCR_ScreenShot_Usage (void) +{ + Con_Printf ("usage: screenshot \n"); + Con_Printf (" format must be \"png\" or \"tga\" or \"jpg\"\n"); + Con_Printf (" quality must be 1-100\n"); + return; +} + +/* +================== +SCR_ScreenShot_f -- johnfitz -- rewritten to use Image_WriteTGA +================== +*/ +void SCR_ScreenShot_f (void) +{ + byte *buffer; + char ext[4]; + char imagename[16]; //johnfitz -- was [80] + char checkname[MAX_OSPATH]; + int i, quality; + qboolean ok; + + Q_strncpy (ext, "png", sizeof(ext)); + + if (Cmd_Argc () >= 2) + { + const char *requested_ext = Cmd_Argv (1); + + if (!q_strcasecmp ("png", requested_ext) + || !q_strcasecmp ("tga", requested_ext) + || !q_strcasecmp ("jpg", requested_ext)) + Q_strncpy (ext, requested_ext, sizeof(ext)); + else + { + SCR_ScreenShot_Usage (); + return; + } + } + +// read quality as the 3rd param (only used for JPG) + quality = 90; + if (Cmd_Argc () >= 3) + quality = Q_atoi (Cmd_Argv(2)); + if (quality < 1 || quality > 100) + { + SCR_ScreenShot_Usage (); + return; + } + +// find a file name to save it to + for (i=0; i<10000; i++) + { + q_snprintf (imagename, sizeof(imagename), "spasm%04i.%s", i, ext); // "fitz%04i.tga" + q_snprintf (checkname, sizeof(checkname), "%s/%s", com_gamedir, imagename); + if (Sys_FileTime(checkname) == -1) + break; // file doesn't exist + } + if (i == 10000) + { + Con_Printf ("SCR_ScreenShot_f: Couldn't find an unused filename\n"); + return; + } + +//get data + if (!(buffer = (byte *) malloc(glwidth*glheight*3))) + { + Con_Printf ("SCR_ScreenShot_f: Couldn't allocate memory\n"); + return; + } + + glPixelStorei (GL_PACK_ALIGNMENT, 1);/* for widths that aren't a multiple of 4 */ + glReadPixels (glx, gly, glwidth, glheight, GL_RGB, GL_UNSIGNED_BYTE, buffer); + +// now write the file + if (!q_strncasecmp (ext, "png", sizeof(ext))) + ok = Image_WritePNG (imagename, buffer, glwidth, glheight, 24, false); + else if (!q_strncasecmp (ext, "tga", sizeof(ext))) + ok = Image_WriteTGA (imagename, buffer, glwidth, glheight, 24, false); + else if (!q_strncasecmp (ext, "jpg", sizeof(ext))) + ok = Image_WriteJPG (imagename, buffer, glwidth, glheight, 24, quality, false); + else + ok = false; + + if (ok) + Con_Printf ("Wrote %s\n", imagename); + else + Con_Printf ("SCR_ScreenShot_f: Couldn't create %s\n", imagename); + + free (buffer); +} + + +//============================================================================= + + +/* +=============== +SCR_BeginLoadingPlaque + +================ +*/ +void SCR_BeginLoadingPlaque (void) +{ + S_StopAllSounds (true); + + if (cls.state != ca_connected) + return; + if (cls.signon != SIGNONS) + return; + +// redraw with no console and the loading plaque + Con_ClearNotify (); + scr_centertime_off = 0; + scr_con_current = 0; + + scr_drawloading = true; + Sbar_Changed (); + SCR_UpdateScreen (); + scr_drawloading = false; + + scr_disabled_for_loading = true; + scr_disabled_time = realtime; +} + +/* +=============== +SCR_EndLoadingPlaque + +================ +*/ +void SCR_EndLoadingPlaque (void) +{ + scr_disabled_for_loading = false; + Con_ClearNotify (); +} + +//============================================================================= + +const char *scr_notifystring; +qboolean scr_drawdialog; + +void SCR_DrawNotifyString (void) +{ + const char *start; + int l; + int j; + int x, y; + + GL_SetCanvas (CANVAS_MENU); //johnfitz + + start = scr_notifystring; + + y = 200 * 0.35; //johnfitz -- stretched overlays + + do + { + // scan the width of the line + for (l=0 ; l<40 ; l++) + if (start[l] == '\n' || !start[l]) + break; + x = (320 - l*8)/2; //johnfitz -- stretched overlays + for (j=0 ; j time1) + return false; + //johnfitz + + return (lastchar == 'y' || lastchar == 'Y' || lastkey == K_ABUTTON); +} + + +//============================================================================= + +//johnfitz -- deleted SCR_BringDownConsole + + +/* +================== +SCR_TileClear +johnfitz -- modified to use glwidth/glheight instead of vid.width/vid.height + also fixed the dimentions of right and top panels + also added scr_tileclear_updates +================== +*/ +void SCR_TileClear (void) +{ + //ericw -- added check for glsl gamma. TODO: remove this ugly optimization? + if (scr_tileclear_updates >= vid.numpages && !gl_clear.value && !(gl_glsl_gamma_able && vid_gamma.value != 1)) + return; + scr_tileclear_updates++; + + if (r_refdef.vrect.x > 0) + { + // left + Draw_TileClear (0, + 0, + r_refdef.vrect.x, + glheight - sb_lines); + // right + Draw_TileClear (r_refdef.vrect.x + r_refdef.vrect.width, + 0, + glwidth - r_refdef.vrect.x - r_refdef.vrect.width, + glheight - sb_lines); + } + + if (r_refdef.vrect.y > 0) + { + // top + Draw_TileClear (r_refdef.vrect.x, + 0, + r_refdef.vrect.width, + r_refdef.vrect.y); + // bottom + Draw_TileClear (r_refdef.vrect.x, + r_refdef.vrect.y + r_refdef.vrect.height, + r_refdef.vrect.width, + glheight - r_refdef.vrect.y - r_refdef.vrect.height - sb_lines); + } +} + +/* +================== +SCR_UpdateScreen + +This is called every frame, and can also be called explicitly to flush +text to the screen. + +WARNING: be very careful calling this from elsewhere, because the refresh +needs almost the entire 256k of stack space! +================== +*/ +void SCR_UpdateScreen (void) +{ + vid.numpages = (gl_triplebuffer.value) ? 3 : 2; + + if (scr_disabled_for_loading) + { + if (realtime - scr_disabled_time > 60) + { + scr_disabled_for_loading = false; + Con_Printf ("load failed.\n"); + } + else + return; + } + + if (!scr_initialized || !con_initialized) + return; // not initialized yet + + + GL_BeginRendering (&glx, &gly, &glwidth, &glheight); + + // + // determine size of refresh window + // + if (vid.recalc_refdef) + SCR_CalcRefdef (); + +// +// do 3D refresh drawing, and then update the screen +// + SCR_SetUpToDrawConsole (); + + V_RenderView (); + + GL_Set2D (); + + //FIXME: only call this when needed + SCR_TileClear (); + + if (scr_drawdialog) //new game confirm + { + if (con_forcedup) + Draw_ConsoleBackground (); + else + Sbar_Draw (); + Draw_FadeScreen (); + SCR_DrawNotifyString (); + } + else if (scr_drawloading) //loading + { + SCR_DrawLoading (); + Sbar_Draw (); + } + else if (cl.intermission == 1 && key_dest == key_game) //end of level + { + Sbar_IntermissionOverlay (); + } + else if (cl.intermission == 2 && key_dest == key_game) //end of episode + { + Sbar_FinaleOverlay (); + SCR_CheckDrawCenterString (); + } + else + { + SCR_DrawCrosshair (); //johnfitz + SCR_DrawRam (); + SCR_DrawNet (); + SCR_DrawTurtle (); + SCR_DrawPause (); + SCR_CheckDrawCenterString (); + Sbar_Draw (); + SCR_DrawDevStats (); //johnfitz + SCR_DrawFPS (); //johnfitz + SCR_DrawClock (); //johnfitz + SCR_DrawConsole (); + M_Draw (); + } + + V_UpdateBlend (); //johnfitz -- V_UpdatePalette cleaned up and renamed + + GLSLGamma_GammaCorrect (); + + GL_EndRendering (); +} + diff --git a/engine/Quake/gl_sky.c b/engine/Quake/gl_sky.c new file mode 100644 index 0000000..89868cc --- /dev/null +++ b/engine/Quake/gl_sky.c @@ -0,0 +1,1029 @@ +/* +Copyright (C) 1996-2001 Id Software, Inc. +Copyright (C) 2002-2009 John Fitzgibbons and others +Copyright (C) 2007-2008 Kristian Duske +Copyright (C) 2010-2014 QuakeSpasm developers + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ +//gl_sky.c + +#include "quakedef.h" + +#define MAX_CLIP_VERTS 64 + +float Fog_GetDensity(void); +float *Fog_GetColor(void); + +extern qmodel_t *loadmodel; +extern int rs_skypolys; //for r_speeds readout +extern int rs_skypasses; //for r_speeds readout +float skyflatcolor[3]; +float skymins[2][6], skymaxs[2][6]; + +char skybox_name[32] = ""; //name of current skybox, or "" if no skybox + +gltexture_t *skybox_textures[6]; +gltexture_t *solidskytexture, *alphaskytexture; + +extern cvar_t gl_farclip; +cvar_t r_fastsky = {"r_fastsky", "0", CVAR_NONE}; +cvar_t r_sky_quality = {"r_sky_quality", "12", CVAR_NONE}; +cvar_t r_skyalpha = {"r_skyalpha", "1", CVAR_NONE}; +cvar_t r_skyfog = {"r_skyfog","0.5",CVAR_NONE}; + +int skytexorder[6] = {0,2,1,3,4,5}; //for skybox + +vec3_t skyclip[6] = { + {1,1,0}, + {1,-1,0}, + {0,-1,1}, + {0,1,1}, + {1,0,1}, + {-1,0,1} +}; + +int st_to_vec[6][3] = +{ + {3,-1,2}, + {-3,1,2}, + {1,3,2}, + {-1,-3,2}, + {-2,-1,3}, // straight up + {2,-1,-3} // straight down +}; + +int vec_to_st[6][3] = +{ + {-2,3,1}, + {2,3,-1}, + {1,3,2}, + {-1,3,-2}, + {-2,-1,3}, + {-2,1,-3} +}; + +float skyfog; // ericw + +//============================================================================== +// +// INIT +// +//============================================================================== + +/* +============= +Sky_LoadTexture + +A sky texture is 256*128, with the left side being a masked overlay +============== +*/ +void Sky_LoadTexture (texture_t *mt) +{ + char texturename[64]; + int i, j, p, r, g, b, count; + byte *src; + static byte front_data[128*128]; //FIXME: Hunk_Alloc + static byte back_data[128*128]; //FIXME: Hunk_Alloc + unsigned *rgba; + + src = (byte *)mt + mt->offsets[0]; + +// extract back layer and upload + for (i=0 ; i<128 ; i++) + for (j=0 ; j<128 ; j++) + back_data[(i*128) + j] = src[i*256 + j + 128]; + + q_snprintf(texturename, sizeof(texturename), "%s:%s_back", loadmodel->name, mt->name); + solidskytexture = TexMgr_LoadImage (loadmodel, texturename, 128, 128, SRC_INDEXED, back_data, "", (src_offset_t)back_data, TEXPREF_NONE); + +// extract front layer and upload + for (i=0 ; i<128 ; i++) + for (j=0 ; j<128 ; j++) + { + front_data[(i*128) + j] = src[i*256 + j]; + if (front_data[(i*128) + j] == 0) + front_data[(i*128) + j] = 255; + } + + q_snprintf(texturename, sizeof(texturename), "%s:%s_front", loadmodel->name, mt->name); + alphaskytexture = TexMgr_LoadImage (loadmodel, texturename, 128, 128, SRC_INDEXED, front_data, "", (src_offset_t)front_data, TEXPREF_ALPHA); + +// calculate r_fastsky color based on average of all opaque foreground colors + r = g = b = count = 0; + for (i=0 ; i<128 ; i++) + for (j=0 ; j<128 ; j++) + { + p = src[i*256 + j]; + if (p != 0) + { + rgba = &d_8to24table[p]; + r += ((byte *)rgba)[0]; + g += ((byte *)rgba)[1]; + b += ((byte *)rgba)[2]; + count++; + } + } + skyflatcolor[0] = (float)r/(count*255); + skyflatcolor[1] = (float)g/(count*255); + skyflatcolor[2] = (float)b/(count*255); +} + +/* +================== +Sky_LoadSkyBox +================== +*/ +const char *suf[6] = {"rt", "bk", "lf", "ft", "up", "dn"}; +void Sky_LoadSkyBox (const char *name) +{ + int i, mark, width, height; + char filename[MAX_OSPATH]; + byte *data; + qboolean nonefound = true; + + if (strcmp(skybox_name, name) == 0) + return; //no change + + //purge old textures + for (i=0; i<6; i++) + { + if (skybox_textures[i] && skybox_textures[i] != notexture) + TexMgr_FreeTexture (skybox_textures[i]); + skybox_textures[i] = NULL; + } + + //turn off skybox if sky is set to "" + if (name[0] == 0) + { + skybox_name[0] = 0; + return; + } + + //load textures + for (i=0; i<6; i++) + { + mark = Hunk_LowMark (); + q_snprintf (filename, sizeof(filename), "gfx/env/%s%s", name, suf[i]); + data = Image_LoadImage (filename, &width, &height); + if (data) + { + skybox_textures[i] = TexMgr_LoadImage (cl.worldmodel, filename, width, height, SRC_RGBA, data, filename, 0, TEXPREF_NONE); + nonefound = false; + } + else + { + Con_Printf ("Couldn't load %s\n", filename); + skybox_textures[i] = notexture; + } + Hunk_FreeToLowMark (mark); + } + + if (nonefound) // go back to scrolling sky if skybox is totally missing + { + for (i=0; i<6; i++) + { + if (skybox_textures[i] && skybox_textures[i] != notexture) + TexMgr_FreeTexture (skybox_textures[i]); + skybox_textures[i] = NULL; + } + skybox_name[0] = 0; + return; + } + + strcpy(skybox_name, name); +} + +/* +================= +Sky_NewMap +================= +*/ +void Sky_NewMap (void) +{ + char key[128], value[4096]; + const char *data; + int i; + + // + // initially no sky + // + skybox_name[0] = 0; + for (i=0; i<6; i++) + skybox_textures[i] = NULL; + skyfog = r_skyfog.value; + + // + // read worldspawn (this is so ugly, and shouldn't it be done on the server?) + // + data = cl.worldmodel->entities; + if (!data) + return; //FIXME: how could this possibly ever happen? -- if there's no + // worldspawn then the sever wouldn't send the loadmap message to the client + + data = COM_Parse(data); + if (!data) //should never happen + return; // error + if (com_token[0] != '{') //should never happen + return; // error + while (1) + { + data = COM_Parse(data); + if (!data) + return; // error + if (com_token[0] == '}') + break; // end of worldspawn + if (com_token[0] == '_') + q_strlcpy(key, com_token + 1, sizeof(key)); + else + q_strlcpy(key, com_token, sizeof(key)); + while (key[0] && key[strlen(key)-1] == ' ') // remove trailing spaces + key[strlen(key)-1] = 0; + data = COM_Parse(data); + if (!data) + return; // error + q_strlcpy(value, com_token, sizeof(value)); + + if (!strcmp("sky", key)) + Sky_LoadSkyBox(value); + + if (!strcmp("skyfog", key)) + skyfog = atof(value); + +#if 1 //also accept non-standard keys + else if (!strcmp("skyname", key)) //half-life + Sky_LoadSkyBox(value); + else if (!strcmp("qlsky", key)) //quake lives + Sky_LoadSkyBox(value); +#endif + } +} + +/* +================= +Sky_SkyCommand_f +================= +*/ +void Sky_SkyCommand_f (void) +{ + switch (Cmd_Argc()) + { + case 1: + Con_Printf("\"sky\" is \"%s\"\n", skybox_name); + break; + case 2: + Sky_LoadSkyBox(Cmd_Argv(1)); + break; + default: + Con_Printf("usage: sky \n"); + } +} + +/* +==================== +R_SetSkyfog_f -- ericw +==================== +*/ +static void R_SetSkyfog_f (cvar_t *var) +{ +// clear any skyfog setting from worldspawn + skyfog = var->value; +} + +/* +============= +Sky_Init +============= +*/ +void Sky_Init (void) +{ + int i; + + Cvar_RegisterVariable (&r_fastsky); + Cvar_RegisterVariable (&r_sky_quality); + Cvar_RegisterVariable (&r_skyalpha); + Cvar_RegisterVariable (&r_skyfog); + Cvar_SetCallback (&r_skyfog, R_SetSkyfog_f); + + Cmd_AddCommand ("sky",Sky_SkyCommand_f); + + for (i=0; i<6; i++) + skybox_textures[i] = NULL; +} + +//============================================================================== +// +// PROCESS SKY SURFS +// +//============================================================================== + +/* +================= +Sky_ProjectPoly + +update sky bounds +================= +*/ +void Sky_ProjectPoly (int nump, vec3_t vecs) +{ + int i,j; + vec3_t v, av; + float s, t, dv; + int axis; + float *vp; + + // decide which face it maps to + VectorCopy (vec3_origin, v); + for (i=0, vp=vecs ; i av[1] && av[0] > av[2]) + { + if (v[0] < 0) + axis = 1; + else + axis = 0; + } + else if (av[1] > av[2] && av[1] > av[0]) + { + if (v[1] < 0) + axis = 3; + else + axis = 2; + } + else + { + if (v[2] < 0) + axis = 5; + else + axis = 4; + } + + // project new texture coords + for (i=0 ; i 0) + dv = vecs[j - 1]; + else + dv = -vecs[-j - 1]; + + j = vec_to_st[axis][0]; + if (j < 0) + s = -vecs[-j -1] / dv; + else + s = vecs[j-1] / dv; + j = vec_to_st[axis][1]; + if (j < 0) + t = -vecs[-j -1] / dv; + else + t = vecs[j-1] / dv; + + if (s < skymins[0][axis]) + skymins[0][axis] = s; + if (t < skymins[1][axis]) + skymins[1][axis] = t; + if (s > skymaxs[0][axis]) + skymaxs[0][axis] = s; + if (t > skymaxs[1][axis]) + skymaxs[1][axis] = t; + } +} + +/* +================= +Sky_ClipPoly +================= +*/ +void Sky_ClipPoly (int nump, vec3_t vecs, int stage) +{ + float *norm; + float *v; + qboolean front, back; + float d, e; + float dists[MAX_CLIP_VERTS]; + int sides[MAX_CLIP_VERTS]; + vec3_t newv[2][MAX_CLIP_VERTS]; + int newc[2]; + int i, j; + + if (nump > MAX_CLIP_VERTS-2) + Sys_Error ("Sky_ClipPoly: MAX_CLIP_VERTS"); + if (stage == 6) // fully clipped + { + Sky_ProjectPoly (nump, vecs); + return; + } + + front = back = false; + norm = skyclip[stage]; + for (i=0, v = vecs ; i ON_EPSILON) + { + front = true; + sides[i] = SIDE_FRONT; + } + else if (d < ON_EPSILON) + { + back = true; + sides[i] = SIDE_BACK; + } + else + sides[i] = SIDE_ON; + dists[i] = d; + } + + if (!front || !back) + { // not clipped + Sky_ClipPoly (nump, vecs, stage+1); + return; + } + + // clip it + sides[i] = sides[0]; + dists[i] = dists[0]; + VectorCopy (vecs, (vecs+(i*3)) ); + newc[0] = newc[1] = 0; + + for (i=0, v = vecs ; inumverts ; i++) + VectorSubtract (p->verts[i], r_origin, verts[i]); + Sky_ClipPoly (p->numverts, verts[0], 0); + } +} + +/* +================ +Sky_ProcessTextureChains -- handles sky polys in world model +================ +*/ +void Sky_ProcessTextureChains (void) +{ + int i; + msurface_t *s; + texture_t *t; + + if (!r_drawworld_cheatsafe) + return; + + for (i=0 ; inumtextures ; i++) + { + t = cl.worldmodel->textures[i]; + + if (!t || !t->texturechains[chain_world] || !(t->texturechains[chain_world]->flags & SURF_DRAWSKY)) + continue; + + for (s = t->texturechains[chain_world]; s; s = s->texturechain) + if (!s->culled) + Sky_ProcessPoly (s->polys); + } +} + +/* +================ +Sky_ProcessEntities -- handles sky polys on brush models +================ +*/ +void Sky_ProcessEntities (void) +{ + entity_t *e; + msurface_t *s; + glpoly_t *p; + int i,j,k,mark; + float dot; + qboolean rotated; + vec3_t temp, forward, right, up; + + if (!r_drawentities.value) + return; + + for (i=0 ; imodel->type != mod_brush) + continue; + + if (R_CullModelForEntity(e)) + continue; + + if (e->alpha == ENTALPHA_ZERO) + continue; + + VectorSubtract (r_refdef.vieworg, e->origin, modelorg); + if (e->angles[0] || e->angles[1] || e->angles[2]) + { + rotated = true; + AngleVectors (e->angles, forward, right, up); + VectorCopy (modelorg, temp); + modelorg[0] = DotProduct (temp, forward); + modelorg[1] = -DotProduct (temp, right); + modelorg[2] = DotProduct (temp, up); + } + else + rotated = false; + + s = &e->model->surfaces[e->model->firstmodelsurface]; + + for (j=0 ; jmodel->nummodelsurfaces ; j++, s++) + { + if (s->flags & SURF_DRAWSKY) + { + dot = DotProduct (modelorg, s->plane->normal) - s->plane->dist; + if (((s->flags & SURF_PLANEBACK) && (dot < -BACKFACE_EPSILON)) || + (!(s->flags & SURF_PLANEBACK) && (dot > BACKFACE_EPSILON))) + { + //copy the polygon and translate manually, since Sky_ProcessPoly needs it to be in world space + mark = Hunk_LowMark(); + p = (glpoly_t *) Hunk_Alloc (sizeof(*s->polys)); //FIXME: don't allocate for each poly + p->numverts = s->polys->numverts; + for (k=0; knumverts; k++) + { + if (rotated) + { + p->verts[k][0] = e->origin[0] + s->polys->verts[k][0] * forward[0] + - s->polys->verts[k][1] * right[0] + + s->polys->verts[k][2] * up[0]; + p->verts[k][1] = e->origin[1] + s->polys->verts[k][0] * forward[1] + - s->polys->verts[k][1] * right[1] + + s->polys->verts[k][2] * up[1]; + p->verts[k][2] = e->origin[2] + s->polys->verts[k][0] * forward[2] + - s->polys->verts[k][1] * right[2] + + s->polys->verts[k][2] * up[2]; + } + else + VectorAdd(s->polys->verts[k], e->origin, p->verts[k]); + } + Sky_ProcessPoly (p); + Hunk_FreeToLowMark (mark); + } + } + } + } +} + +//============================================================================== +// +// RENDER SKYBOX +// +//============================================================================== + +/* +============== +Sky_EmitSkyBoxVertex +============== +*/ +void Sky_EmitSkyBoxVertex (float s, float t, int axis) +{ + vec3_t v, b; + int j, k; + float w, h; + + b[0] = s * gl_farclip.value / sqrt(3.0); + b[1] = t * gl_farclip.value / sqrt(3.0); + b[2] = gl_farclip.value / sqrt(3.0); + + for (j=0 ; j<3 ; j++) + { + k = st_to_vec[axis][j]; + if (k < 0) + v[j] = -b[-k - 1]; + else + v[j] = b[k - 1]; + v[j] += r_origin[j]; + } + + // convert from range [-1,1] to [0,1] + s = (s+1)*0.5; + t = (t+1)*0.5; + + // avoid bilerp seam + w = skybox_textures[skytexorder[axis]]->width; + h = skybox_textures[skytexorder[axis]]->height; + s = s * (w-1)/w + 0.5/w; + t = t * (h-1)/h + 0.5/h; + + t = 1.0 - t; + glTexCoord2f (s, t); + glVertex3fv (v); +} + +/* +============== +Sky_DrawSkyBox + +FIXME: eliminate cracks by adding an extra vert on tjuncs +============== +*/ +void Sky_DrawSkyBox (void) +{ + int i; + + for (i=0 ; i<6 ; i++) + { + if (skymins[0][i] >= skymaxs[0][i] || skymins[1][i] >= skymaxs[1][i]) + continue; + + GL_Bind (skybox_textures[skytexorder[i]]); + +#if 1 //FIXME: this is to avoid tjunctions until i can do it the right way + skymins[0][i] = -1; + skymins[1][i] = -1; + skymaxs[0][i] = 1; + skymaxs[1][i] = 1; +#endif + glBegin (GL_QUADS); + Sky_EmitSkyBoxVertex (skymins[0][i], skymins[1][i], i); + Sky_EmitSkyBoxVertex (skymins[0][i], skymaxs[1][i], i); + Sky_EmitSkyBoxVertex (skymaxs[0][i], skymaxs[1][i], i); + Sky_EmitSkyBoxVertex (skymaxs[0][i], skymins[1][i], i); + glEnd (); + + rs_skypolys++; + rs_skypasses++; + + if (Fog_GetDensity() > 0 && skyfog > 0) + { + float *c; + + c = Fog_GetColor(); + glEnable (GL_BLEND); + glDisable (GL_TEXTURE_2D); + glColor4f (c[0],c[1],c[2], CLAMP(0.0,skyfog,1.0)); + + glBegin (GL_QUADS); + Sky_EmitSkyBoxVertex (skymins[0][i], skymins[1][i], i); + Sky_EmitSkyBoxVertex (skymins[0][i], skymaxs[1][i], i); + Sky_EmitSkyBoxVertex (skymaxs[0][i], skymaxs[1][i], i); + Sky_EmitSkyBoxVertex (skymaxs[0][i], skymins[1][i], i); + glEnd (); + + glColor3f (1, 1, 1); + glEnable (GL_TEXTURE_2D); + glDisable (GL_BLEND); + + rs_skypasses++; + } + } +} + +//============================================================================== +// +// RENDER CLOUDS +// +//============================================================================== + +/* +============== +Sky_SetBoxVert +============== +*/ +void Sky_SetBoxVert (float s, float t, int axis, vec3_t v) +{ + vec3_t b; + int j, k; + + b[0] = s * gl_farclip.value / sqrt(3.0); + b[1] = t * gl_farclip.value / sqrt(3.0); + b[2] = gl_farclip.value / sqrt(3.0); + + for (j=0 ; j<3 ; j++) + { + k = st_to_vec[axis][j]; + if (k < 0) + v[j] = -b[-k - 1]; + else + v[j] = b[k - 1]; + v[j] += r_origin[j]; + } +} + +/* +============= +Sky_GetTexCoord +============= +*/ +void Sky_GetTexCoord (vec3_t v, float speed, float *s, float *t) +{ + vec3_t dir; + float length, scroll; + + VectorSubtract (v, r_origin, dir); + dir[2] *= 3; // flatten the sphere + + length = dir[0]*dir[0] + dir[1]*dir[1] + dir[2]*dir[2]; + length = sqrt (length); + length = 6*63/length; + + scroll = cl.time*speed; + scroll -= (int)scroll & ~127; + + *s = (scroll + dir[0] * length) * (1.0/128); + *t = (scroll + dir[1] * length) * (1.0/128); +} + +/* +=============== +Sky_DrawFaceQuad +=============== +*/ +void Sky_DrawFaceQuad (glpoly_t *p) +{ + float s, t; + float *v; + int i; + + if (gl_mtexable && r_skyalpha.value >= 1.0) + { + GL_Bind (solidskytexture); + GL_EnableMultitexture(); + GL_Bind (alphaskytexture); + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL); + + glBegin (GL_QUADS); + for (i=0, v=p->verts[0] ; i<4 ; i++, v+=VERTEXSIZE) + { + Sky_GetTexCoord (v, 8, &s, &t); + GL_MTexCoord2fFunc (GL_TEXTURE0_ARB, s, t); + Sky_GetTexCoord (v, 16, &s, &t); + GL_MTexCoord2fFunc (GL_TEXTURE1_ARB, s, t); + glVertex3fv (v); + } + glEnd (); + + GL_DisableMultitexture(); + + rs_skypolys++; + rs_skypasses++; + } + else + { + GL_Bind (solidskytexture); + + if (r_skyalpha.value < 1.0) + glColor3f (1, 1, 1); + + glBegin (GL_QUADS); + for (i=0, v=p->verts[0] ; i<4 ; i++, v+=VERTEXSIZE) + { + Sky_GetTexCoord (v, 8, &s, &t); + glTexCoord2f (s, t); + glVertex3fv (v); + } + glEnd (); + + GL_Bind (alphaskytexture); + glEnable (GL_BLEND); + + if (r_skyalpha.value < 1.0) + glColor4f (1, 1, 1, r_skyalpha.value); + + glBegin (GL_QUADS); + for (i=0, v=p->verts[0] ; i<4 ; i++, v+=VERTEXSIZE) + { + Sky_GetTexCoord (v, 16, &s, &t); + glTexCoord2f (s, t); + glVertex3fv (v); + } + glEnd (); + + glDisable (GL_BLEND); + + rs_skypolys++; + rs_skypasses += 2; + } + + if (Fog_GetDensity() > 0 && skyfog > 0) + { + float *c; + + c = Fog_GetColor(); + glEnable (GL_BLEND); + glDisable (GL_TEXTURE_2D); + glColor4f (c[0],c[1],c[2], CLAMP(0.0,skyfog,1.0)); + + glBegin (GL_QUADS); + for (i=0, v=p->verts[0] ; i<4 ; i++, v+=VERTEXSIZE) + glVertex3fv (v); + glEnd (); + + glColor3f (1, 1, 1); + glEnable (GL_TEXTURE_2D); + glDisable (GL_BLEND); + + rs_skypasses++; + } +} + +/* +============== +Sky_DrawFace +============== +*/ + +void Sky_DrawFace (int axis) +{ + glpoly_t *p; + vec3_t verts[4]; + int i, j, start; + float di,qi,dj,qj; + vec3_t vup, vright, temp, temp2; + + Sky_SetBoxVert(-1.0, -1.0, axis, verts[0]); + Sky_SetBoxVert(-1.0, 1.0, axis, verts[1]); + Sky_SetBoxVert(1.0, 1.0, axis, verts[2]); + Sky_SetBoxVert(1.0, -1.0, axis, verts[3]); + + start = Hunk_LowMark (); + p = (glpoly_t *) Hunk_Alloc(sizeof(glpoly_t)); + + VectorSubtract(verts[2],verts[3],vup); + VectorSubtract(verts[2],verts[1],vright); + + di = q_max((int)r_sky_quality.value, 1); + qi = 1.0 / di; + dj = (axis < 4) ? di*2 : di; //subdivide vertically more than horizontally on skybox sides + qj = 1.0 / dj; + + for (i=0; i skymaxs[0][axis]/2+0.5 || + j*qj < skymins[1][axis]/2+0.5 - qj || j*qj > skymaxs[1][axis]/2+0.5) + continue; + + //if (i&1 ^ j&1) continue; //checkerboard test + VectorScale (vright, qi*i, temp); + VectorScale (vup, qj*j, temp2); + VectorAdd(temp,temp2,temp); + VectorAdd(verts[0],temp,p->verts[0]); + + VectorScale (vup, qj, temp); + VectorAdd (p->verts[0],temp,p->verts[1]); + + VectorScale (vright, qi, temp); + VectorAdd (p->verts[1],temp,p->verts[2]); + + VectorAdd (p->verts[0],temp,p->verts[3]); + + Sky_DrawFaceQuad (p); + } + } + Hunk_FreeToLowMark (start); +} + +/* +============== +Sky_DrawSkyLayers + +draws the old-style scrolling cloud layers +============== +*/ +void Sky_DrawSkyLayers (void) +{ + int i; + + if (r_skyalpha.value < 1.0) + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + + for (i=0 ; i<6 ; i++) + if (skymins[0][i] < skymaxs[0][i] && skymins[1][i] < skymaxs[1][i]) + Sky_DrawFace (i); + + if (r_skyalpha.value < 1.0) + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); +} + +/* +============== +Sky_DrawSky + +called once per frame before drawing anything else +============== +*/ +void Sky_DrawSky (void) +{ + int i; + + //in these special render modes, the sky faces are handled in the normal world/brush renderer + if (r_drawflat_cheatsafe || r_lightmap_cheatsafe ) + return; + + // + // reset sky bounds + // + for (i=0 ; i<6 ; i++) + { + skymins[0][i] = skymins[1][i] = 9999; + skymaxs[0][i] = skymaxs[1][i] = -9999; + } + + // + // process world and bmodels: draw flat-shaded sky surfs, and update skybounds + // + Fog_DisableGFog (); + glDisable (GL_TEXTURE_2D); + if (Fog_GetDensity() > 0) + glColor3fv (Fog_GetColor()); + else + glColor3fv (skyflatcolor); + Sky_ProcessTextureChains (); + Sky_ProcessEntities (); + glColor3f (1, 1, 1); + glEnable (GL_TEXTURE_2D); + + // + // render slow sky: cloud layers or skybox + // + if (!r_fastsky.value && !(Fog_GetDensity() > 0 && skyfog >= 1)) + { + glDepthFunc(GL_GEQUAL); + glDepthMask(0); + + if (skybox_name[0]) + Sky_DrawSkyBox (); + else + Sky_DrawSkyLayers(); + + glDepthMask(1); + glDepthFunc(GL_LEQUAL); + } + + Fog_EnableGFog (); +} diff --git a/engine/Quake/gl_texmgr.c b/engine/Quake/gl_texmgr.c new file mode 100644 index 0000000..188907d --- /dev/null +++ b/engine/Quake/gl_texmgr.c @@ -0,0 +1,1544 @@ +/* +Copyright (C) 1996-2001 Id Software, Inc. +Copyright (C) 2002-2009 John Fitzgibbons and others +Copyright (C) 2007-2008 Kristian Duske +Copyright (C) 2010-2014 QuakeSpasm developers + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +//gl_texmgr.c -- fitzquake's texture manager. manages opengl texture images + +#include "quakedef.h" + +const int gl_solid_format = 3; +const int gl_alpha_format = 4; + +static cvar_t gl_texturemode = {"gl_texturemode", "", CVAR_ARCHIVE}; +static cvar_t gl_texture_anisotropy = {"gl_texture_anisotropy", "1", CVAR_ARCHIVE}; +static cvar_t gl_max_size = {"gl_max_size", "0", CVAR_NONE}; +static cvar_t gl_picmip = {"gl_picmip", "0", CVAR_NONE}; +static GLint gl_hardware_maxsize; + +#define MAX_GLTEXTURES 2048 +static int numgltextures; +static gltexture_t *active_gltextures, *free_gltextures; +gltexture_t *notexture, *nulltexture; + +unsigned int d_8to24table[256]; +unsigned int d_8to24table_fbright[256]; +unsigned int d_8to24table_fbright_fence[256]; +unsigned int d_8to24table_nobright[256]; +unsigned int d_8to24table_nobright_fence[256]; +unsigned int d_8to24table_conchars[256]; +unsigned int d_8to24table_shirt[256]; +unsigned int d_8to24table_pants[256]; + +/* +================================================================================ + + COMMANDS + +================================================================================ +*/ + +typedef struct +{ + int magfilter; + int minfilter; + const char *name; +} glmode_t; +static glmode_t glmodes[] = { + {GL_NEAREST, GL_NEAREST, "GL_NEAREST"}, + {GL_NEAREST, GL_NEAREST_MIPMAP_NEAREST, "GL_NEAREST_MIPMAP_NEAREST"}, + {GL_NEAREST, GL_NEAREST_MIPMAP_LINEAR, "GL_NEAREST_MIPMAP_LINEAR"}, + {GL_LINEAR, GL_LINEAR, "GL_LINEAR"}, + {GL_LINEAR, GL_LINEAR_MIPMAP_NEAREST, "GL_LINEAR_MIPMAP_NEAREST"}, + {GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, "GL_LINEAR_MIPMAP_LINEAR"}, +}; +#define NUM_GLMODES (int)(sizeof(glmodes)/sizeof(glmodes[0])) +static int glmode_idx = NUM_GLMODES - 1; /* trilinear */ + +/* +=============== +TexMgr_DescribeTextureModes_f -- report available texturemodes +=============== +*/ +static void TexMgr_DescribeTextureModes_f (void) +{ + int i; + + for (i = 0; i < NUM_GLMODES; i++) + Con_SafePrintf (" %2i: %s\n", i + 1, glmodes[i].name); + + Con_Printf ("%i modes\n", i); +} + +/* +=============== +TexMgr_SetFilterModes +=============== +*/ +static void TexMgr_SetFilterModes (gltexture_t *glt) +{ + GL_Bind (glt); + + if (glt->flags & TEXPREF_NEAREST) + { + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + } + else if (glt->flags & TEXPREF_LINEAR) + { + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + } + else if (glt->flags & TEXPREF_MIPMAP) + { + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, glmodes[glmode_idx].magfilter); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, glmodes[glmode_idx].minfilter); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, gl_texture_anisotropy.value); + } + else + { + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, glmodes[glmode_idx].magfilter); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, glmodes[glmode_idx].magfilter); + } +} + +/* +=============== +TexMgr_TextureMode_f -- called when gl_texturemode changes +=============== +*/ +static void TexMgr_TextureMode_f (cvar_t *var) +{ + gltexture_t *glt; + int i; + + for (i = 0; i < NUM_GLMODES; i++) + { + if (!Q_strcmp (glmodes[i].name, gl_texturemode.string)) + { + if (glmode_idx != i) + { + glmode_idx = i; + for (glt = active_gltextures; glt; glt = glt->next) + TexMgr_SetFilterModes (glt); + Sbar_Changed (); //sbar graphics need to be redrawn with new filter mode + //FIXME: warpimages need to be redrawn, too. + } + return; + } + } + + for (i = 0; i < NUM_GLMODES; i++) + { + if (!q_strcasecmp (glmodes[i].name, gl_texturemode.string)) + { + Cvar_SetQuick (&gl_texturemode, glmodes[i].name); + return; + } + } + + i = atoi(gl_texturemode.string); + if (i >= 1 && i <= NUM_GLMODES) + { + Cvar_SetQuick (&gl_texturemode, glmodes[i-1].name); + return; + } + + Con_Printf ("\"%s\" is not a valid texturemode\n", gl_texturemode.string); + Cvar_SetQuick (&gl_texturemode, glmodes[glmode_idx].name); +} + +/* +=============== +TexMgr_Anisotropy_f -- called when gl_texture_anisotropy changes +=============== +*/ +static void TexMgr_Anisotropy_f (cvar_t *var) +{ + if (gl_texture_anisotropy.value < 1) + { + Cvar_SetQuick (&gl_texture_anisotropy, "1"); + } + else if (gl_texture_anisotropy.value > gl_max_anisotropy) + { + Cvar_SetValueQuick (&gl_texture_anisotropy, gl_max_anisotropy); + } + else + { + gltexture_t *glt; + for (glt = active_gltextures; glt; glt = glt->next) + { + /* TexMgr_SetFilterModes (glt);*/ + if (glt->flags & TEXPREF_MIPMAP) { + GL_Bind (glt); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, glmodes[glmode_idx].magfilter); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, glmodes[glmode_idx].minfilter); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, gl_texture_anisotropy.value); + } + } + } +} + +/* +=============== +TexMgr_Imagelist_f -- report loaded textures +=============== +*/ +static void TexMgr_Imagelist_f (void) +{ + float mb; + float texels = 0; + gltexture_t *glt; + + for (glt = active_gltextures; glt; glt = glt->next) + { + Con_SafePrintf (" %4i x%4i %s\n", glt->width, glt->height, glt->name); + if (glt->flags & TEXPREF_MIPMAP) + texels += glt->width * glt->height * 4.0f / 3.0f; + else + texels += (glt->width * glt->height); + } + + mb = texels * (Cvar_VariableValue("vid_bpp") / 8.0f) / 0x100000; + Con_Printf ("%i textures %i pixels %1.1f megabytes\n", numgltextures, (int)texels, mb); +} + +/* +=============== +TexMgr_Imagedump_f -- dump all current textures to TGA files +=============== +*/ +static void TexMgr_Imagedump_f (void) +{ + char tganame[MAX_OSPATH], tempname[MAX_OSPATH], dirname[MAX_OSPATH]; + gltexture_t *glt; + byte *buffer; + char *c; + + //create directory + q_snprintf(dirname, sizeof(dirname), "%s/imagedump", com_gamedir); + Sys_mkdir (dirname); + + //loop through textures + for (glt = active_gltextures; glt; glt = glt->next) + { + q_strlcpy (tempname, glt->name, sizeof(tempname)); + while ( (c = strchr(tempname, ':')) ) *c = '_'; + while ( (c = strchr(tempname, '/')) ) *c = '_'; + while ( (c = strchr(tempname, '*')) ) *c = '_'; + q_snprintf(tganame, sizeof(tganame), "imagedump/%s.tga", tempname); + + GL_Bind (glt); + glPixelStorei (GL_PACK_ALIGNMENT, 1);/* for widths that aren't a multiple of 4 */ + + if (glt->flags & TEXPREF_ALPHA) + { + buffer = (byte *) malloc(glt->width*glt->height*4); + glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, buffer); + Image_WriteTGA (tganame, buffer, glt->width, glt->height, 32, true); + } + else + { + buffer = (byte *) malloc(glt->width*glt->height*3); + glGetTexImage(GL_TEXTURE_2D, 0, GL_RGB, GL_UNSIGNED_BYTE, buffer); + Image_WriteTGA (tganame, buffer, glt->width, glt->height, 24, true); + } + free (buffer); + } + + Con_Printf ("dumped %i textures to %s\n", numgltextures, dirname); +} + +/* +=============== +TexMgr_FrameUsage -- report texture memory usage for this frame +=============== +*/ +float TexMgr_FrameUsage (void) +{ + float mb; + float texels = 0; + gltexture_t *glt; + + for (glt = active_gltextures; glt; glt = glt->next) + { + if (glt->visframe == r_framecount) + { + if (glt->flags & TEXPREF_MIPMAP) + texels += glt->width * glt->height * 4.0f / 3.0f; + else + texels += (glt->width * glt->height); + } + } + + mb = texels * (Cvar_VariableValue("vid_bpp") / 8.0f) / 0x100000; + return mb; +} + +/* +================================================================================ + + TEXTURE MANAGER + +================================================================================ +*/ + +/* +================ +TexMgr_FindTexture +================ +*/ +gltexture_t *TexMgr_FindTexture (qmodel_t *owner, const char *name) +{ + gltexture_t *glt; + + if (name) + { + for (glt = active_gltextures; glt; glt = glt->next) + { + if (glt->owner == owner && !strcmp (glt->name, name)) + return glt; + } + } + + return NULL; +} + +/* +================ +TexMgr_NewTexture +================ +*/ +gltexture_t *TexMgr_NewTexture (void) +{ + gltexture_t *glt; + + if (numgltextures == MAX_GLTEXTURES) + Sys_Error("numgltextures == MAX_GLTEXTURES\n"); + + glt = free_gltextures; + free_gltextures = glt->next; + glt->next = active_gltextures; + active_gltextures = glt; + + glGenTextures(1, &glt->texnum); + numgltextures++; + return glt; +} + +static void GL_DeleteTexture (gltexture_t *texture); + +//ericw -- workaround for preventing TexMgr_FreeTexture during TexMgr_ReloadImages +static qboolean in_reload_images; + +/* +================ +TexMgr_FreeTexture +================ +*/ +void TexMgr_FreeTexture (gltexture_t *kill) +{ + gltexture_t *glt; + + if (in_reload_images) + return; + + if (kill == NULL) + { + Con_Printf ("TexMgr_FreeTexture: NULL texture\n"); + return; + } + + if (active_gltextures == kill) + { + active_gltextures = kill->next; + kill->next = free_gltextures; + free_gltextures = kill; + + GL_DeleteTexture(kill); + numgltextures--; + return; + } + + for (glt = active_gltextures; glt; glt = glt->next) + { + if (glt->next == kill) + { + glt->next = kill->next; + kill->next = free_gltextures; + free_gltextures = kill; + + GL_DeleteTexture(kill); + numgltextures--; + return; + } + } + + Con_Printf ("TexMgr_FreeTexture: not found\n"); +} + +/* +================ +TexMgr_FreeTextures + +compares each bit in "flags" to the one in glt->flags only if that bit is active in "mask" +================ +*/ +void TexMgr_FreeTextures (unsigned int flags, unsigned int mask) +{ + gltexture_t *glt, *next; + + for (glt = active_gltextures; glt; glt = next) + { + next = glt->next; + if ((glt->flags & mask) == (flags & mask)) + TexMgr_FreeTexture (glt); + } +} + +/* +================ +TexMgr_FreeTexturesForOwner +================ +*/ +void TexMgr_FreeTexturesForOwner (qmodel_t *owner) +{ + gltexture_t *glt, *next; + + for (glt = active_gltextures; glt; glt = next) + { + next = glt->next; + if (glt && glt->owner == owner) + TexMgr_FreeTexture (glt); + } +} + +/* +================ +TexMgr_DeleteTextureObjects +================ +*/ +void TexMgr_DeleteTextureObjects (void) +{ + gltexture_t *glt; + + for (glt = active_gltextures; glt; glt = glt->next) + { + GL_DeleteTexture (glt); + } +} + +/* +================================================================================ + + INIT + +================================================================================ +*/ + +/* +================= +TexMgr_LoadPalette -- johnfitz -- was VID_SetPalette, moved here, renamed, rewritten +================= +*/ +void TexMgr_LoadPalette (void) +{ + byte *pal, *src, *dst; + int i, mark; + FILE *f; + + COM_FOpenFile ("gfx/palette.lmp", &f, NULL); + if (!f) + Sys_Error ("Couldn't load gfx/palette.lmp"); + + mark = Hunk_LowMark (); + pal = (byte *) Hunk_Alloc (768); + fread (pal, 1, 768, f); + fclose(f); + + //standard palette, 255 is transparent + dst = (byte *)d_8to24table; + src = pal; + for (i = 0; i < 256; i++) + { + *dst++ = *src++; + *dst++ = *src++; + *dst++ = *src++; + *dst++ = 255; + } + ((byte *) &d_8to24table[255]) [3] = 0; + + //fullbright palette, 0-223 are black (for additive blending) + src = pal + 224*3; + dst = (byte *) &d_8to24table_fbright[224]; + for (i = 224; i < 256; i++) + { + *dst++ = *src++; + *dst++ = *src++; + *dst++ = *src++; + *dst++ = 255; + } + for (i = 0; i < 224; i++) + { + dst = (byte *) &d_8to24table_fbright[i]; + dst[3] = 255; + dst[2] = dst[1] = dst[0] = 0; + } + + //nobright palette, 224-255 are black (for additive blending) + dst = (byte *)d_8to24table_nobright; + src = pal; + for (i = 0; i < 256; i++) + { + *dst++ = *src++; + *dst++ = *src++; + *dst++ = *src++; + *dst++ = 255; + } + for (i = 224; i < 256; i++) + { + dst = (byte *) &d_8to24table_nobright[i]; + dst[3] = 255; + dst[2] = dst[1] = dst[0] = 0; + } + + //fullbright palette, for fence textures + memcpy(d_8to24table_fbright_fence, d_8to24table_fbright, 256*4); + d_8to24table_fbright_fence[255] = 0; // Alpha of zero. + + //nobright palette, for fence textures + memcpy(d_8to24table_nobright_fence, d_8to24table_nobright, 256*4); + d_8to24table_nobright_fence[255] = 0; // Alpha of zero. + + //conchars palette, 0 and 255 are transparent + memcpy(d_8to24table_conchars, d_8to24table, 256*4); + ((byte *) &d_8to24table_conchars[0]) [3] = 0; + + Hunk_FreeToLowMark (mark); +} + +/* +================ +TexMgr_NewGame +================ +*/ +void TexMgr_NewGame (void) +{ + TexMgr_FreeTextures (0, TEXPREF_PERSIST); //deletes all textures where TEXPREF_PERSIST is unset + TexMgr_LoadPalette (); +} + +/* +============= +TexMgr_RecalcWarpImageSize -- called during init, and after a vid_restart + +choose safe warpimage size and resize existing warpimage textures +============= +*/ +void TexMgr_RecalcWarpImageSize (void) +{ +// int oldsize = gl_warpimagesize; + int mark; + gltexture_t *glt; + byte *dummy; + + // + // find the new correct size + // + gl_warpimagesize = TexMgr_SafeTextureSize (512); + + while (gl_warpimagesize > vid.width) + gl_warpimagesize >>= 1; + while (gl_warpimagesize > vid.height) + gl_warpimagesize >>= 1; + + // ericw -- removed early exit if (gl_warpimagesize == oldsize). + // after vid_restart TexMgr_ReloadImage reloads textures + // to tx->source_width/source_height, which might not match oldsize. + // fixes: https://sourceforge.net/p/quakespasm/bugs/13/ + + // + // resize the textures in opengl + // + mark = Hunk_LowMark(); + dummy = (byte *) Hunk_Alloc (gl_warpimagesize*gl_warpimagesize*4); + + for (glt = active_gltextures; glt; glt = glt->next) + { + if (glt->flags & TEXPREF_WARPIMAGE) + { + GL_Bind (glt); + glTexImage2D (GL_TEXTURE_2D, 0, gl_solid_format, gl_warpimagesize, gl_warpimagesize, 0, GL_RGBA, GL_UNSIGNED_BYTE, dummy); + glt->width = glt->height = gl_warpimagesize; + } + } + + Hunk_FreeToLowMark (mark); +} + +/* +================ +TexMgr_Init + +must be called before any texture loading +================ +*/ +void TexMgr_Init (void) +{ + int i; + static byte notexture_data[16] = {159,91,83,255,0,0,0,255,0,0,0,255,159,91,83,255}; //black and pink checker + static byte nulltexture_data[16] = {127,191,255,255,0,0,0,255,0,0,0,255,127,191,255,255}; //black and blue checker + extern texture_t *r_notexture_mip, *r_notexture_mip2; + + // init texture list + free_gltextures = (gltexture_t *) Hunk_AllocName (MAX_GLTEXTURES * sizeof(gltexture_t), "gltextures"); + active_gltextures = NULL; + for (i = 0; i < MAX_GLTEXTURES - 1; i++) + free_gltextures[i].next = &free_gltextures[i+1]; + free_gltextures[i].next = NULL; + numgltextures = 0; + + // palette + TexMgr_LoadPalette (); + + Cvar_RegisterVariable (&gl_max_size); + Cvar_RegisterVariable (&gl_picmip); + Cvar_RegisterVariable (&gl_texture_anisotropy); + Cvar_SetCallback (&gl_texture_anisotropy, &TexMgr_Anisotropy_f); + gl_texturemode.string = glmodes[glmode_idx].name; + Cvar_RegisterVariable (&gl_texturemode); + Cvar_SetCallback (&gl_texturemode, &TexMgr_TextureMode_f); + Cmd_AddCommand ("gl_describetexturemodes", &TexMgr_DescribeTextureModes_f); + Cmd_AddCommand ("imagelist", &TexMgr_Imagelist_f); + Cmd_AddCommand ("imagedump", &TexMgr_Imagedump_f); + + // poll max size from hardware + glGetIntegerv (GL_MAX_TEXTURE_SIZE, &gl_hardware_maxsize); + + // load notexture images + notexture = TexMgr_LoadImage (NULL, "notexture", 2, 2, SRC_RGBA, notexture_data, "", (src_offset_t)notexture_data, TEXPREF_NEAREST | TEXPREF_PERSIST | TEXPREF_NOPICMIP); + nulltexture = TexMgr_LoadImage (NULL, "nulltexture", 2, 2, SRC_RGBA, nulltexture_data, "", (src_offset_t)nulltexture_data, TEXPREF_NEAREST | TEXPREF_PERSIST | TEXPREF_NOPICMIP); + + //have to assign these here becuase Mod_Init is called before TexMgr_Init + r_notexture_mip->gltexture = r_notexture_mip2->gltexture = notexture; + + //set safe size for warpimages + gl_warpimagesize = 0; + TexMgr_RecalcWarpImageSize (); +} + +/* +================================================================================ + + IMAGE LOADING + +================================================================================ +*/ + +/* +================ +TexMgr_Pad -- return smallest power of two greater than or equal to s +================ +*/ +int TexMgr_Pad (int s) +{ + int i; + for (i = 1; i < s; i<<=1) + ; + return i; +} + +/* +=============== +TexMgr_SafeTextureSize -- return a size with hardware and user prefs in mind +=============== +*/ +int TexMgr_SafeTextureSize (int s) +{ + if (!gl_texture_NPOT) + s = TexMgr_Pad(s); + if ((int)gl_max_size.value > 0) + s = q_min(TexMgr_Pad((int)gl_max_size.value), s); + s = q_min(gl_hardware_maxsize, s); + return s; +} + +/* +================ +TexMgr_PadConditional -- only pad if a texture of that size would be padded. (used for tex coords) +================ +*/ +int TexMgr_PadConditional (int s) +{ + if (s < TexMgr_SafeTextureSize(s)) + return TexMgr_Pad(s); + else + return s; +} + +/* +================ +TexMgr_MipMapW +================ +*/ +static unsigned *TexMgr_MipMapW (unsigned *data, int width, int height) +{ + int i, size; + byte *out, *in; + + out = in = (byte *)data; + size = (width*height)>>1; + + for (i = 0; i < size; i++, out += 4, in += 8) + { + out[0] = (in[0] + in[4])>>1; + out[1] = (in[1] + in[5])>>1; + out[2] = (in[2] + in[6])>>1; + out[3] = (in[3] + in[7])>>1; + } + + return data; +} + +/* +================ +TexMgr_MipMapH +================ +*/ +static unsigned *TexMgr_MipMapH (unsigned *data, int width, int height) +{ + int i, j; + byte *out, *in; + + out = in = (byte *)data; + height>>=1; + width<<=2; + + for (i = 0; i < height; i++, in += width) + { + for (j = 0; j < width; j += 4, out += 4, in += 4) + { + out[0] = (in[0] + in[width+0])>>1; + out[1] = (in[1] + in[width+1])>>1; + out[2] = (in[2] + in[width+2])>>1; + out[3] = (in[3] + in[width+3])>>1; + } + } + + return data; +} + +/* +================ +TexMgr_ResampleTexture -- bilinear resample +================ +*/ +static unsigned *TexMgr_ResampleTexture (unsigned *in, int inwidth, int inheight, qboolean alpha) +{ + byte *nwpx, *nepx, *swpx, *sepx, *dest; + unsigned xfrac, yfrac, x, y, modx, mody, imodx, imody, injump, outjump; + unsigned *out; + int i, j, outwidth, outheight; + + if (inwidth == TexMgr_Pad(inwidth) && inheight == TexMgr_Pad(inheight)) + return in; + + outwidth = TexMgr_Pad(inwidth); + outheight = TexMgr_Pad(inheight); + out = (unsigned *) Hunk_Alloc(outwidth*outheight*4); + + xfrac = ((inwidth-1) << 16) / (outwidth-1); + yfrac = ((inheight-1) << 16) / (outheight-1); + y = outjump = 0; + + for (i = 0; i < outheight; i++) + { + mody = (y>>8) & 0xFF; + imody = 256 - mody; + injump = (y>>16) * inwidth; + x = 0; + + for (j = 0; j < outwidth; j++) + { + modx = (x>>8) & 0xFF; + imodx = 256 - modx; + + nwpx = (byte *)(in + (x>>16) + injump); + nepx = nwpx + 4; + swpx = nwpx + inwidth*4; + sepx = swpx + 4; + + dest = (byte *)(out + outjump + j); + + dest[0] = (nwpx[0]*imodx*imody + nepx[0]*modx*imody + swpx[0]*imodx*mody + sepx[0]*modx*mody)>>16; + dest[1] = (nwpx[1]*imodx*imody + nepx[1]*modx*imody + swpx[1]*imodx*mody + sepx[1]*modx*mody)>>16; + dest[2] = (nwpx[2]*imodx*imody + nepx[2]*modx*imody + swpx[2]*imodx*mody + sepx[2]*modx*mody)>>16; + if (alpha) + dest[3] = (nwpx[3]*imodx*imody + nepx[3]*modx*imody + swpx[3]*imodx*mody + sepx[3]*modx*mody)>>16; + else + dest[3] = 255; + + x += xfrac; + } + outjump += outwidth; + y += yfrac; + } + + return out; +} + +/* +=============== +TexMgr_AlphaEdgeFix + +eliminate pink edges on sprites, etc. +operates in place on 32bit data +=============== +*/ +static void TexMgr_AlphaEdgeFix (byte *data, int width, int height) +{ + int i, j, n = 0, b, c[3] = {0,0,0}, + lastrow, thisrow, nextrow, + lastpix, thispix, nextpix; + byte *dest = data; + + for (i = 0; i < height; i++) + { + lastrow = width * 4 * ((i == 0) ? height-1 : i-1); + thisrow = width * 4 * i; + nextrow = width * 4 * ((i == height-1) ? 0 : i+1); + + for (j = 0; j < width; j++, dest += 4) + { + if (dest[3]) //not transparent + continue; + + lastpix = 4 * ((j == 0) ? width-1 : j-1); + thispix = 4 * j; + nextpix = 4 * ((j == width-1) ? 0 : j+1); + + b = lastrow + lastpix; if (data[b+3]) {c[0] += data[b]; c[1] += data[b+1]; c[2] += data[b+2]; n++;} + b = thisrow + lastpix; if (data[b+3]) {c[0] += data[b]; c[1] += data[b+1]; c[2] += data[b+2]; n++;} + b = nextrow + lastpix; if (data[b+3]) {c[0] += data[b]; c[1] += data[b+1]; c[2] += data[b+2]; n++;} + b = lastrow + thispix; if (data[b+3]) {c[0] += data[b]; c[1] += data[b+1]; c[2] += data[b+2]; n++;} + b = nextrow + thispix; if (data[b+3]) {c[0] += data[b]; c[1] += data[b+1]; c[2] += data[b+2]; n++;} + b = lastrow + nextpix; if (data[b+3]) {c[0] += data[b]; c[1] += data[b+1]; c[2] += data[b+2]; n++;} + b = thisrow + nextpix; if (data[b+3]) {c[0] += data[b]; c[1] += data[b+1]; c[2] += data[b+2]; n++;} + b = nextrow + nextpix; if (data[b+3]) {c[0] += data[b]; c[1] += data[b+1]; c[2] += data[b+2]; n++;} + + //average all non-transparent neighbors + if (n) + { + dest[0] = (byte)(c[0]/n); + dest[1] = (byte)(c[1]/n); + dest[2] = (byte)(c[2]/n); + + n = c[0] = c[1] = c[2] = 0; + } + } + } +} + +/* +=============== +TexMgr_PadEdgeFixW -- special case of AlphaEdgeFix for textures that only need it because they were padded + +operates in place on 32bit data, and expects unpadded height and width values +=============== +*/ +static void TexMgr_PadEdgeFixW (byte *data, int width, int height) +{ + byte *src, *dst; + int i, padw, padh; + + padw = TexMgr_PadConditional(width); + padh = TexMgr_PadConditional(height); + + //copy last full column to first empty column, leaving alpha byte at zero + src = data + (width - 1) * 4; + for (i = 0; i < padh; i++) + { + src[4] = src[0]; + src[5] = src[1]; + src[6] = src[2]; + src += padw * 4; + } + + //copy first full column to last empty column, leaving alpha byte at zero + src = data; + dst = data + (padw - 1) * 4; + for (i = 0; i < padh; i++) + { + dst[0] = src[0]; + dst[1] = src[1]; + dst[2] = src[2]; + src += padw * 4; + dst += padw * 4; + } +} + +/* +=============== +TexMgr_PadEdgeFixH -- special case of AlphaEdgeFix for textures that only need it because they were padded + +operates in place on 32bit data, and expects unpadded height and width values +=============== +*/ +static void TexMgr_PadEdgeFixH (byte *data, int width, int height) +{ + byte *src, *dst; + int i, padw, padh; + + padw = TexMgr_PadConditional(width); + padh = TexMgr_PadConditional(height); + + //copy last full row to first empty row, leaving alpha byte at zero + dst = data + height * padw * 4; + src = dst - padw * 4; + for (i = 0; i < padw; i++) + { + dst[0] = src[0]; + dst[1] = src[1]; + dst[2] = src[2]; + src += 4; + dst += 4; + } + + //copy first full row to last empty row, leaving alpha byte at zero + dst = data + (padh - 1) * padw * 4; + src = data; + for (i = 0; i < padw; i++) + { + dst[0] = src[0]; + dst[1] = src[1]; + dst[2] = src[2]; + src += 4; + dst += 4; + } +} + +/* +================ +TexMgr_8to32 +================ +*/ +static unsigned *TexMgr_8to32 (byte *in, int pixels, unsigned int *usepal) +{ + int i; + unsigned *out, *data; + + out = data = (unsigned *) Hunk_Alloc(pixels*4); + + for (i = 0; i < pixels; i++) + *out++ = usepal[*in++]; + + return data; +} + +/* +================ +TexMgr_PadImageW -- return image with width padded up to power-of-two dimentions +================ +*/ +static byte *TexMgr_PadImageW (byte *in, int width, int height, byte padbyte) +{ + int i, j, outwidth; + byte *out, *data; + + if (width == TexMgr_Pad(width)) + return in; + + outwidth = TexMgr_Pad(width); + + out = data = (byte *) Hunk_Alloc(outwidth*height); + + for (i = 0; i < height; i++) + { + for (j = 0; j < width; j++) + *out++ = *in++; + for ( ; j < outwidth; j++) + *out++ = padbyte; + } + + return data; +} + +/* +================ +TexMgr_PadImageH -- return image with height padded up to power-of-two dimentions +================ +*/ +static byte *TexMgr_PadImageH (byte *in, int width, int height, byte padbyte) +{ + int i, srcpix, dstpix; + byte *data, *out; + + if (height == TexMgr_Pad(height)) + return in; + + srcpix = width * height; + dstpix = width * TexMgr_Pad(height); + + out = data = (byte *) Hunk_Alloc(dstpix); + + for (i = 0; i < srcpix; i++) + *out++ = *in++; + for ( ; i < dstpix; i++) + *out++ = padbyte; + + return data; +} + +/* +================ +TexMgr_LoadImage32 -- handles 32bit source data +================ +*/ +static void TexMgr_LoadImage32 (gltexture_t *glt, unsigned *data) +{ + int internalformat, miplevel, mipwidth, mipheight, picmip; + + if (!gl_texture_NPOT) + { + // resample up + data = TexMgr_ResampleTexture (data, glt->width, glt->height, glt->flags & TEXPREF_ALPHA); + glt->width = TexMgr_Pad(glt->width); + glt->height = TexMgr_Pad(glt->height); + } + + // mipmap down + picmip = (glt->flags & TEXPREF_NOPICMIP) ? 0 : q_max((int)gl_picmip.value, 0); + mipwidth = TexMgr_SafeTextureSize (glt->width >> picmip); + mipheight = TexMgr_SafeTextureSize (glt->height >> picmip); + while ((int) glt->width > mipwidth) + { + TexMgr_MipMapW (data, glt->width, glt->height); + glt->width >>= 1; + if (glt->flags & TEXPREF_ALPHA) + TexMgr_AlphaEdgeFix ((byte *)data, glt->width, glt->height); + } + while ((int) glt->height > mipheight) + { + TexMgr_MipMapH (data, glt->width, glt->height); + glt->height >>= 1; + if (glt->flags & TEXPREF_ALPHA) + TexMgr_AlphaEdgeFix ((byte *)data, glt->width, glt->height); + } + + // upload + GL_Bind (glt); + internalformat = (glt->flags & TEXPREF_ALPHA) ? gl_alpha_format : gl_solid_format; + glTexImage2D (GL_TEXTURE_2D, 0, internalformat, glt->width, glt->height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data); + + // upload mipmaps + if (glt->flags & TEXPREF_MIPMAP) + { + mipwidth = glt->width; + mipheight = glt->height; + + for (miplevel=1; mipwidth > 1 || mipheight > 1; miplevel++) + { + if (mipwidth > 1) + { + TexMgr_MipMapW (data, mipwidth, mipheight); + mipwidth >>= 1; + } + if (mipheight > 1) + { + TexMgr_MipMapH (data, mipwidth, mipheight); + mipheight >>= 1; + } + glTexImage2D (GL_TEXTURE_2D, miplevel, internalformat, mipwidth, mipheight, 0, GL_RGBA, GL_UNSIGNED_BYTE, data); + } + } + + // set filter modes + TexMgr_SetFilterModes (glt); +} + +/* +================ +TexMgr_LoadImage8 -- handles 8bit source data, then passes it to LoadImage32 +================ +*/ +static void TexMgr_LoadImage8 (gltexture_t *glt, byte *data) +{ + extern cvar_t gl_fullbrights; + qboolean padw = false, padh = false; + byte padbyte; + unsigned int *usepal; + int i; + + // HACK HACK HACK -- taken from tomazquake + if (strstr(glt->name, "shot1sid") && + glt->width == 32 && glt->height == 32 && + CRC_Block(data, 1024) == 65393) + { + // This texture in b_shell1.bsp has some of the first 32 pixels painted white. + // They are invisible in software, but look really ugly in GL. So we just copy + // 32 pixels from the bottom to make it look nice. + memcpy (data, data + 32*31, 32); + } + + // detect false alpha cases + if (glt->flags & TEXPREF_ALPHA && !(glt->flags & TEXPREF_CONCHARS)) + { + for (i = 0; i < (int) (glt->width * glt->height); i++) + if (data[i] == 255) //transparent index + break; + if (i == (int) (glt->width * glt->height)) + glt->flags -= TEXPREF_ALPHA; + } + + // choose palette and padbyte + if (glt->flags & TEXPREF_FULLBRIGHT) + { + if (glt->flags & TEXPREF_ALPHA) + usepal = d_8to24table_fbright_fence; + else + usepal = d_8to24table_fbright; + padbyte = 0; + } + else if (glt->flags & TEXPREF_NOBRIGHT && gl_fullbrights.value) + { + if (glt->flags & TEXPREF_ALPHA) + usepal = d_8to24table_nobright_fence; + else + usepal = d_8to24table_nobright; + padbyte = 0; + } + else if (glt->flags & TEXPREF_CONCHARS) + { + usepal = d_8to24table_conchars; + padbyte = 0; + } + else + { + usepal = d_8to24table; + padbyte = 255; + } + + // pad each dimention, but only if it's not going to be downsampled later + if (glt->flags & TEXPREF_PAD) + { + if ((int) glt->width < TexMgr_SafeTextureSize(glt->width)) + { + data = TexMgr_PadImageW (data, glt->width, glt->height, padbyte); + glt->width = TexMgr_Pad(glt->width); + padw = true; + } + if ((int) glt->height < TexMgr_SafeTextureSize(glt->height)) + { + data = TexMgr_PadImageH (data, glt->width, glt->height, padbyte); + glt->height = TexMgr_Pad(glt->height); + padh = true; + } + } + + // convert to 32bit + data = (byte *)TexMgr_8to32(data, glt->width * glt->height, usepal); + + // fix edges + if (glt->flags & TEXPREF_ALPHA) + TexMgr_AlphaEdgeFix (data, glt->width, glt->height); + else + { + if (padw) + TexMgr_PadEdgeFixW (data, glt->source_width, glt->source_height); + if (padh) + TexMgr_PadEdgeFixH (data, glt->source_width, glt->source_height); + } + + // upload it + TexMgr_LoadImage32 (glt, (unsigned *)data); +} + +/* +================ +TexMgr_LoadLightmap -- handles lightmap data +================ +*/ +static void TexMgr_LoadLightmap (gltexture_t *glt, byte *data) +{ + // upload it + GL_Bind (glt); + glTexImage2D (GL_TEXTURE_2D, 0, lightmap_bytes, glt->width, glt->height, 0, gl_lightmap_format, GL_UNSIGNED_BYTE, data); + + // set filter modes + TexMgr_SetFilterModes (glt); +} + +/* +================ +TexMgr_LoadImage -- the one entry point for loading all textures +================ +*/ +gltexture_t *TexMgr_LoadImage (qmodel_t *owner, const char *name, int width, int height, enum srcformat format, + byte *data, const char *source_file, src_offset_t source_offset, unsigned flags) +{ + unsigned short crc; + gltexture_t *glt; + int mark; + + if (isDedicated) + return NULL; + + // cache check + switch (format) + { + case SRC_INDEXED: + crc = CRC_Block(data, width * height); + break; + case SRC_LIGHTMAP: + crc = CRC_Block(data, width * height * lightmap_bytes); + break; + case SRC_RGBA: + crc = CRC_Block(data, width * height * 4); + break; + default: /* not reachable but avoids compiler warnings */ + crc = 0; + } + if ((flags & TEXPREF_OVERWRITE) && (glt = TexMgr_FindTexture (owner, name))) + { + if (glt->source_crc == crc) + return glt; + } + else + glt = TexMgr_NewTexture (); + + // copy data + glt->owner = owner; + q_strlcpy (glt->name, name, sizeof(glt->name)); + glt->width = width; + glt->height = height; + glt->flags = flags; + glt->shirt = -1; + glt->pants = -1; + q_strlcpy (glt->source_file, source_file, sizeof(glt->source_file)); + glt->source_offset = source_offset; + glt->source_format = format; + glt->source_width = width; + glt->source_height = height; + glt->source_crc = crc; + + //upload it + mark = Hunk_LowMark(); + + switch (glt->source_format) + { + case SRC_INDEXED: + TexMgr_LoadImage8 (glt, data); + break; + case SRC_LIGHTMAP: + TexMgr_LoadLightmap (glt, data); + break; + case SRC_RGBA: + TexMgr_LoadImage32 (glt, (unsigned *)data); + break; + } + + Hunk_FreeToLowMark(mark); + + return glt; +} + +/* +================================================================================ + + COLORMAPPING AND TEXTURE RELOADING + +================================================================================ +*/ + +/* +================ +TexMgr_ReloadImage -- reloads a texture, and colormaps it if needed +================ +*/ +void TexMgr_ReloadImage (gltexture_t *glt, int shirt, int pants) +{ + byte translation[256]; + byte *src, *dst, *data = NULL, *translated; + int mark, size, i; +// +// get source data +// + mark = Hunk_LowMark (); + + if (glt->source_file[0] && glt->source_offset) + { + //lump inside file + long size; + FILE *f; + COM_FOpenFile(glt->source_file, &f, NULL); + if (!f) + goto invalid; + fseek (f, glt->source_offset, SEEK_CUR); + size = (long) (glt->source_width * glt->source_height); + /* should be SRC_INDEXED, but no harm being paranoid: */ + if (glt->source_format == SRC_RGBA) + size *= 4; + else if (glt->source_format == SRC_LIGHTMAP) + size *= lightmap_bytes; + data = (byte *) Hunk_Alloc (size); + fread (data, 1, size, f); + fclose (f); + } + else if (glt->source_file[0] && !glt->source_offset) + data = Image_LoadImage (glt->source_file, (int *)&glt->source_width, (int *)&glt->source_height); //simple file + else if (!glt->source_file[0] && glt->source_offset) + data = (byte *) glt->source_offset; //image in memory + + if (!data) + { +invalid: + Con_Printf ("TexMgr_ReloadImage: invalid source for %s\n", glt->name); + Hunk_FreeToLowMark(mark); + return; + } + + glt->width = glt->source_width; + glt->height = glt->source_height; +// +// apply shirt and pants colors +// +// if shirt and pants are -1,-1, use existing shirt and pants colors +// if existing shirt and pants colors are -1,-1, don't bother colormapping + if (shirt > -1 && pants > -1) + { + if (glt->source_format == SRC_INDEXED) + { + glt->shirt = shirt; + glt->pants = pants; + } + else + Con_Printf ("TexMgr_ReloadImage: can't colormap a non SRC_INDEXED texture: %s\n", glt->name); + } + if (glt->shirt > -1 && glt->pants > -1) + { + //create new translation table + for (i = 0; i < 256; i++) + translation[i] = i; + + shirt = glt->shirt * 16; + if (shirt < 128) + { + for (i = 0; i < 16; i++) + translation[TOP_RANGE+i] = shirt + i; + } + else + { + for (i = 0; i < 16; i++) + translation[TOP_RANGE+i] = shirt+15-i; + } + + pants = glt->pants * 16; + if (pants < 128) + { + for (i = 0; i < 16; i++) + translation[BOTTOM_RANGE+i] = pants + i; + } + else + { + for (i = 0; i < 16; i++) + translation[BOTTOM_RANGE+i] = pants+15-i; + } + + //translate texture + size = glt->width * glt->height; + dst = translated = (byte *) Hunk_Alloc (size); + src = data; + + for (i = 0; i < size; i++) + *dst++ = translation[*src++]; + + data = translated; + } +// +// upload it +// + switch (glt->source_format) + { + case SRC_INDEXED: + TexMgr_LoadImage8 (glt, data); + break; + case SRC_LIGHTMAP: + TexMgr_LoadLightmap (glt, data); + break; + case SRC_RGBA: + TexMgr_LoadImage32 (glt, (unsigned *)data); + break; + } + + Hunk_FreeToLowMark(mark); +} + +/* +================ +TexMgr_ReloadImages -- reloads all texture images. called only by vid_restart +================ +*/ +void TexMgr_ReloadImages (void) +{ + gltexture_t *glt; + +// ericw -- tricky bug: if the hunk is almost full, an allocation in TexMgr_ReloadImage +// triggers cache items to be freed, which calls back into TexMgr to free the +// texture. If this frees 'glt' in the loop below, the active_gltextures +// list gets corrupted. +// A test case is jam3_tronyn.bsp with -heapsize 65536, and do several mode +// switches/fullscreen toggles +// 2015-09-04 -- Cache_Flush workaround was causing issues (http://sourceforge.net/p/quakespasm/bugs/10/) +// switching to a boolean flag. + in_reload_images = true; + + for (glt = active_gltextures; glt; glt = glt->next) + { + glGenTextures(1, &glt->texnum); + TexMgr_ReloadImage (glt, -1, -1); + } + + in_reload_images = false; +} + +/* +================ +TexMgr_ReloadNobrightImages -- reloads all texture that were loaded with the nobright palette. called when gl_fullbrights changes +================ +*/ +void TexMgr_ReloadNobrightImages (void) +{ + gltexture_t *glt; + + for (glt = active_gltextures; glt; glt = glt->next) + if (glt->flags & TEXPREF_NOBRIGHT) + TexMgr_ReloadImage(glt, -1, -1); +} + +/* +================================================================================ + + TEXTURE BINDING / TEXTURE UNIT SWITCHING + +================================================================================ +*/ + +static GLuint currenttexture[3] = {GL_UNUSED_TEXTURE, GL_UNUSED_TEXTURE, GL_UNUSED_TEXTURE}; // to avoid unnecessary texture sets +static GLenum currenttarget = GL_TEXTURE0_ARB; +qboolean mtexenabled = false; + +/* +================ +GL_SelectTexture -- johnfitz -- rewritten +================ +*/ +void GL_SelectTexture (GLenum target) +{ + if (target == currenttarget) + return; + + GL_SelectTextureFunc(target); + currenttarget = target; +} + +/* +================ +GL_DisableMultitexture -- selects texture unit 0 +================ +*/ +void GL_DisableMultitexture(void) +{ + if (mtexenabled) + { + glDisable(GL_TEXTURE_2D); + GL_SelectTexture(GL_TEXTURE0_ARB); + mtexenabled = false; + } +} + +/* +================ +GL_EnableMultitexture -- selects texture unit 1 +================ +*/ +void GL_EnableMultitexture(void) +{ + if (gl_mtexable) + { + GL_SelectTexture(GL_TEXTURE1_ARB); + glEnable(GL_TEXTURE_2D); + mtexenabled = true; + } +} + +/* +================ +GL_Bind -- johnfitz -- heavy revision +================ +*/ +void GL_Bind (gltexture_t *texture) +{ + if (!texture) + texture = nulltexture; + + if (texture->texnum != currenttexture[currenttarget - GL_TEXTURE0_ARB]) + { + currenttexture[currenttarget - GL_TEXTURE0_ARB] = texture->texnum; + glBindTexture (GL_TEXTURE_2D, texture->texnum); + texture->visframe = r_framecount; + } +} + +/* +================ +GL_DeleteTexture -- ericw + +Wrapper around glDeleteTextures that also clears the given texture number +from our per-TMU cached texture binding table. +================ +*/ +static void GL_DeleteTexture (gltexture_t *texture) +{ + glDeleteTextures (1, &texture->texnum); + + if (texture->texnum == currenttexture[0]) currenttexture[0] = GL_UNUSED_TEXTURE; + if (texture->texnum == currenttexture[1]) currenttexture[1] = GL_UNUSED_TEXTURE; + if (texture->texnum == currenttexture[2]) currenttexture[2] = GL_UNUSED_TEXTURE; + + texture->texnum = 0; +} + +/* +================ +GL_ClearBindings -- ericw + +Invalidates cached bindings, so the next GL_Bind calls for each TMU will +make real glBindTexture calls. +Call this after changing the binding outside of GL_Bind. +================ +*/ +void GL_ClearBindings(void) +{ + int i; + for (i = 0; i < 3; i++) + { + currenttexture[i] = GL_UNUSED_TEXTURE; + } +} diff --git a/engine/Quake/gl_texmgr.h b/engine/Quake/gl_texmgr.h new file mode 100644 index 0000000..e58ff03 --- /dev/null +++ b/engine/Quake/gl_texmgr.h @@ -0,0 +1,110 @@ +/* +Copyright (C) 1996-2001 Id Software, Inc. +Copyright (C) 2002-2009 John Fitzgibbons and others +Copyright (C) 2010-2014 QuakeSpasm developers + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#ifndef _GL_TEXMAN_H +#define _GL_TEXMAN_H + +//gl_texmgr.h -- fitzquake's texture manager. manages opengl texture images + +#define TEXPREF_NONE 0x0000 +#define TEXPREF_MIPMAP 0x0001 // generate mipmaps +// TEXPREF_NEAREST and TEXPREF_LINEAR aren't supposed to be ORed with TEX_MIPMAP +#define TEXPREF_LINEAR 0x0002 // force linear +#define TEXPREF_NEAREST 0x0004 // force nearest +#define TEXPREF_ALPHA 0x0008 // allow alpha +#define TEXPREF_PAD 0x0010 // allow padding +#define TEXPREF_PERSIST 0x0020 // never free +#define TEXPREF_OVERWRITE 0x0040 // overwrite existing same-name texture +#define TEXPREF_NOPICMIP 0x0080 // always load full-sized +#define TEXPREF_FULLBRIGHT 0x0100 // use fullbright mask palette +#define TEXPREF_NOBRIGHT 0x0200 // use nobright mask palette +#define TEXPREF_CONCHARS 0x0400 // use conchars palette +#define TEXPREF_WARPIMAGE 0x0800 // resize this texture when warpimagesize changes + +enum srcformat {SRC_INDEXED, SRC_LIGHTMAP, SRC_RGBA}; + +typedef uintptr_t src_offset_t; + +typedef struct gltexture_s { +//managed by texture manager + GLuint texnum; + struct gltexture_s *next; + qmodel_t *owner; +//managed by image loading + char name[64]; + unsigned int width; //size of image as it exists in opengl + unsigned int height; //size of image as it exists in opengl + unsigned int flags; + char source_file[MAX_QPATH]; //relative filepath to data source, or "" if source is in memory + src_offset_t source_offset; //byte offset into file, or memory address + enum srcformat source_format; //format of pixel data (indexed, lightmap, or rgba) + unsigned int source_width; //size of image in source data + unsigned int source_height; //size of image in source data + unsigned short source_crc; //generated by source data before modifications + signed char shirt; //0-13 shirt color, or -1 if never colormapped + signed char pants; //0-13 pants color, or -1 if never colormapped +//used for rendering + int visframe; //matches r_framecount if texture was bound this frame +} gltexture_t; + +extern gltexture_t *notexture; +extern gltexture_t *nulltexture; + +extern unsigned int d_8to24table[256]; +extern unsigned int d_8to24table_fbright[256]; +extern unsigned int d_8to24table_nobright[256]; +extern unsigned int d_8to24table_conchars[256]; +extern unsigned int d_8to24table_shirt[256]; +extern unsigned int d_8to24table_pants[256]; + +// TEXTURE MANAGER + +float TexMgr_FrameUsage (void); +gltexture_t *TexMgr_FindTexture (qmodel_t *owner, const char *name); +gltexture_t *TexMgr_NewTexture (void); +void TexMgr_FreeTexture (gltexture_t *kill); +void TexMgr_FreeTextures (unsigned int flags, unsigned int mask); +void TexMgr_FreeTexturesForOwner (qmodel_t *owner); +void TexMgr_NewGame (void); +void TexMgr_Init (void); +void TexMgr_DeleteTextureObjects (void); + +// IMAGE LOADING +gltexture_t *TexMgr_LoadImage (qmodel_t *owner, const char *name, int width, int height, enum srcformat format, + byte *data, const char *source_file, src_offset_t source_offset, unsigned flags); +void TexMgr_ReloadImage (gltexture_t *glt, int shirt, int pants); +void TexMgr_ReloadImages (void); +void TexMgr_ReloadNobrightImages (void); + +int TexMgr_Pad(int s); +int TexMgr_SafeTextureSize (int s); +int TexMgr_PadConditional (int s); + +// TEXTURE BINDING & TEXTURE UNIT SWITCHING + +void GL_SelectTexture (GLenum target); +void GL_DisableMultitexture (void); //selects texture unit 0 +void GL_EnableMultitexture (void); //selects texture unit 1 +void GL_Bind (gltexture_t *texture); +void GL_ClearBindings (void); + +#endif /* _GL_TEXMAN_H */ + diff --git a/engine/Quake/gl_vidsdl.c b/engine/Quake/gl_vidsdl.c new file mode 100644 index 0000000..f09e3e0 --- /dev/null +++ b/engine/Quake/gl_vidsdl.c @@ -0,0 +1,2335 @@ +/* +Copyright (C) 1996-2001 Id Software, Inc. +Copyright (C) 2002-2009 John Fitzgibbons and others +Copyright (C) 2007-2008 Kristian Duske +Copyright (C) 2010-2014 QuakeSpasm developers + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ +// gl_vidsdl.c -- SDL GL vid component + +#include "quakedef.h" +#include "cfgfile.h" +#include "bgmusic.h" +#include "resource.h" +#if defined(SDL_FRAMEWORK) || defined(NO_SDL_CONFIG) +#if defined(USE_SDL2) +#include +#else +#include +#endif +#else +#include "SDL.h" +#endif + +//ericw -- for putting the driver into multithreaded mode +#ifdef __APPLE__ +#include +#endif + +#define MAX_MODE_LIST 600 //johnfitz -- was 30 +#define MAX_BPPS_LIST 5 +#define MAX_RATES_LIST 20 +#define WARP_WIDTH 320 +#define WARP_HEIGHT 200 +#define MAXWIDTH 10000 +#define MAXHEIGHT 10000 + +#define DEFAULT_SDL_FLAGS SDL_OPENGL + +#define DEFAULT_REFRESHRATE 60 + +typedef struct { + int width; + int height; + int refreshrate; + int bpp; +} vmode_t; + +static const char *gl_vendor; +static const char *gl_renderer; +static const char *gl_version; +static int gl_version_major; +static int gl_version_minor; +static const char *gl_extensions; +static char * gl_extensions_nice; + +static vmode_t modelist[MAX_MODE_LIST]; +static int nummodes; + +static qboolean vid_initialized = false; + +#if defined(USE_SDL2) +static SDL_Window *draw_context; +static SDL_GLContext gl_context; +#else +static SDL_Surface *draw_context; +#endif + +static qboolean vid_locked = false; //johnfitz +static qboolean vid_changed = false; + +static void VID_Menu_Init (void); //johnfitz +static void VID_Menu_f (void); //johnfitz +static void VID_MenuDraw (void); +static void VID_MenuKey (int key); + +static void ClearAllStates (void); +static void GL_Init (void); +static void GL_SetupState (void); //johnfitz + +viddef_t vid; // global video state +modestate_t modestate = MS_UNINIT; +qboolean scr_skipupdate; + +qboolean gl_mtexable = false; +qboolean gl_texture_env_combine = false; //johnfitz +qboolean gl_texture_env_add = false; //johnfitz +qboolean gl_swap_control = false; //johnfitz +qboolean gl_anisotropy_able = false; //johnfitz +float gl_max_anisotropy; //johnfitz +qboolean gl_texture_NPOT = false; //ericw +qboolean gl_vbo_able = false; //ericw +qboolean gl_glsl_able = false; //ericw +GLint gl_max_texture_units = 0; //ericw +qboolean gl_glsl_gamma_able = false; //ericw +qboolean gl_glsl_alias_able = false; //ericw +int gl_stencilbits; + +PFNGLMULTITEXCOORD2FARBPROC GL_MTexCoord2fFunc = NULL; //johnfitz +PFNGLACTIVETEXTUREARBPROC GL_SelectTextureFunc = NULL; //johnfitz +PFNGLCLIENTACTIVETEXTUREARBPROC GL_ClientActiveTextureFunc = NULL; //ericw +PFNGLBINDBUFFERARBPROC GL_BindBufferFunc = NULL; //ericw +PFNGLBUFFERDATAARBPROC GL_BufferDataFunc = NULL; //ericw +PFNGLBUFFERSUBDATAARBPROC GL_BufferSubDataFunc = NULL; //ericw +PFNGLDELETEBUFFERSARBPROC GL_DeleteBuffersFunc = NULL; //ericw +PFNGLGENBUFFERSARBPROC GL_GenBuffersFunc = NULL; //ericw + +QS_PFNGLCREATESHADERPROC GL_CreateShaderFunc = NULL; //ericw +QS_PFNGLDELETESHADERPROC GL_DeleteShaderFunc = NULL; //ericw +QS_PFNGLDELETEPROGRAMPROC GL_DeleteProgramFunc = NULL; //ericw +QS_PFNGLSHADERSOURCEPROC GL_ShaderSourceFunc = NULL; //ericw +QS_PFNGLCOMPILESHADERPROC GL_CompileShaderFunc = NULL; //ericw +QS_PFNGLGETSHADERIVPROC GL_GetShaderivFunc = NULL; //ericw +QS_PFNGLGETSHADERINFOLOGPROC GL_GetShaderInfoLogFunc = NULL; //ericw +QS_PFNGLGETPROGRAMIVPROC GL_GetProgramivFunc = NULL; //ericw +QS_PFNGLGETPROGRAMINFOLOGPROC GL_GetProgramInfoLogFunc = NULL; //ericw +QS_PFNGLCREATEPROGRAMPROC GL_CreateProgramFunc = NULL; //ericw +QS_PFNGLATTACHSHADERPROC GL_AttachShaderFunc = NULL; //ericw +QS_PFNGLLINKPROGRAMPROC GL_LinkProgramFunc = NULL; //ericw +QS_PFNGLBINDATTRIBLOCATIONFUNC GL_BindAttribLocationFunc = NULL; //ericw +QS_PFNGLUSEPROGRAMPROC GL_UseProgramFunc = NULL; //ericw +QS_PFNGLGETATTRIBLOCATIONPROC GL_GetAttribLocationFunc = NULL; //ericw +QS_PFNGLVERTEXATTRIBPOINTERPROC GL_VertexAttribPointerFunc = NULL; //ericw +QS_PFNGLENABLEVERTEXATTRIBARRAYPROC GL_EnableVertexAttribArrayFunc = NULL; //ericw +QS_PFNGLDISABLEVERTEXATTRIBARRAYPROC GL_DisableVertexAttribArrayFunc = NULL; //ericw +QS_PFNGLGETUNIFORMLOCATIONPROC GL_GetUniformLocationFunc = NULL; //ericw +QS_PFNGLUNIFORM1IPROC GL_Uniform1iFunc = NULL; //ericw +QS_PFNGLUNIFORM1FPROC GL_Uniform1fFunc = NULL; //ericw +QS_PFNGLUNIFORM3FPROC GL_Uniform3fFunc = NULL; //ericw +QS_PFNGLUNIFORM4FPROC GL_Uniform4fFunc = NULL; //ericw + +//==================================== + +//johnfitz -- new cvars +static cvar_t vid_fullscreen = {"vid_fullscreen", "0", CVAR_ARCHIVE}; // QuakeSpasm, was "1" +static cvar_t vid_width = {"vid_width", "800", CVAR_ARCHIVE}; // QuakeSpasm, was 640 +static cvar_t vid_height = {"vid_height", "600", CVAR_ARCHIVE}; // QuakeSpasm, was 480 +static cvar_t vid_bpp = {"vid_bpp", "16", CVAR_ARCHIVE}; +static cvar_t vid_refreshrate = {"vid_refreshrate", "60", CVAR_ARCHIVE}; +static cvar_t vid_vsync = {"vid_vsync", "0", CVAR_ARCHIVE}; +static cvar_t vid_fsaa = {"vid_fsaa", "0", CVAR_ARCHIVE}; // QuakeSpasm +static cvar_t vid_desktopfullscreen = {"vid_desktopfullscreen", "0", CVAR_ARCHIVE}; // QuakeSpasm +static cvar_t vid_borderless = {"vid_borderless", "0", CVAR_ARCHIVE}; // QuakeSpasm +//johnfitz + +cvar_t vid_gamma = {"gamma", "1", CVAR_ARCHIVE}; //johnfitz -- moved here from view.c +cvar_t vid_contrast = {"contrast", "1", CVAR_ARCHIVE}; //QuakeSpasm, MarkV + +//========================================================================== +// +// HARDWARE GAMMA -- johnfitz +// +//========================================================================== + +#define USE_GAMMA_RAMPS 0 + +#if USE_GAMMA_RAMPS +static unsigned short vid_gamma_red[256]; +static unsigned short vid_gamma_green[256]; +static unsigned short vid_gamma_blue[256]; + +static unsigned short vid_sysgamma_red[256]; +static unsigned short vid_sysgamma_green[256]; +static unsigned short vid_sysgamma_blue[256]; +#endif + +static qboolean gammaworks = false; // whether hw-gamma works +static int fsaa; + +/* +================ +VID_Gamma_SetGamma -- apply gamma correction +================ +*/ +static void VID_Gamma_SetGamma (void) +{ + if (gl_glsl_gamma_able) + return; + + if (draw_context && gammaworks) + { + float value; + + if (vid_gamma.value > (1.0f / GAMMA_MAX)) + value = 1.0f / vid_gamma.value; + else + value = GAMMA_MAX; + +#if defined(USE_SDL2) +# if USE_GAMMA_RAMPS + if (SDL_SetWindowGammaRamp(draw_context, vid_gamma_red, vid_gamma_green, vid_gamma_blue) != 0) + Con_Printf ("VID_Gamma_SetGamma: failed on SDL_SetWindowGammaRamp\n"); +# else + if (SDL_SetWindowBrightness(draw_context, value) != 0) + Con_Printf ("VID_Gamma_SetGamma: failed on SDL_SetWindowBrightness\n"); +# endif +#else /* USE_SDL2 */ +# if USE_GAMMA_RAMPS + if (SDL_SetGammaRamp(vid_gamma_red, vid_gamma_green, vid_gamma_blue) == -1) + Con_Printf ("VID_Gamma_SetGamma: failed on SDL_SetGammaRamp\n"); +# else + if (SDL_SetGamma(value,value,value) == -1) + Con_Printf ("VID_Gamma_SetGamma: failed on SDL_SetGamma\n"); +# endif +#endif /* USE_SDL2 */ + } +} + +/* +================ +VID_Gamma_Restore -- restore system gamma +================ +*/ +static void VID_Gamma_Restore (void) +{ + if (gl_glsl_gamma_able) + return; + + if (draw_context && gammaworks) + { +#if defined(USE_SDL2) +# if USE_GAMMA_RAMPS + if (SDL_SetWindowGammaRamp(draw_context, vid_sysgamma_red, vid_sysgamma_green, vid_sysgamma_blue) != 0) + Con_Printf ("VID_Gamma_Restore: failed on SDL_SetWindowGammaRamp\n"); +# else + if (SDL_SetWindowBrightness(draw_context, 1) != 0) + Con_Printf ("VID_Gamma_Restore: failed on SDL_SetWindowBrightness\n"); +# endif +#else /* USE_SDL2 */ +# if USE_GAMMA_RAMPS + if (SDL_SetGammaRamp(vid_sysgamma_red, vid_sysgamma_green, vid_sysgamma_blue) == -1) + Con_Printf ("VID_Gamma_Restore: failed on SDL_SetGammaRamp\n"); +# else + if (SDL_SetGamma(1, 1, 1) == -1) + Con_Printf ("VID_Gamma_Restore: failed on SDL_SetGamma\n"); +# endif +#endif /* USE_SDL2 */ + } +} + +/* +================ +VID_Gamma_Shutdown -- called on exit +================ +*/ +static void VID_Gamma_Shutdown (void) +{ + VID_Gamma_Restore (); +} + +/* +================ +VID_Gamma_f -- callback when the cvar changes +================ +*/ +static void VID_Gamma_f (cvar_t *var) +{ + if (gl_glsl_gamma_able) + return; + +#if USE_GAMMA_RAMPS + int i; + + for (i = 0; i < 256; i++) + { + vid_gamma_red[i] = + CLAMP(0, (int) ((255 * pow((i + 0.5)/255.5, vid_gamma.value) + 0.5) * vid_contrast.value), 255) << 8; + vid_gamma_green[i] = vid_gamma_red[i]; + vid_gamma_blue[i] = vid_gamma_red[i]; + } +#endif + VID_Gamma_SetGamma (); +} + +/* +================ +VID_Gamma_Init -- call on init +================ +*/ +static void VID_Gamma_Init (void) +{ + Cvar_RegisterVariable (&vid_gamma); + Cvar_RegisterVariable (&vid_contrast); + Cvar_SetCallback (&vid_gamma, VID_Gamma_f); + Cvar_SetCallback (&vid_contrast, VID_Gamma_f); + + if (gl_glsl_gamma_able) + return; + +#if defined(USE_SDL2) +# if USE_GAMMA_RAMPS + gammaworks = (SDL_GetWindowGammaRamp(draw_context, vid_sysgamma_red, vid_sysgamma_green, vid_sysgamma_blue) == 0); + if (gammaworks) + gammaworks = (SDL_SetWindowGammaRamp(draw_context, vid_sysgamma_red, vid_sysgamma_green, vid_sysgamma_blue) == 0); +# else + gammaworks = (SDL_SetWindowBrightness(draw_context, 1) == 0); +# endif +#else /* USE_SDL2 */ +# if USE_GAMMA_RAMPS + gammaworks = (SDL_GetGammaRamp(vid_sysgamma_red, vid_sysgamma_green, vid_sysgamma_blue) == 0); + if (gammaworks) + gammaworks = (SDL_SetGammaRamp(vid_sysgamma_red, vid_sysgamma_green, vid_sysgamma_blue) == 0); +# else + gammaworks = (SDL_SetGamma(1, 1, 1) == 0); +# endif +#endif /* USE_SDL2 */ + + if (!gammaworks) + Con_SafePrintf("gamma adjustment not available\n"); +} + +/* +====================== +VID_GetCurrentWidth +====================== +*/ +static int VID_GetCurrentWidth (void) +{ +#if defined(USE_SDL2) + int w = 0, h = 0; + SDL_GetWindowSize(draw_context, &w, &h); + return w; +#else + return draw_context->w; +#endif +} + +/* +======================= +VID_GetCurrentHeight +======================= +*/ +static int VID_GetCurrentHeight (void) +{ +#if defined(USE_SDL2) + int w = 0, h = 0; + SDL_GetWindowSize(draw_context, &w, &h); + return h; +#else + return draw_context->h; +#endif +} + +/* +==================== +VID_GetCurrentRefreshRate +==================== +*/ +static int VID_GetCurrentRefreshRate (void) +{ +#if defined(USE_SDL2) + SDL_DisplayMode mode; + int current_display; + + current_display = SDL_GetWindowDisplayIndex(draw_context); + + if (0 != SDL_GetCurrentDisplayMode(current_display, &mode)) + return DEFAULT_REFRESHRATE; + + return mode.refresh_rate; +#else + // SDL1.2 doesn't support refresh rates + return DEFAULT_REFRESHRATE; +#endif +} + + +/* +==================== +VID_GetCurrentBPP +==================== +*/ +static int VID_GetCurrentBPP (void) +{ +#if defined(USE_SDL2) + const Uint32 pixelFormat = SDL_GetWindowPixelFormat(draw_context); + return SDL_BITSPERPIXEL(pixelFormat); +#else + return draw_context->format->BitsPerPixel; +#endif +} + +/* +==================== +VID_GetFullscreen + +returns true if we are in regular fullscreen or "desktop fullscren" +==================== +*/ +static qboolean VID_GetFullscreen (void) +{ +#if defined(USE_SDL2) + return (SDL_GetWindowFlags(draw_context) & SDL_WINDOW_FULLSCREEN) != 0; +#else + return (draw_context->flags & SDL_FULLSCREEN) != 0; +#endif +} + +/* +==================== +VID_GetDesktopFullscreen + +returns true if we are specifically in "desktop fullscreen" mode +==================== +*/ +static qboolean VID_GetDesktopFullscreen (void) +{ +#if defined(USE_SDL2) + return (SDL_GetWindowFlags(draw_context) & SDL_WINDOW_FULLSCREEN_DESKTOP) == SDL_WINDOW_FULLSCREEN_DESKTOP; +#else + return false; +#endif +} + +/* +==================== +VID_GetVSync +==================== +*/ +static qboolean VID_GetVSync (void) +{ +#if defined(USE_SDL2) + return SDL_GL_GetSwapInterval() == 1; +#else + int swap_control; + if (SDL_GL_GetAttribute(SDL_GL_SWAP_CONTROL, &swap_control) == 0) + return swap_control > 0; + return false; +#endif +} + +/* +==================== +VID_GetWindow + +used by pl_win.c +==================== +*/ +void *VID_GetWindow (void) +{ +#if defined(USE_SDL2) + return draw_context; +#else + return NULL; +#endif +} + +/* +==================== +VID_HasMouseOrInputFocus +==================== +*/ +qboolean VID_HasMouseOrInputFocus (void) +{ +#if defined(USE_SDL2) + return (SDL_GetWindowFlags(draw_context) & (SDL_WINDOW_MOUSE_FOCUS | SDL_WINDOW_INPUT_FOCUS)) != 0; +#else + return (SDL_GetAppState() & (SDL_APPMOUSEFOCUS | SDL_APPINPUTFOCUS)) != 0; +#endif +} + +/* +==================== +VID_IsMinimized +==================== +*/ +qboolean VID_IsMinimized (void) +{ +#if defined(USE_SDL2) + return !(SDL_GetWindowFlags(draw_context) & SDL_WINDOW_SHOWN); +#else + /* SDL_APPACTIVE in SDL 1.x means "not minimized" */ + return !(SDL_GetAppState() & SDL_APPACTIVE); +#endif +} + +#if defined(USE_SDL2) +/* +================ +VID_SDL2_GetDisplayMode + +Returns a pointer to a statically allocated SDL_DisplayMode structure +if there is one with the requested params on the default display. +Otherwise returns NULL. + +This is passed to SDL_SetWindowDisplayMode to specify a pixel format +with the requested bpp. If we didn't care about bpp we could just pass NULL. +================ +*/ +static SDL_DisplayMode *VID_SDL2_GetDisplayMode(int width, int height, int refreshrate, int bpp) +{ + static SDL_DisplayMode mode; + const int sdlmodes = SDL_GetNumDisplayModes(0); + int i; + + for (i = 0; i < sdlmodes; i++) + { + if (SDL_GetDisplayMode(0, i, &mode) != 0) + continue; + + if (mode.w == width && mode.h == height + && SDL_BITSPERPIXEL(mode.format) == bpp + && mode.refresh_rate == refreshrate) + { + return &mode; + } + } + return NULL; +} +#endif /* USE_SDL2 */ + +/* +================ +VID_ValidMode +================ +*/ +static qboolean VID_ValidMode (int width, int height, int refreshrate, int bpp, qboolean fullscreen) +{ +// ignore width / height / bpp if vid_desktopfullscreen is enabled + if (fullscreen && vid_desktopfullscreen.value) + return true; + + if (width < 320) + return false; + + if (height < 200) + return false; + +#if defined(USE_SDL2) + if (fullscreen && VID_SDL2_GetDisplayMode(width, height, refreshrate, bpp) == NULL) + bpp = 0; +#else + { + Uint32 flags = DEFAULT_SDL_FLAGS; + if (fullscreen) + flags |= SDL_FULLSCREEN; + + bpp = SDL_VideoModeOK(width, height, bpp, flags); + } +#endif + + switch (bpp) + { + case 16: + case 24: + case 32: + break; + default: + return false; + } + + return true; +} + +/* +================ +VID_SetMode +================ +*/ +static qboolean VID_SetMode (int width, int height, int refreshrate, int bpp, qboolean fullscreen) +{ + int temp; + Uint32 flags; + char caption[50]; + int depthbits, stencilbits; + int fsaa_obtained; +#if defined(USE_SDL2) + int previous_display; +#endif + + // so Con_Printfs don't mess us up by forcing vid and snd updates + temp = scr_disabled_for_loading; + scr_disabled_for_loading = true; + + CDAudio_Pause (); + BGM_Pause (); + + /* z-buffer depth */ + if (bpp == 16) + { + depthbits = 16; + stencilbits = 0; + } + else + { + depthbits = 24; + stencilbits = 8; + } + SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, depthbits); + SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, stencilbits); + + /* fsaa */ + SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, fsaa > 0 ? 1 : 0); + SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, fsaa); + + q_snprintf(caption, sizeof(caption), "QuakeSpasm " QUAKESPASM_VER_STRING); + +#if defined(USE_SDL2) + /* Create the window if needed, hidden */ + if (!draw_context) + { + flags = SDL_WINDOW_OPENGL | SDL_WINDOW_HIDDEN; + + if (vid_borderless.value) + flags |= SDL_WINDOW_BORDERLESS; + + draw_context = SDL_CreateWindow (caption, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, width, height, flags); + if (!draw_context) { // scale back fsaa + SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 0); + SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 0); + draw_context = SDL_CreateWindow (caption, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, width, height, flags); + } + if (!draw_context) { // scale back SDL_GL_DEPTH_SIZE + SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16); + draw_context = SDL_CreateWindow (caption, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, width, height, flags); + } + if (!draw_context) { // scale back SDL_GL_STENCIL_SIZE + SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 0); + draw_context = SDL_CreateWindow (caption, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, width, height, flags); + } + if (!draw_context) + Sys_Error ("Couldn't create window"); + + previous_display = -1; + } + else + { + previous_display = SDL_GetWindowDisplayIndex(draw_context); + } + + /* Ensure the window is not fullscreen */ + if (VID_GetFullscreen ()) + { + if (SDL_SetWindowFullscreen (draw_context, 0) != 0) + Sys_Error("Couldn't set fullscreen state mode"); + } + + /* Set window size and display mode */ + SDL_SetWindowSize (draw_context, width, height); + if (previous_display >= 0) + SDL_SetWindowPosition (draw_context, SDL_WINDOWPOS_CENTERED_DISPLAY(previous_display), SDL_WINDOWPOS_CENTERED_DISPLAY(previous_display)); + else + SDL_SetWindowPosition(draw_context, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED); + SDL_SetWindowDisplayMode (draw_context, VID_SDL2_GetDisplayMode(width, height, refreshrate, bpp)); + SDL_SetWindowBordered (draw_context, vid_borderless.value ? SDL_FALSE : SDL_TRUE); + + /* Make window fullscreen if needed, and show the window */ + + if (fullscreen) { + Uint32 flags = vid_desktopfullscreen.value ? + SDL_WINDOW_FULLSCREEN_DESKTOP : + SDL_WINDOW_FULLSCREEN; + if (SDL_SetWindowFullscreen (draw_context, flags) != 0) + Sys_Error ("Couldn't set fullscreen state mode"); + } + + SDL_ShowWindow (draw_context); + + /* Create GL context if needed */ + if (!gl_context) { + gl_context = SDL_GL_CreateContext(draw_context); + if (!gl_context) + Sys_Error("Couldn't create GL context"); + } + + gl_swap_control = true; + if (SDL_GL_SetSwapInterval ((vid_vsync.value) ? 1 : 0) == -1) + gl_swap_control = false; + +#else /* !defined(USE_SDL2) */ + + flags = DEFAULT_SDL_FLAGS; + if (fullscreen) + flags |= SDL_FULLSCREEN; + if (vid_borderless.value) + flags |= SDL_NOFRAME; + + gl_swap_control = true; + if (SDL_GL_SetAttribute(SDL_GL_SWAP_CONTROL, (vid_vsync.value) ? 1 : 0) == -1) + gl_swap_control = false; + + bpp = SDL_VideoModeOK(width, height, bpp, flags); + + draw_context = SDL_SetVideoMode(width, height, bpp, flags); + if (!draw_context) { // scale back fsaa + SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 0); + SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 0); + draw_context = SDL_SetVideoMode(width, height, bpp, flags); + } + if (!draw_context) { // scale back SDL_GL_DEPTH_SIZE + SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16); + draw_context = SDL_SetVideoMode(width, height, bpp, flags); + } + if (!draw_context) { // scale back SDL_GL_STENCIL_SIZE + SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 0); + draw_context = SDL_SetVideoMode(width, height, bpp, flags); + if (!draw_context) + Sys_Error ("Couldn't set video mode"); + } + + SDL_WM_SetCaption(caption, caption); +#endif /* !defined(USE_SDL2) */ + + vid.width = VID_GetCurrentWidth(); + vid.height = VID_GetCurrentHeight(); + vid.conwidth = vid.width & 0xFFFFFFF8; + vid.conheight = vid.conwidth * vid.height / vid.width; + vid.numpages = 2; + +// read the obtained z-buffer depth + if (SDL_GL_GetAttribute(SDL_GL_DEPTH_SIZE, &depthbits) == -1) + depthbits = 0; + +// read obtained fsaa samples + if (SDL_GL_GetAttribute(SDL_GL_MULTISAMPLESAMPLES, &fsaa_obtained) == -1) + fsaa_obtained = 0; + +// read stencil bits + if (SDL_GL_GetAttribute(SDL_GL_STENCIL_SIZE, &gl_stencilbits) == -1) + gl_stencilbits = 0; + + modestate = VID_GetFullscreen() ? MS_FULLSCREEN : MS_WINDOWED; + + CDAudio_Resume (); + BGM_Resume (); + scr_disabled_for_loading = temp; + +// fix the leftover Alt from any Alt-Tab or the like that switched us away + ClearAllStates (); + + Con_SafePrintf ("Video mode %dx%dx%d %dHz (%d-bit z-buffer, %dx FSAA) initialized\n", + VID_GetCurrentWidth(), + VID_GetCurrentHeight(), + VID_GetCurrentBPP(), + VID_GetCurrentRefreshRate(), + depthbits, + fsaa_obtained); + + vid.recalc_refdef = 1; + +// no pending changes + vid_changed = false; + + return true; +} + +/* +=================== +VID_Changed_f -- kristian -- notify us that a value has changed that requires a vid_restart +=================== +*/ +static void VID_Changed_f (cvar_t *var) +{ + vid_changed = true; +} + +/* +=================== +VID_Restart -- johnfitz -- change video modes on the fly +=================== +*/ +static void VID_Restart (void) +{ + int width, height, refreshrate, bpp; + qboolean fullscreen; + + if (vid_locked || !vid_changed) + return; + + width = (int)vid_width.value; + height = (int)vid_height.value; + refreshrate = (int)vid_refreshrate.value; + bpp = (int)vid_bpp.value; + fullscreen = vid_fullscreen.value ? true : false; + +// +// validate new mode +// + if (!VID_ValidMode (width, height, refreshrate, bpp, fullscreen)) + { + Con_Printf ("%dx%dx%d %dHz %s is not a valid mode\n", + width, height, bpp, refreshrate, fullscreen? "fullscreen" : "windowed"); + return; + } + +// ericw -- OS X, SDL1: textures, VBO's invalid after mode change +// OS X, SDL2: still valid after mode change +// To handle both cases, delete all GL objects (textures, VBO, GLSL) now. +// We must not interleave deleting the old objects with creating new ones, because +// one of the new objects could be given the same ID as an invalid handle +// which is later deleted. + + TexMgr_DeleteTextureObjects (); + GLSLGamma_DeleteTexture (); + R_ScaleView_DeleteTexture (); + R_DeleteShaders (); + GL_DeleteBModelVertexBuffer (); + GLMesh_DeleteVertexBuffers (); + +// +// set new mode +// + VID_SetMode (width, height, refreshrate, bpp, fullscreen); + + GL_Init (); + TexMgr_ReloadImages (); + GL_BuildBModelVertexBuffer (); + GLMesh_LoadVertexBuffers (); + GL_SetupState (); + Fog_SetupState (); + + //warpimages needs to be recalculated + TexMgr_RecalcWarpImageSize (); + + //conwidth and conheight need to be recalculated + vid.conwidth = (scr_conwidth.value > 0) ? (int)scr_conwidth.value : (scr_conscale.value > 0) ? (int)(vid.width/scr_conscale.value) : vid.width; + vid.conwidth = CLAMP (320, vid.conwidth, vid.width); + vid.conwidth &= 0xFFFFFFF8; + vid.conheight = vid.conwidth * vid.height / vid.width; +// +// keep cvars in line with actual mode +// + VID_SyncCvars(); +// +// update mouse grab +// + if (key_dest == key_console || key_dest == key_menu) + { + if (modestate == MS_WINDOWED) + IN_Deactivate(true); + else if (modestate == MS_FULLSCREEN) + IN_Activate(); + } +} + +/* +================ +VID_Test -- johnfitz -- like vid_restart, but asks for confirmation after switching modes +================ +*/ +static void VID_Test (void) +{ + int old_width, old_height, old_refreshrate, old_bpp, old_fullscreen; + + if (vid_locked || !vid_changed) + return; +// +// now try the switch +// + old_width = VID_GetCurrentWidth(); + old_height = VID_GetCurrentHeight(); + old_refreshrate = VID_GetCurrentRefreshRate(); + old_bpp = VID_GetCurrentBPP(); + old_fullscreen = VID_GetFullscreen() ? true : false; + + VID_Restart (); + + //pop up confirmation dialoge + if (!SCR_ModalMessage("Would you like to keep this\nvideo mode? (y/n)\n", 5.0f)) + { + //revert cvars and mode + Cvar_SetValueQuick (&vid_width, old_width); + Cvar_SetValueQuick (&vid_height, old_height); + Cvar_SetValueQuick (&vid_refreshrate, old_refreshrate); + Cvar_SetValueQuick (&vid_bpp, old_bpp); + Cvar_SetQuick (&vid_fullscreen, old_fullscreen ? "1" : "0"); + VID_Restart (); + } +} + +/* +================ +VID_Unlock -- johnfitz +================ +*/ +static void VID_Unlock (void) +{ + vid_locked = false; + VID_SyncCvars(); +} + +/* +================ +VID_Lock -- ericw + +Subsequent changes to vid_* mode settings, and vid_restart commands, will +be ignored until the "vid_unlock" command is run. + +Used when changing gamedirs so the current settings override what was saved +in the config.cfg. +================ +*/ +void VID_Lock (void) +{ + vid_locked = true; +} + +//============================================================================== +// +// OPENGL STUFF +// +//============================================================================== + +/* +=============== +GL_MakeNiceExtensionsList -- johnfitz +=============== +*/ +static char *GL_MakeNiceExtensionsList (const char *in) +{ + char *copy, *token, *out; + int i, count; + + if (!in) return Z_Strdup("(none)"); + + //each space will be replaced by 4 chars, so count the spaces before we malloc + for (i = 0, count = 1; i < (int) strlen(in); i++) + { + if (in[i] == ' ') + count++; + } + + out = (char *) Z_Malloc (strlen(in) + count*3 + 1); //usually about 1-2k + out[0] = 0; + + copy = (char *) Z_Strdup(in); + for (token = strtok(copy, " "); token; token = strtok(NULL, " ")) + { + strcat(out, "\n "); + strcat(out, token); + } + + Z_Free (copy); + return out; +} + +/* +=============== +GL_Info_f -- johnfitz +=============== +*/ +static void GL_Info_f (void) +{ + Con_SafePrintf ("GL_VENDOR: %s\n", gl_vendor); + Con_SafePrintf ("GL_RENDERER: %s\n", gl_renderer); + Con_SafePrintf ("GL_VERSION: %s\n", gl_version); + Con_Printf ("GL_EXTENSIONS: %s\n", gl_extensions_nice); +} + +/* +=============== +GL_CheckExtensions +=============== +*/ +static qboolean GL_ParseExtensionList (const char *list, const char *name) +{ + const char *start; + const char *where, *terminator; + + if (!list || !name || !*name) + return false; + if (strchr(name, ' ') != NULL) + return false; // extension names must not have spaces + + start = list; + while (1) { + where = strstr (start, name); + if (!where) + break; + terminator = where + strlen (name); + if (where == start || where[-1] == ' ') + if (*terminator == ' ' || *terminator == '\0') + return true; + start = terminator; + } + return false; +} + +static void GL_CheckExtensions (void) +{ + int swap_control; + + // ARB_vertex_buffer_object + // + if (COM_CheckParm("-novbo")) + Con_Warning ("Vertex buffer objects disabled at command line\n"); + else if (gl_version_major < 1 || (gl_version_major == 1 && gl_version_minor < 5)) + Con_Warning ("OpenGL version < 1.5, skipping ARB_vertex_buffer_object check\n"); + else + { + GL_BindBufferFunc = (PFNGLBINDBUFFERARBPROC) SDL_GL_GetProcAddress("glBindBufferARB"); + GL_BufferDataFunc = (PFNGLBUFFERDATAARBPROC) SDL_GL_GetProcAddress("glBufferDataARB"); + GL_BufferSubDataFunc = (PFNGLBUFFERSUBDATAARBPROC) SDL_GL_GetProcAddress("glBufferSubDataARB"); + GL_DeleteBuffersFunc = (PFNGLDELETEBUFFERSARBPROC) SDL_GL_GetProcAddress("glDeleteBuffersARB"); + GL_GenBuffersFunc = (PFNGLGENBUFFERSARBPROC) SDL_GL_GetProcAddress("glGenBuffersARB"); + if (GL_BindBufferFunc && GL_BufferDataFunc && GL_BufferSubDataFunc && GL_DeleteBuffersFunc && GL_GenBuffersFunc) + { + Con_Printf("FOUND: ARB_vertex_buffer_object\n"); + gl_vbo_able = true; + } + else + { + Con_Warning ("ARB_vertex_buffer_object not available\n"); + } + } + + // multitexture + // + if (COM_CheckParm("-nomtex")) + Con_Warning ("Mutitexture disabled at command line\n"); + else if (GL_ParseExtensionList(gl_extensions, "GL_ARB_multitexture")) + { + GL_MTexCoord2fFunc = (PFNGLMULTITEXCOORD2FARBPROC) SDL_GL_GetProcAddress("glMultiTexCoord2fARB"); + GL_SelectTextureFunc = (PFNGLACTIVETEXTUREARBPROC) SDL_GL_GetProcAddress("glActiveTextureARB"); + GL_ClientActiveTextureFunc = (PFNGLCLIENTACTIVETEXTUREARBPROC) SDL_GL_GetProcAddress("glClientActiveTextureARB"); + if (GL_MTexCoord2fFunc && GL_SelectTextureFunc && GL_ClientActiveTextureFunc) + { + Con_Printf("FOUND: ARB_multitexture\n"); + gl_mtexable = true; + + glGetIntegerv(GL_MAX_TEXTURE_UNITS, &gl_max_texture_units); + Con_Printf("GL_MAX_TEXTURE_UNITS: %d\n", (int)gl_max_texture_units); + } + else + { + Con_Warning ("Couldn't link to multitexture functions\n"); + } + } + else + { + Con_Warning ("multitexture not supported (extension not found)\n"); + } + + // texture_env_combine + // + if (COM_CheckParm("-nocombine")) + Con_Warning ("texture_env_combine disabled at command line\n"); + else if (GL_ParseExtensionList(gl_extensions, "GL_ARB_texture_env_combine")) + { + Con_Printf("FOUND: ARB_texture_env_combine\n"); + gl_texture_env_combine = true; + } + else if (GL_ParseExtensionList(gl_extensions, "GL_EXT_texture_env_combine")) + { + Con_Printf("FOUND: EXT_texture_env_combine\n"); + gl_texture_env_combine = true; + } + else + { + Con_Warning ("texture_env_combine not supported\n"); + } + + // texture_env_add + // + if (COM_CheckParm("-noadd")) + Con_Warning ("texture_env_add disabled at command line\n"); + else if (GL_ParseExtensionList(gl_extensions, "GL_ARB_texture_env_add")) + { + Con_Printf("FOUND: ARB_texture_env_add\n"); + gl_texture_env_add = true; + } + else if (GL_ParseExtensionList(gl_extensions, "GL_EXT_texture_env_add")) + { + Con_Printf("FOUND: EXT_texture_env_add\n"); + gl_texture_env_add = true; + } + else + { + Con_Warning ("texture_env_add not supported\n"); + } + + // swap control + // + if (!gl_swap_control) + { +#if defined(USE_SDL2) + Con_Warning ("vertical sync not supported (SDL_GL_SetSwapInterval failed)\n"); +#else + Con_Warning ("vertical sync not supported (SDL_GL_SetAttribute failed)\n"); +#endif + } +#if defined(USE_SDL2) + else if ((swap_control = SDL_GL_GetSwapInterval()) == -1) +#else + else if (SDL_GL_GetAttribute(SDL_GL_SWAP_CONTROL, &swap_control) == -1) +#endif + { + gl_swap_control = false; +#if defined(USE_SDL2) + Con_Warning ("vertical sync not supported (SDL_GL_GetSwapInterval failed)\n"); +#else + Con_Warning ("vertical sync not supported (SDL_GL_GetAttribute failed)\n"); +#endif + } + else if ((vid_vsync.value && swap_control != 1) || (!vid_vsync.value && swap_control != 0)) + { + gl_swap_control = false; + Con_Warning ("vertical sync not supported (swap_control doesn't match vid_vsync)\n"); + } + else + { +#if defined(USE_SDL2) + Con_Printf("FOUND: SDL_GL_SetSwapInterval\n"); +#else + Con_Printf("FOUND: SDL_GL_SWAP_CONTROL\n"); +#endif + } + + // anisotropic filtering + // + if (GL_ParseExtensionList(gl_extensions, "GL_EXT_texture_filter_anisotropic")) + { + float test1,test2; + GLuint tex; + + // test to make sure we really have control over it + // 1.0 and 2.0 should always be legal values + glGenTextures(1, &tex); + glBindTexture (GL_TEXTURE_2D, tex); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1.0f); + glGetTexParameterfv (GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, &test1); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 2.0f); + glGetTexParameterfv (GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, &test2); + glDeleteTextures(1, &tex); + + if (test1 == 1 && test2 == 2) + { + Con_Printf("FOUND: EXT_texture_filter_anisotropic\n"); + gl_anisotropy_able = true; + } + else + { + Con_Warning ("anisotropic filtering locked by driver. Current driver setting is %f\n", test1); + } + + //get max value either way, so the menu and stuff know it + glGetFloatv (GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &gl_max_anisotropy); + if (gl_max_anisotropy < 2) + { + gl_anisotropy_able = false; + gl_max_anisotropy = 1; + Con_Warning ("anisotropic filtering broken: disabled\n"); + } + } + else + { + gl_max_anisotropy = 1; + Con_Warning ("texture_filter_anisotropic not supported\n"); + } + + // texture_non_power_of_two + // + if (COM_CheckParm("-notexturenpot")) + Con_Warning ("texture_non_power_of_two disabled at command line\n"); + else if (GL_ParseExtensionList(gl_extensions, "GL_ARB_texture_non_power_of_two")) + { + Con_Printf("FOUND: ARB_texture_non_power_of_two\n"); + gl_texture_NPOT = true; + } + else + { + Con_Warning ("texture_non_power_of_two not supported\n"); + } + + // GLSL + // + if (COM_CheckParm("-noglsl")) + Con_Warning ("GLSL disabled at command line\n"); + else if (gl_version_major >= 2) + { + GL_CreateShaderFunc = (QS_PFNGLCREATESHADERPROC) SDL_GL_GetProcAddress("glCreateShader"); + GL_DeleteShaderFunc = (QS_PFNGLDELETESHADERPROC) SDL_GL_GetProcAddress("glDeleteShader"); + GL_DeleteProgramFunc = (QS_PFNGLDELETEPROGRAMPROC) SDL_GL_GetProcAddress("glDeleteProgram"); + GL_ShaderSourceFunc = (QS_PFNGLSHADERSOURCEPROC) SDL_GL_GetProcAddress("glShaderSource"); + GL_CompileShaderFunc = (QS_PFNGLCOMPILESHADERPROC) SDL_GL_GetProcAddress("glCompileShader"); + GL_GetShaderivFunc = (QS_PFNGLGETSHADERIVPROC) SDL_GL_GetProcAddress("glGetShaderiv"); + GL_GetShaderInfoLogFunc = (QS_PFNGLGETSHADERINFOLOGPROC) SDL_GL_GetProcAddress("glGetShaderInfoLog"); + GL_GetProgramivFunc = (QS_PFNGLGETPROGRAMIVPROC) SDL_GL_GetProcAddress("glGetProgramiv"); + GL_GetProgramInfoLogFunc = (QS_PFNGLGETPROGRAMINFOLOGPROC) SDL_GL_GetProcAddress("glGetProgramInfoLog"); + GL_CreateProgramFunc = (QS_PFNGLCREATEPROGRAMPROC) SDL_GL_GetProcAddress("glCreateProgram"); + GL_AttachShaderFunc = (QS_PFNGLATTACHSHADERPROC) SDL_GL_GetProcAddress("glAttachShader"); + GL_LinkProgramFunc = (QS_PFNGLLINKPROGRAMPROC) SDL_GL_GetProcAddress("glLinkProgram"); + GL_BindAttribLocationFunc = (QS_PFNGLBINDATTRIBLOCATIONFUNC) SDL_GL_GetProcAddress("glBindAttribLocation"); + GL_UseProgramFunc = (QS_PFNGLUSEPROGRAMPROC) SDL_GL_GetProcAddress("glUseProgram"); + GL_GetAttribLocationFunc = (QS_PFNGLGETATTRIBLOCATIONPROC) SDL_GL_GetProcAddress("glGetAttribLocation"); + GL_VertexAttribPointerFunc = (QS_PFNGLVERTEXATTRIBPOINTERPROC) SDL_GL_GetProcAddress("glVertexAttribPointer"); + GL_EnableVertexAttribArrayFunc = (QS_PFNGLENABLEVERTEXATTRIBARRAYPROC) SDL_GL_GetProcAddress("glEnableVertexAttribArray"); + GL_DisableVertexAttribArrayFunc = (QS_PFNGLDISABLEVERTEXATTRIBARRAYPROC) SDL_GL_GetProcAddress("glDisableVertexAttribArray"); + GL_GetUniformLocationFunc = (QS_PFNGLGETUNIFORMLOCATIONPROC) SDL_GL_GetProcAddress("glGetUniformLocation"); + GL_Uniform1iFunc = (QS_PFNGLUNIFORM1IPROC) SDL_GL_GetProcAddress("glUniform1i"); + GL_Uniform1fFunc = (QS_PFNGLUNIFORM1FPROC) SDL_GL_GetProcAddress("glUniform1f"); + GL_Uniform3fFunc = (QS_PFNGLUNIFORM3FPROC) SDL_GL_GetProcAddress("glUniform3f"); + GL_Uniform4fFunc = (QS_PFNGLUNIFORM4FPROC) SDL_GL_GetProcAddress("glUniform4f"); + + if (GL_CreateShaderFunc && + GL_DeleteShaderFunc && + GL_DeleteProgramFunc && + GL_ShaderSourceFunc && + GL_CompileShaderFunc && + GL_GetShaderivFunc && + GL_GetShaderInfoLogFunc && + GL_GetProgramivFunc && + GL_GetProgramInfoLogFunc && + GL_CreateProgramFunc && + GL_AttachShaderFunc && + GL_LinkProgramFunc && + GL_BindAttribLocationFunc && + GL_UseProgramFunc && + GL_GetAttribLocationFunc && + GL_VertexAttribPointerFunc && + GL_EnableVertexAttribArrayFunc && + GL_DisableVertexAttribArrayFunc && + GL_GetUniformLocationFunc && + GL_Uniform1iFunc && + GL_Uniform1fFunc && + GL_Uniform3fFunc && + GL_Uniform4fFunc) + { + Con_Printf("FOUND: GLSL\n"); + gl_glsl_able = true; + } + else + { + Con_Warning ("GLSL not available\n"); + } + } + else + { + Con_Warning ("OpenGL version < 2, GLSL not available\n"); + } + + // GLSL gamma + // + if (COM_CheckParm("-noglslgamma")) + Con_Warning ("GLSL gamma disabled at command line\n"); + else if (gl_glsl_able) + { + gl_glsl_gamma_able = true; + } + else + { + Con_Warning ("GLSL gamma not available, using hardware gamma\n"); + } + + // GLSL alias model rendering + // + if (COM_CheckParm("-noglslalias")) + Con_Warning ("GLSL alias model rendering disabled at command line\n"); + else if (gl_glsl_able && gl_vbo_able && gl_max_texture_units >= 3) + { + gl_glsl_alias_able = true; + } + else + { + Con_Warning ("GLSL alias model rendering not available, using Fitz renderer\n"); + } +} + +/* +=============== +GL_SetupState -- johnfitz + +does all the stuff from GL_Init that needs to be done every time a new GL render context is created +=============== +*/ +static void GL_SetupState (void) +{ + glClearColor (0.15,0.15,0.15,0); //johnfitz -- originally 1,0,0,0 + glCullFace(GL_BACK); //johnfitz -- glquake used CCW with backwards culling -- let's do it right + glFrontFace(GL_CW); //johnfitz -- glquake used CCW with backwards culling -- let's do it right + glEnable(GL_TEXTURE_2D); + glEnable(GL_ALPHA_TEST); + glAlphaFunc(GL_GREATER, 0.666); + glPolygonMode (GL_FRONT_AND_BACK, GL_FILL); + glShadeModel (GL_FLAT); + glHint (GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); //johnfitz + glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + glDepthRange (0, 1); //johnfitz -- moved here becuase gl_ztrick is gone. + glDepthFunc (GL_LEQUAL); //johnfitz -- moved here becuase gl_ztrick is gone. +} + +/* +=============== +GL_Init +=============== +*/ +static void GL_Init (void) +{ + gl_vendor = (const char *) glGetString (GL_VENDOR); + gl_renderer = (const char *) glGetString (GL_RENDERER); + gl_version = (const char *) glGetString (GL_VERSION); + gl_extensions = (const char *) glGetString (GL_EXTENSIONS); + + Con_SafePrintf ("GL_VENDOR: %s\n", gl_vendor); + Con_SafePrintf ("GL_RENDERER: %s\n", gl_renderer); + Con_SafePrintf ("GL_VERSION: %s\n", gl_version); + + if (gl_version == NULL || sscanf(gl_version, "%d.%d", &gl_version_major, &gl_version_minor) < 2) + { + gl_version_major = 0; + gl_version_minor = 0; + } + + if (gl_extensions_nice != NULL) + Z_Free (gl_extensions_nice); + gl_extensions_nice = GL_MakeNiceExtensionsList (gl_extensions); + + GL_CheckExtensions (); //johnfitz + +#ifdef __APPLE__ + // ericw -- enable multi-threaded OpenGL, gives a decent FPS boost. + // https://developer.apple.com/library/mac/technotes/tn2085/ + if (host_parms->numcpus > 1 && + kCGLNoError != CGLEnable(CGLGetCurrentContext(), kCGLCEMPEngine)) + { + Con_Warning ("Couldn't enable multi-threaded OpenGL"); + } +#endif + + //johnfitz -- intel video workarounds from Baker + if (!strcmp(gl_vendor, "Intel")) + { + Con_Printf ("Intel Display Adapter detected, enabling gl_clear\n"); + Cbuf_AddText ("gl_clear 1"); + } + //johnfitz + + GLAlias_CreateShaders (); + GLWorld_CreateShaders (); + GL_ClearBufferBindings (); +} + +/* +================= +GL_BeginRendering -- sets values of glx, gly, glwidth, glheight +================= +*/ +void GL_BeginRendering (int *x, int *y, int *width, int *height) +{ + *x = *y = 0; + *width = vid.width; + *height = vid.height; +} + +/* +================= +GL_EndRendering +================= +*/ +void GL_EndRendering (void) +{ + if (!scr_skipupdate) + { +#if defined(USE_SDL2) + SDL_GL_SwapWindow(draw_context); +#else + SDL_GL_SwapBuffers(); +#endif + } +} + + +void VID_Shutdown (void) +{ + if (vid_initialized) + { + VID_Gamma_Shutdown (); //johnfitz + + SDL_QuitSubSystem(SDL_INIT_VIDEO); + draw_context = NULL; +#if defined(USE_SDL2) + gl_context = NULL; +#endif + PL_VID_Shutdown(); + } +} + +/* +=================================================================== + +MAIN WINDOW + +=================================================================== +*/ + +/* +================ +ClearAllStates +================ +*/ +static void ClearAllStates (void) +{ + Key_ClearStates (); + IN_ClearStates (); +} + + +//========================================================================== +// +// COMMANDS +// +//========================================================================== + +/* +================= +VID_DescribeCurrentMode_f +================= +*/ +static void VID_DescribeCurrentMode_f (void) +{ + if (draw_context) + Con_Printf("%dx%dx%d %dHz %s\n", + VID_GetCurrentWidth(), + VID_GetCurrentHeight(), + VID_GetCurrentBPP(), + VID_GetCurrentRefreshRate(), + VID_GetFullscreen() ? "fullscreen" : "windowed"); +} + +/* +================= +VID_DescribeModes_f -- johnfitz -- changed formatting, and added refresh rates after each mode. +================= +*/ +static void VID_DescribeModes_f (void) +{ + int i; + int lastwidth, lastheight, lastbpp, count; + + lastwidth = lastheight = lastbpp = count = 0; + + for (i = 0; i < nummodes; i++) + { + if (lastwidth != modelist[i].width || lastheight != modelist[i].height || lastbpp != modelist[i].bpp) + { + if (count > 0) + Con_SafePrintf ("\n"); + Con_SafePrintf (" %4i x %4i x %i : %i", modelist[i].width, modelist[i].height, modelist[i].bpp, modelist[i].refreshrate); + lastwidth = modelist[i].width; + lastheight = modelist[i].height; + lastbpp = modelist[i].bpp; + count++; + } + } + Con_Printf ("\n%i modes\n", count); +} + +/* +=================== +VID_FSAA_f -- ericw -- warn that vid_fsaa requires engine restart +=================== +*/ +static void VID_FSAA_f (cvar_t *var) +{ + // don't print the warning if vid_fsaa is set during startup + if (vid_initialized) + Con_Printf("%s %d requires engine restart to take effect\n", var->name, (int)var->value); +} + +//========================================================================== +// +// INIT +// +//========================================================================== + +/* +================= +VID_InitModelist +================= +*/ +static void VID_InitModelist (void) +{ +#if defined(USE_SDL2) + const int sdlmodes = SDL_GetNumDisplayModes(0); + int i; + + nummodes = 0; + for (i = 0; i < sdlmodes; i++) + { + SDL_DisplayMode mode; + + if (nummodes >= MAX_MODE_LIST) + break; + if (SDL_GetDisplayMode(0, i, &mode) == 0) + { + modelist[nummodes].width = mode.w; + modelist[nummodes].height = mode.h; + modelist[nummodes].bpp = SDL_BITSPERPIXEL(mode.format); + modelist[nummodes].refreshrate = mode.refresh_rate; + nummodes++; + } + } +#else /* !defined(USE_SDL2) */ + SDL_PixelFormat format; + SDL_Rect **modes; + Uint32 flags; + int i, j, k, originalnummodes, existingmode; + int bpps[] = {16, 24, 32}; // enumerate >8 bpp modes + + originalnummodes = nummodes = 0; + format.palette = NULL; + + // enumerate fullscreen modes + flags = DEFAULT_SDL_FLAGS | SDL_FULLSCREEN; + for (i = 0; i < (int)(sizeof(bpps)/sizeof(bpps[0])); i++) + { + if (nummodes >= MAX_MODE_LIST) + break; + + format.BitsPerPixel = bpps[i]; + modes = SDL_ListModes(&format, flags); + + if (modes == (SDL_Rect **)0 || modes == (SDL_Rect **)-1) + continue; + + for (j = 0; modes[j]; j++) + { + if (modes[j]->w > MAXWIDTH || modes[j]->h > MAXHEIGHT || nummodes >= MAX_MODE_LIST) + continue; + + modelist[nummodes].width = modes[j]->w; + modelist[nummodes].height = modes[j]->h; + modelist[nummodes].bpp = bpps[i]; + modelist[nummodes].refreshrate = DEFAULT_REFRESHRATE; + + for (k=originalnummodes, existingmode = 0 ; k < nummodes ; k++) + { + if ((modelist[nummodes].width == modelist[k].width) && + (modelist[nummodes].height == modelist[k].height) && + (modelist[nummodes].bpp == modelist[k].bpp)) + { + existingmode = 1; + break; + } + } + + if (!existingmode) + { + nummodes++; + } + } + } + + if (nummodes == originalnummodes) + Con_SafePrintf ("No fullscreen DIB modes found\n"); +#endif /* !defined(USE_SDL2) */ +} + +/* +=================== +VID_Init +=================== +*/ +void VID_Init (void) +{ + static char vid_center[] = "SDL_VIDEO_CENTERED=center"; + int p, width, height, refreshrate, bpp; + int display_width, display_height, display_refreshrate, display_bpp; + qboolean fullscreen; + const char *read_vars[] = { "vid_fullscreen", + "vid_width", + "vid_height", + "vid_refreshrate", + "vid_bpp", + "vid_vsync", + "vid_fsaa", + "vid_desktopfullscreen", + "vid_borderless"}; +#define num_readvars ( sizeof(read_vars)/sizeof(read_vars[0]) ) + + Cvar_RegisterVariable (&vid_fullscreen); //johnfitz + Cvar_RegisterVariable (&vid_width); //johnfitz + Cvar_RegisterVariable (&vid_height); //johnfitz + Cvar_RegisterVariable (&vid_refreshrate); //johnfitz + Cvar_RegisterVariable (&vid_bpp); //johnfitz + Cvar_RegisterVariable (&vid_vsync); //johnfitz + Cvar_RegisterVariable (&vid_fsaa); //QuakeSpasm + Cvar_RegisterVariable (&vid_desktopfullscreen); //QuakeSpasm + Cvar_RegisterVariable (&vid_borderless); //QuakeSpasm + Cvar_SetCallback (&vid_fullscreen, VID_Changed_f); + Cvar_SetCallback (&vid_width, VID_Changed_f); + Cvar_SetCallback (&vid_height, VID_Changed_f); + Cvar_SetCallback (&vid_refreshrate, VID_Changed_f); + Cvar_SetCallback (&vid_bpp, VID_Changed_f); + Cvar_SetCallback (&vid_vsync, VID_Changed_f); + Cvar_SetCallback (&vid_fsaa, VID_FSAA_f); + Cvar_SetCallback (&vid_desktopfullscreen, VID_Changed_f); + Cvar_SetCallback (&vid_borderless, VID_Changed_f); + + Cmd_AddCommand ("vid_unlock", VID_Unlock); //johnfitz + Cmd_AddCommand ("vid_restart", VID_Restart); //johnfitz + Cmd_AddCommand ("vid_test", VID_Test); //johnfitz + Cmd_AddCommand ("vid_describecurrentmode", VID_DescribeCurrentMode_f); + Cmd_AddCommand ("vid_describemodes", VID_DescribeModes_f); + + putenv (vid_center); /* SDL_putenv is problematic in versions <= 1.2.9 */ + + if (SDL_InitSubSystem(SDL_INIT_VIDEO) < 0) + Sys_Error("Couldn't init SDL video: %s", SDL_GetError()); + +#if defined(USE_SDL2) + { + SDL_DisplayMode mode; + if (SDL_GetDesktopDisplayMode(0, &mode) != 0) + Sys_Error("Could not get desktop display mode"); + + display_width = mode.w; + display_height = mode.h; + display_refreshrate = mode.refresh_rate; + display_bpp = SDL_BITSPERPIXEL(mode.format); + } +#else + { + const SDL_VideoInfo *info = SDL_GetVideoInfo(); + display_width = info->current_w; + display_height = info->current_h; + display_refreshrate = DEFAULT_REFRESHRATE; + display_bpp = info->vfmt->BitsPerPixel; + } +#endif + + Cvar_SetValueQuick (&vid_bpp, (float)display_bpp); + + if (CFG_OpenConfig("config.cfg") == 0) + { + CFG_ReadCvars(read_vars, num_readvars); + CFG_CloseConfig(); + } + CFG_ReadCvarOverrides(read_vars, num_readvars); + + VID_InitModelist(); + + width = (int)vid_width.value; + height = (int)vid_height.value; + refreshrate = (int)vid_refreshrate.value; + bpp = (int)vid_bpp.value; + fullscreen = (int)vid_fullscreen.value; + fsaa = (int)vid_fsaa.value; + + if (COM_CheckParm("-current")) + { + width = display_width; + height = display_height; + refreshrate = display_refreshrate; + bpp = display_bpp; + fullscreen = true; + } + else + { + p = COM_CheckParm("-width"); + if (p && p < com_argc-1) + { + width = Q_atoi(com_argv[p+1]); + + if(!COM_CheckParm("-height")) + height = width * 3 / 4; + } + + p = COM_CheckParm("-height"); + if (p && p < com_argc-1) + { + height = Q_atoi(com_argv[p+1]); + + if(!COM_CheckParm("-width")) + width = height * 4 / 3; + } + + p = COM_CheckParm("-refreshrate"); + if (p && p < com_argc-1) + refreshrate = Q_atoi(com_argv[p+1]); + + p = COM_CheckParm("-bpp"); + if (p && p < com_argc-1) + bpp = Q_atoi(com_argv[p+1]); + + if (COM_CheckParm("-window") || COM_CheckParm("-w")) + fullscreen = false; + else if (COM_CheckParm("-fullscreen") || COM_CheckParm("-f")) + fullscreen = true; + } + + p = COM_CheckParm ("-fsaa"); + if (p && p < com_argc-1) + fsaa = atoi(com_argv[p+1]); + + if (!VID_ValidMode(width, height, refreshrate, bpp, fullscreen)) + { + width = (int)vid_width.value; + height = (int)vid_height.value; + refreshrate = (int)vid_refreshrate.value; + bpp = (int)vid_bpp.value; + fullscreen = (int)vid_fullscreen.value; + } + + if (!VID_ValidMode(width, height, refreshrate, bpp, fullscreen)) + { + width = 640; + height = 480; + refreshrate = display_refreshrate; + bpp = display_bpp; + fullscreen = false; + } + + vid_initialized = true; + + vid.maxwarpwidth = WARP_WIDTH; + vid.maxwarpheight = WARP_HEIGHT; + vid.colormap = host_colormap; + vid.fullbright = 256 - LittleLong (*((int *)vid.colormap + 2048)); + + // set window icon + PL_SetWindowIcon(); + + VID_SetMode (width, height, refreshrate, bpp, fullscreen); + + GL_Init (); + GL_SetupState (); + Cmd_AddCommand ("gl_info", GL_Info_f); //johnfitz + + //johnfitz -- removed code creating "glquake" subdirectory + + vid_menucmdfn = VID_Menu_f; //johnfitz + vid_menudrawfn = VID_MenuDraw; + vid_menukeyfn = VID_MenuKey; + + VID_Gamma_Init(); //johnfitz + VID_Menu_Init(); //johnfitz + + //QuakeSpasm: current vid settings should override config file settings. + //so we have to lock the vid mode from now until after all config files are read. + vid_locked = true; +} + +// new proc by S.A., called by alt-return key binding. +void VID_Toggle (void) +{ + // disabling the fast path completely because SDL_SetWindowFullscreen was changing + // the window size on SDL2/WinXP and we weren't set up to handle it. --ericw + // + // TODO: Clear out the dead code, reinstate the fast path using SDL_SetWindowFullscreen + // inside VID_SetMode, check window size to fix WinXP issue. This will + // keep all the mode changing code in one place. + static qboolean vid_toggle_works = false; + qboolean toggleWorked; +#if defined(USE_SDL2) + Uint32 flags = 0; +#endif + + S_ClearBuffer (); + + if (!vid_toggle_works) + goto vrestart; + else if (gl_vbo_able) + { + // disabling the fast path because with SDL 1.2 it invalidates VBOs (using them + // causes a crash, sugesting that the fullscreen toggle created a new GL context, + // although texture objects remain valid for some reason). + // + // SDL2 does promise window resizes / fullscreen changes preserve the GL context, + // so we could use the fast path with SDL2. --ericw + vid_toggle_works = false; + goto vrestart; + } + +#if defined(USE_SDL2) + if (!VID_GetFullscreen()) { + flags = vid_desktopfullscreen.value ? SDL_WINDOW_FULLSCREEN_DESKTOP : SDL_WINDOW_FULLSCREEN; + } + + toggleWorked = SDL_SetWindowFullscreen(draw_context, flags) == 0; +#else + toggleWorked = SDL_WM_ToggleFullScreen(draw_context) == 1; +#endif + + if (toggleWorked) + { + Sbar_Changed (); // Sbar seems to need refreshing + + modestate = VID_GetFullscreen() ? MS_FULLSCREEN : MS_WINDOWED; + + VID_SyncCvars(); + + // update mouse grab + if (key_dest == key_console || key_dest == key_menu) + { + if (modestate == MS_WINDOWED) + IN_Deactivate(true); + else if (modestate == MS_FULLSCREEN) + IN_Activate(); + } + } + else + { + vid_toggle_works = false; + Con_DPrintf ("SDL_WM_ToggleFullScreen failed, attempting VID_Restart\n"); + vrestart: + Cvar_SetQuick (&vid_fullscreen, VID_GetFullscreen() ? "0" : "1"); + Cbuf_AddText ("vid_restart\n"); + } +} + +/* +================ +VID_SyncCvars -- johnfitz -- set vid cvars to match current video mode +================ +*/ +void VID_SyncCvars (void) +{ + if (draw_context) + { + if (!VID_GetDesktopFullscreen()) + { + Cvar_SetValueQuick (&vid_width, VID_GetCurrentWidth()); + Cvar_SetValueQuick (&vid_height, VID_GetCurrentHeight()); + } + Cvar_SetValueQuick (&vid_refreshrate, VID_GetCurrentRefreshRate()); + Cvar_SetValueQuick (&vid_bpp, VID_GetCurrentBPP()); + Cvar_SetQuick (&vid_fullscreen, VID_GetFullscreen() ? "1" : "0"); + // don't sync vid_desktopfullscreen, it's a user preference that + // should persist even if we are in windowed mode. + Cvar_SetQuick (&vid_vsync, VID_GetVSync() ? "1" : "0"); + } + + vid_changed = false; +} + +//========================================================================== +// +// NEW VIDEO MENU -- johnfitz +// +//========================================================================== + +enum { + VID_OPT_MODE, + VID_OPT_BPP, + VID_OPT_REFRESHRATE, + VID_OPT_FULLSCREEN, + VID_OPT_VSYNC, + VID_OPT_TEST, + VID_OPT_APPLY, + VIDEO_OPTIONS_ITEMS +}; + +static int video_options_cursor = 0; + +typedef struct { + int width,height; +} vid_menu_mode; + +//TODO: replace these fixed-length arrays with hunk_allocated buffers +static vid_menu_mode vid_menu_modes[MAX_MODE_LIST]; +static int vid_menu_nummodes = 0; + +static int vid_menu_bpps[MAX_BPPS_LIST]; +static int vid_menu_numbpps = 0; + +static int vid_menu_rates[MAX_RATES_LIST]; +static int vid_menu_numrates=0; + +/* +================ +VID_Menu_Init +================ +*/ +static void VID_Menu_Init (void) +{ + int i, j, h, w; + + for (i = 0; i < nummodes; i++) + { + w = modelist[i].width; + h = modelist[i].height; + + for (j = 0; j < vid_menu_nummodes; j++) + { + if (vid_menu_modes[j].width == w && + vid_menu_modes[j].height == h) + break; + } + + if (j == vid_menu_nummodes) + { + vid_menu_modes[j].width = w; + vid_menu_modes[j].height = h; + vid_menu_nummodes++; + } + } +} + +/* +================ +VID_Menu_RebuildBppList + +regenerates bpp list based on current vid_width and vid_height +================ +*/ +static void VID_Menu_RebuildBppList (void) +{ + int i, j, b; + + vid_menu_numbpps = 0; + + for (i = 0; i < nummodes; i++) + { + if (vid_menu_numbpps >= MAX_BPPS_LIST) + break; + + //bpp list is limited to bpps available with current width/height + if (modelist[i].width != vid_width.value || + modelist[i].height != vid_height.value) + continue; + + b = modelist[i].bpp; + + for (j = 0; j < vid_menu_numbpps; j++) + { + if (vid_menu_bpps[j] == b) + break; + } + + if (j == vid_menu_numbpps) + { + vid_menu_bpps[j] = b; + vid_menu_numbpps++; + } + } + + //if there are no valid fullscreen bpps for this width/height, just pick one + if (vid_menu_numbpps == 0) + { + Cvar_SetValueQuick (&vid_bpp, (float)modelist[0].bpp); + return; + } + + //if vid_bpp is not in the new list, change vid_bpp + for (i = 0; i < vid_menu_numbpps; i++) + if (vid_menu_bpps[i] == (int)(vid_bpp.value)) + break; + + if (i == vid_menu_numbpps) + Cvar_SetValueQuick (&vid_bpp, (float)vid_menu_bpps[0]); +} + +/* +================ +VID_Menu_RebuildRateList + +regenerates rate list based on current vid_width, vid_height and vid_bpp +================ +*/ +static void VID_Menu_RebuildRateList (void) +{ + int i,j,r; + + vid_menu_numrates=0; + + for (i=0;i= vid_menu_nummodes) + i = 0; + else if (i < 0) + i = vid_menu_nummodes-1; + } + + Cvar_SetValueQuick (&vid_width, (float)vid_menu_modes[i].width); + Cvar_SetValueQuick (&vid_height, (float)vid_menu_modes[i].height); + VID_Menu_RebuildBppList (); + VID_Menu_RebuildRateList (); + } +} + +/* +================ +VID_Menu_ChooseNextBpp + +chooses next bpp in order, then updates vid_bpp cvar +================ +*/ +static void VID_Menu_ChooseNextBpp (int dir) +{ + int i; + + if (vid_menu_numbpps) + { + for (i = 0; i < vid_menu_numbpps; i++) + { + if (vid_menu_bpps[i] == vid_bpp.value) + break; + } + + if (i == vid_menu_numbpps) //can't find it in list + { + i = 0; + } + else + { + i += dir; + if (i >= vid_menu_numbpps) + i = 0; + else if (i < 0) + i = vid_menu_numbpps-1; + } + + Cvar_SetValueQuick (&vid_bpp, (float)vid_menu_bpps[i]); + } +} + +/* +================ +VID_Menu_ChooseNextRate + +chooses next refresh rate in order, then updates vid_refreshrate cvar +================ +*/ +static void VID_Menu_ChooseNextRate (int dir) +{ + int i; + + for (i=0;i=vid_menu_numrates) + i = 0; + else if (i<0) + i = vid_menu_numrates-1; + } + + Cvar_SetValue ("vid_refreshrate",(float)vid_menu_rates[i]); +} + +/* +================ +VID_MenuKey +================ +*/ +static void VID_MenuKey (int key) +{ + switch (key) + { + case K_ESCAPE: + case K_BBUTTON: + VID_SyncCvars (); //sync cvars before leaving menu. FIXME: there are other ways to leave menu + S_LocalSound ("misc/menu1.wav"); + M_Menu_Options_f (); + break; + + case K_UPARROW: + S_LocalSound ("misc/menu1.wav"); + video_options_cursor--; + if (video_options_cursor < 0) + video_options_cursor = VIDEO_OPTIONS_ITEMS-1; + break; + + case K_DOWNARROW: + S_LocalSound ("misc/menu1.wav"); + video_options_cursor++; + if (video_options_cursor >= VIDEO_OPTIONS_ITEMS) + video_options_cursor = 0; + break; + + case K_LEFTARROW: + S_LocalSound ("misc/menu3.wav"); + switch (video_options_cursor) + { + case VID_OPT_MODE: + VID_Menu_ChooseNextMode (1); + break; + case VID_OPT_BPP: + VID_Menu_ChooseNextBpp (1); + break; + case VID_OPT_REFRESHRATE: + VID_Menu_ChooseNextRate (1); + break; + case VID_OPT_FULLSCREEN: + Cbuf_AddText ("toggle vid_fullscreen\n"); + break; + case VID_OPT_VSYNC: + Cbuf_AddText ("toggle vid_vsync\n"); // kristian + break; + default: + break; + } + break; + + case K_RIGHTARROW: + S_LocalSound ("misc/menu3.wav"); + switch (video_options_cursor) + { + case VID_OPT_MODE: + VID_Menu_ChooseNextMode (-1); + break; + case VID_OPT_BPP: + VID_Menu_ChooseNextBpp (-1); + break; + case VID_OPT_REFRESHRATE: + VID_Menu_ChooseNextRate (-1); + break; + case VID_OPT_FULLSCREEN: + Cbuf_AddText ("toggle vid_fullscreen\n"); + break; + case VID_OPT_VSYNC: + Cbuf_AddText ("toggle vid_vsync\n"); + break; + default: + break; + } + break; + + case K_ENTER: + case K_KP_ENTER: + case K_ABUTTON: + m_entersound = true; + switch (video_options_cursor) + { + case VID_OPT_MODE: + VID_Menu_ChooseNextMode (1); + break; + case VID_OPT_BPP: + VID_Menu_ChooseNextBpp (1); + break; + case VID_OPT_REFRESHRATE: + VID_Menu_ChooseNextRate (1); + break; + case VID_OPT_FULLSCREEN: + Cbuf_AddText ("toggle vid_fullscreen\n"); + break; + case VID_OPT_VSYNC: + Cbuf_AddText ("toggle vid_vsync\n"); + break; + case VID_OPT_TEST: + Cbuf_AddText ("vid_test\n"); + break; + case VID_OPT_APPLY: + Cbuf_AddText ("vid_restart\n"); + key_dest = key_game; + m_state = m_none; + IN_Activate(); + break; + default: + break; + } + break; + + default: + break; + } +} + +/* +================ +VID_MenuDraw +================ +*/ +static void VID_MenuDraw (void) +{ + int i, y; + qpic_t *p; + const char *title; + + y = 4; + + // plaque + p = Draw_CachePic ("gfx/qplaque.lmp"); + M_DrawTransPic (16, y, p); + + //p = Draw_CachePic ("gfx/vidmodes.lmp"); + p = Draw_CachePic ("gfx/p_option.lmp"); + M_DrawPic ( (320-p->width)/2, y, p); + + y += 28; + + // title + title = "Video Options"; + M_PrintWhite ((320-8*strlen(title))/2, y, title); + + y += 16; + + // options + for (i = 0; i < VIDEO_OPTIONS_ITEMS; i++) + { + switch (i) + { + case VID_OPT_MODE: + M_Print (16, y, " Video mode"); + M_Print (184, y, va("%ix%i", (int)vid_width.value, (int)vid_height.value)); + break; + case VID_OPT_BPP: + M_Print (16, y, " Color depth"); + M_Print (184, y, va("%i", (int)vid_bpp.value)); + break; + case VID_OPT_REFRESHRATE: + M_Print (16, y, " Refresh rate"); + M_Print (184, y, va("%i", (int)vid_refreshrate.value)); + break; + case VID_OPT_FULLSCREEN: + M_Print (16, y, " Fullscreen"); + M_DrawCheckbox (184, y, (int)vid_fullscreen.value); + break; + case VID_OPT_VSYNC: + M_Print (16, y, " Vertical sync"); + if (gl_swap_control) + M_DrawCheckbox (184, y, (int)vid_vsync.value); + else + M_Print (184, y, "N/A"); + break; + case VID_OPT_TEST: + y += 8; //separate the test and apply items + M_Print (16, y, " Test changes"); + break; + case VID_OPT_APPLY: + M_Print (16, y, " Apply changes"); + break; + } + + if (video_options_cursor == i) + M_DrawCharacter (168, y, 12+((int)(realtime*4)&1)); + + y += 8; + } +} + +/* +================ +VID_Menu_f +================ +*/ +static void VID_Menu_f (void) +{ + IN_Deactivate(modestate == MS_WINDOWED); + key_dest = key_menu; + m_state = m_video; + m_entersound = true; + + //set all the cvars to match the current mode when entering the menu + VID_SyncCvars (); + + //set up bpp and rate lists based on current cvars + VID_Menu_RebuildBppList (); + VID_Menu_RebuildRateList (); +} + diff --git a/engine/Quake/gl_warp.c b/engine/Quake/gl_warp.c new file mode 100644 index 0000000..0214531 --- /dev/null +++ b/engine/Quake/gl_warp.c @@ -0,0 +1,272 @@ +/* +Copyright (C) 1996-2001 Id Software, Inc. +Copyright (C) 2002-2009 John Fitzgibbons and others +Copyright (C) 2010-2014 QuakeSpasm developers + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +//gl_warp.c -- warping animation support + +#include "quakedef.h" + +extern cvar_t r_drawflat; + +cvar_t r_oldwater = {"r_oldwater", "0", CVAR_ARCHIVE}; +cvar_t r_waterquality = {"r_waterquality", "8", CVAR_NONE}; +cvar_t r_waterwarp = {"r_waterwarp", "1", CVAR_NONE}; + +int gl_warpimagesize; +float load_subdivide_size; //johnfitz -- remember what subdivide_size value was when this map was loaded + +float turbsin[] = +{ +#include "gl_warp_sin.h" +}; + +#define WARPCALC(s,t) ((s + turbsin[(int)((t*2)+(cl.time*(128.0/M_PI))) & 255]) * (1.0/64)) //johnfitz -- correct warp +#define WARPCALC2(s,t) ((s + turbsin[(int)((t*0.125+cl.time)*(128.0/M_PI)) & 255]) * (1.0/64)) //johnfitz -- old warp + +//============================================================================== +// +// OLD-STYLE WATER +// +//============================================================================== + +extern qmodel_t *loadmodel; + +msurface_t *warpface; + +cvar_t gl_subdivide_size = {"gl_subdivide_size", "128", CVAR_ARCHIVE}; + +void BoundPoly (int numverts, float *verts, vec3_t mins, vec3_t maxs) +{ + int i, j; + float *v; + + mins[0] = mins[1] = mins[2] = 999999999; + maxs[0] = maxs[1] = maxs[2] = -999999999; + v = verts; + for (i=0 ; i maxs[j]) + maxs[j] = *v; + } +} + +void SubdividePolygon (int numverts, float *verts) +{ + int i, j, k; + vec3_t mins, maxs; + float m; + float *v; + vec3_t front[64], back[64]; + int f, b; + float dist[64]; + float frac; + glpoly_t *poly; + float s, t; + + if (numverts > 60) + Sys_Error ("numverts = %i", numverts); + + BoundPoly (numverts, verts, mins, maxs); + + for (i=0 ; i<3 ; i++) + { + m = (mins[i] + maxs[i]) * 0.5; + m = gl_subdivide_size.value * floor (m/gl_subdivide_size.value + 0.5); + if (maxs[i] - m < 8) + continue; + if (m - mins[i] < 8) + continue; + + // cut it + v = verts + i; + for (j=0 ; j= 0) + { + VectorCopy (v, front[f]); + f++; + } + if (dist[j] <= 0) + { + VectorCopy (v, back[b]); + b++; + } + if (dist[j] == 0 || dist[j+1] == 0) + continue; + if ( (dist[j] > 0) != (dist[j+1] > 0) ) + { + // clip point + frac = dist[j] / (dist[j] - dist[j+1]); + for (k=0 ; k<3 ; k++) + front[f][k] = back[b][k] = v[k] + frac*(v[3+k] - v[k]); + f++; + b++; + } + } + + SubdividePolygon (f, front[0]); + SubdividePolygon (b, back[0]); + return; + } + + poly = (glpoly_t *) Hunk_Alloc (sizeof(glpoly_t) + (numverts-4) * VERTEXSIZE*sizeof(float)); + poly->next = warpface->polys->next; + warpface->polys->next = poly; + poly->numverts = numverts; + for (i=0 ; iverts[i]); + s = DotProduct (verts, warpface->texinfo->vecs[0]); + t = DotProduct (verts, warpface->texinfo->vecs[1]); + poly->verts[i][3] = s; + poly->verts[i][4] = t; + } +} + +/* +================ +GL_SubdivideSurface +================ +*/ +void GL_SubdivideSurface (msurface_t *fa) +{ + vec3_t verts[64]; + int i; + + warpface = fa; + + //the first poly in the chain is the undivided poly for newwater rendering. + //grab the verts from that. + for (i=0; ipolys->numverts; i++) + VectorCopy (fa->polys->verts[i], verts[i]); + + SubdividePolygon (fa->polys->numverts, verts[0]); +} + +/* +================ +DrawWaterPoly -- johnfitz +================ +*/ +void DrawWaterPoly (glpoly_t *p) +{ + float *v; + int i; + + if (load_subdivide_size > 48) + { + glBegin (GL_POLYGON); + v = p->verts[0]; + for (i=0 ; inumverts ; i++, v+= VERTEXSIZE) + { + glTexCoord2f (WARPCALC2(v[3],v[4]), WARPCALC2(v[4],v[3])); + glVertex3fv (v); + } + glEnd (); + } + else + { + glBegin (GL_POLYGON); + v = p->verts[0]; + for (i=0 ; inumverts ; i++, v+= VERTEXSIZE) + { + glTexCoord2f (WARPCALC(v[3],v[4]), WARPCALC(v[4],v[3])); + glVertex3fv (v); + } + glEnd (); + } +} + +//============================================================================== +// +// RENDER-TO-FRAMEBUFFER WATER +// +//============================================================================== + +/* +============= +R_UpdateWarpTextures -- johnfitz -- each frame, update warping textures +============= +*/ +void R_UpdateWarpTextures (void) +{ + texture_t *tx; + int i; + float x, y, x2, warptess; + + if (r_oldwater.value || cl.paused || r_drawflat_cheatsafe || r_lightmap_cheatsafe) + return; + + warptess = 128.0/CLAMP (3.0, floor(r_waterquality.value), 64.0); + + for (i=0; inumtextures; i++) + { + if (!(tx = cl.worldmodel->textures[i])) + continue; + + if (!tx->update_warp) + continue; + + //render warp + GL_SetCanvas (CANVAS_WARPIMAGE); + GL_Bind (tx->gltexture); + for (x=0.0; x<128.0; x=x2) + { + x2 = x + warptess; + glBegin (GL_TRIANGLE_STRIP); + for (y=0.0; y<128.01; y+=warptess) // .01 for rounding errors + { + glTexCoord2f (WARPCALC(x,y), WARPCALC(y,x)); + glVertex2f (x,y); + glTexCoord2f (WARPCALC(x2,y), WARPCALC(y,x2)); + glVertex2f (x2,y); + } + glEnd(); + } + + //copy to texture + GL_Bind (tx->warpimage); + glCopyTexSubImage2D (GL_TEXTURE_2D, 0, 0, 0, glx, gly+glheight-gl_warpimagesize, gl_warpimagesize, gl_warpimagesize); + + tx->update_warp = false; + } + + // ericw -- workaround for osx 10.6 driver bug when using FSAA. R_Clear only clears the warpimage part of the screen. + GL_SetCanvas(CANVAS_DEFAULT); + + //if warp render went down into sbar territory, we need to be sure to refresh it next frame + if (gl_warpimagesize + sb_lines > glheight) + Sbar_Changed (); + + //if viewsize is less than 100, we need to redraw the frame around the viewport + scr_tileclear_updates = 0; +} diff --git a/engine/Quake/gl_warp_sin.h b/engine/Quake/gl_warp_sin.h new file mode 100644 index 0000000..313ab4e --- /dev/null +++ b/engine/Quake/gl_warp_sin.h @@ -0,0 +1,84 @@ +/* + * gl_warp_sin.h + * Copyright (C) 1996-1997 Id Software, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + + 0, 0.19633, 0.392541, 0.588517, + 0.784137, 0.979285, 1.17384, 1.3677, + 1.56072, 1.75281, 1.94384, 2.1337, + 2.32228, 2.50945, 2.69512, 2.87916, + 3.06147, 3.24193, 3.42044, 3.59689, + 3.77117, 3.94319, 4.11282, 4.27998, + 4.44456, 4.60647, 4.76559, 4.92185, + 5.07515, 5.22538, 5.37247, 5.51632, + 5.65685, 5.79398, 5.92761, 6.05767, + 6.18408, 6.30677, 6.42566, 6.54068, + 6.65176, 6.75883, 6.86183, 6.9607, + 7.05537, 7.14579, 7.23191, 7.31368, + 7.39104, 7.46394, 7.53235, 7.59623, + 7.65552, 7.71021, 7.76025, 7.80562, + 7.84628, 7.88222, 7.91341, 7.93984, + 7.96148, 7.97832, 7.99036, 7.99759, + 8, 7.99759, 7.99036, 7.97832, + 7.96148, 7.93984, 7.91341, 7.88222, + 7.84628, 7.80562, 7.76025, 7.71021, + 7.65552, 7.59623, 7.53235, 7.46394, + 7.39104, 7.31368, 7.23191, 7.14579, + 7.05537, 6.9607, 6.86183, 6.75883, + 6.65176, 6.54068, 6.42566, 6.30677, + 6.18408, 6.05767, 5.92761, 5.79398, + 5.65685, 5.51632, 5.37247, 5.22538, + 5.07515, 4.92185, 4.76559, 4.60647, + 4.44456, 4.27998, 4.11282, 3.94319, + 3.77117, 3.59689, 3.42044, 3.24193, + 3.06147, 2.87916, 2.69512, 2.50945, + 2.32228, 2.1337, 1.94384, 1.75281, + 1.56072, 1.3677, 1.17384, 0.979285, + 0.784137, 0.588517, 0.392541, 0.19633, + 9.79717e-16, -0.19633, -0.392541, -0.588517, + -0.784137, -0.979285, -1.17384, -1.3677, + -1.56072, -1.75281, -1.94384, -2.1337, + -2.32228, -2.50945, -2.69512, -2.87916, + -3.06147, -3.24193, -3.42044, -3.59689, + -3.77117, -3.94319, -4.11282, -4.27998, + -4.44456, -4.60647, -4.76559, -4.92185, + -5.07515, -5.22538, -5.37247, -5.51632, + -5.65685, -5.79398, -5.92761, -6.05767, + -6.18408, -6.30677, -6.42566, -6.54068, + -6.65176, -6.75883, -6.86183, -6.9607, + -7.05537, -7.14579, -7.23191, -7.31368, + -7.39104, -7.46394, -7.53235, -7.59623, + -7.65552, -7.71021, -7.76025, -7.80562, + -7.84628, -7.88222, -7.91341, -7.93984, + -7.96148, -7.97832, -7.99036, -7.99759, + -8, -7.99759, -7.99036, -7.97832, + -7.96148, -7.93984, -7.91341, -7.88222, + -7.84628, -7.80562, -7.76025, -7.71021, + -7.65552, -7.59623, -7.53235, -7.46394, + -7.39104, -7.31368, -7.23191, -7.14579, + -7.05537, -6.9607, -6.86183, -6.75883, + -6.65176, -6.54068, -6.42566, -6.30677, + -6.18408, -6.05767, -5.92761, -5.79398, + -5.65685, -5.51632, -5.37247, -5.22538, + -5.07515, -4.92185, -4.76559, -4.60647, + -4.44456, -4.27998, -4.11282, -3.94319, + -3.77117, -3.59689, -3.42044, -3.24193, + -3.06147, -2.87916, -2.69512, -2.50945, + -2.32228, -2.1337, -1.94384, -1.75281, + -1.56072, -1.3677, -1.17384, -0.979285, + -0.784137, -0.588517, -0.392541, -0.19633, + diff --git a/engine/Quake/glquake.h b/engine/Quake/glquake.h new file mode 100644 index 0000000..315be98 --- /dev/null +++ b/engine/Quake/glquake.h @@ -0,0 +1,423 @@ +/* +Copyright (C) 1996-2001 Id Software, Inc. +Copyright (C) 2002-2009 John Fitzgibbons and others +Copyright (C) 2007-2008 Kristian Duske +Copyright (C) 2010-2014 QuakeSpasm developers + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#ifndef __GLQUAKE_H +#define __GLQUAKE_H + +void GL_BeginRendering (int *x, int *y, int *width, int *height); +void GL_EndRendering (void); +void GL_Set2D (void); + +extern int glx, gly, glwidth, glheight; + +#define GL_UNUSED_TEXTURE (~(GLuint)0) + +// r_local.h -- private refresh defs + +#define ALIAS_BASE_SIZE_RATIO (1.0 / 11.0) + // normalizing factor so player model works out to about + // 1 pixel per triangle +#define MAX_LBM_HEIGHT 480 + +#define TILE_SIZE 128 // size of textures generated by R_GenTiledSurf + +#define SKYSHIFT 7 +#define SKYSIZE (1 << SKYSHIFT) +#define SKYMASK (SKYSIZE - 1) + +#define BACKFACE_EPSILON 0.01 + + +void R_TimeRefresh_f (void); +void R_ReadPointFile_f (void); +texture_t *R_TextureAnimation (texture_t *base, int frame); + +typedef struct surfcache_s +{ + struct surfcache_s *next; + struct surfcache_s **owner; // NULL is an empty chunk of memory + int lightadj[MAXLIGHTMAPS]; // checked for strobe flush + int dlight; + int size; // including header + unsigned width; + unsigned height; // DEBUG only needed for debug + float mipscale; + struct texture_s *texture; // checked for animating textures + byte data[4]; // width*height elements +} surfcache_t; + + +typedef struct +{ + pixel_t *surfdat; // destination for generated surface + int rowbytes; // destination logical width in bytes + msurface_t *surf; // description for surface to generate + fixed8_t lightadj[MAXLIGHTMAPS]; + // adjust for lightmap levels for dynamic lighting + texture_t *texture; // corrected for animating textures + int surfmip; // mipmapped ratio of surface texels / world pixels + int surfwidth; // in mipmapped texels + int surfheight; // in mipmapped texels +} drawsurf_t; + + +typedef enum { + pt_static, pt_grav, pt_slowgrav, pt_fire, pt_explode, pt_explode2, pt_blob, pt_blob2 +} ptype_t; + +// !!! if this is changed, it must be changed in d_ifacea.h too !!! +typedef struct particle_s +{ +// driver-usable fields + vec3_t org; + float color; +// drivers never touch the following fields + struct particle_s *next; + vec3_t vel; + float ramp; + float die; + ptype_t type; +} particle_t; + + +//==================================================== + +extern qboolean r_cache_thrash; // compatability +extern vec3_t modelorg, r_entorigin; +extern entity_t *currententity; +extern int r_visframecount; // ??? what difs? +extern int r_framecount; +extern mplane_t frustum[4]; + +// +// view origin +// +extern vec3_t vup; +extern vec3_t vpn; +extern vec3_t vright; +extern vec3_t r_origin; + +// +// screen size info +// +extern refdef_t r_refdef; +extern mleaf_t *r_viewleaf, *r_oldviewleaf; +extern int d_lightstylevalue[256]; // 8.8 fraction of base light value + +extern cvar_t r_norefresh; +extern cvar_t r_drawentities; +extern cvar_t r_drawworld; +extern cvar_t r_drawviewmodel; +extern cvar_t r_speeds; +extern cvar_t r_pos; +extern cvar_t r_waterwarp; +extern cvar_t r_fullbright; +extern cvar_t r_lightmap; +extern cvar_t r_shadows; +extern cvar_t r_wateralpha; +extern cvar_t r_lavaalpha; +extern cvar_t r_telealpha; +extern cvar_t r_slimealpha; +extern cvar_t r_dynamic; +extern cvar_t r_novis; +extern cvar_t r_scale; + +extern cvar_t gl_clear; +extern cvar_t gl_cull; +extern cvar_t gl_smoothmodels; +extern cvar_t gl_affinemodels; +extern cvar_t gl_polyblend; +extern cvar_t gl_flashblend; +extern cvar_t gl_nocolors; + +extern cvar_t gl_playermip; + +extern cvar_t gl_subdivide_size; +extern float load_subdivide_size; //johnfitz -- remember what subdivide_size value was when this map was loaded + +extern int gl_stencilbits; + +// Multitexture +extern qboolean mtexenabled; +extern qboolean gl_mtexable; +extern PFNGLMULTITEXCOORD2FARBPROC GL_MTexCoord2fFunc; +extern PFNGLACTIVETEXTUREARBPROC GL_SelectTextureFunc; +extern PFNGLCLIENTACTIVETEXTUREARBPROC GL_ClientActiveTextureFunc; +extern GLint gl_max_texture_units; //ericw + +//johnfitz -- anisotropic filtering +#define GL_TEXTURE_MAX_ANISOTROPY_EXT 0x84FE +#define GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT 0x84FF +extern float gl_max_anisotropy; +extern qboolean gl_anisotropy_able; + +//ericw -- VBO +extern PFNGLBINDBUFFERARBPROC GL_BindBufferFunc; +extern PFNGLBUFFERDATAARBPROC GL_BufferDataFunc; +extern PFNGLBUFFERSUBDATAARBPROC GL_BufferSubDataFunc; +extern PFNGLDELETEBUFFERSARBPROC GL_DeleteBuffersFunc; +extern PFNGLGENBUFFERSARBPROC GL_GenBuffersFunc; +extern qboolean gl_vbo_able; +//ericw + +//ericw -- GLSL + +// SDL 1.2 has a bug where it doesn't provide these typedefs on OS X! +typedef GLuint (APIENTRYP QS_PFNGLCREATESHADERPROC) (GLenum type); +typedef void (APIENTRYP QS_PFNGLDELETESHADERPROC) (GLuint shader); +typedef void (APIENTRYP QS_PFNGLDELETEPROGRAMPROC) (GLuint program); +typedef void (APIENTRYP QS_PFNGLSHADERSOURCEPROC) (GLuint shader, GLsizei count, const GLchar *const*string, const GLint *length); +typedef void (APIENTRYP QS_PFNGLCOMPILESHADERPROC) (GLuint shader); +typedef void (APIENTRYP QS_PFNGLGETSHADERIVPROC) (GLuint shader, GLenum pname, GLint *params); +typedef void (APIENTRYP QS_PFNGLGETSHADERINFOLOGPROC) (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *infoLog); +typedef void (APIENTRYP QS_PFNGLGETPROGRAMIVPROC) (GLuint program, GLenum pname, GLint *params); +typedef void (APIENTRYP QS_PFNGLGETPROGRAMINFOLOGPROC) (GLuint program, GLsizei bufSize, GLsizei *length, GLchar *infoLog); +typedef GLuint (APIENTRYP QS_PFNGLCREATEPROGRAMPROC) (void); +typedef void (APIENTRYP QS_PFNGLATTACHSHADERPROC) (GLuint program, GLuint shader); +typedef void (APIENTRYP QS_PFNGLLINKPROGRAMPROC) (GLuint program); +typedef void (APIENTRYP QS_PFNGLBINDATTRIBLOCATIONFUNC) (GLuint program, GLuint index, const GLchar *name); +typedef void (APIENTRYP QS_PFNGLUSEPROGRAMPROC) (GLuint program); +typedef GLint (APIENTRYP QS_PFNGLGETATTRIBLOCATIONPROC) (GLuint program, const GLchar *name); +typedef void (APIENTRYP QS_PFNGLVERTEXATTRIBPOINTERPROC) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void *pointer); +typedef void (APIENTRYP QS_PFNGLENABLEVERTEXATTRIBARRAYPROC) (GLuint index); +typedef void (APIENTRYP QS_PFNGLDISABLEVERTEXATTRIBARRAYPROC) (GLuint index); +typedef GLint (APIENTRYP QS_PFNGLGETUNIFORMLOCATIONPROC) (GLuint program, const GLchar *name); +typedef void (APIENTRYP QS_PFNGLUNIFORM1IPROC) (GLint location, GLint v0); +typedef void (APIENTRYP QS_PFNGLUNIFORM1FPROC) (GLint location, GLfloat v0); +typedef void (APIENTRYP QS_PFNGLUNIFORM3FPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2); +typedef void (APIENTRYP QS_PFNGLUNIFORM4FPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); + +extern QS_PFNGLCREATESHADERPROC GL_CreateShaderFunc; +extern QS_PFNGLDELETESHADERPROC GL_DeleteShaderFunc; +extern QS_PFNGLDELETEPROGRAMPROC GL_DeleteProgramFunc; +extern QS_PFNGLSHADERSOURCEPROC GL_ShaderSourceFunc; +extern QS_PFNGLCOMPILESHADERPROC GL_CompileShaderFunc; +extern QS_PFNGLGETSHADERIVPROC GL_GetShaderivFunc; +extern QS_PFNGLGETSHADERINFOLOGPROC GL_GetShaderInfoLogFunc; +extern QS_PFNGLGETPROGRAMIVPROC GL_GetProgramivFunc; +extern QS_PFNGLGETPROGRAMINFOLOGPROC GL_GetProgramInfoLogFunc; +extern QS_PFNGLCREATEPROGRAMPROC GL_CreateProgramFunc; +extern QS_PFNGLATTACHSHADERPROC GL_AttachShaderFunc; +extern QS_PFNGLLINKPROGRAMPROC GL_LinkProgramFunc; +extern QS_PFNGLBINDATTRIBLOCATIONFUNC GL_BindAttribLocationFunc; +extern QS_PFNGLUSEPROGRAMPROC GL_UseProgramFunc; +extern QS_PFNGLGETATTRIBLOCATIONPROC GL_GetAttribLocationFunc; +extern QS_PFNGLVERTEXATTRIBPOINTERPROC GL_VertexAttribPointerFunc; +extern QS_PFNGLENABLEVERTEXATTRIBARRAYPROC GL_EnableVertexAttribArrayFunc; +extern QS_PFNGLDISABLEVERTEXATTRIBARRAYPROC GL_DisableVertexAttribArrayFunc; +extern QS_PFNGLGETUNIFORMLOCATIONPROC GL_GetUniformLocationFunc; +extern QS_PFNGLUNIFORM1IPROC GL_Uniform1iFunc; +extern QS_PFNGLUNIFORM1FPROC GL_Uniform1fFunc; +extern QS_PFNGLUNIFORM3FPROC GL_Uniform3fFunc; +extern QS_PFNGLUNIFORM4FPROC GL_Uniform4fFunc; +extern qboolean gl_glsl_able; +extern qboolean gl_glsl_gamma_able; +extern qboolean gl_glsl_alias_able; +// ericw -- + +//ericw -- NPOT texture support +extern qboolean gl_texture_NPOT; + +//johnfitz -- polygon offset +#define OFFSET_BMODEL 1 +#define OFFSET_NONE 0 +#define OFFSET_DECAL -1 +#define OFFSET_FOG -2 +#define OFFSET_SHOWTRIS -3 +void GL_PolygonOffset (int); + +//johnfitz -- GL_EXT_texture_env_combine +//the values for GL_ARB_ are identical +#define GL_COMBINE_EXT 0x8570 +#define GL_COMBINE_RGB_EXT 0x8571 +#define GL_COMBINE_ALPHA_EXT 0x8572 +#define GL_RGB_SCALE_EXT 0x8573 +#define GL_CONSTANT_EXT 0x8576 +#define GL_PRIMARY_COLOR_EXT 0x8577 +#define GL_PREVIOUS_EXT 0x8578 +#define GL_SOURCE0_RGB_EXT 0x8580 +#define GL_SOURCE1_RGB_EXT 0x8581 +#define GL_SOURCE0_ALPHA_EXT 0x8588 +#define GL_SOURCE1_ALPHA_EXT 0x8589 +extern qboolean gl_texture_env_combine; +extern qboolean gl_texture_env_add; // for GL_EXT_texture_env_add + +//johnfitz -- rendering statistics +extern int rs_brushpolys, rs_aliaspolys, rs_skypolys, rs_particles, rs_fogpolys; +extern int rs_dynamiclightmaps, rs_brushpasses, rs_aliaspasses, rs_skypasses; +extern float rs_megatexels; + +//johnfitz -- track developer statistics that vary every frame +extern cvar_t devstats; +typedef struct { + int packetsize; + int edicts; + int visedicts; + int efrags; + int tempents; + int beams; + int dlights; +} devstats_t; +extern devstats_t dev_stats, dev_peakstats; + +//ohnfitz -- reduce overflow warning spam +typedef struct { + double packetsize; + double efrags; + double beams; + double varstring; +} overflowtimes_t; +extern overflowtimes_t dev_overflows; //this stores the last time overflow messages were displayed, not the last time overflows occured +#define CONSOLE_RESPAM_TIME 3 // seconds between repeated warning messages + +//johnfitz -- moved here from r_brush.c +extern int gl_lightmap_format, lightmap_bytes; + +#define LMBLOCK_WIDTH 256 //FIXME: make dynamic. if we have a decent card there's no real reason not to use 4k or 16k (assuming there's no lightstyles/dynamics that need uploading...) +#define LMBLOCK_HEIGHT 256 //Alternatively, use texture arrays, which would avoid the need to switch textures as often. + +typedef struct glRect_s { + unsigned short l,t,w,h; +} glRect_t; +struct lightmap_s +{ + gltexture_t *texture; + glpoly_t *polys; + qboolean modified; + glRect_t rectchange; + + // the lightmap texture data needs to be kept in + // main memory so texsubimage can update properly + byte *data;//[4*LMBLOCK_WIDTH*LMBLOCK_HEIGHT]; +}; +extern struct lightmap_s *lightmap; +extern int lightmap_count; //allocated lightmaps + +extern int gl_warpimagesize; //johnfitz -- for water warp + +extern qboolean r_drawflat_cheatsafe, r_fullbright_cheatsafe, r_lightmap_cheatsafe, r_drawworld_cheatsafe; //johnfitz + +typedef struct glsl_attrib_binding_s { + const char *name; + GLuint attrib; +} glsl_attrib_binding_t; + +extern float map_wateralpha, map_lavaalpha, map_telealpha, map_slimealpha; //ericw + +//johnfitz -- fog functions called from outside gl_fog.c +void Fog_ParseServerMessage (void); +float *Fog_GetColor (void); +float Fog_GetDensity (void); +void Fog_EnableGFog (void); +void Fog_DisableGFog (void); +void Fog_StartAdditive (void); +void Fog_StopAdditive (void); +void Fog_SetupFrame (void); +void Fog_NewMap (void); +void Fog_Init (void); +void Fog_SetupState (void); + +void R_NewGame (void); + +void R_AnimateLight (void); +void R_MarkSurfaces (void); +void R_CullSurfaces (void); +qboolean R_CullBox (vec3_t emins, vec3_t emaxs); +void R_StoreEfrags (efrag_t **ppefrag); +qboolean R_CullModelForEntity (entity_t *e); +void R_RotateForEntity (vec3_t origin, vec3_t angles); +void R_MarkLights (dlight_t *light, int num, mnode_t *node); + +void R_InitParticles (void); +void R_DrawParticles (void); +void CL_RunParticles (void); +void R_ClearParticles (void); + +void R_TranslatePlayerSkin (int playernum); +void R_TranslateNewPlayerSkin (int playernum); //johnfitz -- this handles cases when the actual texture changes +void R_UpdateWarpTextures (void); + +void R_DrawWorld (void); +void R_DrawAliasModel (entity_t *e); +void R_DrawBrushModel (entity_t *e); +void R_DrawSpriteModel (entity_t *e); + +void R_DrawTextureChains_Water (qmodel_t *model, entity_t *ent, texchain_t chain); + +void R_RenderDlights (void); +void GL_BuildLightmaps (void); +void GL_DeleteBModelVertexBuffer (void); +void GL_BuildBModelVertexBuffer (void); +void GLMesh_LoadVertexBuffers (void); +void GLMesh_DeleteVertexBuffers (void); +void R_RebuildAllLightmaps (void); + +int R_LightPoint (vec3_t p); + +void GL_SubdivideSurface (msurface_t *fa); +void R_BuildLightMap (msurface_t *surf, byte *dest, int stride); +void R_RenderDynamicLightmaps (msurface_t *fa); +void R_UploadLightmaps (void); + +void R_DrawWorld_ShowTris (void); +void R_DrawBrushModel_ShowTris (entity_t *e); +void R_DrawAliasModel_ShowTris (entity_t *e); +void R_DrawParticles_ShowTris (void); + +GLint GL_GetUniformLocation (GLuint *programPtr, const char *name); +GLuint GL_CreateProgram (const GLchar *vertSource, const GLchar *fragSource, int numbindings, const glsl_attrib_binding_t *bindings); +void R_DeleteShaders (void); + +void GLWorld_CreateShaders (void); +void GLAlias_CreateShaders (void); +void GL_DrawAliasShadow (entity_t *e); +void DrawGLTriangleFan (glpoly_t *p); +void DrawGLPoly (glpoly_t *p); +void DrawWaterPoly (glpoly_t *p); +void GL_MakeAliasModelDisplayLists (qmodel_t *m, aliashdr_t *hdr); + +void Sky_Init (void); +void Sky_DrawSky (void); +void Sky_NewMap (void); +void Sky_LoadTexture (texture_t *mt); +void Sky_LoadSkyBox (const char *name); + +void TexMgr_RecalcWarpImageSize (void); + +void R_ClearTextureChains (qmodel_t *mod, texchain_t chain); +void R_ChainSurface (msurface_t *surf, texchain_t chain); +void R_DrawTextureChains (qmodel_t *model, entity_t *ent, texchain_t chain); +void R_DrawWorld_Water (void); + +void GL_BindBuffer (GLenum target, GLuint buffer); +void GL_ClearBufferBindings (); + +void GLSLGamma_DeleteTexture (void); +void GLSLGamma_GammaCorrect (void); + +void R_ScaleView_DeleteTexture (void); + +float GL_WaterAlphaForSurface (msurface_t *fa); + +#endif /* __GLQUAKE_H */ + diff --git a/engine/code/host.c b/engine/Quake/host.c similarity index 60% rename from engine/code/host.c rename to engine/Quake/host.c index 88b076f..ad60160 100644 --- a/engine/code/host.c +++ b/engine/Quake/host.c @@ -1,5 +1,8 @@ /* -Copyright (C) 1996-1997 Id Software, Inc. +Copyright (C) 1996-2001 Id Software, Inc. +Copyright (C) 2002-2009 John Fitzgibbons and others +Copyright (C) 2007-2008 Kristian Duske +Copyright (C) 2010-2014 QuakeSpasm developers This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -8,7 +11,7 @@ of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. @@ -20,7 +23,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // host.c -- coordinates spawning and killing of local servers #include "quakedef.h" -//#include "r_local.h" // jkrige - removed +#include "bgmusic.h" +#include /* @@ -33,91 +37,99 @@ Memory is cleared / released when a server or client begins, not when they end. */ -quakeparms_t host_parms; +quakeparms_t *host_parms; qboolean host_initialized; // true if into command execution double host_frametime; -double host_time; double realtime; // without any filtering or bounding double oldrealtime; // last frame run -int host_framecount; -int host_hunklevel; +int host_framecount; -int minimum_memory; +int host_hunklevel; + +int minimum_memory; client_t *host_client; // current client jmp_buf host_abortserver; -byte *host_basepal; byte *host_colormap; -// jkrige - configurable fps caps -extern cvar_t sv_fps; -// jkrige - configurable fps caps - -cvar_t host_framerate = {"host_framerate","0"}; // set for slow motion -cvar_t host_speeds = {"host_speeds","0"}; // set for running times - -// jkrige - configurable fps caps -// defaults to 0 since sv_fps takes care of framerate -cvar_t sys_ticrate = {"sys_ticrate","0"}; -//cvar_t sys_ticrate = {"sys_ticrate","0.05"}; -// jkrige - configurable fps caps +cvar_t host_framerate = {"host_framerate","0",CVAR_NONE}; // set for slow motion +cvar_t host_speeds = {"host_speeds","0",CVAR_NONE}; // set for running times +cvar_t host_maxfps = {"host_maxfps", "72", CVAR_ARCHIVE}; //johnfitz +cvar_t host_timescale = {"host_timescale", "0", CVAR_NONE}; //johnfitz +cvar_t max_edicts = {"max_edicts", "8192", CVAR_NONE}; //johnfitz //ericw -- changed from 2048 to 8192, removed CVAR_ARCHIVE -cvar_t serverprofile = {"serverprofile","0"}; +cvar_t sys_ticrate = {"sys_ticrate","0.05",CVAR_NONE}; // dedicated server +cvar_t serverprofile = {"serverprofile","0",CVAR_NONE}; -cvar_t fraglimit = {"fraglimit","0",false,true}; -cvar_t timelimit = {"timelimit","0",false,true}; -cvar_t teamplay = {"teamplay","0",false,true}; +cvar_t fraglimit = {"fraglimit","0",CVAR_NOTIFY|CVAR_SERVERINFO}; +cvar_t timelimit = {"timelimit","0",CVAR_NOTIFY|CVAR_SERVERINFO}; +cvar_t teamplay = {"teamplay","0",CVAR_NOTIFY|CVAR_SERVERINFO}; +cvar_t samelevel = {"samelevel","0",CVAR_NONE}; +cvar_t noexit = {"noexit","0",CVAR_NOTIFY|CVAR_SERVERINFO}; +cvar_t skill = {"skill","1",CVAR_NONE}; // 0 - 3 +cvar_t deathmatch = {"deathmatch","0",CVAR_NONE}; // 0, 1, or 2 +cvar_t coop = {"coop","0",CVAR_NONE}; // 0 or 1 -cvar_t samelevel = {"samelevel","0"}; -cvar_t noexit = {"noexit","0",false,true}; +cvar_t pausable = {"pausable","1",CVAR_NONE}; -#ifdef QUAKE2 -cvar_t developer = {"developer","1"}; // should be 0 for release! -#else -cvar_t developer = {"developer","0"}; -#endif +cvar_t developer = {"developer","0",CVAR_NONE}; -cvar_t skill = {"skill","1"}; // 0 - 3 -cvar_t deathmatch = {"deathmatch","0"}; // 0, 1, or 2 -cvar_t coop = {"coop","0"}; // 0 or 1 +cvar_t temp1 = {"temp1","0",CVAR_NONE}; -cvar_t pausable = {"pausable","1"}; +cvar_t devstats = {"devstats","0",CVAR_NONE}; //johnfitz -- track developer statistics that vary every frame -cvar_t temp1 = {"temp1","0"}; +devstats_t dev_stats, dev_peakstats; +overflowtimes_t dev_overflows; //this stores the last time overflow messages were displayed, not the last time overflows occured +/* +================ +Max_Edicts_f -- johnfitz +================ +*/ +static void Max_Edicts_f (cvar_t *var) +{ + //TODO: clamp it here? + if (cls.state == ca_connected || sv.active) + Con_Printf ("Changes to max_edicts will not take effect until the next time a map is loaded.\n"); +} -// jkrige - fps counter -cvar_t r_fps = {"r_fps","0",true}; -int fps_count; -// jkrige - fps counter - +/* +================ +Max_Fps_f -- ericw +================ +*/ +static void Max_Fps_f (cvar_t *var) +{ + if (var->value > 72) + Con_Warning ("host_maxfps above 72 breaks physics.\n"); +} /* ================ Host_EndGame ================ */ -void Host_EndGame (char *message, ...) +void Host_EndGame (const char *message, ...) { va_list argptr; char string[1024]; - + va_start (argptr,message); - vsprintf (string,message,argptr); + q_vsnprintf (string, sizeof(string), message, argptr); va_end (argptr); Con_DPrintf ("Host_EndGame: %s\n",string); - + if (sv.active) Host_ShutdownServer (false); if (cls.state == ca_dedicated) Sys_Error ("Host_EndGame: %s\n",string); // dedicated servers exit - + if (cls.demonum != -1) CL_NextDemo (); else @@ -133,23 +145,23 @@ Host_Error This shuts down both the client and server ================ */ -void Host_Error (char *error, ...) +void Host_Error (const char *error, ...) { va_list argptr; char string[1024]; static qboolean inerror = false; - + if (inerror) Sys_Error ("Host_Error: recursively entered"); inerror = true; - + SCR_EndLoadingPlaque (); // reenable screen updates va_start (argptr,error); - vsprintf (string,error,argptr); + q_vsnprintf (string, sizeof(string), error, argptr); va_end (argptr); Con_Printf ("Host_Error: %s\n",string); - + if (sv.active) Host_ShutdownServer (false); @@ -158,6 +170,7 @@ void Host_Error (char *error, ...) CL_Disconnect (); cls.demonum = -1; + cl.intermission = 0; //johnfitz -- for errors during intermissions (changelevel with no map found, etc.) inerror = false; @@ -174,7 +187,7 @@ void Host_FindMaxClients (void) int i; svs.maxclients = 1; - + i = COM_CheckParm ("-dedicated"); if (i) { @@ -207,14 +220,27 @@ void Host_FindMaxClients (void) svs.maxclientslimit = svs.maxclients; if (svs.maxclientslimit < 4) svs.maxclientslimit = 4; - svs.clients = Hunk_AllocName (svs.maxclientslimit*sizeof(client_t), "clients"); + svs.clients = (struct client_s *) Hunk_AllocName (svs.maxclientslimit*sizeof(client_t), "clients"); if (svs.maxclients > 1) - Cvar_SetValue ("deathmatch", 1.0); + Cvar_SetQuick (&deathmatch, "1"); else - Cvar_SetValue ("deathmatch", 0.0); + Cvar_SetQuick (&deathmatch, "0"); } +void Host_Version_f (void) +{ + Con_Printf ("Quake Version %1.2f\n", VERSION); + Con_Printf ("QuakeSpasm Version " QUAKESPASM_VER_STRING "\n"); + Con_Printf ("Exe: " __TIME__ " " __DATE__ "\n"); +} + +/* cvar callback functions : */ +void Host_Callback_Notify (cvar_t *var) +{ + if (sv.active) + SV_BroadcastPrintf ("\"%s\" changed to \"%s\"\n", var->name, var->string); +} /* ======================= @@ -223,33 +249,43 @@ Host_InitLocal */ void Host_InitLocal (void) { + Cmd_AddCommand ("version", Host_Version_f); + Host_InitCommands (); - + Cvar_RegisterVariable (&host_framerate); Cvar_RegisterVariable (&host_speeds); + Cvar_RegisterVariable (&host_maxfps); //johnfitz + Cvar_SetCallback (&host_maxfps, Max_Fps_f); + Cvar_RegisterVariable (&host_timescale); //johnfitz + + Cvar_RegisterVariable (&max_edicts); //johnfitz + Cvar_SetCallback (&max_edicts, Max_Edicts_f); + Cvar_RegisterVariable (&devstats); //johnfitz Cvar_RegisterVariable (&sys_ticrate); + Cvar_RegisterVariable (&sys_throttle); Cvar_RegisterVariable (&serverprofile); Cvar_RegisterVariable (&fraglimit); Cvar_RegisterVariable (&timelimit); Cvar_RegisterVariable (&teamplay); + Cvar_SetCallback (&fraglimit, Host_Callback_Notify); + Cvar_SetCallback (&timelimit, Host_Callback_Notify); + Cvar_SetCallback (&teamplay, Host_Callback_Notify); Cvar_RegisterVariable (&samelevel); Cvar_RegisterVariable (&noexit); + Cvar_SetCallback (&noexit, Host_Callback_Notify); Cvar_RegisterVariable (&skill); Cvar_RegisterVariable (&developer); - Cvar_RegisterVariable (&deathmatch); Cvar_RegisterVariable (&coop); + Cvar_RegisterVariable (&deathmatch); Cvar_RegisterVariable (&pausable); Cvar_RegisterVariable (&temp1); - Cvar_RegisterVariable (&r_fps); // jkrige - fps counter - Host_FindMaxClients (); - - host_time = 1.0; // so a think at time 0 won't get called } @@ -266,18 +302,25 @@ void Host_WriteConfiguration (void) // dedicated servers initialize the host but don't parse and set the // config.cfg cvars - if (host_initialized & !isDedicated) + if (host_initialized && !isDedicated && !host_parms->errstate) { - f = fopen (va("%s/config.cfg",com_gamedir), "w"); + f = fopen (va("%s/config.cfg", com_gamedir), "w"); if (!f) { Con_Printf ("Couldn't write config.cfg.\n"); return; } - + + //VID_SyncCvars (); //johnfitz -- write actual current mode to config file, in case cvars were messed with + Key_WriteBindings (f); Cvar_WriteVariables (f); + //johnfitz -- extra commands to preserve state + fprintf (f, "vid_restart\n"); + if (in_mlook.state & 1) fprintf (f, "+mlook\n"); + //johnfitz + fclose (f); } } @@ -287,19 +330,19 @@ void Host_WriteConfiguration (void) ================= SV_ClientPrintf -Sends text across to be displayed +Sends text across to be displayed FIXME: make this just a stuffed echo? ================= */ -void SV_ClientPrintf (char *fmt, ...) +void SV_ClientPrintf (const char *fmt, ...) { va_list argptr; char string[1024]; - + va_start (argptr,fmt); - vsprintf (string, fmt,argptr); + q_vsnprintf (string, sizeof(string), fmt,argptr); va_end (argptr); - + MSG_WriteByte (&host_client->message, svc_print); MSG_WriteString (&host_client->message, string); } @@ -311,22 +354,24 @@ SV_BroadcastPrintf Sends text to all active clients ================= */ -void SV_BroadcastPrintf (char *fmt, ...) +void SV_BroadcastPrintf (const char *fmt, ...) { va_list argptr; char string[1024]; int i; - + va_start (argptr,fmt); - vsprintf (string, fmt,argptr); + q_vsnprintf (string, sizeof(string), fmt, argptr); va_end (argptr); - - for (i=0 ; imessage, svc_stufftext); MSG_WriteString (&host_client->message, string); } @@ -371,7 +416,7 @@ void SV_DropClient (qboolean crash) MSG_WriteByte (&host_client->message, svc_disconnect); NET_SendMessage (host_client->netconnection, &host_client->message); } - + if (host_client->edict && host_client->spawned) { // call the prog function for removing a client @@ -396,7 +441,7 @@ void SV_DropClient (qboolean crash) net_activeconnections--; // send notification to all clients - for (i=0, client = svs.clients ; iactive) continue; @@ -424,7 +469,7 @@ void Host_ShutdownServer(qboolean crash) int i; int count; sizebuf_t buf; - char message[4]; + byte message[4]; double start; if (!sv.active) @@ -437,7 +482,7 @@ void Host_ShutdownServer(qboolean crash) CL_Disconnect (); // flush any pending messages - like the score!!! - start = Sys_FloatTime(); + start = Sys_DoubleTime(); do { count = 0; @@ -457,7 +502,7 @@ void Host_ShutdownServer(qboolean crash) } } } - if ((Sys_FloatTime() - start) > 3.0) + if ((Sys_DoubleTime() - start) > 3.0) break; } while (count); @@ -467,18 +512,18 @@ void Host_ShutdownServer(qboolean crash) buf.maxsize = 4; buf.cursize = 0; MSG_WriteByte(&buf, svc_disconnect); - count = NET_SendToAll(&buf, 5); + count = NET_SendToAll(&buf, 5.0); if (count) Con_Printf("Host_ShutdownServer: NET_SendToAll failed for %u clients\n", count); - for (i=0, host_client = svs.clients ; iactive) SV_DropClient(crash); // // clear structures // - memset (&sv, 0, sizeof(sv)); +// memset (&sv, 0, sizeof(sv)); // ServerSpawn already do this by Host_ClearMemory memset (svs.clients, 0, svs.maxclientslimit*sizeof(client_t)); } @@ -496,17 +541,20 @@ void Host_ClearMemory (void) Con_DPrintf ("Clearing memory\n"); D_FlushCaches (); Mod_ClearAll (); - if (host_hunklevel) - Hunk_FreeToLowMark (host_hunklevel); - +/* host_hunklevel MUST be set at this point */ + Hunk_FreeToLowMark (host_hunklevel); cls.signon = 0; + free(sv.edicts); // ericw -- sv.edicts switched to use malloc() memset (&sv, 0, sizeof(sv)); memset (&cl, 0, sizeof(cl)); } -//============================================================================ - +//============================================================================== +// +// Host Frame +// +//============================================================================== /* =================== @@ -517,70 +565,31 @@ Returns false if the time is too short to run a frame */ qboolean Host_FilterTime (float time) { - // jkrige - configurable fps caps - static double min_frametime; - // jkrige - configurable fps caps + float maxfps; //johnfitz realtime += time; - - // jkrige - configurable fps caps - // added configurable fps caps, different for dedicated and - // listen servers. Listen servers run at 72 fps by default, - // dedicated ones at 20. - if (cls.state != ca_dedicated) - { - min_frametime = 1.0 / cl_maxfps.value; - } - else - { - min_frametime = 1.0 / sv_fps.value; - } - - // Avoid infinite loop - if (min_frametime > 1) - { - min_frametime = 1.0; - } - if ((realtime - oldrealtime < min_frametime) && !cls.timedemo) - { - // Keep the CPU cool for the remainder of time, rather than run - // a loop delay. And always keep a slack of 15% of frametime for - // ouselves, so that we don't "oversleep" our next frame. - if (realtime - oldrealtime < 0.80 * min_frametime) - { - Sys_LongSleep((0.85 * min_frametime - (realtime - oldrealtime)) * 1000.0); - } - return false; - } - - //if (!cls.timedemo && realtime - oldrealtime < 1.0/72.0) - // return false; // framerate is too high - // jkrige - configurable fps caps + //johnfitz -- max fps cvar + maxfps = CLAMP (10.0, host_maxfps.value, 1000.0); + if (!cls.timedemo && realtime - oldrealtime < 1.0/maxfps) + return false; // framerate is too high + //johnfitz host_frametime = realtime - oldrealtime; oldrealtime = realtime; - if (host_framerate.value > 0) + //johnfitz -- host_timescale is more intuitive than host_framerate + if (host_timescale.value > 0) + host_frametime *= host_timescale.value; + //johnfitz + else if (host_framerate.value > 0) host_frametime = host_framerate.value; - else - { // don't allow really long or short frames - if (host_frametime > 0.1) - host_frametime = 0.1; - - // jkrige - configurable fps caps - // short frames should better be allowed now; it seems - // that 1000 fps is in fact attainable nowadays, and we - // got rid of framerate cap - //if (host_frametime < 0.001) - // host_frametime = 0.001; - // jkrige - configurable fps caps - } - + else // don't allow really long or short frames + host_frametime = CLAMP (0.001, host_frametime, 0.1); //johnfitz -- use CLAMP + return true; } - /* =================== Host_GetConsoleCommands @@ -590,7 +599,10 @@ Add them exactly as if they had been typed at the console */ void Host_GetConsoleCommands (void) { - char *cmd; + const char *cmd; + + if (!isDedicated) + return; // no stdin necessary in graphical mode while (1) { @@ -601,87 +613,53 @@ void Host_GetConsoleCommands (void) } } - /* ================== Host_ServerFrame - ================== */ -#ifdef FPS_20 - -void _Host_ServerFrame (void) -{ -// run the world state - pr_global_struct->frametime = host_frametime; - -// read client messages - SV_RunClients (); - -// move things around and think -// always pause in single player if in console or menus - if (!sv.paused && (svs.maxclients > 1 || key_dest == key_game) ) - SV_Physics (); -} - void Host_ServerFrame (void) { - float save_host_frametime; - float temp_host_frametime; + int i, active; //johnfitz + edict_t *ent; //johnfitz -// run the world state +// run the world state pr_global_struct->frametime = host_frametime; // set the time and clear the general datagram SV_ClearDatagram (); - -// check for new clients - SV_CheckForNewClients (); - - temp_host_frametime = save_host_frametime = host_frametime; - while(temp_host_frametime > (1.0/72.0)) - { - if (temp_host_frametime > 0.05) - host_frametime = 0.05; - else - host_frametime = temp_host_frametime; - temp_host_frametime -= host_frametime; - _Host_ServerFrame (); - } - host_frametime = save_host_frametime; -// send all messages to the clients - SV_SendClientMessages (); -} - -#else - -void Host_ServerFrame (void) -{ -// run the world state - pr_global_struct->frametime = host_frametime; - -// set the time and clear the general datagram - SV_ClearDatagram (); - // check for new clients SV_CheckForNewClients (); // read client messages SV_RunClients (); - + // move things around and think // always pause in single player if in console or menus if (!sv.paused && (svs.maxclients > 1 || key_dest == key_game) ) SV_Physics (); +//johnfitz -- devstats + if (cls.signon == SIGNONS) + { + for (i=0, active=0; ifree) + active++; + } + if (active > 600 && dev_peakstats.edicts <= 600) + Con_DWarning ("%i edicts exceeds standard limit of 600 (max = %d).\n", active, sv.max_edicts); + dev_stats.edicts = active; + dev_peakstats.edicts = q_max(active, dev_peakstats.edicts); + } +//johnfitz + // send all messages to the clients SV_SendClientMessages (); } -#endif - - /* ================== Host_Frame @@ -701,12 +679,14 @@ void _Host_Frame (float time) // keep the random time dependent rand (); - + // decide the simulation time if (!Host_FilterTime (time)) return; // don't run too fast, or packets will flood out - + // get new key events + Key_UpdateForDest (); + IN_UpdateInputMode (); Sys_SendKeyEvents (); // allow mice or other external controllers to add commands @@ -720,7 +700,7 @@ void _Host_Frame (float time) // if running the server locally, make intentions now if (sv.active) CL_SendCmd (); - + //------------------- // // server operations @@ -729,7 +709,7 @@ void _Host_Frame (float time) // check for commands typed to the host Host_GetConsoleCommands (); - + if (sv.active) Host_ServerFrame (); @@ -744,24 +724,23 @@ void _Host_Frame (float time) if (!sv.active) CL_SendCmd (); - host_time += host_frametime; - // fetch results from server if (cls.state == ca_connected) - { CL_ReadFromServer (); - } // update video if (host_speeds.value) - time1 = Sys_FloatTime (); - + time1 = Sys_DoubleTime (); + SCR_UpdateScreen (); + CL_RunParticles (); //johnfitz -- seperated from rendering + if (host_speeds.value) - time2 = Sys_FloatTime (); - + time2 = Sys_DoubleTime (); + // update audio + BGM_Update(); // adds music raw samples and/or advances midi driver if (cls.signon == SIGNONS) { S_Update (r_origin, vpn, vright, vup); @@ -769,27 +748,21 @@ void _Host_Frame (float time) } else S_Update (vec3_origin, vec3_origin, vec3_origin, vec3_origin); - - // jkrige - fmod sound system - begin -#ifdef UQE_FMOD - FMOD_MusicUpdate(NULL); -#else + CDAudio_Update(); -#endif - // jkrige - fmod sound system - end if (host_speeds.value) { pass1 = (time1 - time3)*1000; - time3 = Sys_FloatTime (); + time3 = Sys_DoubleTime (); pass2 = (time2 - time1)*1000; pass3 = (time3 - time2)*1000; - Con_Printf ("%3i tot %3i server %3i gfx %3i snd\n", pass1+pass2+pass3, pass1, pass2, pass3); + Con_Printf ("%3i tot %3i server %3i gfx %3i snd\n", + pass1+pass2+pass3, pass1, pass2, pass3); } - + host_framecount++; - fps_count++; // jkrige - fps counter } void Host_Frame (float time) @@ -804,14 +777,14 @@ void Host_Frame (float time) _Host_Frame (time); return; } - - time1 = Sys_FloatTime (); + + time1 = Sys_DoubleTime (); _Host_Frame (time); - time2 = Sys_FloatTime (); - + time2 = Sys_DoubleTime (); + timetotal += time2 - time1; timecount++; - + if (timecount < 1000) return; @@ -819,7 +792,7 @@ void Host_Frame (float time) timecount = 0; timetotal = 0; c = 0; - for (i=0 ; iargv[0]; - for (i = 0; i < com_argc; i++) - { - Sys_FileRead (vcrFile, &len, sizeof(int)); - p = malloc(len); - Sys_FileRead (vcrFile, p, len); - com_argv[i+1] = p; - } - com_argc++; /* add one for arg[0] */ - parms->argc = com_argc; - parms->argv = com_argv; - } - - if ( (n = COM_CheckParm("-record")) != 0) - { - vcrFile = Sys_FileOpenWrite("quake.vcr"); - - i = VCR_SIGNATURE; - Sys_FileWrite(vcrFile, &i, sizeof(int)); - i = com_argc - 1; - Sys_FileWrite(vcrFile, &i, sizeof(int)); - for (i = 1; i < com_argc; i++) - { - if (i == n) - { - len = 10; - Sys_FileWrite(vcrFile, &len, sizeof(int)); - Sys_FileWrite(vcrFile, "-playback", len); - continue; - } - len = Q_strlen(com_argv[i]) + 1; - Sys_FileWrite(vcrFile, &len, sizeof(int)); - Sys_FileWrite(vcrFile, com_argv[i], len); - } - } - -} - /* ==================== Host_Init ==================== */ -void Host_Init (quakeparms_t *parms) +void Host_Init (void) { - if (standard_quake) minimum_memory = MINIMUM_MEMORY; - else - minimum_memory = MINIMUM_MEMORY_LEVELPAK; + else minimum_memory = MINIMUM_MEMORY_LEVELPAK; if (COM_CheckParm ("-minmemory")) - parms->memsize = minimum_memory; - - host_parms = *parms; + host_parms->memsize = minimum_memory; - if (parms->memsize < minimum_memory) - Sys_Error ("Only %4.1f megs of memory available, can't execute game", parms->memsize / (float)0x100000); + if (host_parms->memsize < minimum_memory) + Sys_Error ("Only %4.1f megs of memory available, can't execute game", host_parms->memsize / (float)0x100000); - com_argc = parms->argc; - com_argv = parms->argv; + com_argc = host_parms->argc; + com_argv = host_parms->argv; - Memory_Init (parms->membase, parms->memsize); + Memory_Init (host_parms->membase, host_parms->memsize); Cbuf_Init (); - Cmd_Init (); - V_Init (); - - // jkrige - removed chase - //Chase_Init (); - // jkrige - removed chase - - Host_InitVCR (parms); - COM_Init (parms->basedir); + Cmd_Init (); + LOG_Init (host_parms); + Cvar_Init (); //johnfitz + COM_Init (); + COM_InitFilesystem (); Host_InitLocal (); - W_LoadWadFile ("gfx.wad"); - Key_Init (); - Con_Init (); - M_Init (); + W_LoadWadFile (); //johnfitz -- filename is now hard-coded for honesty + if (cls.state != ca_dedicated) + { + Key_Init (); + Con_Init (); + } PR_Init (); Mod_Init (); NET_Init (); SV_Init (); - Con_Printf ("Exe: "__TIME__" "__DATE__"\n"); - Con_Printf ("%4.1f megabyte heap\n",parms->memsize/ (1024*1024.0)); - - R_InitTextures (); // needed even for dedicated servers - + Con_Printf ("Exe: " __TIME__ " " __DATE__ "\n"); + Con_Printf ("%4.1f megabyte heap\n", host_parms->memsize/ (1024*1024.0)); + if (cls.state != ca_dedicated) { - host_basepal = (byte *)COM_LoadHunkFile ("gfx/palette.lmp"); - if (!host_basepal) - Sys_Error ("Couldn't load gfx/palette.lmp"); - host_colormap = (byte *)COM_LoadHunkFile ("gfx/colormap.lmp"); + host_colormap = (byte *)COM_LoadHunkFile ("gfx/colormap.lmp", NULL); if (!host_colormap) Sys_Error ("Couldn't load gfx/colormap.lmp"); -#ifndef _WIN32 // on non win32, mouse comes before video for security reasons + V_Init (); + Chase_Init (); + M_Init (); + ExtraMaps_Init (); //johnfitz + Modlist_Init (); //johnfitz + DemoList_Init (); //ericw + VID_Init (); IN_Init (); -#endif - VID_Init (host_basepal); - + TexMgr_Init (); //johnfitz Draw_Init (); SCR_Init (); R_Init (); -#ifndef _WIN32 - // on Win32, sound initialization has to come before video initialization, so we - // can put up a popup if the sound hardware is in use - S_Init (); -#else - -#ifdef GLQUAKE - // FIXME: doesn't use the new one-window approach yet S_Init (); -#endif - -#endif // _WIN32 - - //CDAudio_Init (); // jkrige - fmod sound system - + CDAudio_Init (); + BGM_Init(); Sbar_Init (); CL_Init (); -#ifdef _WIN32 // on non win32, mouse comes before video for security reasons - IN_Init (); -#endif } - Cbuf_InsertText ("exec quake.rc\n"); - Hunk_AllocName (0, "-HOST_HUNKLEVEL-"); host_hunklevel = Hunk_LowMark (); host_initialized = true; - - Sys_Printf ("========Quake Initialized=========\n"); + Con_Printf ("\n========= Quake Initialized =========\n\n"); + + if (cls.state != ca_dedicated) + { + Cbuf_InsertText ("exec quake.rc\n"); + // johnfitz -- in case the vid mode was locked during vid_init, we can unlock it now. + // note: two leading newlines because the command buffer swallows one of them. + Cbuf_AddText ("\n\nvid_unlock\n"); + } + + if (cls.state == ca_dedicated) + { + Cbuf_AddText ("exec autoexec.cfg\n"); + Cbuf_AddText ("stuffcmds"); + Cbuf_Execute (); + if (!sv.active) + Cbuf_AddText ("map start\n"); + } } @@ -1004,7 +904,7 @@ to run quit through here before the final handoff to the sys code. void Host_Shutdown(void) { static qboolean isdown = false; - + if (isdown) { printf ("recursive shutdown\n"); @@ -1015,26 +915,21 @@ void Host_Shutdown(void) // keep Con_Printf from trying to update the screen scr_disabled_for_loading = true; - Host_WriteConfiguration (); - - //CDAudio_Shutdown (); // jkrige - fmod sound system + Host_WriteConfiguration (); NET_Shutdown (); - // jkrige - fmod sound system - begin -#ifdef UQE_FMOD - FMOD_Shutdown(); -#else - CDAudio_Shutdown(); -#endif - // jkrige - fmod sound system - end - - S_Shutdown(); - IN_Shutdown (); - if (cls.state != ca_dedicated) { + if (con_initialized) + History_Shutdown (); + BGM_Shutdown(); + CDAudio_Shutdown (); + S_Shutdown (); + IN_Shutdown (); VID_Shutdown(); } + + LOG_Close (); } diff --git a/engine/Quake/host_cmd.c b/engine/Quake/host_cmd.c new file mode 100644 index 0000000..70cc0d8 --- /dev/null +++ b/engine/Quake/host_cmd.c @@ -0,0 +1,2338 @@ +/* +Copyright (C) 1996-2001 Id Software, Inc. +Copyright (C) 2002-2009 John Fitzgibbons and others +Copyright (C) 2007-2008 Kristian Duske +Copyright (C) 2010-2014 QuakeSpasm developers + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#include "quakedef.h" +#ifndef _WIN32 +#include +#endif + +extern cvar_t pausable; + +int current_skill; + +void Mod_Print (void); + +/* +================== +Host_Quit_f +================== +*/ + +void Host_Quit_f (void) +{ + if (key_dest != key_console && cls.state != ca_dedicated) + { + M_Menu_Quit_f (); + return; + } + CL_Disconnect (); + Host_ShutdownServer(false); + + Sys_Quit (); +} + +//============================================================================== +//johnfitz -- extramaps management +//============================================================================== + +/* +================== +FileList_Add +================== +*/ +void FileList_Add (const char *name, filelist_item_t **list) +{ + filelist_item_t *item,*cursor,*prev; + + // ignore duplicate + for (item = *list; item; item = item->next) + { + if (!Q_strcmp (name, item->name)) + return; + } + + item = (filelist_item_t *) Z_Malloc(sizeof(filelist_item_t)); + q_strlcpy (item->name, name, sizeof(item->name)); + + // insert each entry in alphabetical order + if (*list == NULL || + q_strcasecmp(item->name, (*list)->name) < 0) //insert at front + { + item->next = *list; + *list = item; + } + else //insert later + { + prev = *list; + cursor = (*list)->next; + while (cursor && (q_strcasecmp(item->name, cursor->name) > 0)) + { + prev = cursor; + cursor = cursor->next; + } + item->next = prev->next; + prev->next = item; + } +} + +static void FileList_Clear (filelist_item_t **list) +{ + filelist_item_t *blah; + + while (*list) + { + blah = (*list)->next; + Z_Free(*list); + *list = blah; + } +} + +filelist_item_t *extralevels; + +void ExtraMaps_Add (const char *name) +{ + FileList_Add(name, &extralevels); +} + +void ExtraMaps_Init (void) +{ +#ifdef _WIN32 + WIN32_FIND_DATA fdat; + HANDLE fhnd; +#else + DIR *dir_p; + struct dirent *dir_t; +#endif + char filestring[MAX_OSPATH]; + char mapname[32]; + char ignorepakdir[32]; + searchpath_t *search; + pack_t *pak; + int i; + + // we don't want to list the maps in id1 pakfiles, + // because these are not "add-on" levels + q_snprintf (ignorepakdir, sizeof(ignorepakdir), "/%s/", GAMENAME); + + for (search = com_searchpaths; search; search = search->next) + { + if (*search->filename) //directory + { +#ifdef _WIN32 + q_snprintf (filestring, sizeof(filestring), "%s/maps/*.bsp", search->filename); + fhnd = FindFirstFile(filestring, &fdat); + if (fhnd == INVALID_HANDLE_VALUE) + continue; + do + { + COM_StripExtension(fdat.cFileName, mapname, sizeof(mapname)); + ExtraMaps_Add (mapname); + } while (FindNextFile(fhnd, &fdat)); + FindClose(fhnd); +#else + q_snprintf (filestring, sizeof(filestring), "%s/maps/", search->filename); + dir_p = opendir(filestring); + if (dir_p == NULL) + continue; + while ((dir_t = readdir(dir_p)) != NULL) + { + if (q_strcasecmp(COM_FileGetExtension(dir_t->d_name), "bsp") != 0) + continue; + COM_StripExtension(dir_t->d_name, mapname, sizeof(mapname)); + ExtraMaps_Add (mapname); + } + closedir(dir_p); +#endif + } + else //pakfile + { + if (!strstr(search->pack->filename, ignorepakdir)) + { //don't list standard id maps + for (i = 0, pak = search->pack; i < pak->numfiles; i++) + { + if (!strcmp(COM_FileGetExtension(pak->files[i].name), "bsp")) + { + if (pak->files[i].filelen > 32*1024) + { // don't list files under 32k (ammo boxes etc) + COM_StripExtension(pak->files[i].name + 5, mapname, sizeof(mapname)); + ExtraMaps_Add (mapname); + } + } + } + } + } + } +} + +static void ExtraMaps_Clear (void) +{ + FileList_Clear(&extralevels); +} + +void ExtraMaps_NewGame (void) +{ + ExtraMaps_Clear (); + ExtraMaps_Init (); +} + +/* +================== +Host_Maps_f +================== +*/ +void Host_Maps_f (void) +{ + int i; + filelist_item_t *level; + + for (level = extralevels, i = 0; level; level = level->next, i++) + Con_SafePrintf (" %s\n", level->name); + + if (i) + Con_SafePrintf ("%i map(s)\n", i); + else + Con_SafePrintf ("no maps found\n"); +} + +//============================================================================== +//johnfitz -- modlist management +//============================================================================== + +filelist_item_t *modlist; + +void Modlist_Add (const char *name) +{ + FileList_Add(name, &modlist); +} + +#ifdef _WIN32 +void Modlist_Init (void) +{ + WIN32_FIND_DATA fdat; + HANDLE fhnd; + DWORD attribs; + char dir_string[MAX_OSPATH], mod_string[MAX_OSPATH]; + + q_snprintf (dir_string, sizeof(dir_string), "%s/*", com_basedir); + fhnd = FindFirstFile(dir_string, &fdat); + if (fhnd == INVALID_HANDLE_VALUE) + return; + + do + { + if (!strcmp(fdat.cFileName, ".") || !strcmp(fdat.cFileName, "..")) + continue; + q_snprintf (mod_string, sizeof(mod_string), "%s/%s", com_basedir, fdat.cFileName); + attribs = GetFileAttributes (mod_string); + if (attribs != INVALID_FILE_ATTRIBUTES && (attribs & FILE_ATTRIBUTE_DIRECTORY)) { + /* don't bother testing for pak files / progs.dat */ + Modlist_Add(fdat.cFileName); + } + } while (FindNextFile(fhnd, &fdat)); + + FindClose(fhnd); +} +#else +void Modlist_Init (void) +{ + DIR *dir_p, *mod_dir_p; + struct dirent *dir_t; + char dir_string[MAX_OSPATH], mod_string[MAX_OSPATH]; + + q_snprintf (dir_string, sizeof(dir_string), "%s/", com_basedir); + dir_p = opendir(dir_string); + if (dir_p == NULL) + return; + + while ((dir_t = readdir(dir_p)) != NULL) + { + if (!strcmp(dir_t->d_name, ".") || !strcmp(dir_t->d_name, "..")) + continue; + if (!q_strcasecmp (COM_FileGetExtension (dir_t->d_name), "app")) // skip .app bundles on macOS + continue; + q_snprintf(mod_string, sizeof(mod_string), "%s%s/", dir_string, dir_t->d_name); + mod_dir_p = opendir(mod_string); + if (mod_dir_p == NULL) + continue; + /* don't bother testing for pak files / progs.dat */ + Modlist_Add(dir_t->d_name); + closedir(mod_dir_p); + } + + closedir(dir_p); +} +#endif + +//============================================================================== +//ericw -- demo list management +//============================================================================== + +filelist_item_t *demolist; + +static void DemoList_Clear (void) +{ + FileList_Clear (&demolist); +} + +void DemoList_Rebuild (void) +{ + DemoList_Clear (); + DemoList_Init (); +} + +// TODO: Factor out to a general-purpose file searching function +void DemoList_Init (void) +{ +#ifdef _WIN32 + WIN32_FIND_DATA fdat; + HANDLE fhnd; +#else + DIR *dir_p; + struct dirent *dir_t; +#endif + char filestring[MAX_OSPATH]; + char demname[32]; + char ignorepakdir[32]; + searchpath_t *search; + pack_t *pak; + int i; + + // we don't want to list the demos in id1 pakfiles, + // because these are not "add-on" demos + q_snprintf (ignorepakdir, sizeof(ignorepakdir), "/%s/", GAMENAME); + + for (search = com_searchpaths; search; search = search->next) + { + if (*search->filename) //directory + { +#ifdef _WIN32 + q_snprintf (filestring, sizeof(filestring), "%s/*.dem", search->filename); + fhnd = FindFirstFile(filestring, &fdat); + if (fhnd == INVALID_HANDLE_VALUE) + continue; + do + { + COM_StripExtension(fdat.cFileName, demname, sizeof(demname)); + FileList_Add (demname, &demolist); + } while (FindNextFile(fhnd, &fdat)); + FindClose(fhnd); +#else + q_snprintf (filestring, sizeof(filestring), "%s/", search->filename); + dir_p = opendir(filestring); + if (dir_p == NULL) + continue; + while ((dir_t = readdir(dir_p)) != NULL) + { + if (q_strcasecmp(COM_FileGetExtension(dir_t->d_name), "dem") != 0) + continue; + COM_StripExtension(dir_t->d_name, demname, sizeof(demname)); + FileList_Add (demname, &demolist); + } + closedir(dir_p); +#endif + } + else //pakfile + { + if (!strstr(search->pack->filename, ignorepakdir)) + { //don't list standard id demos + for (i = 0, pak = search->pack; i < pak->numfiles; i++) + { + if (!strcmp(COM_FileGetExtension(pak->files[i].name), "dem")) + { + COM_StripExtension(pak->files[i].name, demname, sizeof(demname)); + FileList_Add (demname, &demolist); + } + } + } + } + } +} + + +/* +================== +Host_Mods_f -- johnfitz + +list all potential mod directories (contain either a pak file or a progs.dat) +================== +*/ +void Host_Mods_f (void) +{ + int i; + filelist_item_t *mod; + + for (mod = modlist, i=0; mod; mod = mod->next, i++) + Con_SafePrintf (" %s\n", mod->name); + + if (i) + Con_SafePrintf ("%i mod(s)\n", i); + else + Con_SafePrintf ("no mods found\n"); +} + +//============================================================================== + +/* +============= +Host_Mapname_f -- johnfitz +============= +*/ +void Host_Mapname_f (void) +{ + if (sv.active) + { + Con_Printf ("\"mapname\" is \"%s\"\n", sv.name); + return; + } + + if (cls.state == ca_connected) + { + Con_Printf ("\"mapname\" is \"%s\"\n", cl.mapname); + return; + } + + Con_Printf ("no map loaded\n"); +} + +/* +================== +Host_Status_f +================== +*/ +void Host_Status_f (void) +{ + void (*print_fn) (const char *fmt, ...) + FUNCP_PRINTF(1,2); + client_t *client; + int seconds; + int minutes; + int hours = 0; + int j; + + if (cmd_source == src_command) + { + if (!sv.active) + { + Cmd_ForwardToServer (); + return; + } + print_fn = Con_Printf; + } + else + print_fn = SV_ClientPrintf; + + print_fn ("host: %s\n", Cvar_VariableString ("hostname")); + print_fn ("version: %4.2f\n", VERSION); + if (tcpipAvailable) + print_fn ("tcp/ip: %s\n", my_tcpip_address); + if (ipxAvailable) + print_fn ("ipx: %s\n", my_ipx_address); + print_fn ("map: %s\n", sv.name); + print_fn ("players: %i active (%i max)\n\n", net_activeconnections, svs.maxclients); + for (j = 0, client = svs.clients; j < svs.maxclients; j++, client++) + { + if (!client->active) + continue; + seconds = (int)(net_time - NET_QSocketGetTime(client->netconnection)); + minutes = seconds / 60; + if (minutes) + { + seconds -= (minutes * 60); + hours = minutes / 60; + if (hours) + minutes -= (hours * 60); + } + else + hours = 0; + print_fn ("#%-2u %-16.16s %3i %2i:%02i:%02i\n", j+1, client->name, (int)client->edict->v.frags, hours, minutes, seconds); + print_fn (" %s\n", NET_QSocketGetAddressString(client->netconnection)); + } +} + +/* +================== +Host_God_f + +Sets client to godmode +================== +*/ +void Host_God_f (void) +{ + if (cmd_source == src_command) + { + Cmd_ForwardToServer (); + return; + } + + if (pr_global_struct->deathmatch) + return; + + //johnfitz -- allow user to explicitly set god mode to on or off + switch (Cmd_Argc()) + { + case 1: + sv_player->v.flags = (int)sv_player->v.flags ^ FL_GODMODE; + if (!((int)sv_player->v.flags & FL_GODMODE) ) + SV_ClientPrintf ("godmode OFF\n"); + else + SV_ClientPrintf ("godmode ON\n"); + break; + case 2: + if (Q_atof(Cmd_Argv(1))) + { + sv_player->v.flags = (int)sv_player->v.flags | FL_GODMODE; + SV_ClientPrintf ("godmode ON\n"); + } + else + { + sv_player->v.flags = (int)sv_player->v.flags & ~FL_GODMODE; + SV_ClientPrintf ("godmode OFF\n"); + } + break; + default: + Con_Printf("god [value] : toggle god mode. values: 0 = off, 1 = on\n"); + break; + } + //johnfitz +} + +/* +================== +Host_Notarget_f +================== +*/ +void Host_Notarget_f (void) +{ + if (cmd_source == src_command) + { + Cmd_ForwardToServer (); + return; + } + + if (pr_global_struct->deathmatch) + return; + + //johnfitz -- allow user to explicitly set notarget to on or off + switch (Cmd_Argc()) + { + case 1: + sv_player->v.flags = (int)sv_player->v.flags ^ FL_NOTARGET; + if (!((int)sv_player->v.flags & FL_NOTARGET) ) + SV_ClientPrintf ("notarget OFF\n"); + else + SV_ClientPrintf ("notarget ON\n"); + break; + case 2: + if (Q_atof(Cmd_Argv(1))) + { + sv_player->v.flags = (int)sv_player->v.flags | FL_NOTARGET; + SV_ClientPrintf ("notarget ON\n"); + } + else + { + sv_player->v.flags = (int)sv_player->v.flags & ~FL_NOTARGET; + SV_ClientPrintf ("notarget OFF\n"); + } + break; + default: + Con_Printf("notarget [value] : toggle notarget mode. values: 0 = off, 1 = on\n"); + break; + } + //johnfitz +} + +qboolean noclip_anglehack; + +/* +================== +Host_Noclip_f +================== +*/ +void Host_Noclip_f (void) +{ + if (cmd_source == src_command) + { + Cmd_ForwardToServer (); + return; + } + + if (pr_global_struct->deathmatch) + return; + + //johnfitz -- allow user to explicitly set noclip to on or off + switch (Cmd_Argc()) + { + case 1: + if (sv_player->v.movetype != MOVETYPE_NOCLIP) + { + noclip_anglehack = true; + sv_player->v.movetype = MOVETYPE_NOCLIP; + SV_ClientPrintf ("noclip ON\n"); + } + else + { + noclip_anglehack = false; + sv_player->v.movetype = MOVETYPE_WALK; + SV_ClientPrintf ("noclip OFF\n"); + } + break; + case 2: + if (Q_atof(Cmd_Argv(1))) + { + noclip_anglehack = true; + sv_player->v.movetype = MOVETYPE_NOCLIP; + SV_ClientPrintf ("noclip ON\n"); + } + else + { + noclip_anglehack = false; + sv_player->v.movetype = MOVETYPE_WALK; + SV_ClientPrintf ("noclip OFF\n"); + } + break; + default: + Con_Printf("noclip [value] : toggle noclip mode. values: 0 = off, 1 = on\n"); + break; + } + //johnfitz +} + +/* +==================== +Host_SetPos_f + +adapted from fteqw, originally by Alex Shadowalker +==================== +*/ +void Host_SetPos_f(void) +{ + if (cmd_source == src_command) + { + Cmd_ForwardToServer (); + return; + } + + if (pr_global_struct->deathmatch) + return; + + if (Cmd_Argc() != 7 && Cmd_Argc() != 4) + { + SV_ClientPrintf("usage:\n"); + SV_ClientPrintf(" setpos \n"); + SV_ClientPrintf(" setpos \n"); + SV_ClientPrintf("current values:\n"); + SV_ClientPrintf(" %i %i %i %i %i %i\n", + (int)sv_player->v.origin[0], + (int)sv_player->v.origin[1], + (int)sv_player->v.origin[2], + (int)sv_player->v.v_angle[0], + (int)sv_player->v.v_angle[1], + (int)sv_player->v.v_angle[2]); + return; + } + + if (sv_player->v.movetype != MOVETYPE_NOCLIP) + { + noclip_anglehack = true; + sv_player->v.movetype = MOVETYPE_NOCLIP; + SV_ClientPrintf ("noclip ON\n"); + } + + //make sure they're not going to whizz away from it + sv_player->v.velocity[0] = 0; + sv_player->v.velocity[1] = 0; + sv_player->v.velocity[2] = 0; + + sv_player->v.origin[0] = atof(Cmd_Argv(1)); + sv_player->v.origin[1] = atof(Cmd_Argv(2)); + sv_player->v.origin[2] = atof(Cmd_Argv(3)); + + if (Cmd_Argc() == 7) + { + sv_player->v.angles[0] = atof(Cmd_Argv(4)); + sv_player->v.angles[1] = atof(Cmd_Argv(5)); + sv_player->v.angles[2] = atof(Cmd_Argv(6)); + sv_player->v.fixangle = 1; + } + + SV_LinkEdict (sv_player, false); +} + +/* +================== +Host_Fly_f + +Sets client to flymode +================== +*/ +void Host_Fly_f (void) +{ + if (cmd_source == src_command) + { + Cmd_ForwardToServer (); + return; + } + + if (pr_global_struct->deathmatch) + return; + + //johnfitz -- allow user to explicitly set noclip to on or off + switch (Cmd_Argc()) + { + case 1: + if (sv_player->v.movetype != MOVETYPE_FLY) + { + sv_player->v.movetype = MOVETYPE_FLY; + SV_ClientPrintf ("flymode ON\n"); + } + else + { + sv_player->v.movetype = MOVETYPE_WALK; + SV_ClientPrintf ("flymode OFF\n"); + } + break; + case 2: + if (Q_atof(Cmd_Argv(1))) + { + sv_player->v.movetype = MOVETYPE_FLY; + SV_ClientPrintf ("flymode ON\n"); + } + else + { + sv_player->v.movetype = MOVETYPE_WALK; + SV_ClientPrintf ("flymode OFF\n"); + } + break; + default: + Con_Printf("fly [value] : toggle fly mode. values: 0 = off, 1 = on\n"); + break; + } + //johnfitz +} + + +/* +================== +Host_Ping_f + +================== +*/ +void Host_Ping_f (void) +{ + int i, j; + float total; + client_t *client; + + if (cmd_source == src_command) + { + Cmd_ForwardToServer (); + return; + } + + SV_ClientPrintf ("Client ping times:\n"); + for (i = 0, client = svs.clients; i < svs.maxclients; i++, client++) + { + if (!client->active) + continue; + total = 0; + for (j = 0; j < NUM_PING_TIMES; j++) + total+=client->ping_times[j]; + total /= NUM_PING_TIMES; + SV_ClientPrintf ("%4i %s\n", (int)(total*1000), client->name); + } +} + +/* +=============================================================================== + +SERVER TRANSITIONS + +=============================================================================== +*/ + + +/* +====================== +Host_Map_f + +handle a +map +command from the console. Active clients are kicked off. +====================== +*/ +void Host_Map_f (void) +{ + int i; + char name[MAX_QPATH], *p; + + if (Cmd_Argc() < 2) //no map name given + { + if (cls.state == ca_dedicated) + { + if (sv.active) + Con_Printf ("Current map: %s\n", sv.name); + else + Con_Printf ("Server not active\n"); + } + else if (cls.state == ca_connected) + { + Con_Printf ("Current map: %s ( %s )\n", cl.levelname, cl.mapname); + } + else + { + Con_Printf ("map : start a new server\n"); + } + return; + } + + if (cmd_source != src_command) + return; + + cls.demonum = -1; // stop demo loop in case this fails + + CL_Disconnect (); + Host_ShutdownServer(false); + + if (cls.state != ca_dedicated) + IN_Activate(); + key_dest = key_game; // remove console or menu + SCR_BeginLoadingPlaque (); + + svs.serverflags = 0; // haven't completed an episode yet + q_strlcpy (name, Cmd_Argv(1), sizeof(name)); + // remove (any) trailing ".bsp" from mapname -- S.A. + p = strstr(name, ".bsp"); + if (p && p[4] == '\0') + *p = '\0'; + SV_SpawnServer (name); + if (!sv.active) + return; + + if (cls.state != ca_dedicated) + { + memset (cls.spawnparms, 0, MAX_MAPSTRING); + for (i = 2; i < Cmd_Argc(); i++) + { + q_strlcat (cls.spawnparms, Cmd_Argv(i), MAX_MAPSTRING); + q_strlcat (cls.spawnparms, " ", MAX_MAPSTRING); + } + + Cmd_ExecuteString ("connect local", src_command); + } +} + +/* +====================== +Host_Randmap_f + +Loads a random map from the "maps" list. +====================== +*/ +void Host_Randmap_f (void) +{ + int i, randlevel, numlevels; + filelist_item_t *level; + + if (cmd_source != src_command) + return; + + for (level = extralevels, numlevels = 0; level; level = level->next) + numlevels++; + + if (numlevels == 0) + { + Con_Printf ("no maps\n"); + return; + } + + randlevel = (rand() % numlevels); + + for (level = extralevels, i = 0; level; level = level->next, i++) + { + if (i == randlevel) + { + Con_Printf ("Starting map %s...\n", level->name); + Cbuf_AddText (va("map %s\n", level->name)); + return; + } + } +} + +/* +================== +Host_Changelevel_f + +Goes to a new map, taking all clients along +================== +*/ +void Host_Changelevel_f (void) +{ + char level[MAX_QPATH]; + + if (Cmd_Argc() != 2) + { + Con_Printf ("changelevel : continue game on a new level\n"); + return; + } + if (!sv.active || cls.demoplayback) + { + Con_Printf ("Only the server may changelevel\n"); + return; + } + + //johnfitz -- check for client having map before anything else + q_snprintf (level, sizeof(level), "maps/%s.bsp", Cmd_Argv(1)); + if (!COM_FileExists(level, NULL)) + Host_Error ("cannot find map %s", level); + //johnfitz + + if (cls.state != ca_dedicated) + IN_Activate(); // -- S.A. + key_dest = key_game; // remove console or menu + SV_SaveSpawnparms (); + q_strlcpy (level, Cmd_Argv(1), sizeof(level)); + SV_SpawnServer (level); + // also issue an error if spawn failed -- O.S. + if (!sv.active) + Host_Error ("cannot run map %s", level); +} + +/* +================== +Host_Restart_f + +Restarts the current server for a dead player +================== +*/ +void Host_Restart_f (void) +{ + char mapname[MAX_QPATH]; + + if (cls.demoplayback || !sv.active) + return; + + if (cmd_source != src_command) + return; + q_strlcpy (mapname, sv.name, sizeof(mapname)); // mapname gets cleared in spawnserver + SV_SpawnServer (mapname); + if (!sv.active) + Host_Error ("cannot restart map %s", mapname); +} + +/* +================== +Host_Reconnect_f + +This command causes the client to wait for the signon messages again. +This is sent just before a server changes levels +================== +*/ +void Host_Reconnect_f (void) +{ + if (cls.demoplayback) // cross-map demo playback fix from Baker + return; + + SCR_BeginLoadingPlaque (); + cls.signon = 0; // need new connection messages +} + +/* +===================== +Host_Connect_f + +User command to connect to server +===================== +*/ +void Host_Connect_f (void) +{ + char name[MAX_QPATH]; + + cls.demonum = -1; // stop demo loop in case this fails + if (cls.demoplayback) + { + CL_StopPlayback (); + CL_Disconnect (); + } + q_strlcpy (name, Cmd_Argv(1), sizeof(name)); + CL_EstablishConnection (name); + Host_Reconnect_f (); +} + + +/* +=============================================================================== + +LOAD / SAVE GAME + +=============================================================================== +*/ + +#define SAVEGAME_VERSION 5 + +/* +=============== +Host_SavegameComment + +Writes a SAVEGAME_COMMENT_LENGTH character comment describing the current +=============== +*/ +void Host_SavegameComment (char *text) +{ + int i; + char kills[20]; + + for (i = 0; i < SAVEGAME_COMMENT_LENGTH; i++) + text[i] = ' '; + memcpy (text, cl.levelname, q_min(strlen(cl.levelname),22)); //johnfitz -- only copy 22 chars. + sprintf (kills,"kills:%3i/%3i", cl.stats[STAT_MONSTERS], cl.stats[STAT_TOTALMONSTERS]); + memcpy (text+22, kills, strlen(kills)); +// convert space to _ to make stdio happy + for (i = 0; i < SAVEGAME_COMMENT_LENGTH; i++) + { + if (text[i] == ' ') + text[i] = '_'; + } + text[SAVEGAME_COMMENT_LENGTH] = '\0'; +} + + +/* +=============== +Host_Savegame_f +=============== +*/ +void Host_Savegame_f (void) +{ + char name[MAX_OSPATH]; + FILE *f; + int i; + char comment[SAVEGAME_COMMENT_LENGTH+1]; + + if (cmd_source != src_command) + return; + + if (!sv.active) + { + Con_Printf ("Not playing a local game.\n"); + return; + } + + if (cl.intermission) + { + Con_Printf ("Can't save in intermission.\n"); + return; + } + + if (svs.maxclients != 1) + { + Con_Printf ("Can't save multiplayer games.\n"); + return; + } + + if (Cmd_Argc() != 2) + { + Con_Printf ("save : save a game\n"); + return; + } + + if (strstr(Cmd_Argv(1), "..")) + { + Con_Printf ("Relative pathnames are not allowed.\n"); + return; + } + + for (i=0 ; iv.health <= 0) ) + { + Con_Printf ("Can't savegame with a dead player\n"); + return; + } + } + + q_snprintf (name, sizeof(name), "%s/%s", com_gamedir, Cmd_Argv(1)); + COM_AddExtension (name, ".sav", sizeof(name)); + + Con_Printf ("Saving game to %s...\n", name); + f = fopen (name, "w"); + if (!f) + { + Con_Printf ("ERROR: couldn't open.\n"); + return; + } + + fprintf (f, "%i\n", SAVEGAME_VERSION); + Host_SavegameComment (comment); + fprintf (f, "%s\n", comment); + for (i = 0; i < NUM_SPAWN_PARMS; i++) + fprintf (f, "%f\n", svs.clients->spawn_parms[i]); + fprintf (f, "%d\n", current_skill); + fprintf (f, "%s\n", sv.name); + fprintf (f, "%f\n",sv.time); + +// write the light styles + + for (i = 0; i < MAX_LIGHTSTYLES; i++) + { + if (sv.lightstyles[i]) + fprintf (f, "%s\n", sv.lightstyles[i]); + else + fprintf (f,"m\n"); + } + + + ED_WriteGlobals (f); + for (i = 0; i < sv.num_edicts; i++) + { + ED_Write (f, EDICT_NUM(i)); + fflush (f); + } + fclose (f); + Con_Printf ("done.\n"); +} + + +/* +=============== +Host_Loadgame_f +=============== +*/ +void Host_Loadgame_f (void) +{ + static char *start; + + char name[MAX_OSPATH]; + char mapname[MAX_QPATH]; + float time, tfloat; + const char *data; + int i; + edict_t *ent; + int entnum; + int version; + float spawn_parms[NUM_SPAWN_PARMS]; + + if (cmd_source != src_command) + return; + + if (Cmd_Argc() != 2) + { + Con_Printf ("load : load a game\n"); + return; + } + + if (strstr(Cmd_Argv(1), "..")) + { + Con_Printf ("Relative pathnames are not allowed.\n"); + return; + } + + cls.demonum = -1; // stop demo loop in case this fails + + q_snprintf (name, sizeof(name), "%s/%s", com_gamedir, Cmd_Argv(1)); + COM_AddExtension (name, ".sav", sizeof(name)); + +// we can't call SCR_BeginLoadingPlaque, because too much stack space has +// been used. The menu calls it before stuffing loadgame command +// SCR_BeginLoadingPlaque (); + + Con_Printf ("Loading game from %s...\n", name); + +// avoid leaking if the previous Host_Loadgame_f failed with a Host_Error + if (start != NULL) + free (start); + + start = (char *) COM_LoadMallocFile_TextMode_OSPath(name, NULL); + if (start == NULL) + { + Con_Printf ("ERROR: couldn't open.\n"); + return; + } + + data = start; + data = COM_ParseIntNewline (data, &version); + if (version != SAVEGAME_VERSION) + { + free (start); + start = NULL; + Con_Printf ("Savegame is version %i, not %i\n", version, SAVEGAME_VERSION); + return; + } + data = COM_ParseStringNewline (data); + for (i = 0; i < NUM_SPAWN_PARMS; i++) + data = COM_ParseFloatNewline (data, &spawn_parms[i]); +// this silliness is so we can load 1.06 save files, which have float skill values + data = COM_ParseFloatNewline(data, &tfloat); + current_skill = (int)(tfloat + 0.1); + Cvar_SetValue ("skill", (float)current_skill); + + data = COM_ParseStringNewline (data); + q_strlcpy (mapname, com_token, sizeof(mapname)); + data = COM_ParseFloatNewline (data, &time); + + CL_Disconnect_f (); + + SV_SpawnServer (mapname); + + if (!sv.active) + { + free (start); + start = NULL; + Con_Printf ("Couldn't load map\n"); + return; + } + sv.paused = true; // pause until all clients connect + sv.loadgame = true; + +// load the light styles + + for (i = 0; i < MAX_LIGHTSTYLES; i++) + { + data = COM_ParseStringNewline (data); + sv.lightstyles[i] = (const char *)Hunk_Strdup (com_token, "lightstyles"); + } + +// load the edicts out of the savegame file + entnum = -1; // -1 is the globals + while (*data) + { + data = COM_Parse (data); + if (!com_token[0]) + break; // end of file + if (strcmp(com_token,"{")) + { + Sys_Error ("First token isn't a brace"); + } + + if (entnum == -1) + { // parse the global vars + data = ED_ParseGlobals (data); + } + else + { // parse an edict + ent = EDICT_NUM(entnum); + if (entnum < sv.num_edicts) { + ent->free = false; + memset (&ent->v, 0, progs->entityfields * 4); + } + else { + memset (ent, 0, pr_edict_size); + } + data = ED_ParseEdict (data, ent); + + // link it into the bsp tree + if (!ent->free) + SV_LinkEdict (ent, false); + } + + entnum++; + } + + sv.num_edicts = entnum; + sv.time = time; + + free (start); + start = NULL; + + for (i = 0; i < NUM_SPAWN_PARMS; i++) + svs.clients->spawn_parms[i] = spawn_parms[i]; + + if (cls.state != ca_dedicated) + { + CL_EstablishConnection ("local"); + Host_Reconnect_f (); + } +} + +//============================================================================ + +/* +====================== +Host_Name_f +====================== +*/ +void Host_Name_f (void) +{ + char newName[32]; + + if (Cmd_Argc () == 1) + { + Con_Printf ("\"name\" is \"%s\"\n", cl_name.string); + return; + } + if (Cmd_Argc () == 2) + q_strlcpy(newName, Cmd_Argv(1), sizeof(newName)); + else + q_strlcpy(newName, Cmd_Args(), sizeof(newName)); + newName[15] = 0; // client_t structure actually says name[32]. + + if (cmd_source == src_command) + { + if (Q_strcmp(cl_name.string, newName) == 0) + return; + Cvar_Set ("_cl_name", newName); + if (cls.state == ca_connected) + Cmd_ForwardToServer (); + return; + } + + if (host_client->name[0] && strcmp(host_client->name, "unconnected") ) + { + if (Q_strcmp(host_client->name, newName) != 0) + Con_Printf ("%s renamed to %s\n", host_client->name, newName); + } + Q_strcpy (host_client->name, newName); + host_client->edict->v.netname = PR_SetEngineString(host_client->name); + +// send notification to all clients + + MSG_WriteByte (&sv.reliable_datagram, svc_updatename); + MSG_WriteByte (&sv.reliable_datagram, host_client - svs.clients); + MSG_WriteString (&sv.reliable_datagram, host_client->name); +} + +void Host_Say(qboolean teamonly) +{ + int j; + client_t *client; + client_t *save; + const char *p; + char text[MAXCMDLINE], *p2; + qboolean quoted; + qboolean fromServer = false; + + if (cmd_source == src_command) + { + if (cls.state != ca_dedicated) + { + Cmd_ForwardToServer (); + return; + } + fromServer = true; + teamonly = false; + } + + if (Cmd_Argc () < 2) + return; + + save = host_client; + + p = Cmd_Args(); +// remove quotes if present + quoted = false; + if (*p == '\"') + { + p++; + quoted = true; + } +// turn on color set 1 + if (!fromServer) + q_snprintf (text, sizeof(text), "\001%s: %s", save->name, p); + else + q_snprintf (text, sizeof(text), "\001<%s> %s", hostname.string, p); + +// check length & truncate if necessary + j = (int) strlen(text); + if (j >= (int) sizeof(text) - 1) + { + text[sizeof(text) - 2] = '\n'; + text[sizeof(text) - 1] = '\0'; + } + else + { + p2 = text + j; + while ((const char *)p2 > (const char *)text && + (p2[-1] == '\r' || p2[-1] == '\n' || (p2[-1] == '\"' && quoted)) ) + { + if (p2[-1] == '\"' && quoted) + quoted = false; + p2[-1] = '\0'; + p2--; + } + p2[0] = '\n'; + p2[1] = '\0'; + } + + for (j = 0, client = svs.clients; j < svs.maxclients; j++, client++) + { + if (!client || !client->active || !client->spawned) + continue; + if (teamplay.value && teamonly && client->edict->v.team != save->edict->v.team) + continue; + host_client = client; + SV_ClientPrintf("%s", text); + } + host_client = save; + + if (cls.state == ca_dedicated) + Sys_Printf("%s", &text[1]); +} + + +void Host_Say_f(void) +{ + Host_Say(false); +} + + +void Host_Say_Team_f(void) +{ + Host_Say(true); +} + + +void Host_Tell_f(void) +{ + int j; + client_t *client; + client_t *save; + const char *p; + char text[MAXCMDLINE], *p2; + qboolean quoted; + + if (cmd_source == src_command) + { + Cmd_ForwardToServer (); + return; + } + + if (Cmd_Argc () < 3) + return; + + p = Cmd_Args(); +// remove quotes if present + quoted = false; + if (*p == '\"') + { + p++; + quoted = true; + } + q_snprintf (text, sizeof(text), "%s: %s", host_client->name, p); + +// check length & truncate if necessary + j = (int) strlen(text); + if (j >= (int) sizeof(text) - 1) + { + text[sizeof(text) - 2] = '\n'; + text[sizeof(text) - 1] = '\0'; + } + else + { + p2 = text + j; + while ((const char *)p2 > (const char *)text && + (p2[-1] == '\r' || p2[-1] == '\n' || (p2[-1] == '\"' && quoted)) ) + { + if (p2[-1] == '\"' && quoted) + quoted = false; + p2[-1] = '\0'; + p2--; + } + p2[0] = '\n'; + p2[1] = '\0'; + } + + save = host_client; + for (j = 0, client = svs.clients; j < svs.maxclients; j++, client++) + { + if (!client->active || !client->spawned) + continue; + if (q_strcasecmp(client->name, Cmd_Argv(1))) + continue; + host_client = client; + SV_ClientPrintf("%s", text); + break; + } + host_client = save; +} + + +/* +================== +Host_Color_f +================== +*/ +void Host_Color_f(void) +{ + int top, bottom; + int playercolor; + + if (Cmd_Argc() == 1) + { + Con_Printf ("\"color\" is \"%i %i\"\n", ((int)cl_color.value) >> 4, ((int)cl_color.value) & 0x0f); + Con_Printf ("color <0-13> [0-13]\n"); + return; + } + + if (Cmd_Argc() == 2) + top = bottom = atoi(Cmd_Argv(1)); + else + { + top = atoi(Cmd_Argv(1)); + bottom = atoi(Cmd_Argv(2)); + } + + top &= 15; + if (top > 13) + top = 13; + bottom &= 15; + if (bottom > 13) + bottom = 13; + + playercolor = top*16 + bottom; + + if (cmd_source == src_command) + { + Cvar_SetValue ("_cl_color", playercolor); + if (cls.state == ca_connected) + Cmd_ForwardToServer (); + return; + } + + host_client->colors = playercolor; + host_client->edict->v.team = bottom + 1; + +// send notification to all clients + MSG_WriteByte (&sv.reliable_datagram, svc_updatecolors); + MSG_WriteByte (&sv.reliable_datagram, host_client - svs.clients); + MSG_WriteByte (&sv.reliable_datagram, host_client->colors); +} + +/* +================== +Host_Kill_f +================== +*/ +void Host_Kill_f (void) +{ + if (cmd_source == src_command) + { + Cmd_ForwardToServer (); + return; + } + + if (sv_player->v.health <= 0) + { + SV_ClientPrintf ("Can't suicide -- allready dead!\n"); + return; + } + + pr_global_struct->time = sv.time; + pr_global_struct->self = EDICT_TO_PROG(sv_player); + PR_ExecuteProgram (pr_global_struct->ClientKill); +} + + +/* +================== +Host_Pause_f +================== +*/ +void Host_Pause_f (void) +{ +//ericw -- demo pause support (inspired by MarkV) + if (cls.demoplayback) + { + cls.demopaused = !cls.demopaused; + cl.paused = cls.demopaused; + return; + } + + if (cmd_source == src_command) + { + Cmd_ForwardToServer (); + return; + } + if (!pausable.value) + SV_ClientPrintf ("Pause not allowed.\n"); + else + { + sv.paused ^= 1; + + if (sv.paused) + { + SV_BroadcastPrintf ("%s paused the game\n", PR_GetString(sv_player->v.netname)); + } + else + { + SV_BroadcastPrintf ("%s unpaused the game\n",PR_GetString(sv_player->v.netname)); + } + + // send notification to all clients + MSG_WriteByte (&sv.reliable_datagram, svc_setpause); + MSG_WriteByte (&sv.reliable_datagram, sv.paused); + } +} + +//=========================================================================== + + +/* +================== +Host_PreSpawn_f +================== +*/ +void Host_PreSpawn_f (void) +{ + if (cmd_source == src_command) + { + Con_Printf ("prespawn is not valid from the console\n"); + return; + } + + if (host_client->spawned) + { + Con_Printf ("prespawn not valid -- allready spawned\n"); + return; + } + + SZ_Write (&host_client->message, sv.signon.data, sv.signon.cursize); + MSG_WriteByte (&host_client->message, svc_signonnum); + MSG_WriteByte (&host_client->message, 2); + host_client->sendsignon = true; +} + +/* +================== +Host_Spawn_f +================== +*/ +void Host_Spawn_f (void) +{ + int i; + client_t *client; + edict_t *ent; + + if (cmd_source == src_command) + { + Con_Printf ("spawn is not valid from the console\n"); + return; + } + + if (host_client->spawned) + { + Con_Printf ("Spawn not valid -- allready spawned\n"); + return; + } + +// run the entrance script + if (sv.loadgame) + { // loaded games are fully inited allready + // if this is the last client to be connected, unpause + sv.paused = false; + } + else + { + // set up the edict + ent = host_client->edict; + + memset (&ent->v, 0, progs->entityfields * 4); + ent->v.colormap = NUM_FOR_EDICT(ent); + ent->v.team = (host_client->colors & 15) + 1; + ent->v.netname = PR_SetEngineString(host_client->name); + + // copy spawn parms out of the client_t + for (i=0 ; i< NUM_SPAWN_PARMS ; i++) + (&pr_global_struct->parm1)[i] = host_client->spawn_parms[i]; + // call the spawn function + pr_global_struct->time = sv.time; + pr_global_struct->self = EDICT_TO_PROG(sv_player); + PR_ExecuteProgram (pr_global_struct->ClientConnect); + + if ((Sys_DoubleTime() - NET_QSocketGetTime(host_client->netconnection)) <= sv.time) + Sys_Printf ("%s entered the game\n", host_client->name); + + PR_ExecuteProgram (pr_global_struct->PutClientInServer); + } + + +// send all current names, colors, and frag counts + SZ_Clear (&host_client->message); + +// send time of update + MSG_WriteByte (&host_client->message, svc_time); + MSG_WriteFloat (&host_client->message, sv.time); + + for (i = 0, client = svs.clients; i < svs.maxclients; i++, client++) + { + MSG_WriteByte (&host_client->message, svc_updatename); + MSG_WriteByte (&host_client->message, i); + MSG_WriteString (&host_client->message, client->name); + MSG_WriteByte (&host_client->message, svc_updatefrags); + MSG_WriteByte (&host_client->message, i); + MSG_WriteShort (&host_client->message, client->old_frags); + MSG_WriteByte (&host_client->message, svc_updatecolors); + MSG_WriteByte (&host_client->message, i); + MSG_WriteByte (&host_client->message, client->colors); + } + +// send all current light styles + for (i = 0; i < MAX_LIGHTSTYLES; i++) + { + MSG_WriteByte (&host_client->message, svc_lightstyle); + MSG_WriteByte (&host_client->message, (char)i); + MSG_WriteString (&host_client->message, sv.lightstyles[i]); + } + +// +// send some stats +// + MSG_WriteByte (&host_client->message, svc_updatestat); + MSG_WriteByte (&host_client->message, STAT_TOTALSECRETS); + MSG_WriteLong (&host_client->message, pr_global_struct->total_secrets); + + MSG_WriteByte (&host_client->message, svc_updatestat); + MSG_WriteByte (&host_client->message, STAT_TOTALMONSTERS); + MSG_WriteLong (&host_client->message, pr_global_struct->total_monsters); + + MSG_WriteByte (&host_client->message, svc_updatestat); + MSG_WriteByte (&host_client->message, STAT_SECRETS); + MSG_WriteLong (&host_client->message, pr_global_struct->found_secrets); + + MSG_WriteByte (&host_client->message, svc_updatestat); + MSG_WriteByte (&host_client->message, STAT_MONSTERS); + MSG_WriteLong (&host_client->message, pr_global_struct->killed_monsters); + +// +// send a fixangle +// Never send a roll angle, because savegames can catch the server +// in a state where it is expecting the client to correct the angle +// and it won't happen if the game was just loaded, so you wind up +// with a permanent head tilt + ent = EDICT_NUM( 1 + (host_client - svs.clients) ); + MSG_WriteByte (&host_client->message, svc_setangle); + for (i = 0; i < 2; i++) + MSG_WriteAngle (&host_client->message, ent->v.angles[i], sv.protocolflags ); + MSG_WriteAngle (&host_client->message, 0, sv.protocolflags ); + + SV_WriteClientdataToMessage (sv_player, &host_client->message); + + MSG_WriteByte (&host_client->message, svc_signonnum); + MSG_WriteByte (&host_client->message, 3); + host_client->sendsignon = true; +} + +/* +================== +Host_Begin_f +================== +*/ +void Host_Begin_f (void) +{ + if (cmd_source == src_command) + { + Con_Printf ("begin is not valid from the console\n"); + return; + } + + host_client->spawned = true; +} + +//=========================================================================== + + +/* +================== +Host_Kick_f + +Kicks a user off of the server +================== +*/ +void Host_Kick_f (void) +{ + const char *who; + const char *message = NULL; + client_t *save; + int i; + qboolean byNumber = false; + + if (cmd_source == src_command) + { + if (!sv.active) + { + Cmd_ForwardToServer (); + return; + } + } + else if (pr_global_struct->deathmatch) + return; + + save = host_client; + + if (Cmd_Argc() > 2 && Q_strcmp(Cmd_Argv(1), "#") == 0) + { + i = Q_atof(Cmd_Argv(2)) - 1; + if (i < 0 || i >= svs.maxclients) + return; + if (!svs.clients[i].active) + return; + host_client = &svs.clients[i]; + byNumber = true; + } + else + { + for (i = 0, host_client = svs.clients; i < svs.maxclients; i++, host_client++) + { + if (!host_client->active) + continue; + if (q_strcasecmp(host_client->name, Cmd_Argv(1)) == 0) + break; + } + } + + if (i < svs.maxclients) + { + if (cmd_source == src_command) + if (cls.state == ca_dedicated) + who = "Console"; + else + who = cl_name.string; + else + who = save->name; + + // can't kick yourself! + if (host_client == save) + return; + + if (Cmd_Argc() > 2) + { + message = COM_Parse(Cmd_Args()); + if (byNumber) + { + message++; // skip the # + while (*message == ' ') // skip white space + message++; + message += strlen(Cmd_Argv(2)); // skip the number + } + while (*message && *message == ' ') + message++; + } + if (message) + SV_ClientPrintf ("Kicked by %s: %s\n", who, message); + else + SV_ClientPrintf ("Kicked by %s\n", who); + SV_DropClient (false); + } + + host_client = save; +} + +/* +=============================================================================== + +DEBUGGING TOOLS + +=============================================================================== +*/ + +/* +================== +Host_Give_f +================== +*/ +void Host_Give_f (void) +{ + const char *t; + int v; + eval_t *val; + + if (cmd_source == src_command) + { + Cmd_ForwardToServer (); + return; + } + + if (pr_global_struct->deathmatch) + return; + + t = Cmd_Argv(1); + v = atoi (Cmd_Argv(2)); + + switch (t[0]) + { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + // MED 01/04/97 added hipnotic give stuff + if (hipnotic) + { + if (t[0] == '6') + { + if (t[1] == 'a') + sv_player->v.items = (int)sv_player->v.items | HIT_PROXIMITY_GUN; + else + sv_player->v.items = (int)sv_player->v.items | IT_GRENADE_LAUNCHER; + } + else if (t[0] == '9') + sv_player->v.items = (int)sv_player->v.items | HIT_LASER_CANNON; + else if (t[0] == '0') + sv_player->v.items = (int)sv_player->v.items | HIT_MJOLNIR; + else if (t[0] >= '2') + sv_player->v.items = (int)sv_player->v.items | (IT_SHOTGUN << (t[0] - '2')); + } + else + { + if (t[0] >= '2') + sv_player->v.items = (int)sv_player->v.items | (IT_SHOTGUN << (t[0] - '2')); + } + break; + + case 's': + if (rogue) + { + val = GetEdictFieldValue(sv_player, "ammo_shells1"); + if (val) + val->_float = v; + } + sv_player->v.ammo_shells = v; + break; + + case 'n': + if (rogue) + { + val = GetEdictFieldValue(sv_player, "ammo_nails1"); + if (val) + { + val->_float = v; + if (sv_player->v.weapon <= IT_LIGHTNING) + sv_player->v.ammo_nails = v; + } + } + else + { + sv_player->v.ammo_nails = v; + } + break; + + case 'l': + if (rogue) + { + val = GetEdictFieldValue(sv_player, "ammo_lava_nails"); + if (val) + { + val->_float = v; + if (sv_player->v.weapon > IT_LIGHTNING) + sv_player->v.ammo_nails = v; + } + } + break; + + case 'r': + if (rogue) + { + val = GetEdictFieldValue(sv_player, "ammo_rockets1"); + if (val) + { + val->_float = v; + if (sv_player->v.weapon <= IT_LIGHTNING) + sv_player->v.ammo_rockets = v; + } + } + else + { + sv_player->v.ammo_rockets = v; + } + break; + + case 'm': + if (rogue) + { + val = GetEdictFieldValue(sv_player, "ammo_multi_rockets"); + if (val) + { + val->_float = v; + if (sv_player->v.weapon > IT_LIGHTNING) + sv_player->v.ammo_rockets = v; + } + } + break; + + case 'h': + sv_player->v.health = v; + break; + + case 'c': + if (rogue) + { + val = GetEdictFieldValue(sv_player, "ammo_cells1"); + if (val) + { + val->_float = v; + if (sv_player->v.weapon <= IT_LIGHTNING) + sv_player->v.ammo_cells = v; + } + } + else + { + sv_player->v.ammo_cells = v; + } + break; + + case 'p': + if (rogue) + { + val = GetEdictFieldValue(sv_player, "ammo_plasma"); + if (val) + { + val->_float = v; + if (sv_player->v.weapon > IT_LIGHTNING) + sv_player->v.ammo_cells = v; + } + } + break; + + //johnfitz -- give armour + case 'a': + if (v > 150) + { + sv_player->v.armortype = 0.8; + sv_player->v.armorvalue = v; + sv_player->v.items = sv_player->v.items - + ((int)(sv_player->v.items) & (int)(IT_ARMOR1 | IT_ARMOR2 | IT_ARMOR3)) + + IT_ARMOR3; + } + else if (v > 100) + { + sv_player->v.armortype = 0.6; + sv_player->v.armorvalue = v; + sv_player->v.items = sv_player->v.items - + ((int)(sv_player->v.items) & (int)(IT_ARMOR1 | IT_ARMOR2 | IT_ARMOR3)) + + IT_ARMOR2; + } + else if (v >= 0) + { + sv_player->v.armortype = 0.3; + sv_player->v.armorvalue = v; + sv_player->v.items = sv_player->v.items - + ((int)(sv_player->v.items) & (int)(IT_ARMOR1 | IT_ARMOR2 | IT_ARMOR3)) + + IT_ARMOR1; + } + break; + //johnfitz + } + + //johnfitz -- update currentammo to match new ammo (so statusbar updates correctly) + switch ((int)(sv_player->v.weapon)) + { + case IT_SHOTGUN: + case IT_SUPER_SHOTGUN: + sv_player->v.currentammo = sv_player->v.ammo_shells; + break; + case IT_NAILGUN: + case IT_SUPER_NAILGUN: + case RIT_LAVA_SUPER_NAILGUN: + sv_player->v.currentammo = sv_player->v.ammo_nails; + break; + case IT_GRENADE_LAUNCHER: + case IT_ROCKET_LAUNCHER: + case RIT_MULTI_GRENADE: + case RIT_MULTI_ROCKET: + sv_player->v.currentammo = sv_player->v.ammo_rockets; + break; + case IT_LIGHTNING: + case HIT_LASER_CANNON: + case HIT_MJOLNIR: + sv_player->v.currentammo = sv_player->v.ammo_cells; + break; + case RIT_LAVA_NAILGUN: //same as IT_AXE + if (rogue) + sv_player->v.currentammo = sv_player->v.ammo_nails; + break; + case RIT_PLASMA_GUN: //same as HIT_PROXIMITY_GUN + if (rogue) + sv_player->v.currentammo = sv_player->v.ammo_cells; + if (hipnotic) + sv_player->v.currentammo = sv_player->v.ammo_rockets; + break; + } + //johnfitz +} + +edict_t *FindViewthing (void) +{ + int i; + edict_t *e; + + for (i=0 ; iv.classname), "viewthing") ) + return e; + } + Con_Printf ("No viewthing on map\n"); + return NULL; +} + +/* +================== +Host_Viewmodel_f +================== +*/ +void Host_Viewmodel_f (void) +{ + edict_t *e; + qmodel_t *m; + + e = FindViewthing (); + if (!e) + return; + + m = Mod_ForName (Cmd_Argv(1), false); + if (!m) + { + Con_Printf ("Can't load %s\n", Cmd_Argv(1)); + return; + } + + e->v.frame = 0; + cl.model_precache[(int)e->v.modelindex] = m; +} + +/* +================== +Host_Viewframe_f +================== +*/ +void Host_Viewframe_f (void) +{ + edict_t *e; + int f; + qmodel_t *m; + + e = FindViewthing (); + if (!e) + return; + m = cl.model_precache[(int)e->v.modelindex]; + + f = atoi(Cmd_Argv(1)); + if (f >= m->numframes) + f = m->numframes - 1; + + e->v.frame = f; +} + + +void PrintFrameName (qmodel_t *m, int frame) +{ + aliashdr_t *hdr; + maliasframedesc_t *pframedesc; + + hdr = (aliashdr_t *)Mod_Extradata (m); + if (!hdr) + return; + pframedesc = &hdr->frames[frame]; + + Con_Printf ("frame %i: %s\n", frame, pframedesc->name); +} + +/* +================== +Host_Viewnext_f +================== +*/ +void Host_Viewnext_f (void) +{ + edict_t *e; + qmodel_t *m; + + e = FindViewthing (); + if (!e) + return; + m = cl.model_precache[(int)e->v.modelindex]; + + e->v.frame = e->v.frame + 1; + if (e->v.frame >= m->numframes) + e->v.frame = m->numframes - 1; + + PrintFrameName (m, e->v.frame); +} + +/* +================== +Host_Viewprev_f +================== +*/ +void Host_Viewprev_f (void) +{ + edict_t *e; + qmodel_t *m; + + e = FindViewthing (); + if (!e) + return; + + m = cl.model_precache[(int)e->v.modelindex]; + + e->v.frame = e->v.frame - 1; + if (e->v.frame < 0) + e->v.frame = 0; + + PrintFrameName (m, e->v.frame); +} + +/* +=============================================================================== + +DEMO LOOP CONTROL + +=============================================================================== +*/ + + +/* +================== +Host_Startdemos_f +================== +*/ +void Host_Startdemos_f (void) +{ + int i, c; + + if (cls.state == ca_dedicated) + return; + + c = Cmd_Argc() - 1; + if (c > MAX_DEMOS) + { + Con_Printf ("Max %i demos in demoloop\n", MAX_DEMOS); + c = MAX_DEMOS; + } + Con_Printf ("%i demo(s) in loop\n", c); + + for (i = 1; i < c + 1; i++) + q_strlcpy (cls.demos[i-1], Cmd_Argv(i), sizeof(cls.demos[0])); + + if (!sv.active && cls.demonum != -1 && !cls.demoplayback) + { + cls.demonum = 0; + if (!fitzmode) + { /* QuakeSpasm customization: */ + /* go straight to menu, no CL_NextDemo */ + cls.demonum = -1; + Cbuf_InsertText("menu_main\n"); + return; + } + CL_NextDemo (); + } + else + { + cls.demonum = -1; + } +} + + +/* +================== +Host_Demos_f + +Return to looping demos +================== +*/ +void Host_Demos_f (void) +{ + if (cls.state == ca_dedicated) + return; + if (cls.demonum == -1) + cls.demonum = 1; + CL_Disconnect_f (); + CL_NextDemo (); +} + +/* +================== +Host_Stopdemo_f + +Return to looping demos +================== +*/ +void Host_Stopdemo_f (void) +{ + if (cls.state == ca_dedicated) + return; + if (!cls.demoplayback) + return; + CL_StopPlayback (); + CL_Disconnect (); +} + +//============================================================================= + +/* +================== +Host_InitCommands +================== +*/ +void Host_InitCommands (void) +{ + Cmd_AddCommand ("maps", Host_Maps_f); //johnfitz + Cmd_AddCommand ("mods", Host_Mods_f); //johnfitz + Cmd_AddCommand ("games", Host_Mods_f); // as an alias to "mods" -- S.A. / QuakeSpasm + Cmd_AddCommand ("mapname", Host_Mapname_f); //johnfitz + Cmd_AddCommand ("randmap", Host_Randmap_f); //ericw + + Cmd_AddCommand ("status", Host_Status_f); + Cmd_AddCommand ("quit", Host_Quit_f); + Cmd_AddCommand ("god", Host_God_f); + Cmd_AddCommand ("notarget", Host_Notarget_f); + Cmd_AddCommand ("fly", Host_Fly_f); + Cmd_AddCommand ("map", Host_Map_f); + Cmd_AddCommand ("restart", Host_Restart_f); + Cmd_AddCommand ("changelevel", Host_Changelevel_f); + Cmd_AddCommand ("connect", Host_Connect_f); + Cmd_AddCommand ("reconnect", Host_Reconnect_f); + Cmd_AddCommand ("name", Host_Name_f); + Cmd_AddCommand ("noclip", Host_Noclip_f); + Cmd_AddCommand ("setpos", Host_SetPos_f); //QuakeSpasm + + Cmd_AddCommand ("say", Host_Say_f); + Cmd_AddCommand ("say_team", Host_Say_Team_f); + Cmd_AddCommand ("tell", Host_Tell_f); + Cmd_AddCommand ("color", Host_Color_f); + Cmd_AddCommand ("kill", Host_Kill_f); + Cmd_AddCommand ("pause", Host_Pause_f); + Cmd_AddCommand ("spawn", Host_Spawn_f); + Cmd_AddCommand ("begin", Host_Begin_f); + Cmd_AddCommand ("prespawn", Host_PreSpawn_f); + Cmd_AddCommand ("kick", Host_Kick_f); + Cmd_AddCommand ("ping", Host_Ping_f); + Cmd_AddCommand ("load", Host_Loadgame_f); + Cmd_AddCommand ("save", Host_Savegame_f); + Cmd_AddCommand ("give", Host_Give_f); + + Cmd_AddCommand ("startdemos", Host_Startdemos_f); + Cmd_AddCommand ("demos", Host_Demos_f); + Cmd_AddCommand ("stopdemo", Host_Stopdemo_f); + + Cmd_AddCommand ("viewmodel", Host_Viewmodel_f); + Cmd_AddCommand ("viewframe", Host_Viewframe_f); + Cmd_AddCommand ("viewnext", Host_Viewnext_f); + Cmd_AddCommand ("viewprev", Host_Viewprev_f); + + Cmd_AddCommand ("mcache", Mod_Print); +} + diff --git a/engine/Quake/image.c b/engine/Quake/image.c new file mode 100644 index 0000000..ece0faa --- /dev/null +++ b/engine/Quake/image.c @@ -0,0 +1,601 @@ +/* +Copyright (C) 1996-2001 Id Software, Inc. +Copyright (C) 2002-2009 John Fitzgibbons and others +Copyright (C) 2010-2014 QuakeSpasm developers + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ +//image.c -- image loading + +#include "quakedef.h" + +#define STB_IMAGE_WRITE_IMPLEMENTATION +#define STB_IMAGE_WRITE_STATIC +#include "stb_image_write.h" + +#define LODEPNG_NO_COMPILE_DECODER +#define LODEPNG_NO_COMPILE_CPP +#define LODEPNG_NO_COMPILE_ANCILLARY_CHUNKS +#define LODEPNG_NO_COMPILE_ERROR_TEXT +#include "lodepng.h" +#include "lodepng.c" + +static char loadfilename[MAX_OSPATH]; //file scope so that error messages can use it + +typedef struct stdio_buffer_s { + FILE *f; + unsigned char buffer[1024]; + int size; + int pos; +} stdio_buffer_t; + +static stdio_buffer_t *Buf_Alloc(FILE *f) +{ + stdio_buffer_t *buf = (stdio_buffer_t *) calloc(1, sizeof(stdio_buffer_t)); + buf->f = f; + return buf; +} + +static void Buf_Free(stdio_buffer_t *buf) +{ + free(buf); +} + +static inline int Buf_GetC(stdio_buffer_t *buf) +{ + if (buf->pos >= buf->size) + { + buf->size = fread(buf->buffer, 1, sizeof(buf->buffer), buf->f); + buf->pos = 0; + + if (buf->size == 0) + return EOF; + } + + return buf->buffer[buf->pos++]; +} + +/* +============ +Image_LoadImage + +returns a pointer to hunk allocated RGBA data + +TODO: search order: tga png jpg pcx lmp +============ +*/ +byte *Image_LoadImage (const char *name, int *width, int *height) +{ + FILE *f; + + q_snprintf (loadfilename, sizeof(loadfilename), "%s.tga", name); + COM_FOpenFile (loadfilename, &f, NULL); + if (f) + return Image_LoadTGA (f, width, height); + + q_snprintf (loadfilename, sizeof(loadfilename), "%s.pcx", name); + COM_FOpenFile (loadfilename, &f, NULL); + if (f) + return Image_LoadPCX (f, width, height); + + return NULL; +} + +//============================================================================== +// +// TGA +// +//============================================================================== + +typedef struct targaheader_s { + unsigned char id_length, colormap_type, image_type; + unsigned short colormap_index, colormap_length; + unsigned char colormap_size; + unsigned short x_origin, y_origin, width, height; + unsigned char pixel_size, attributes; +} targaheader_t; + +#define TARGAHEADERSIZE 18 //size on disk + +targaheader_t targa_header; + +int fgetLittleShort (FILE *f) +{ + byte b1, b2; + + b1 = fgetc(f); + b2 = fgetc(f); + + return (short)(b1 + b2*256); +} + +int fgetLittleLong (FILE *f) +{ + byte b1, b2, b3, b4; + + b1 = fgetc(f); + b2 = fgetc(f); + b3 = fgetc(f); + b4 = fgetc(f); + + return b1 + (b2<<8) + (b3<<16) + (b4<<24); +} + +/* +============ +Image_WriteTGA -- writes RGB or RGBA data to a TGA file + +returns true if successful + +TODO: support BGRA and BGR formats (since opengl can return them, and we don't have to swap) +============ +*/ +qboolean Image_WriteTGA (const char *name, byte *data, int width, int height, int bpp, qboolean upsidedown) +{ + int handle, i, size, temp, bytes; + char pathname[MAX_OSPATH]; + byte header[TARGAHEADERSIZE]; + + Sys_mkdir (com_gamedir); //if we've switched to a nonexistant gamedir, create it now so we don't crash + q_snprintf (pathname, sizeof(pathname), "%s/%s", com_gamedir, name); + handle = Sys_FileOpenWrite (pathname); + if (handle == -1) + return false; + + Q_memset (header, 0, TARGAHEADERSIZE); + header[2] = 2; // uncompressed type + header[12] = width&255; + header[13] = width>>8; + header[14] = height&255; + header[15] = height>>8; + header[16] = bpp; // pixel size + if (upsidedown) + header[17] = 0x20; //upside-down attribute + + // swap red and blue bytes + bytes = bpp/8; + size = width*height*bytes; + for (i=0; i=0; row--) + { + //johnfitz -- fix for upside-down targas + realrow = upside_down ? row : rows - 1 - row; + pixbuf = targa_rgba + realrow*columns*4; + //johnfitz + for(column=0; column=0; row--) + { + //johnfitz -- fix for upside-down targas + realrow = upside_down ? row : rows - 1 - row; + pixbuf = targa_rgba + realrow*columns*4; + //johnfitz + for(column=0; column0) + row--; + else + goto breakOut; + //johnfitz -- fix for upside-down targas + realrow = upside_down ? row : rows - 1 - row; + pixbuf = targa_rgba + realrow*columns*4; + //johnfitz + } + } + } + else // non run-length packet + { + for(j=0;j0) + row--; + else + goto breakOut; + //johnfitz -- fix for upside-down targas + realrow = upside_down ? row : rows - 1 - row; + pixbuf = targa_rgba + realrow*columns*4; + //johnfitz + } + } + } + } + breakOut:; + } + } + + Buf_Free(buf); + fclose(fin); + + *width = (int)(targa_header.width); + *height = (int)(targa_header.height); + return targa_rgba; +} + +//============================================================================== +// +// PCX +// +//============================================================================== + +typedef struct +{ + char signature; + char version; + char encoding; + char bits_per_pixel; + unsigned short xmin,ymin,xmax,ymax; + unsigned short hdpi,vdpi; + byte colortable[48]; + char reserved; + char color_planes; + unsigned short bytes_per_line; + unsigned short palette_type; + char filler[58]; +} pcxheader_t; + +/* +============ +Image_LoadPCX +============ +*/ +byte *Image_LoadPCX (FILE *f, int *width, int *height) +{ + pcxheader_t pcx; + int x, y, w, h, readbyte, runlength, start; + byte *p, *data; + byte palette[768]; + stdio_buffer_t *buf; + + start = ftell (f); //save start of file (since we might be inside a pak file, SEEK_SET might not be the start of the pcx) + + fread(&pcx, sizeof(pcx), 1, f); + pcx.xmin = (unsigned short)LittleShort (pcx.xmin); + pcx.ymin = (unsigned short)LittleShort (pcx.ymin); + pcx.xmax = (unsigned short)LittleShort (pcx.xmax); + pcx.ymax = (unsigned short)LittleShort (pcx.ymax); + pcx.bytes_per_line = (unsigned short)LittleShort (pcx.bytes_per_line); + + if (pcx.signature != 0x0A) + Sys_Error ("'%s' is not a valid PCX file", loadfilename); + + if (pcx.version != 5) + Sys_Error ("'%s' is version %i, should be 5", loadfilename, pcx.version); + + if (pcx.encoding != 1 || pcx.bits_per_pixel != 8 || pcx.color_planes != 1) + Sys_Error ("'%s' has wrong encoding or bit depth", loadfilename); + + w = pcx.xmax - pcx.xmin + 1; + h = pcx.ymax - pcx.ymin + 1; + + data = (byte *) Hunk_Alloc((w*h+1)*4); //+1 to allow reading padding byte on last line + + //load palette + fseek (f, start + com_filesize - 768, SEEK_SET); + fread (palette, 1, 768, f); + + //back to start of image data + fseek (f, start + sizeof(pcx), SEEK_SET); + + buf = Buf_Alloc(f); + + for (y=0; y= 0xC0) + { + runlength = readbyte & 0x3F; + readbyte = Buf_GetC(buf); + } + else + runlength = 1; + + while(runlength--) + { + p[0] = palette[readbyte*3]; + p[1] = palette[readbyte*3+1]; + p[2] = palette[readbyte*3+2]; + p[3] = 255; + p += 4; + x++; + } + } + } + + Buf_Free(buf); + fclose(f); + + *width = w; + *height = h; + return data; +} + +//============================================================================== +// +// STB_IMAGE_WRITE +// +//============================================================================== + +static byte *CopyFlipped(const byte *data, int width, int height, int bpp) +{ + int y, rowsize; + byte *flipped; + + rowsize = width * (bpp / 8); + flipped = (byte *) malloc(height * rowsize); + if (!flipped) + return NULL; + + for (y=0; y +#else +#include +#endif +#else +#include "SDL.h" +#endif + +static qboolean textmode; + +static cvar_t in_debugkeys = {"in_debugkeys", "0", CVAR_NONE}; + +#ifdef __APPLE__ +/* Mouse acceleration needs to be disabled on OS X */ +#define MACOS_X_ACCELERATION_HACK +#endif + +#ifdef MACOS_X_ACCELERATION_HACK +#include +#include +#include +#include +#endif + +// SDL2 Game Controller cvars +cvar_t joy_deadzone = { "joy_deadzone", "0.175", CVAR_ARCHIVE }; +cvar_t joy_deadzone_trigger = { "joy_deadzone_trigger", "0.2", CVAR_ARCHIVE }; +cvar_t joy_sensitivity_yaw = { "joy_sensitivity_yaw", "300", CVAR_ARCHIVE }; +cvar_t joy_sensitivity_pitch = { "joy_sensitivity_pitch", "150", CVAR_ARCHIVE }; +cvar_t joy_invert = { "joy_invert", "0", CVAR_ARCHIVE }; +cvar_t joy_exponent = { "joy_exponent", "3", CVAR_ARCHIVE }; +cvar_t joy_exponent_move = { "joy_exponent_move", "3", CVAR_ARCHIVE }; +cvar_t joy_swapmovelook = { "joy_swapmovelook", "0", CVAR_ARCHIVE }; +cvar_t joy_enable = { "joy_enable", "1", CVAR_ARCHIVE }; + +#if defined(USE_SDL2) +static SDL_JoystickID joy_active_instaceid = -1; +static SDL_GameController *joy_active_controller = NULL; +#endif + +static qboolean no_mouse = false; + +static int buttonremap[] = +{ + K_MOUSE1, + K_MOUSE3, /* right button */ + K_MOUSE2, /* middle button */ +#if !defined(USE_SDL2) /* mousewheel up/down not counted as buttons in SDL2 */ + K_MWHEELUP, + K_MWHEELDOWN, +#endif + K_MOUSE4, + K_MOUSE5 +}; + +/* total accumulated mouse movement since last frame */ +static int total_dx, total_dy = 0; + +static int SDLCALL IN_FilterMouseEvents (const SDL_Event *event) +{ + switch (event->type) + { + case SDL_MOUSEMOTION: + // case SDL_MOUSEBUTTONDOWN: + // case SDL_MOUSEBUTTONUP: + return 0; + } + + return 1; +} + +#if defined(USE_SDL2) +static int SDLCALL IN_SDL2_FilterMouseEvents (void *userdata, SDL_Event *event) +{ + return IN_FilterMouseEvents (event); +} +#endif + +static void IN_BeginIgnoringMouseEvents(void) +{ +#if defined(USE_SDL2) + SDL_EventFilter currentFilter = NULL; + void *currentUserdata = NULL; + SDL_GetEventFilter(¤tFilter, ¤tUserdata); + + if (currentFilter != IN_SDL2_FilterMouseEvents) + SDL_SetEventFilter(IN_SDL2_FilterMouseEvents, NULL); +#else + if (SDL_GetEventFilter() != IN_FilterMouseEvents) + SDL_SetEventFilter(IN_FilterMouseEvents); +#endif +} + +static void IN_EndIgnoringMouseEvents(void) +{ +#if defined(USE_SDL2) + SDL_EventFilter currentFilter; + void *currentUserdata; + if (SDL_GetEventFilter(¤tFilter, ¤tUserdata) == SDL_TRUE) + SDL_SetEventFilter(NULL, NULL); +#else + if (SDL_GetEventFilter() != NULL) + SDL_SetEventFilter(NULL); +#endif +} + +#ifdef MACOS_X_ACCELERATION_HACK +static cvar_t in_disablemacosxmouseaccel = {"in_disablemacosxmouseaccel", "1", CVAR_ARCHIVE}; +static double originalMouseSpeed = -1.0; + +static io_connect_t IN_GetIOHandle(void) +{ + io_connect_t iohandle = MACH_PORT_NULL; + io_service_t iohidsystem = MACH_PORT_NULL; + mach_port_t masterport; + kern_return_t status; + + status = IOMasterPort(MACH_PORT_NULL, &masterport); + if (status != KERN_SUCCESS) + return 0; + + iohidsystem = IORegistryEntryFromPath(masterport, kIOServicePlane ":/IOResources/IOHIDSystem"); + if (!iohidsystem) + return 0; + + status = IOServiceOpen(iohidsystem, mach_task_self(), kIOHIDParamConnectType, &iohandle); + IOObjectRelease(iohidsystem); + + return iohandle; +} + +static void IN_DisableOSXMouseAccel (void) +{ + io_connect_t mouseDev = IN_GetIOHandle(); + if (mouseDev != 0) + { + if (IOHIDGetAccelerationWithKey(mouseDev, CFSTR(kIOHIDMouseAccelerationType), &originalMouseSpeed) == kIOReturnSuccess) + { + if (IOHIDSetAccelerationWithKey(mouseDev, CFSTR(kIOHIDMouseAccelerationType), -1.0) != kIOReturnSuccess) + { + Cvar_Set("in_disablemacosxmouseaccel", "0"); + Con_Printf("WARNING: Could not disable mouse acceleration (failed at IOHIDSetAccelerationWithKey).\n"); + } + } + else + { + Cvar_Set("in_disablemacosxmouseaccel", "0"); + Con_Printf("WARNING: Could not disable mouse acceleration (failed at IOHIDGetAccelerationWithKey).\n"); + } + IOServiceClose(mouseDev); + } + else + { + Cvar_Set("in_disablemacosxmouseaccel", "0"); + Con_Printf("WARNING: Could not disable mouse acceleration (failed at IO_GetIOHandle).\n"); + } +} + +static void IN_ReenableOSXMouseAccel (void) +{ + io_connect_t mouseDev = IN_GetIOHandle(); + if (mouseDev != 0) + { + if (IOHIDSetAccelerationWithKey(mouseDev, CFSTR(kIOHIDMouseAccelerationType), originalMouseSpeed) != kIOReturnSuccess) + Con_Printf("WARNING: Could not re-enable mouse acceleration (failed at IOHIDSetAccelerationWithKey).\n"); + IOServiceClose(mouseDev); + } + else + { + Con_Printf("WARNING: Could not re-enable mouse acceleration (failed at IO_GetIOHandle).\n"); + } + originalMouseSpeed = -1; +} +#endif /* MACOS_X_ACCELERATION_HACK */ + + +void IN_Activate (void) +{ + if (no_mouse) + return; + +#ifdef MACOS_X_ACCELERATION_HACK + /* Save the status of mouse acceleration */ + if (originalMouseSpeed == -1 && in_disablemacosxmouseaccel.value) + IN_DisableOSXMouseAccel(); +#endif + +#if defined(USE_SDL2) + if (SDL_SetRelativeMouseMode(SDL_TRUE) != 0) + { + Con_Printf("WARNING: SDL_SetRelativeMouseMode(SDL_TRUE) failed.\n"); + } +#else + if (SDL_WM_GrabInput(SDL_GRAB_QUERY) != SDL_GRAB_ON) + { + SDL_WM_GrabInput(SDL_GRAB_ON); + if (SDL_WM_GrabInput(SDL_GRAB_QUERY) != SDL_GRAB_ON) + Con_Printf("WARNING: SDL_WM_GrabInput(SDL_GRAB_ON) failed.\n"); + } + + if (SDL_ShowCursor(SDL_QUERY) != SDL_DISABLE) + { + SDL_ShowCursor(SDL_DISABLE); + if (SDL_ShowCursor(SDL_QUERY) != SDL_DISABLE) + Con_Printf("WARNING: SDL_ShowCursor(SDL_DISABLE) failed.\n"); + } +#endif + + IN_EndIgnoringMouseEvents(); + + total_dx = 0; + total_dy = 0; +} + +void IN_Deactivate (qboolean free_cursor) +{ + if (no_mouse) + return; + +#ifdef MACOS_X_ACCELERATION_HACK + if (originalMouseSpeed != -1) + IN_ReenableOSXMouseAccel(); +#endif + + if (free_cursor) + { +#if defined(USE_SDL2) + SDL_SetRelativeMouseMode(SDL_FALSE); +#else + if (SDL_WM_GrabInput(SDL_GRAB_QUERY) != SDL_GRAB_OFF) + { + SDL_WM_GrabInput(SDL_GRAB_OFF); + if (SDL_WM_GrabInput(SDL_GRAB_QUERY) != SDL_GRAB_OFF) + Con_Printf("WARNING: SDL_WM_GrabInput(SDL_GRAB_OFF) failed.\n"); + } + + if (SDL_ShowCursor(SDL_QUERY) != SDL_ENABLE) + { + SDL_ShowCursor(SDL_ENABLE); + if (SDL_ShowCursor(SDL_QUERY) != SDL_ENABLE) + Con_Printf("WARNING: SDL_ShowCursor(SDL_ENABLE) failed.\n"); + } +#endif + } + + /* discard all mouse events when input is deactivated */ + IN_BeginIgnoringMouseEvents(); +} + +void IN_StartupJoystick (void) +{ +#if defined(USE_SDL2) + int i; + int nummappings; + char controllerdb[MAX_OSPATH]; + SDL_GameController *gamecontroller; + + if (COM_CheckParm("-nojoy")) + return; + + if (SDL_InitSubSystem(SDL_INIT_GAMECONTROLLER) == -1 ) + { + Con_Warning("could not initialize SDL Game Controller\n"); + return; + } + + // Load additional SDL2 controller definitions from gamecontrollerdb.txt + q_snprintf (controllerdb, sizeof(controllerdb), "%s/gamecontrollerdb.txt", com_basedir); + nummappings = SDL_GameControllerAddMappingsFromFile(controllerdb); + if (nummappings > 0) + Con_Printf("%d mappings loaded from gamecontrollerdb.txt\n", nummappings); + + // Also try host_parms->userdir + if (host_parms->userdir != host_parms->basedir) + { + q_snprintf (controllerdb, sizeof(controllerdb), "%s/gamecontrollerdb.txt", host_parms->userdir); + nummappings = SDL_GameControllerAddMappingsFromFile(controllerdb); + if (nummappings > 0) + Con_Printf("%d mappings loaded from gamecontrollerdb.txt\n", nummappings); + } + + for (i = 0; i < SDL_NumJoysticks(); i++) + { + const char *joyname = SDL_JoystickNameForIndex(i); + if ( SDL_IsGameController(i) ) + { + const char *controllername = SDL_GameControllerNameForIndex(i); + gamecontroller = SDL_GameControllerOpen(i); + if (gamecontroller) + { + Con_Printf("detected controller: %s\n", controllername != NULL ? controllername : "NULL"); + + joy_active_instaceid = SDL_JoystickInstanceID(SDL_GameControllerGetJoystick(gamecontroller)); + joy_active_controller = gamecontroller; + break; + } + else + { + Con_Warning("failed to open controller: %s\n", controllername != NULL ? controllername : "NULL"); + } + } + else + { + Con_Warning("joystick missing controller mappings: %s\n", joyname != NULL ? joyname : "NULL" ); + } + } +#endif +} + +void IN_ShutdownJoystick (void) +{ +#if defined(USE_SDL2) + SDL_QuitSubSystem(SDL_INIT_GAMECONTROLLER); +#endif +} + +void IN_Init (void) +{ + textmode = Key_TextEntry(); + +#if !defined(USE_SDL2) + SDL_EnableUNICODE (textmode); + if (SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL) == -1) + Con_Printf("Warning: SDL_EnableKeyRepeat() failed.\n"); +#else + if (textmode) + SDL_StartTextInput(); + else + SDL_StopTextInput(); +#endif + if (safemode || COM_CheckParm("-nomouse")) + { + no_mouse = true; + /* discard all mouse events when input is deactivated */ + IN_BeginIgnoringMouseEvents(); + } + +#ifdef MACOS_X_ACCELERATION_HACK + Cvar_RegisterVariable(&in_disablemacosxmouseaccel); +#endif + Cvar_RegisterVariable(&in_debugkeys); + Cvar_RegisterVariable(&joy_sensitivity_yaw); + Cvar_RegisterVariable(&joy_sensitivity_pitch); + Cvar_RegisterVariable(&joy_deadzone); + Cvar_RegisterVariable(&joy_deadzone_trigger); + Cvar_RegisterVariable(&joy_invert); + Cvar_RegisterVariable(&joy_exponent); + Cvar_RegisterVariable(&joy_exponent_move); + Cvar_RegisterVariable(&joy_swapmovelook); + Cvar_RegisterVariable(&joy_enable); + + IN_Activate(); + IN_StartupJoystick(); +} + +void IN_Shutdown (void) +{ + IN_Deactivate(true); + IN_ShutdownJoystick(); +} + +extern cvar_t cl_maxpitch; /* johnfitz -- variable pitch clamping */ +extern cvar_t cl_minpitch; /* johnfitz -- variable pitch clamping */ + + +void IN_MouseMotion(int dx, int dy) +{ + total_dx += dx; + total_dy += dy; +} + +#if defined(USE_SDL2) +typedef struct joyaxis_s +{ + float x; + float y; +} joyaxis_t; + +typedef struct joy_buttonstate_s +{ + qboolean buttondown[SDL_CONTROLLER_BUTTON_MAX]; +} joybuttonstate_t; + +typedef struct axisstate_s +{ + float axisvalue[SDL_CONTROLLER_AXIS_MAX]; // normalized to +-1 +} joyaxisstate_t; + +static joybuttonstate_t joy_buttonstate; +static joyaxisstate_t joy_axisstate; + +static double joy_buttontimer[SDL_CONTROLLER_BUTTON_MAX]; +static double joy_emulatedkeytimer[10]; + +#ifdef __WATCOMC__ /* OW1.9 doesn't have powf() / sqrtf() */ +#define powf pow +#define sqrtf sqrt +#endif + +/* +================ +IN_AxisMagnitude + +Returns the vector length of the given joystick axis +================ +*/ +static vec_t IN_AxisMagnitude(joyaxis_t axis) +{ + vec_t magnitude = sqrtf((axis.x * axis.x) + (axis.y * axis.y)); + return magnitude; +} + +/* +================ +IN_ApplyEasing + +assumes axis values are in [-1, 1] and the vector magnitude has been clamped at 1. +Raises the axis values to the given exponent, keeping signs. +================ +*/ +static joyaxis_t IN_ApplyEasing(joyaxis_t axis, float exponent) +{ + joyaxis_t result = {0}; + vec_t eased_magnitude; + vec_t magnitude = IN_AxisMagnitude(axis); + + if (magnitude == 0) + return result; + + eased_magnitude = powf(magnitude, exponent); + + result.x = axis.x * (eased_magnitude / magnitude); + result.y = axis.y * (eased_magnitude / magnitude); + return result; +} + +/* +================ +IN_ApplyMoveEasing + +same as IN_ApplyEasing, but scales the output by sqrt(2). +this gives diagonal stick inputs coordinates of (+/-1,+/-1). + +forward/back/left/right will return +/- 1.41; this shouldn't be a problem because +you can pull back on the stick to go slower (and the final speed is clamped +by sv_maxspeed). +================ +*/ +static joyaxis_t IN_ApplyMoveEasing(joyaxis_t axis, float exponent) +{ + joyaxis_t result = IN_ApplyEasing(axis, exponent); + const float v = sqrtf(2.0f); + + result.x *= v; + result.y *= v; + + return result; +} + +/* +================ +IN_ApplyDeadzone + +in: raw joystick axis values converted to floats in +-1 +out: applies a circular deadzone and clamps the magnitude at 1 + (my 360 controller is slightly non-circular and the stick travels further on the diagonals) + +deadzone is expected to satisfy 0 < deadzone < 1 + +from https://github.com/jeremiah-sypult/Quakespasm-Rift +and adapted from http://www.third-helix.com/2013/04/12/doing-thumbstick-dead-zones-right.html +================ +*/ +static joyaxis_t IN_ApplyDeadzone(joyaxis_t axis, float deadzone) +{ + joyaxis_t result = {0}; + vec_t magnitude = IN_AxisMagnitude(axis); + + if ( magnitude > deadzone ) { + const vec_t new_magnitude = q_min(1.0, (magnitude - deadzone) / (1.0 - deadzone)); + const vec_t scale = new_magnitude / magnitude; + result.x = axis.x * scale; + result.y = axis.y * scale; + } + + return result; +} + +/* +================ +IN_KeyForControllerButton +================ +*/ +static int IN_KeyForControllerButton(SDL_GameControllerButton button) +{ + switch (button) + { + case SDL_CONTROLLER_BUTTON_A: return K_ABUTTON; + case SDL_CONTROLLER_BUTTON_B: return K_BBUTTON; + case SDL_CONTROLLER_BUTTON_X: return K_XBUTTON; + case SDL_CONTROLLER_BUTTON_Y: return K_YBUTTON; + case SDL_CONTROLLER_BUTTON_BACK: return K_TAB; + case SDL_CONTROLLER_BUTTON_START: return K_ESCAPE; + case SDL_CONTROLLER_BUTTON_LEFTSTICK: return K_LTHUMB; + case SDL_CONTROLLER_BUTTON_RIGHTSTICK: return K_RTHUMB; + case SDL_CONTROLLER_BUTTON_LEFTSHOULDER: return K_LSHOULDER; + case SDL_CONTROLLER_BUTTON_RIGHTSHOULDER: return K_RSHOULDER; + case SDL_CONTROLLER_BUTTON_DPAD_UP: return K_UPARROW; + case SDL_CONTROLLER_BUTTON_DPAD_DOWN: return K_DOWNARROW; + case SDL_CONTROLLER_BUTTON_DPAD_LEFT: return K_LEFTARROW; + case SDL_CONTROLLER_BUTTON_DPAD_RIGHT: return K_RIGHTARROW; + default: return 0; + } +} + +/* +================ +IN_JoyKeyEvent + +Sends a Key_Event if a unpressed -> pressed or pressed -> unpressed transition occurred, +and generates key repeats if the button is held down. + +Adapted from DarkPlaces by lordhavoc +================ +*/ +static void IN_JoyKeyEvent(qboolean wasdown, qboolean isdown, int key, double *timer) +{ + // we can't use `realtime` for key repeats because it is not monotomic + const double currenttime = Sys_DoubleTime(); + + if (wasdown) + { + if (isdown) + { + if (currenttime >= *timer) + { + *timer = currenttime + 0.1; + Key_Event(key, true); + } + } + else + { + *timer = 0; + Key_Event(key, false); + } + } + else + { + if (isdown) + { + *timer = currenttime + 0.5; + Key_Event(key, true); + } + } +} +#endif + +/* +================ +IN_Commands + +Emit key events for game controller buttons, including emulated buttons for analog sticks/triggers +================ +*/ +void IN_Commands (void) +{ +#if defined(USE_SDL2) + joyaxisstate_t newaxisstate; + int i; + const float stickthreshold = 0.9; + const float triggerthreshold = joy_deadzone_trigger.value; + + if (!joy_enable.value) + return; + + if (!joy_active_controller) + return; + + // emit key events for controller buttons + for (i = 0; i < SDL_CONTROLLER_BUTTON_MAX; i++) + { + qboolean newstate = SDL_GameControllerGetButton(joy_active_controller, (SDL_GameControllerButton)i); + qboolean oldstate = joy_buttonstate.buttondown[i]; + + joy_buttonstate.buttondown[i] = newstate; + + // NOTE: This can cause a reentrant call of IN_Commands, via SCR_ModalMessage when confirming a new game. + IN_JoyKeyEvent(oldstate, newstate, IN_KeyForControllerButton((SDL_GameControllerButton)i), &joy_buttontimer[i]); + } + + for (i = 0; i < SDL_CONTROLLER_AXIS_MAX; i++) + { + newaxisstate.axisvalue[i] = SDL_GameControllerGetAxis(joy_active_controller, (SDL_GameControllerAxis)i) / 32768.0f; + } + + // emit emulated arrow keys so the analog sticks can be used in the menu + if (key_dest != key_game) + { + IN_JoyKeyEvent(joy_axisstate.axisvalue[SDL_CONTROLLER_AXIS_LEFTX] < -stickthreshold, newaxisstate.axisvalue[SDL_CONTROLLER_AXIS_LEFTX] < -stickthreshold, K_LEFTARROW, &joy_emulatedkeytimer[0]); + IN_JoyKeyEvent(joy_axisstate.axisvalue[SDL_CONTROLLER_AXIS_LEFTX] > stickthreshold, newaxisstate.axisvalue[SDL_CONTROLLER_AXIS_LEFTX] > stickthreshold, K_RIGHTARROW, &joy_emulatedkeytimer[1]); + IN_JoyKeyEvent(joy_axisstate.axisvalue[SDL_CONTROLLER_AXIS_LEFTY] < -stickthreshold, newaxisstate.axisvalue[SDL_CONTROLLER_AXIS_LEFTY] < -stickthreshold, K_UPARROW, &joy_emulatedkeytimer[2]); + IN_JoyKeyEvent(joy_axisstate.axisvalue[SDL_CONTROLLER_AXIS_LEFTY] > stickthreshold, newaxisstate.axisvalue[SDL_CONTROLLER_AXIS_LEFTY] > stickthreshold, K_DOWNARROW, &joy_emulatedkeytimer[3]); + IN_JoyKeyEvent(joy_axisstate.axisvalue[SDL_CONTROLLER_AXIS_RIGHTX] < -stickthreshold,newaxisstate.axisvalue[SDL_CONTROLLER_AXIS_RIGHTX] < -stickthreshold, K_LEFTARROW, &joy_emulatedkeytimer[4]); + IN_JoyKeyEvent(joy_axisstate.axisvalue[SDL_CONTROLLER_AXIS_RIGHTX] > stickthreshold, newaxisstate.axisvalue[SDL_CONTROLLER_AXIS_RIGHTX] > stickthreshold, K_RIGHTARROW, &joy_emulatedkeytimer[5]); + IN_JoyKeyEvent(joy_axisstate.axisvalue[SDL_CONTROLLER_AXIS_RIGHTY] < -stickthreshold,newaxisstate.axisvalue[SDL_CONTROLLER_AXIS_RIGHTY] < -stickthreshold, K_UPARROW, &joy_emulatedkeytimer[6]); + IN_JoyKeyEvent(joy_axisstate.axisvalue[SDL_CONTROLLER_AXIS_RIGHTY] > stickthreshold, newaxisstate.axisvalue[SDL_CONTROLLER_AXIS_RIGHTY] > stickthreshold, K_DOWNARROW, &joy_emulatedkeytimer[7]); + } + + // emit emulated keys for the analog triggers + IN_JoyKeyEvent(joy_axisstate.axisvalue[SDL_CONTROLLER_AXIS_TRIGGERLEFT] > triggerthreshold, newaxisstate.axisvalue[SDL_CONTROLLER_AXIS_TRIGGERLEFT] > triggerthreshold, K_LTRIGGER, &joy_emulatedkeytimer[8]); + IN_JoyKeyEvent(joy_axisstate.axisvalue[SDL_CONTROLLER_AXIS_TRIGGERRIGHT] > triggerthreshold, newaxisstate.axisvalue[SDL_CONTROLLER_AXIS_TRIGGERRIGHT] > triggerthreshold, K_RTRIGGER, &joy_emulatedkeytimer[9]); + + joy_axisstate = newaxisstate; +#endif +} + +/* +================ +IN_JoyMove +================ +*/ +void IN_JoyMove (usercmd_t *cmd) +{ +#if defined(USE_SDL2) + float speed; + joyaxis_t moveRaw, moveDeadzone, moveEased; + joyaxis_t lookRaw, lookDeadzone, lookEased; + + if (!joy_enable.value) + return; + + if (!joy_active_controller) + return; + + moveRaw.x = joy_axisstate.axisvalue[SDL_CONTROLLER_AXIS_LEFTX]; + moveRaw.y = joy_axisstate.axisvalue[SDL_CONTROLLER_AXIS_LEFTY]; + lookRaw.x = joy_axisstate.axisvalue[SDL_CONTROLLER_AXIS_RIGHTX]; + lookRaw.y = joy_axisstate.axisvalue[SDL_CONTROLLER_AXIS_RIGHTY]; + + if (joy_swapmovelook.value) + { + joyaxis_t temp = moveRaw; + moveRaw = lookRaw; + lookRaw = temp; + } + + moveDeadzone = IN_ApplyDeadzone(moveRaw, joy_deadzone.value); + lookDeadzone = IN_ApplyDeadzone(lookRaw, joy_deadzone.value); + + moveEased = IN_ApplyMoveEasing(moveDeadzone, joy_exponent_move.value); + lookEased = IN_ApplyEasing(lookDeadzone, joy_exponent.value); + + if ((in_speed.state & 1) ^ (cl_alwaysrun.value != 0.0)) + speed = cl_movespeedkey.value; + else + speed = 1; + + cmd->sidemove += (cl_sidespeed.value * speed * moveEased.x); + cmd->forwardmove -= (cl_forwardspeed.value * speed * moveEased.y); + + cl.viewangles[YAW] -= lookEased.x * joy_sensitivity_yaw.value * host_frametime; + cl.viewangles[PITCH] += lookEased.y * joy_sensitivity_pitch.value * (joy_invert.value ? -1.0 : 1.0) * host_frametime; + + if (lookEased.x != 0 || lookEased.y != 0) + V_StopPitchDrift(); + + /* johnfitz -- variable pitch clamping */ + if (cl.viewangles[PITCH] > cl_maxpitch.value) + cl.viewangles[PITCH] = cl_maxpitch.value; + if (cl.viewangles[PITCH] < cl_minpitch.value) + cl.viewangles[PITCH] = cl_minpitch.value; +#endif +} + +void IN_MouseMove(usercmd_t *cmd) +{ + int dmx, dmy; + + dmx = total_dx * sensitivity.value; + dmy = total_dy * sensitivity.value; + + total_dx = 0; + total_dy = 0; + + if ( (in_strafe.state & 1) || (lookstrafe.value && (in_mlook.state & 1) )) + cmd->sidemove += m_side.value * dmx; + else + cl.viewangles[YAW] -= m_yaw.value * dmx; + + if (in_mlook.state & 1) + { + if (dmx || dmy) + V_StopPitchDrift (); + } + + if ( (in_mlook.state & 1) && !(in_strafe.state & 1)) + { + cl.viewangles[PITCH] += m_pitch.value * dmy; + /* johnfitz -- variable pitch clamping */ + if (cl.viewangles[PITCH] > cl_maxpitch.value) + cl.viewangles[PITCH] = cl_maxpitch.value; + if (cl.viewangles[PITCH] < cl_minpitch.value) + cl.viewangles[PITCH] = cl_minpitch.value; + } + else + { + if ((in_strafe.state & 1) && noclip_anglehack) + cmd->upmove -= m_forward.value * dmy; + else + cmd->forwardmove -= m_forward.value * dmy; + } +} + +void IN_Move(usercmd_t *cmd) +{ + IN_JoyMove(cmd); + IN_MouseMove(cmd); +} + +void IN_ClearStates (void) +{ +} + +void IN_UpdateInputMode (void) +{ + qboolean want_textmode = Key_TextEntry(); + if (textmode != want_textmode) + { + textmode = want_textmode; +#if !defined(USE_SDL2) + SDL_EnableUNICODE(textmode); + if (in_debugkeys.value) + Con_Printf("SDL_EnableUNICODE %d time: %g\n", textmode, Sys_DoubleTime()); +#else + if (textmode) + { + SDL_StartTextInput(); + if (in_debugkeys.value) + Con_Printf("SDL_StartTextInput time: %g\n", Sys_DoubleTime()); + } + else + { + SDL_StopTextInput(); + if (in_debugkeys.value) + Con_Printf("SDL_StopTextInput time: %g\n", Sys_DoubleTime()); + } +#endif + } +} + +#if !defined(USE_SDL2) +static inline int IN_SDL_KeysymToQuakeKey(SDLKey sym) +{ + if (sym > SDLK_SPACE && sym < SDLK_DELETE) + return sym; + + switch (sym) + { + case SDLK_TAB: return K_TAB; + case SDLK_RETURN: return K_ENTER; + case SDLK_ESCAPE: return K_ESCAPE; + case SDLK_SPACE: return K_SPACE; + + case SDLK_BACKSPACE: return K_BACKSPACE; + case SDLK_UP: return K_UPARROW; + case SDLK_DOWN: return K_DOWNARROW; + case SDLK_LEFT: return K_LEFTARROW; + case SDLK_RIGHT: return K_RIGHTARROW; + + case SDLK_LALT: return K_ALT; + case SDLK_RALT: return K_ALT; + case SDLK_LCTRL: return K_CTRL; + case SDLK_RCTRL: return K_CTRL; + case SDLK_LSHIFT: return K_SHIFT; + case SDLK_RSHIFT: return K_SHIFT; + + case SDLK_F1: return K_F1; + case SDLK_F2: return K_F2; + case SDLK_F3: return K_F3; + case SDLK_F4: return K_F4; + case SDLK_F5: return K_F5; + case SDLK_F6: return K_F6; + case SDLK_F7: return K_F7; + case SDLK_F8: return K_F8; + case SDLK_F9: return K_F9; + case SDLK_F10: return K_F10; + case SDLK_F11: return K_F11; + case SDLK_F12: return K_F12; + case SDLK_INSERT: return K_INS; + case SDLK_DELETE: return K_DEL; + case SDLK_PAGEDOWN: return K_PGDN; + case SDLK_PAGEUP: return K_PGUP; + case SDLK_HOME: return K_HOME; + case SDLK_END: return K_END; + + case SDLK_NUMLOCK: return K_KP_NUMLOCK; + case SDLK_KP_DIVIDE: return K_KP_SLASH; + case SDLK_KP_MULTIPLY: return K_KP_STAR; + case SDLK_KP_MINUS:return K_KP_MINUS; + case SDLK_KP7: return K_KP_HOME; + case SDLK_KP8: return K_KP_UPARROW; + case SDLK_KP9: return K_KP_PGUP; + case SDLK_KP_PLUS: return K_KP_PLUS; + case SDLK_KP4: return K_KP_LEFTARROW; + case SDLK_KP5: return K_KP_5; + case SDLK_KP6: return K_KP_RIGHTARROW; + case SDLK_KP1: return K_KP_END; + case SDLK_KP2: return K_KP_DOWNARROW; + case SDLK_KP3: return K_KP_PGDN; + case SDLK_KP_ENTER: return K_KP_ENTER; + case SDLK_KP0: return K_KP_INS; + case SDLK_KP_PERIOD: return K_KP_DEL; + + case SDLK_LMETA: return K_COMMAND; + case SDLK_RMETA: return K_COMMAND; + + case SDLK_BREAK: return K_PAUSE; + case SDLK_PAUSE: return K_PAUSE; + + case SDLK_WORLD_18: return '~'; // the '²' key + + default: return 0; + } +} +#endif + +#if defined(USE_SDL2) +static inline int IN_SDL2_ScancodeToQuakeKey(SDL_Scancode scancode) +{ + switch (scancode) + { + case SDL_SCANCODE_TAB: return K_TAB; + case SDL_SCANCODE_RETURN: return K_ENTER; + case SDL_SCANCODE_RETURN2: return K_ENTER; + case SDL_SCANCODE_ESCAPE: return K_ESCAPE; + case SDL_SCANCODE_SPACE: return K_SPACE; + + case SDL_SCANCODE_A: return 'a'; + case SDL_SCANCODE_B: return 'b'; + case SDL_SCANCODE_C: return 'c'; + case SDL_SCANCODE_D: return 'd'; + case SDL_SCANCODE_E: return 'e'; + case SDL_SCANCODE_F: return 'f'; + case SDL_SCANCODE_G: return 'g'; + case SDL_SCANCODE_H: return 'h'; + case SDL_SCANCODE_I: return 'i'; + case SDL_SCANCODE_J: return 'j'; + case SDL_SCANCODE_K: return 'k'; + case SDL_SCANCODE_L: return 'l'; + case SDL_SCANCODE_M: return 'm'; + case SDL_SCANCODE_N: return 'n'; + case SDL_SCANCODE_O: return 'o'; + case SDL_SCANCODE_P: return 'p'; + case SDL_SCANCODE_Q: return 'q'; + case SDL_SCANCODE_R: return 'r'; + case SDL_SCANCODE_S: return 's'; + case SDL_SCANCODE_T: return 't'; + case SDL_SCANCODE_U: return 'u'; + case SDL_SCANCODE_V: return 'v'; + case SDL_SCANCODE_W: return 'w'; + case SDL_SCANCODE_X: return 'x'; + case SDL_SCANCODE_Y: return 'y'; + case SDL_SCANCODE_Z: return 'z'; + + case SDL_SCANCODE_1: return '1'; + case SDL_SCANCODE_2: return '2'; + case SDL_SCANCODE_3: return '3'; + case SDL_SCANCODE_4: return '4'; + case SDL_SCANCODE_5: return '5'; + case SDL_SCANCODE_6: return '6'; + case SDL_SCANCODE_7: return '7'; + case SDL_SCANCODE_8: return '8'; + case SDL_SCANCODE_9: return '9'; + case SDL_SCANCODE_0: return '0'; + + case SDL_SCANCODE_MINUS: return '-'; + case SDL_SCANCODE_EQUALS: return '='; + case SDL_SCANCODE_LEFTBRACKET: return '['; + case SDL_SCANCODE_RIGHTBRACKET: return ']'; + case SDL_SCANCODE_BACKSLASH: return '\\'; + case SDL_SCANCODE_NONUSHASH: return '#'; + case SDL_SCANCODE_SEMICOLON: return ';'; + case SDL_SCANCODE_APOSTROPHE: return '\''; + case SDL_SCANCODE_GRAVE: return '`'; + case SDL_SCANCODE_COMMA: return ','; + case SDL_SCANCODE_PERIOD: return '.'; + case SDL_SCANCODE_SLASH: return '/'; + case SDL_SCANCODE_NONUSBACKSLASH: return '\\'; + + case SDL_SCANCODE_BACKSPACE: return K_BACKSPACE; + case SDL_SCANCODE_UP: return K_UPARROW; + case SDL_SCANCODE_DOWN: return K_DOWNARROW; + case SDL_SCANCODE_LEFT: return K_LEFTARROW; + case SDL_SCANCODE_RIGHT: return K_RIGHTARROW; + + case SDL_SCANCODE_LALT: return K_ALT; + case SDL_SCANCODE_RALT: return K_ALT; + case SDL_SCANCODE_LCTRL: return K_CTRL; + case SDL_SCANCODE_RCTRL: return K_CTRL; + case SDL_SCANCODE_LSHIFT: return K_SHIFT; + case SDL_SCANCODE_RSHIFT: return K_SHIFT; + + case SDL_SCANCODE_F1: return K_F1; + case SDL_SCANCODE_F2: return K_F2; + case SDL_SCANCODE_F3: return K_F3; + case SDL_SCANCODE_F4: return K_F4; + case SDL_SCANCODE_F5: return K_F5; + case SDL_SCANCODE_F6: return K_F6; + case SDL_SCANCODE_F7: return K_F7; + case SDL_SCANCODE_F8: return K_F8; + case SDL_SCANCODE_F9: return K_F9; + case SDL_SCANCODE_F10: return K_F10; + case SDL_SCANCODE_F11: return K_F11; + case SDL_SCANCODE_F12: return K_F12; + case SDL_SCANCODE_INSERT: return K_INS; + case SDL_SCANCODE_DELETE: return K_DEL; + case SDL_SCANCODE_PAGEDOWN: return K_PGDN; + case SDL_SCANCODE_PAGEUP: return K_PGUP; + case SDL_SCANCODE_HOME: return K_HOME; + case SDL_SCANCODE_END: return K_END; + + case SDL_SCANCODE_NUMLOCKCLEAR: return K_KP_NUMLOCK; + case SDL_SCANCODE_KP_DIVIDE: return K_KP_SLASH; + case SDL_SCANCODE_KP_MULTIPLY: return K_KP_STAR; + case SDL_SCANCODE_KP_MINUS: return K_KP_MINUS; + case SDL_SCANCODE_KP_7: return K_KP_HOME; + case SDL_SCANCODE_KP_8: return K_KP_UPARROW; + case SDL_SCANCODE_KP_9: return K_KP_PGUP; + case SDL_SCANCODE_KP_PLUS: return K_KP_PLUS; + case SDL_SCANCODE_KP_4: return K_KP_LEFTARROW; + case SDL_SCANCODE_KP_5: return K_KP_5; + case SDL_SCANCODE_KP_6: return K_KP_RIGHTARROW; + case SDL_SCANCODE_KP_1: return K_KP_END; + case SDL_SCANCODE_KP_2: return K_KP_DOWNARROW; + case SDL_SCANCODE_KP_3: return K_KP_PGDN; + case SDL_SCANCODE_KP_ENTER: return K_KP_ENTER; + case SDL_SCANCODE_KP_0: return K_KP_INS; + case SDL_SCANCODE_KP_PERIOD: return K_KP_DEL; + + case SDL_SCANCODE_LGUI: return K_COMMAND; + case SDL_SCANCODE_RGUI: return K_COMMAND; + + case SDL_SCANCODE_PAUSE: return K_PAUSE; + + default: return 0; + } +} +#endif + +#if defined(USE_SDL2) +static void IN_DebugTextEvent(SDL_Event *event) +{ + Con_Printf ("SDL_TEXTINPUT '%s' time: %g\n", event->text.text, Sys_DoubleTime()); +} +#endif + +static void IN_DebugKeyEvent(SDL_Event *event) +{ + const char *eventtype = (event->key.state == SDL_PRESSED) ? "SDL_KEYDOWN" : "SDL_KEYUP"; +#if defined(USE_SDL2) + Con_Printf ("%s scancode: '%s' keycode: '%s' time: %g\n", + eventtype, + SDL_GetScancodeName(event->key.keysym.scancode), + SDL_GetKeyName(event->key.keysym.sym), + Sys_DoubleTime()); +#else + Con_Printf ("%s sym: '%s' unicode: %04x time: %g\n", + eventtype, + SDL_GetKeyName(event->key.keysym.sym), + (int)event->key.keysym.unicode, + Sys_DoubleTime()); +#endif +} + +void IN_SendKeyEvents (void) +{ + SDL_Event event; + int key; + qboolean down; + + while (SDL_PollEvent(&event)) + { + switch (event.type) + { +#if defined(USE_SDL2) + case SDL_WINDOWEVENT: + if (event.window.event == SDL_WINDOWEVENT_FOCUS_GAINED) + S_UnblockSound(); + else if (event.window.event == SDL_WINDOWEVENT_FOCUS_LOST) + S_BlockSound(); + break; +#else + case SDL_ACTIVEEVENT: + if (event.active.state & (SDL_APPINPUTFOCUS|SDL_APPACTIVE)) + { + if (event.active.gain) + S_UnblockSound(); + else S_BlockSound(); + } + break; +#endif +#if defined(USE_SDL2) + case SDL_TEXTINPUT: + if (in_debugkeys.value) + IN_DebugTextEvent(&event); + + // SDL2: We use SDL_TEXTINPUT for typing in the console / chat. + // SDL2 uses the local keyboard layout and handles modifiers + // (shift for uppercase, etc.) for us. + { + unsigned char *ch; + for (ch = (unsigned char *)event.text.text; *ch; ch++) + if ((*ch & ~0x7F) == 0) + Char_Event (*ch); + } + break; +#endif + case SDL_KEYDOWN: + case SDL_KEYUP: + down = (event.key.state == SDL_PRESSED); + + if (in_debugkeys.value) + IN_DebugKeyEvent(&event); + +#if defined(USE_SDL2) + // SDL2: we interpret the keyboard as the US layout, so keybindings + // are based on key position, not the label on the key cap. + key = IN_SDL2_ScancodeToQuakeKey(event.key.keysym.scancode); +#else + key = IN_SDL_KeysymToQuakeKey(event.key.keysym.sym); +#endif + + Key_Event (key, down); + +#if !defined(USE_SDL2) + if (down && (event.key.keysym.unicode & ~0x7F) == 0) + Char_Event (event.key.keysym.unicode); +#endif + break; + + case SDL_MOUSEBUTTONDOWN: + case SDL_MOUSEBUTTONUP: + if (event.button.button < 1 || + event.button.button > sizeof(buttonremap) / sizeof(buttonremap[0])) + { + Con_Printf ("Ignored event for mouse button %d\n", + event.button.button); + break; + } + Key_Event(buttonremap[event.button.button - 1], event.button.state == SDL_PRESSED); + break; + +#if defined(USE_SDL2) + case SDL_MOUSEWHEEL: + if (event.wheel.y > 0) + { + Key_Event(K_MWHEELUP, true); + Key_Event(K_MWHEELUP, false); + } + else if (event.wheel.y < 0) + { + Key_Event(K_MWHEELDOWN, true); + Key_Event(K_MWHEELDOWN, false); + } + break; +#endif + + case SDL_MOUSEMOTION: + IN_MouseMotion(event.motion.xrel, event.motion.yrel); + break; + +#if defined(USE_SDL2) + case SDL_CONTROLLERDEVICEADDED: + if (joy_active_instaceid == -1) + { + joy_active_controller = SDL_GameControllerOpen(event.cdevice.which); + if (joy_active_controller == NULL) + Con_DPrintf("Couldn't open game controller\n"); + else + { + SDL_Joystick *joy; + joy = SDL_GameControllerGetJoystick(joy_active_controller); + joy_active_instaceid = SDL_JoystickInstanceID(joy); + } + } + else + Con_DPrintf("Ignoring SDL_CONTROLLERDEVICEADDED\n"); + break; + case SDL_CONTROLLERDEVICEREMOVED: + if (joy_active_instaceid != -1 && event.cdevice.which == joy_active_instaceid) + { + SDL_GameControllerClose(joy_active_controller); + joy_active_controller = NULL; + joy_active_instaceid = -1; + } + else + Con_DPrintf("Ignoring SDL_CONTROLLERDEVICEREMOVED\n"); + break; + case SDL_CONTROLLERDEVICEREMAPPED: + Con_DPrintf("Ignoring SDL_CONTROLLERDEVICEREMAPPED\n"); + break; +#endif + + case SDL_QUIT: + CL_Disconnect (); + Sys_Quit (); + break; + + default: + break; + } + } +} + diff --git a/engine/code/input.h b/engine/Quake/input.h similarity index 60% rename from engine/code/input.h rename to engine/Quake/input.h index c3daa17..fe551fb 100644 --- a/engine/code/input.h +++ b/engine/Quake/input.h @@ -1,5 +1,6 @@ /* -Copyright (C) 1996-1997 Id Software, Inc. +Copyright (C) 1996-2001 Id Software, Inc. +Copyright (C) 2010-2014 QuakeSpasm developers This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -8,7 +9,7 @@ of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. @@ -17,6 +18,10 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +#ifndef _QUAKE_INPUT_H +#define _QUAKE_INPUT_H + // input.h -- external (non-keyboard) input devices void IN_Init (void); @@ -26,9 +31,27 @@ void IN_Shutdown (void); void IN_Commands (void); // oportunity for devices to stick commands on the script buffer +// mouse moved by dx and dy pixels +void IN_MouseMotion(int dx, int dy); + + +void IN_SendKeyEvents (void); +// used as a callback for Sys_SendKeyEvents() by some drivers + +void IN_UpdateInputMode (void); +// do stuff if input mode (text/non-text) changes matter to the keyboard driver + void IN_Move (usercmd_t *cmd); // add additional movement on top of the keyboard move cmd void IN_ClearStates (void); // restores all button and position states to defaults +// called when the app becomes active +void IN_Activate (); + +// called when the app becomes inactive +void IN_Deactivate (qboolean free_cursor); + +#endif /* _QUAKE_INPUT_H */ + diff --git a/engine/Quake/keys.c b/engine/Quake/keys.c new file mode 100644 index 0000000..15f77ed --- /dev/null +++ b/engine/Quake/keys.c @@ -0,0 +1,1201 @@ +/* +Copyright (C) 1996-2001 Id Software, Inc. +Copyright (C) 2002-2009 John Fitzgibbons and others +Copyright (C) 2007-2008 Kristian Duske +Copyright (C) 2010-2014 QuakeSpasm developers + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#include "quakedef.h" +#include "arch_def.h" + +/* key up events are sent even if in console mode */ + +#define HISTORY_FILE_NAME "history.txt" + +char key_lines[CMDLINES][MAXCMDLINE]; + +int key_linepos; +int key_insert; //johnfitz -- insert key toggle (for editing) +double key_blinktime; //johnfitz -- fudge cursor blinking to make it easier to spot in certain cases + +int edit_line = 0; +int history_line = 0; + +keydest_t key_dest; + +char *keybindings[MAX_KEYS]; +qboolean consolekeys[MAX_KEYS]; // if true, can't be rebound while in console +qboolean menubound[MAX_KEYS]; // if true, can't be rebound while in menu +qboolean keydown[MAX_KEYS]; + +typedef struct +{ + const char *name; + int keynum; +} keyname_t; + +keyname_t keynames[] = +{ + {"TAB", K_TAB}, + {"ENTER", K_ENTER}, + {"ESCAPE", K_ESCAPE}, + {"SPACE", K_SPACE}, + {"BACKSPACE", K_BACKSPACE}, + {"UPARROW", K_UPARROW}, + {"DOWNARROW", K_DOWNARROW}, + {"LEFTARROW", K_LEFTARROW}, + {"RIGHTARROW", K_RIGHTARROW}, + + {"ALT", K_ALT}, + {"CTRL", K_CTRL}, + {"SHIFT", K_SHIFT}, + +// {"KP_NUMLOCK", K_KP_NUMLOCK}, + {"KP_SLASH", K_KP_SLASH}, + {"KP_STAR", K_KP_STAR}, + {"KP_MINUS", K_KP_MINUS}, + {"KP_HOME", K_KP_HOME}, + {"KP_UPARROW", K_KP_UPARROW}, + {"KP_PGUP", K_KP_PGUP}, + {"KP_PLUS", K_KP_PLUS}, + {"KP_LEFTARROW", K_KP_LEFTARROW}, + {"KP_5", K_KP_5}, + {"KP_RIGHTARROW", K_KP_RIGHTARROW}, + {"KP_END", K_KP_END}, + {"KP_DOWNARROW", K_KP_DOWNARROW}, + {"KP_PGDN", K_KP_PGDN}, + {"KP_ENTER", K_KP_ENTER}, + {"KP_INS", K_KP_INS}, + {"KP_DEL", K_KP_DEL}, + + {"F1", K_F1}, + {"F2", K_F2}, + {"F3", K_F3}, + {"F4", K_F4}, + {"F5", K_F5}, + {"F6", K_F6}, + {"F7", K_F7}, + {"F8", K_F8}, + {"F9", K_F9}, + {"F10", K_F10}, + {"F11", K_F11}, + {"F12", K_F12}, + + {"INS", K_INS}, + {"DEL", K_DEL}, + {"PGDN", K_PGDN}, + {"PGUP", K_PGUP}, + {"HOME", K_HOME}, + {"END", K_END}, + + {"COMMAND", K_COMMAND}, + + {"MOUSE1", K_MOUSE1}, + {"MOUSE2", K_MOUSE2}, + {"MOUSE3", K_MOUSE3}, + {"MOUSE4", K_MOUSE4}, + {"MOUSE5", K_MOUSE5}, + + {"JOY1", K_JOY1}, + {"JOY2", K_JOY2}, + {"JOY3", K_JOY3}, + {"JOY4", K_JOY4}, + + {"AUX1", K_AUX1}, + {"AUX2", K_AUX2}, + {"AUX3", K_AUX3}, + {"AUX4", K_AUX4}, + {"AUX5", K_AUX5}, + {"AUX6", K_AUX6}, + {"AUX7", K_AUX7}, + {"AUX8", K_AUX8}, + {"AUX9", K_AUX9}, + {"AUX10", K_AUX10}, + {"AUX11", K_AUX11}, + {"AUX12", K_AUX12}, + {"AUX13", K_AUX13}, + {"AUX14", K_AUX14}, + {"AUX15", K_AUX15}, + {"AUX16", K_AUX16}, + {"AUX17", K_AUX17}, + {"AUX18", K_AUX18}, + {"AUX19", K_AUX19}, + {"AUX20", K_AUX20}, + {"AUX21", K_AUX21}, + {"AUX22", K_AUX22}, + {"AUX23", K_AUX23}, + {"AUX24", K_AUX24}, + {"AUX25", K_AUX25}, + {"AUX26", K_AUX26}, + {"AUX27", K_AUX27}, + {"AUX28", K_AUX28}, + {"AUX29", K_AUX29}, + {"AUX30", K_AUX30}, + {"AUX31", K_AUX31}, + {"AUX32", K_AUX32}, + + {"PAUSE", K_PAUSE}, + + {"MWHEELUP", K_MWHEELUP}, + {"MWHEELDOWN", K_MWHEELDOWN}, + + {"SEMICOLON", ';'}, // because a raw semicolon seperates commands + + {"BACKQUOTE", '`'}, // because a raw backquote may toggle the console + {"TILDE", '~'}, // because a raw tilde may toggle the console + + {"LTHUMB", K_LTHUMB}, + {"RTHUMB", K_RTHUMB}, + {"LSHOULDER", K_LSHOULDER}, + {"RSHOULDER", K_RSHOULDER}, + {"ABUTTON", K_ABUTTON}, + {"BBUTTON", K_BBUTTON}, + {"XBUTTON", K_XBUTTON}, + {"YBUTTON", K_YBUTTON}, + {"LTRIGGER", K_LTRIGGER}, + {"RTRIGGER", K_RTRIGGER}, + + {NULL, 0} +}; + +/* +============================================================================== + + LINE TYPING INTO THE CONSOLE + +============================================================================== +*/ + +static void PasteToConsole (void) +{ + char *cbd, *p, *workline; + int mvlen, inslen; + + if (key_linepos == MAXCMDLINE - 1) + return; + + if ((cbd = PL_GetClipboardData()) == NULL) + return; + + p = cbd; + while (*p) + { + if (*p == '\n' || *p == '\r' || *p == '\b') + { + *p = 0; + break; + } + p++; + } + + inslen = (int) (p - cbd); + if (inslen + key_linepos > MAXCMDLINE - 1) + inslen = MAXCMDLINE - 1 - key_linepos; + if (inslen <= 0) goto done; + + workline = key_lines[edit_line]; + workline += key_linepos; + mvlen = (int) strlen(workline); + if (mvlen + inslen + key_linepos > MAXCMDLINE - 1) + { + mvlen = MAXCMDLINE - 1 - key_linepos - inslen; + if (mvlen < 0) mvlen = 0; + } + + // insert the string + if (mvlen != 0) + memmove (workline + inslen, workline, mvlen); + memcpy (workline, cbd, inslen); + key_linepos += inslen; + workline[mvlen + inslen] = '\0'; + done: + Z_Free(cbd); +} + +/* +==================== +Key_Console -- johnfitz -- heavy revision + +Interactive line editing and console scrollback +==================== +*/ +extern char *con_text, key_tabpartial[MAXCMDLINE]; +extern int con_current, con_linewidth, con_vislines; + +void Key_Console (int key) +{ + static char current[MAXCMDLINE] = ""; + int history_line_last; + size_t len; + char *workline = key_lines[edit_line]; + + switch (key) + { + case K_ENTER: + case K_KP_ENTER: + key_tabpartial[0] = 0; + Cbuf_AddText (workline + 1); // skip the prompt + Cbuf_AddText ("\n"); + Con_Printf ("%s\n", workline); + + // If the last two lines are identical, skip storing this line in history + // by not incrementing edit_line + if (strcmp(workline, key_lines[(edit_line-1)&31])) + edit_line = (edit_line + 1) & 31; + + history_line = edit_line; + key_lines[edit_line][0] = ']'; + key_lines[edit_line][1] = 0; //johnfitz -- otherwise old history items show up in the new edit line + key_linepos = 1; + if (cls.state == ca_disconnected) + SCR_UpdateScreen (); // force an update, because the command may take some time + return; + + case K_TAB: + Con_TabComplete (); + return; + + case K_BACKSPACE: + key_tabpartial[0] = 0; + if (key_linepos > 1) + { + workline += key_linepos - 1; + if (workline[1]) + { + len = strlen(workline); + memmove (workline, workline + 1, len); + } + else *workline = 0; + key_linepos--; + } + return; + + case K_DEL: + key_tabpartial[0] = 0; + workline += key_linepos; + if (*workline) + { + if (workline[1]) + { + len = strlen(workline); + memmove (workline, workline + 1, len); + } + else *workline = 0; + } + return; + + case K_HOME: + if (keydown[K_CTRL]) + { + //skip initial empty lines + int i, x; + char *line; + + for (i = con_current - con_totallines + 1; i <= con_current; i++) + { + line = con_text + (i % con_totallines) * con_linewidth; + for (x = 0; x < con_linewidth; x++) + { + if (line[x] != ' ') + break; + } + if (x != con_linewidth) + break; + } + con_backscroll = CLAMP(0, con_current-i%con_totallines-2, con_totallines-(glheight>>3)-1); + } + else key_linepos = 1; + return; + + case K_END: + if (keydown[K_CTRL]) + con_backscroll = 0; + else key_linepos = strlen(workline); + return; + + case K_PGUP: + case K_MWHEELUP: + con_backscroll += keydown[K_CTRL] ? ((con_vislines>>3) - 4) : 2; + if (con_backscroll > con_totallines - (vid.height>>3) - 1) + con_backscroll = con_totallines - (vid.height>>3) - 1; + return; + + case K_PGDN: + case K_MWHEELDOWN: + con_backscroll -= keydown[K_CTRL] ? ((con_vislines>>3) - 4) : 2; + if (con_backscroll < 0) + con_backscroll = 0; + return; + + case K_LEFTARROW: + if (key_linepos > 1) + { + key_linepos--; + key_blinktime = realtime; + } + return; + + case K_RIGHTARROW: + len = strlen(workline); + if ((int)len == key_linepos) + { + len = strlen(key_lines[(edit_line + 31) & 31]); + if ((int)len <= key_linepos) + return; // no character to get + workline += key_linepos; + *workline = key_lines[(edit_line + 31) & 31][key_linepos]; + workline[1] = 0; + key_linepos++; + } + else + { + key_linepos++; + key_blinktime = realtime; + } + return; + + case K_UPARROW: + if (history_line == edit_line) + Q_strcpy(current, workline); + + history_line_last = history_line; + do + { + history_line = (history_line - 1) & 31; + } while (history_line != edit_line && !key_lines[history_line][1]); + + if (history_line == edit_line) + { + history_line = history_line_last; + return; + } + + key_tabpartial[0] = 0; + Q_strcpy(workline, key_lines[history_line]); + key_linepos = Q_strlen(workline); + return; + + case K_DOWNARROW: + if (history_line == edit_line) + return; + + key_tabpartial[0] = 0; + + do + { + history_line = (history_line + 1) & 31; + } while (history_line != edit_line && !key_lines[history_line][1]); + + if (history_line == edit_line) + Q_strcpy(workline, current); + else Q_strcpy(workline, key_lines[history_line]); + key_linepos = Q_strlen(workline); + return; + + case K_INS: + if (keydown[K_SHIFT]) /* Shift-Ins paste */ + PasteToConsole(); + else key_insert ^= 1; + return; + + case 'v': + case 'V': +#if defined(PLATFORM_OSX) || defined(PLATFORM_MAC) + if (keydown[K_COMMAND]) { /* Cmd+v paste (Mac-only) */ + PasteToConsole(); + return; + } +#endif + if (keydown[K_CTRL]) { /* Ctrl+v paste */ + PasteToConsole(); + return; + } + break; + + case 'c': + case 'C': + if (keydown[K_CTRL]) { /* Ctrl+C: abort the line -- S.A */ + Con_Printf ("%s\n", workline); + workline[0] = ']'; + workline[1] = 0; + key_linepos = 1; + history_line= edit_line; + return; + } + break; + } +} + +void Char_Console (int key) +{ + size_t len; + char *workline = key_lines[edit_line]; + + if (key_linepos < MAXCMDLINE-1) + { + qboolean endpos = !workline[key_linepos]; + + key_tabpartial[0] = 0; //johnfitz + // if inserting, move the text to the right + if (key_insert && !endpos) + { + workline[MAXCMDLINE - 2] = 0; + workline += key_linepos; + len = strlen(workline) + 1; + memmove (workline + 1, workline, len); + *workline = key; + } + else + { + workline += key_linepos; + *workline = key; + // null terminate if at the end + if (endpos) + workline[1] = 0; + } + key_linepos++; + } +} + +//============================================================================ + +qboolean chat_team = false; +static char chat_buffer[MAXCMDLINE]; +static int chat_bufferlen = 0; + +const char *Key_GetChatBuffer (void) +{ + return chat_buffer; +} + +int Key_GetChatMsgLen (void) +{ + return chat_bufferlen; +} + +void Key_EndChat (void) +{ + key_dest = key_game; + chat_bufferlen = 0; + chat_buffer[0] = 0; +} + +void Key_Message (int key) +{ + switch (key) + { + case K_ENTER: + case K_KP_ENTER: + if (chat_team) + Cbuf_AddText ("say_team \""); + else + Cbuf_AddText ("say \""); + Cbuf_AddText(chat_buffer); + Cbuf_AddText("\"\n"); + + Key_EndChat (); + return; + + case K_ESCAPE: + Key_EndChat (); + return; + + case K_BACKSPACE: + if (chat_bufferlen) + chat_buffer[--chat_bufferlen] = 0; + return; + } +} + +void Char_Message (int key) +{ + if (chat_bufferlen == sizeof(chat_buffer) - 1) + return; // all full + + chat_buffer[chat_bufferlen++] = key; + chat_buffer[chat_bufferlen] = 0; +} + +//============================================================================ + + +/* +=================== +Key_StringToKeynum + +Returns a key number to be used to index keybindings[] by looking at +the given string. Single ascii characters return themselves, while +the K_* names are matched up. +=================== +*/ +int Key_StringToKeynum (const char *str) +{ + keyname_t *kn; + + if (!str || !str[0]) + return -1; + if (!str[1]) + return str[0]; + + for (kn=keynames ; kn->name ; kn++) + { + if (!q_strcasecmp(str,kn->name)) + return kn->keynum; + } + return -1; +} + +/* +=================== +Key_KeynumToString + +Returns a string (either a single ascii char, or a K_* name) for the +given keynum. +FIXME: handle quote special (general escape sequence?) +=================== +*/ +const char *Key_KeynumToString (int keynum) +{ + static char tinystr[2]; + keyname_t *kn; + + if (keynum == -1) + return ""; + if (keynum > 32 && keynum < 127) + { // printable ascii + tinystr[0] = keynum; + tinystr[1] = 0; + return tinystr; + } + + for (kn = keynames; kn->name; kn++) + { + if (keynum == kn->keynum) + return kn->name; + } + + return ""; +} + + +/* +=================== +Key_SetBinding +=================== +*/ +void Key_SetBinding (int keynum, const char *binding) +{ + if (keynum == -1) + return; + +// free old bindings + if (keybindings[keynum]) + { + Z_Free (keybindings[keynum]); + keybindings[keynum] = NULL; + } + +// allocate memory for new binding + if (binding) + keybindings[keynum] = Z_Strdup(binding); +} + +/* +=================== +Key_Unbind_f +=================== +*/ +void Key_Unbind_f (void) +{ + int b; + + if (Cmd_Argc() != 2) + { + Con_Printf ("unbind : remove commands from a key\n"); + return; + } + + b = Key_StringToKeynum (Cmd_Argv(1)); + if (b == -1) + { + Con_Printf ("\"%s\" isn't a valid key\n", Cmd_Argv(1)); + return; + } + + Key_SetBinding (b, NULL); +} + +void Key_Unbindall_f (void) +{ + int i; + + for (i = 0; i < MAX_KEYS; i++) + { + if (keybindings[i]) + Key_SetBinding (i, NULL); + } +} + +/* +============ +Key_Bindlist_f -- johnfitz +============ +*/ +void Key_Bindlist_f (void) +{ + int i, count; + + count = 0; + for (i = 0; i < MAX_KEYS; i++) + { + if (keybindings[i] && *keybindings[i]) + { + Con_SafePrintf (" %s \"%s\"\n", Key_KeynumToString(i), keybindings[i]); + count++; + } + } + Con_SafePrintf ("%i bindings\n", count); +} + +/* +=================== +Key_Bind_f +=================== +*/ +void Key_Bind_f (void) +{ + int i, c, b; + char cmd[1024]; + + c = Cmd_Argc(); + + if (c != 2 && c != 3) + { + Con_Printf ("bind [command] : attach a command to a key\n"); + return; + } + b = Key_StringToKeynum (Cmd_Argv(1)); + if (b == -1) + { + Con_Printf ("\"%s\" isn't a valid key\n", Cmd_Argv(1)); + return; + } + + if (c == 2) + { + if (keybindings[b]) + Con_Printf ("\"%s\" = \"%s\"\n", Cmd_Argv(1), keybindings[b] ); + else + Con_Printf ("\"%s\" is not bound\n", Cmd_Argv(1) ); + return; + } + +// copy the rest of the command line + cmd[0] = 0; + for (i = 2; i < c; i++) + { + q_strlcat (cmd, Cmd_Argv(i), sizeof(cmd)); + if (i != (c-1)) + q_strlcat (cmd, " ", sizeof(cmd)); + } + + Key_SetBinding (b, cmd); +} + +/* +============ +Key_WriteBindings + +Writes lines containing "bind key value" +============ +*/ +void Key_WriteBindings (FILE *f) +{ + int i; + + // unbindall before loading stored bindings: + if (cfg_unbindall.value) + fprintf (f, "unbindall\n"); + for (i = 0; i < MAX_KEYS; i++) + { + if (keybindings[i] && *keybindings[i]) + fprintf (f, "bind \"%s\" \"%s\"\n", Key_KeynumToString(i), keybindings[i]); + } +} + + +void History_Init (void) +{ + int i, c; + FILE *hf; + + for (i = 0; i < CMDLINES; i++) + { + key_lines[i][0] = ']'; + key_lines[i][1] = 0; + } + key_linepos = 1; + + hf = fopen(va("%s/%s", host_parms->userdir, HISTORY_FILE_NAME), "rt"); + if (hf != NULL) + { + do + { + i = 1; + do + { + c = fgetc(hf); + key_lines[edit_line][i++] = c; + } while (c != '\r' && c != '\n' && c != EOF && i < MAXCMDLINE); + key_lines[edit_line][i - 1] = 0; + edit_line = (edit_line + 1) & (CMDLINES - 1); + /* for people using a windows-generated history file on unix: */ + if (c == '\r' || c == '\n') + { + do + c = fgetc(hf); + while (c == '\r' || c == '\n'); + if (c != EOF) + ungetc(c, hf); + else c = 0; /* loop once more, otherwise last line is lost */ + } + } while (c != EOF && edit_line < CMDLINES); + fclose(hf); + + history_line = edit_line = (edit_line - 1) & (CMDLINES - 1); + key_lines[edit_line][0] = ']'; + key_lines[edit_line][1] = 0; + } +} + +void History_Shutdown (void) +{ + int i; + FILE *hf; + + hf = fopen(va("%s/%s", host_parms->userdir, HISTORY_FILE_NAME), "wt"); + if (hf != NULL) + { + i = edit_line; + do + { + i = (i + 1) & (CMDLINES - 1); + } while (i != edit_line && !key_lines[i][1]); + + while (i != edit_line && key_lines[i][1]) + { + fprintf(hf, "%s\n", key_lines[i] + 1); + i = (i + 1) & (CMDLINES - 1); + } + fclose(hf); + } +} + +/* +=================== +Key_Init +=================== +*/ +void Key_Init (void) +{ + int i; + + History_Init (); + + key_blinktime = realtime; //johnfitz + +// +// initialize consolekeys[] +// + for (i = 32; i < 127; i++) // ascii characters + consolekeys[i] = true; + consolekeys['`'] = false; + consolekeys['~'] = false; + consolekeys[K_TAB] = true; + consolekeys[K_ENTER] = true; + consolekeys[K_ESCAPE] = true; + consolekeys[K_BACKSPACE] = true; + consolekeys[K_UPARROW] = true; + consolekeys[K_DOWNARROW] = true; + consolekeys[K_LEFTARROW] = true; + consolekeys[K_RIGHTARROW] = true; + consolekeys[K_CTRL] = true; + consolekeys[K_SHIFT] = true; + consolekeys[K_INS] = true; + consolekeys[K_DEL] = true; + consolekeys[K_PGDN] = true; + consolekeys[K_PGUP] = true; + consolekeys[K_HOME] = true; + consolekeys[K_END] = true; + consolekeys[K_KP_NUMLOCK] = true; + consolekeys[K_KP_SLASH] = true; + consolekeys[K_KP_STAR] = true; + consolekeys[K_KP_MINUS] = true; + consolekeys[K_KP_HOME] = true; + consolekeys[K_KP_UPARROW] = true; + consolekeys[K_KP_PGUP] = true; + consolekeys[K_KP_PLUS] = true; + consolekeys[K_KP_LEFTARROW] = true; + consolekeys[K_KP_5] = true; + consolekeys[K_KP_RIGHTARROW] = true; + consolekeys[K_KP_END] = true; + consolekeys[K_KP_DOWNARROW] = true; + consolekeys[K_KP_PGDN] = true; + consolekeys[K_KP_ENTER] = true; + consolekeys[K_KP_INS] = true; + consolekeys[K_KP_DEL] = true; +#if defined(PLATFORM_OSX) || defined(PLATFORM_MAC) + consolekeys[K_COMMAND] = true; +#endif + consolekeys[K_MWHEELUP] = true; + consolekeys[K_MWHEELDOWN] = true; + +// +// initialize menubound[] +// + menubound[K_ESCAPE] = true; + for (i = 0; i < 12; i++) + menubound[K_F1+i] = true; + +// +// register our functions +// + Cmd_AddCommand ("bindlist",Key_Bindlist_f); //johnfitz + Cmd_AddCommand ("bind",Key_Bind_f); + Cmd_AddCommand ("unbind",Key_Unbind_f); + Cmd_AddCommand ("unbindall",Key_Unbindall_f); +} + +static struct { + qboolean active; + int lastkey; + int lastchar; +} key_inputgrab = { false, -1, -1 }; + +/* +=================== +Key_BeginInputGrab +=================== +*/ +void Key_BeginInputGrab (void) +{ + Key_ClearStates (); + + key_inputgrab.active = true; + key_inputgrab.lastkey = -1; + key_inputgrab.lastchar = -1; + + IN_UpdateInputMode (); +} + +/* +=================== +Key_EndInputGrab +=================== +*/ +void Key_EndInputGrab (void) +{ + Key_ClearStates (); + + key_inputgrab.active = false; + + IN_UpdateInputMode (); +} + +/* +=================== +Key_GetGrabbedInput +=================== +*/ +void Key_GetGrabbedInput (int *lastkey, int *lastchar) +{ + if (lastkey) + *lastkey = key_inputgrab.lastkey; + if (lastchar) + *lastchar = key_inputgrab.lastchar; +} + +/* +=================== +Key_Event + +Called by the system between frames for both key up and key down events +Should NOT be called during an interrupt! +=================== +*/ +void Key_Event (int key, qboolean down) +{ + char *kb; + char cmd[1024]; + + if (key < 0 || key >= MAX_KEYS) + return; + +// handle fullscreen toggle + if (down && (key == K_ENTER || key == K_KP_ENTER) && keydown[K_ALT]) + { + VID_Toggle(); + return; + } + +// handle autorepeats and stray key up events + if (down) + { + if (keydown[key]) + { + if (key_dest == key_game && !con_forcedup) + return; // ignore autorepeats in game mode + } + else if (key >= 200 && !keybindings[key]) + Con_Printf ("%s is unbound, hit F4 to set.\n", Key_KeynumToString(key)); + } + else if (!keydown[key]) + return; // ignore stray key up events + + keydown[key] = down; + + if (key_inputgrab.active) + { + if (down) + key_inputgrab.lastkey = key; + return; + } + +// handle escape specialy, so the user can never unbind it + if (key == K_ESCAPE) + { + if (!down) + return; + + if (keydown[K_SHIFT]) + { + Con_ToggleConsole_f(); + return; + } + + switch (key_dest) + { + case key_message: + Key_Message (key); + break; + case key_menu: + M_Keydown (key); + break; + case key_game: + case key_console: + M_ToggleMenu_f (); + break; + default: + Sys_Error ("Bad key_dest"); + } + + return; + } + +// key up events only generate commands if the game key binding is +// a button command (leading + sign). These will occur even in console mode, +// to keep the character from continuing an action started before a console +// switch. Button commands include the kenum as a parameter, so multiple +// downs can be matched with ups + if (!down) + { + kb = keybindings[key]; + if (kb && kb[0] == '+') + { + sprintf (cmd, "-%s %i\n", kb+1, key); + Cbuf_AddText (cmd); + } + return; + } + +// during demo playback, most keys bring up the main menu + if (cls.demoplayback && down && consolekeys[key] && key_dest == key_game && key != K_TAB) + { + M_ToggleMenu_f (); + return; + } + +// if not a consolekey, send to the interpreter no matter what mode is + if ((key_dest == key_menu && menubound[key]) || + (key_dest == key_console && !consolekeys[key]) || + (key_dest == key_game && (!con_forcedup || !consolekeys[key]))) + { + kb = keybindings[key]; + if (kb) + { + if (kb[0] == '+') + { // button commands add keynum as a parm + sprintf (cmd, "%s %i\n", kb, key); + Cbuf_AddText (cmd); + } + else + { + Cbuf_AddText (kb); + Cbuf_AddText ("\n"); + } + } + return; + } + + if (!down) + return; // other systems only care about key down events + + switch (key_dest) + { + case key_message: + Key_Message (key); + break; + case key_menu: + M_Keydown (key); + break; + + case key_game: + case key_console: + Key_Console (key); + break; + default: + Sys_Error ("Bad key_dest"); + } +} + +/* +=================== +Char_Event + +Called by the backend when the user has input a character. +=================== +*/ +void Char_Event (int key) +{ + if (key < 32 || key > 126) + return; + +#if defined(PLATFORM_OSX) || defined(PLATFORM_MAC) + if (keydown[K_COMMAND]) + return; +#endif + if (keydown[K_CTRL]) + return; + + if (key_inputgrab.active) + { + key_inputgrab.lastchar = key; + return; + } + + switch (key_dest) + { + case key_message: + Char_Message (key); + break; + case key_menu: + M_Charinput (key); + break; + case key_game: + if (!con_forcedup) + break; + /* fallthrough */ + case key_console: + Char_Console (key); + break; + default: + break; + } +} + +/* +=================== +Key_TextEntry +=================== +*/ +qboolean Key_TextEntry (void) +{ + if (key_inputgrab.active) + return true; + + switch (key_dest) + { + case key_message: + return true; + case key_menu: + return M_TextEntry(); + case key_game: + if (!con_forcedup) + return false; + /* fallthrough */ + case key_console: + return true; + default: + return false; + } +} + +/* +=================== +Key_ClearStates +=================== +*/ +void Key_ClearStates (void) +{ + int i; + + for (i = 0; i < MAX_KEYS; i++) + { + if (keydown[i]) + Key_Event (i, false); + } +} + +/* +=================== +Key_UpdateForDest +=================== +*/ +void Key_UpdateForDest (void) +{ + static qboolean forced = false; + + if (cls.state == ca_dedicated) + return; + + switch (key_dest) + { + case key_console: + if (forced && cls.state == ca_connected) + { + forced = false; + IN_Activate(); + key_dest = key_game; + } + break; + case key_game: + if (cls.state != ca_connected) + { + forced = true; + IN_Deactivate(modestate == MS_WINDOWED); + key_dest = key_console; + break; + } + /* fallthrough */ + default: + forced = false; + break; + } +} + diff --git a/engine/code/keys.h b/engine/Quake/keys.h similarity index 59% rename from engine/code/keys.h rename to engine/Quake/keys.h index db13aa9..2e178ef 100644 --- a/engine/code/keys.h +++ b/engine/Quake/keys.h @@ -1,5 +1,7 @@ /* -Copyright (C) 1996-1997 Id Software, Inc. +Copyright (C) 1996-2001 Id Software, Inc. +Copyright (C) 2002-2009 John Fitzgibbons and others +Copyright (C) 2010-2014 QuakeSpasm developers This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -8,7 +10,7 @@ of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. @@ -18,6 +20,9 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#ifndef _QUAKE_KEYS_H +#define _QUAKE_KEYS_H + // // these are the key numbers that should be passed to Key_Event // @@ -56,6 +61,26 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #define K_HOME 151 #define K_END 152 +#define K_KP_NUMLOCK 153 +#define K_KP_SLASH 154 +#define K_KP_STAR 155 +#define K_KP_MINUS 156 +#define K_KP_HOME 157 +#define K_KP_UPARROW 158 +#define K_KP_PGUP 159 +#define K_KP_PLUS 160 +#define K_KP_LEFTARROW 161 +#define K_KP_5 162 +#define K_KP_RIGHTARROW 163 +#define K_KP_END 164 +#define K_KP_DOWNARROW 165 +#define K_KP_PGDN 166 +#define K_KP_ENTER 167 +#define K_KP_INS 168 +#define K_KP_DEL 169 + +#define K_COMMAND 170 + #define K_PAUSE 255 // @@ -72,11 +97,9 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #define K_JOY2 204 #define K_JOY3 205 #define K_JOY4 206 - -// // aux keys are for multi-buttoned joysticks to generate so they can use // the normal binding process -// +// aux29-32: reserved for the HAT (POV) switch motion #define K_AUX1 207 #define K_AUX2 208 #define K_AUX3 209 @@ -113,24 +136,65 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // JACK: Intellimouse(c) Mouse Wheel Support #define K_MWHEELUP 239 -#define K_MWHEELDOWN 240 +#define K_MWHEELDOWN 240 + +// thumb buttons +#define K_MOUSE4 241 +#define K_MOUSE5 242 -// jkrige - mouse thumb buttons -#define K_MOUSE4 241 -#define K_MOUSE5 242 -// jkrige - mouse thumb buttons +// SDL2 game controller keys +#define K_LTHUMB 243 +#define K_RTHUMB 244 +#define K_LSHOULDER 245 +#define K_RSHOULDER 246 +#define K_ABUTTON 247 +#define K_BBUTTON 248 +#define K_XBUTTON 249 +#define K_YBUTTON 250 +#define K_LTRIGGER 251 +#define K_RTRIGGER 252 +#define MAX_KEYS 256 + +#define MAXCMDLINE 256 typedef enum {key_game, key_console, key_message, key_menu} keydest_t; extern keydest_t key_dest; -extern char *keybindings[256]; -extern int key_repeats[256]; -extern int key_count; // incremented every key event -extern int key_lastpress; +extern char *keybindings[MAX_KEYS]; + +#define CMDLINES 64 + +extern char key_lines[CMDLINES][MAXCMDLINE]; +extern int edit_line; +extern int key_linepos; +extern int key_insert; +extern double key_blinktime; + +extern qboolean chat_team; -void Key_Event (int key, qboolean down); void Key_Init (void); -void Key_WriteBindings (FILE *f); -void Key_SetBinding (int keynum, char *binding); void Key_ClearStates (void); +void Key_UpdateForDest (void); + +void Key_BeginInputGrab (void); +void Key_EndInputGrab (void); +void Key_GetGrabbedInput (int *lastkey, int *lastchar); + +void Key_Event (int key, qboolean down); +void Char_Event (int key); +qboolean Key_TextEntry (void); + +void Key_SetBinding (int keynum, const char *binding); +const char *Key_KeynumToString (int keynum); +void Key_WriteBindings (FILE *f); + +void Key_EndChat (void); +const char *Key_GetChatBuffer (void); +int Key_GetChatMsgLen (void); + +void History_Init (void); +void History_Shutdown (void); + +#endif /* _QUAKE_KEYS_H */ + diff --git a/engine/Quake/lodepng.c b/engine/Quake/lodepng.c new file mode 100644 index 0000000..5d8ab4a --- /dev/null +++ b/engine/Quake/lodepng.c @@ -0,0 +1,6113 @@ +/* +LodePNG version 20190824 + +Copyright (c) 2005-2019 Lode Vandevenne + +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any damages +arising from the use of this software. + +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it +freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + + 3. This notice may not be removed or altered from any source + distribution. +*/ + +/* +The manual and changelog are in the header file "lodepng.h" +Rename this file to lodepng.cpp to use it for C++, or to lodepng.c to use it for C. +*/ + +#include "lodepng.h" + +#ifdef LODEPNG_COMPILE_DISK +#include /* LONG_MAX */ +#include /* file handling */ +#endif /* LODEPNG_COMPILE_DISK */ + +#ifdef LODEPNG_COMPILE_ALLOCATORS +#include /* allocations */ +#endif /* LODEPNG_COMPILE_ALLOCATORS */ + +#if defined(_MSC_VER) && (_MSC_VER >= 1310) /*Visual Studio: A few warning types are not desired here.*/ +#pragma warning( disable : 4244 ) /*implicit conversions: not warned by gcc -Wall -Wextra and requires too much casts*/ +#pragma warning( disable : 4996 ) /*VS does not like fopen, but fopen_s is not standard C so unusable here*/ +#endif /*_MSC_VER */ + +const char* LODEPNG_VERSION_STRING = "20190824"; + +/* +This source file is built up in the following large parts. The code sections +with the "LODEPNG_COMPILE_" #defines divide this up further in an intermixed way. +-Tools for C and common code for PNG and Zlib +-C Code for Zlib (huffman, deflate, ...) +-C Code for PNG (file format chunks, adam7, PNG filters, color conversions, ...) +-The C++ wrapper around all of the above +*/ + +/* ////////////////////////////////////////////////////////////////////////// */ +/* ////////////////////////////////////////////////////////////////////////// */ +/* // Tools for C, and common code for PNG and Zlib. // */ +/* ////////////////////////////////////////////////////////////////////////// */ +/* ////////////////////////////////////////////////////////////////////////// */ + +/*The malloc, realloc and free functions defined here with "lodepng_" in front +of the name, so that you can easily change them to others related to your +platform if needed. Everything else in the code calls these. Pass +-DLODEPNG_NO_COMPILE_ALLOCATORS to the compiler, or comment out +#define LODEPNG_COMPILE_ALLOCATORS in the header, to disable the ones here and +define them in your own project's source files without needing to change +lodepng source code. Don't forget to remove "static" if you copypaste them +from here.*/ + +#ifdef LODEPNG_COMPILE_ALLOCATORS +static void* lodepng_malloc(size_t size) { +#ifdef LODEPNG_MAX_ALLOC + if(size > LODEPNG_MAX_ALLOC) return 0; +#endif + return malloc(size); +} + +static void* lodepng_realloc(void* ptr, size_t new_size) { +#ifdef LODEPNG_MAX_ALLOC + if(new_size > LODEPNG_MAX_ALLOC) return 0; +#endif + return realloc(ptr, new_size); +} + +static void lodepng_free(void* ptr) { + free(ptr); +} +#else /*LODEPNG_COMPILE_ALLOCATORS*/ +/* TODO: support giving additional void* payload to the custom allocators */ +void* lodepng_malloc(size_t size); +void* lodepng_realloc(void* ptr, size_t new_size); +void lodepng_free(void* ptr); +#endif /*LODEPNG_COMPILE_ALLOCATORS*/ + +/* restrict is not available in C90, but use it when supported by the compiler */ +#if (defined(__GNUC__) && defined(__GNUC_MINOR__) && (__GNUC__ >= 3) && (__GNUC_MINOR__ >= 1)) ||\ + (defined(_MSC_VER) && (_MSC_VER >= 1400)) || \ + (defined(__WATCOMC__) && (__WATCOMC__ >= 1250) && !defined(__cplusplus)) +#define LODEPNG_RESTRICT __restrict +#else +#define LODEPNG_RESTRICT /* not available */ +#endif + +/* Replacements for C library functions memcpy and strlen, to support those platforms +where a full C library is not available. The compiler can recognize them and compile +to something as fast. */ + +static void lodepng_memcpy(void* LODEPNG_RESTRICT dst, + const void* LODEPNG_RESTRICT src, size_t size) { + size_t i; + for(i = 0; i < size; i++) ((char*)dst)[i] = ((const char*)src)[i]; +} + +/* does not check memory out of bounds, do not use on untrusted data */ +static size_t lodepng_strlen(const char* a) { + const char* orig = a; + /* avoid warning about unused function in case of disabled COMPILE... macros */ + (void)lodepng_strlen; + while(*a) a++; + return (size_t)(a - orig); +} + +#define LODEPNG_MAX(a, b) (((a) > (b)) ? (a) : (b)) +#define LODEPNG_MIN(a, b) (((a) < (b)) ? (a) : (b)) +#define LODEPNG_ABS(x) ((x) < 0 ? -(x) : (x)) + +/* +Often in case of an error a value is assigned to a variable and then it breaks +out of a loop (to go to the cleanup phase of a function). This macro does that. +It makes the error handling code shorter and more readable. + +Example: if(!uivector_resizev(&frequencies_ll, 286, 0)) ERROR_BREAK(83); +*/ +#define CERROR_BREAK(errorvar, code){\ + errorvar = code;\ + break;\ +} + +/*version of CERROR_BREAK that assumes the common case where the error variable is named "error"*/ +#define ERROR_BREAK(code) CERROR_BREAK(error, code) + +/*Set error var to the error code, and return it.*/ +#define CERROR_RETURN_ERROR(errorvar, code){\ + errorvar = code;\ + return code;\ +} + +/*Try the code, if it returns error, also return the error.*/ +#define CERROR_TRY_RETURN(call){\ + unsigned error = call;\ + if(error) return error;\ +} + +/*Set error var to the error code, and return from the void function.*/ +#define CERROR_RETURN(errorvar, code){\ + errorvar = code;\ + return;\ +} + +/* +About uivector, ucvector and string: +-All of them wrap dynamic arrays or text strings in a similar way. +-LodePNG was originally written in C++. The vectors replace the std::vectors that were used in the C++ version. +-The string tools are made to avoid problems with compilers that declare things like strncat as deprecated. +-They're not used in the interface, only internally in this file as static functions. +-As with many other structs in this file, the init and cleanup functions serve as ctor and dtor. +*/ + +#ifdef LODEPNG_COMPILE_ZLIB +#ifdef LODEPNG_COMPILE_ENCODER +/*dynamic vector of unsigned ints*/ +typedef struct uivector { + unsigned* data; + size_t size; /*size in number of unsigned longs*/ + size_t allocsize; /*allocated size in bytes*/ +} uivector; + +static void uivector_cleanup(void* p) { + ((uivector*)p)->size = ((uivector*)p)->allocsize = 0; + lodepng_free(((uivector*)p)->data); + ((uivector*)p)->data = NULL; +} + +/*returns 1 if success, 0 if failure ==> nothing done*/ +static unsigned uivector_reserve(uivector* p, size_t allocsize) { + if(allocsize > p->allocsize) { + size_t newsize = (allocsize > p->allocsize * 2u) ? allocsize : ((allocsize * 3u) >> 1u); + void* data = lodepng_realloc(p->data, newsize); + if(data) { + p->allocsize = newsize; + p->data = (unsigned*)data; + } + else return 0; /*error: not enough memory*/ + } + return 1; +} + +/*returns 1 if success, 0 if failure ==> nothing done*/ +static unsigned uivector_resize(uivector* p, size_t size) { + if(!uivector_reserve(p, size * sizeof(unsigned))) return 0; + p->size = size; + return 1; /*success*/ +} + +/*resize and give all new elements the value*/ +static unsigned uivector_resizev(uivector* p, size_t size, unsigned value) { + size_t oldsize = p->size, i; + if(!uivector_resize(p, size)) return 0; + for(i = oldsize; i < size; ++i) p->data[i] = value; + return 1; +} + +static void uivector_init(uivector* p) { + p->data = NULL; + p->size = p->allocsize = 0; +} + +/*returns 1 if success, 0 if failure ==> nothing done*/ +static unsigned uivector_push_back(uivector* p, unsigned c) { + if(!uivector_resize(p, p->size + 1)) return 0; + p->data[p->size - 1] = c; + return 1; +} +#endif /*LODEPNG_COMPILE_ENCODER*/ +#endif /*LODEPNG_COMPILE_ZLIB*/ + +/* /////////////////////////////////////////////////////////////////////////// */ + +/*dynamic vector of unsigned chars*/ +typedef struct ucvector { + unsigned char* data; + size_t size; /*used size*/ + size_t allocsize; /*allocated size*/ +} ucvector; + +/*returns 1 if success, 0 if failure ==> nothing done*/ +static unsigned ucvector_reserve(ucvector* p, size_t allocsize) { + if(allocsize > p->allocsize) { + size_t newsize = (allocsize > p->allocsize * 2u) ? allocsize : ((allocsize * 3u) >> 1u); + void* data = lodepng_realloc(p->data, newsize); + if(data) { + p->allocsize = newsize; + p->data = (unsigned char*)data; + } + else return 0; /*error: not enough memory*/ + } + return 1; +} + +/*returns 1 if success, 0 if failure ==> nothing done*/ +static unsigned ucvector_resize(ucvector* p, size_t size) { + if(!ucvector_reserve(p, size * sizeof(unsigned char))) return 0; + p->size = size; + return 1; /*success*/ +} + +#ifdef LODEPNG_COMPILE_PNG + +static void ucvector_cleanup(void* p) { + ((ucvector*)p)->size = ((ucvector*)p)->allocsize = 0; + lodepng_free(((ucvector*)p)->data); + ((ucvector*)p)->data = NULL; +} + +static void ucvector_init(ucvector* p) { + p->data = NULL; + p->size = p->allocsize = 0; +} +#endif /*LODEPNG_COMPILE_PNG*/ + +#ifdef LODEPNG_COMPILE_ZLIB +/*you can both convert from vector to buffer&size and vica versa. If you use +init_buffer to take over a buffer and size, it is not needed to use cleanup*/ +static void ucvector_init_buffer(ucvector* p, unsigned char* buffer, size_t size) { + p->data = buffer; + p->allocsize = p->size = size; +} +#endif /*LODEPNG_COMPILE_ZLIB*/ + +#if (defined(LODEPNG_COMPILE_PNG) && defined(LODEPNG_COMPILE_ANCILLARY_CHUNKS)) || defined(LODEPNG_COMPILE_ENCODER) +/*returns 1 if success, 0 if failure ==> nothing done*/ +static unsigned ucvector_push_back(ucvector* p, unsigned char c) { + if(!ucvector_resize(p, p->size + 1)) return 0; + p->data[p->size - 1] = c; + return 1; +} +#endif /*defined(LODEPNG_COMPILE_PNG) || defined(LODEPNG_COMPILE_ENCODER)*/ + + +/* ////////////////////////////////////////////////////////////////////////// */ + +#ifdef LODEPNG_COMPILE_PNG +#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS + +/*free string pointer and set it to NULL*/ +static void string_cleanup(char** out) { + lodepng_free(*out); + *out = NULL; +} + +/* dynamically allocates a new string with a copy of the null terminated input text */ +static char* alloc_string(const char* in) { + size_t insize = lodepng_strlen(in); + char* out = (char*)lodepng_malloc(insize + 1); + if(out) { + size_t i; + for(i = 0; i != insize; ++i) { + out[i] = in[i]; + } + out[i] = 0; + } + return out; +} +#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ +#endif /*LODEPNG_COMPILE_PNG*/ + +/* ////////////////////////////////////////////////////////////////////////// */ + +#if defined(LODEPNG_COMPILE_DECODER) || defined(LODEPNG_COMPILE_PNG) +static unsigned lodepng_read32bitInt(const unsigned char* buffer) { + return (((unsigned)buffer[0] << 24u) | ((unsigned)buffer[1] << 16u) | + ((unsigned)buffer[2] << 8u) | (unsigned)buffer[3]); +} +#endif /*defined(LODEPNG_COMPILE_DECODER) || defined(LODEPNG_COMPILE_PNG)*/ + +#if defined(LODEPNG_COMPILE_PNG) || defined(LODEPNG_COMPILE_ENCODER) +/*buffer must have at least 4 allocated bytes available*/ +static void lodepng_set32bitInt(unsigned char* buffer, unsigned value) { + buffer[0] = (unsigned char)((value >> 24) & 0xff); + buffer[1] = (unsigned char)((value >> 16) & 0xff); + buffer[2] = (unsigned char)((value >> 8) & 0xff); + buffer[3] = (unsigned char)((value ) & 0xff); +} +#endif /*defined(LODEPNG_COMPILE_PNG) || defined(LODEPNG_COMPILE_ENCODER)*/ + +/* ////////////////////////////////////////////////////////////////////////// */ +/* / File IO / */ +/* ////////////////////////////////////////////////////////////////////////// */ + +#ifdef LODEPNG_COMPILE_DISK + +#ifdef LODEPNG_COMPILE_DECODER +/* returns negative value on error. This should be pure C compatible, so no fstat. */ +static long lodepng_filesize(const char* filename) { + FILE* file; + long size; + file = fopen(filename, "rb"); + if(!file) return -1; + + if(fseek(file, 0, SEEK_END) != 0) { + fclose(file); + return -1; + } + + size = ftell(file); + /* It may give LONG_MAX as directory size, this is invalid for us. */ + if(size == LONG_MAX) size = -1; + + fclose(file); + return size; +} + +/* load file into buffer that already has the correct allocated size. Returns error code.*/ +static unsigned lodepng_buffer_file(unsigned char* out, size_t size, const char* filename) { + FILE* file; + size_t readsize; + file = fopen(filename, "rb"); + if(!file) return 78; + + readsize = fread(out, 1, size, file); + fclose(file); + + if (readsize != size) return 78; + return 0; +} + +unsigned lodepng_load_file(unsigned char** out, size_t* outsize, const char* filename) { + long size = lodepng_filesize(filename); + if (size < 0) return 78; + *outsize = (size_t)size; + + *out = (unsigned char*)lodepng_malloc((size_t)size); + if(!(*out) && size > 0) return 83; /*the above malloc failed*/ + + return lodepng_buffer_file(*out, (size_t)size, filename); +} +#endif /*LODEPNG_COMPILE_DECODER*/ + +/*write given buffer to the file, overwriting the file, it doesn't append to it.*/ +unsigned lodepng_save_file(const unsigned char* buffer, size_t buffersize, const char* filename) { + FILE* file; + file = fopen(filename, "wb" ); + if(!file) return 79; + fwrite(buffer, 1, buffersize, file); + fclose(file); + return 0; +} + +#endif /*LODEPNG_COMPILE_DISK*/ + +/* ////////////////////////////////////////////////////////////////////////// */ +/* ////////////////////////////////////////////////////////////////////////// */ +/* // End of common code and tools. Begin of Zlib related code. // */ +/* ////////////////////////////////////////////////////////////////////////// */ +/* ////////////////////////////////////////////////////////////////////////// */ + +#ifdef LODEPNG_COMPILE_ZLIB +#ifdef LODEPNG_COMPILE_ENCODER + +typedef struct { + ucvector* data; + size_t bp; +} LodePNGBitWriter; + +void LodePNGBitWriter_init(LodePNGBitWriter* writer, ucvector* data) { + writer->data = data; + writer->bp = 0; +} + +/*TODO: this ignores potential out of memory errors*/ +#define WRITEBIT(/*size_t**/ writer, /*unsigned char*/ bit){\ + /* append new byte */\ + if(((writer->bp) & 7u) == 0) ucvector_push_back(writer->data, (unsigned char)0);\ + (writer->data->data[writer->data->size - 1]) |= (bit << ((writer->bp) & 7u));\ + ++writer->bp;\ +} + +/* LSB of value is written first, and LSB of bytes is used first */ +static void writeBits(LodePNGBitWriter* writer, unsigned value, size_t nbits) { + if(nbits == 1) { /* compiler should statically compile this case if nbits == 1 */ + WRITEBIT(writer, value); + } else { + /* TODO: increase output size nly once here rather than in each WRITEBIT */ + size_t i; + for(i = 0; i != nbits; ++i) { + WRITEBIT(writer, (unsigned char)((value >> i) & 1)); + } + } +} + +/* This one is to use for adding huffman symbol, the value bits are written MSB first */ +static void writeBitsReversed(LodePNGBitWriter* writer, unsigned value, size_t nbits) { + size_t i; + for(i = 0; i != nbits; ++i) { + /* TODO: increase output size only once here rather than in each WRITEBIT */ + WRITEBIT(writer, (unsigned char)((value >> (nbits - 1u - i)) & 1u)); + } +} +#endif /*LODEPNG_COMPILE_ENCODER*/ + +#ifdef LODEPNG_COMPILE_DECODER + +typedef struct { + const unsigned char* data; + size_t size; /*size of data in bytes*/ + size_t bitsize; /*size of data in bits, end of valid bp values, should be 8*size*/ + size_t bp; + unsigned buffer; /*buffer for reading bits. NOTE: 'unsigned' must support at least 32 bits*/ +} LodePNGBitReader; + +/* data size argument is in bytes */ +void LodePNGBitReader_init(LodePNGBitReader* reader, const unsigned char* data, size_t size) { + reader->data = data; + reader->size = size; + reader->bitsize = size << 3u; /* size in bits */ + reader->bp = 0; + reader->buffer = 0; +} + +/*Ensures the reader can at least read nbits bits in one or more readBits calls. +Returns 0 if there are enough bits available, or amount of shortage of bits if not. +The 'nbits' parameter must be <= 17. */ +static unsigned ensureBits(LodePNGBitReader* reader, size_t nbits) { + if(nbits == 1) { /*the compiler is intended to perform do this 'if' statically for efficiency*/ + if(reader->bp >= reader->bitsize) return 1; + reader->buffer = (unsigned)reader->data[reader->bp >> 3u] >> (reader->bp & 7u); + return 0; + } else { + size_t start = reader->bp >> 3u; + unsigned rem = reader->bitsize - reader->bp; + if(rem >= 24) { + reader->buffer = (unsigned)(reader->data[start + 0] | (unsigned)((reader->data[start + 1] << 8u)) | + (unsigned)(reader->data[start + 2] << 16u)) >> (reader->bp & 7u); + return 0; + } else { + size_t size = reader->size; + reader->buffer = 0; + if(start + 0 < size) reader->buffer |= reader->data[start + 0]; + if(start + 1 < size) reader->buffer |= (unsigned)(reader->data[start + 1] << 8u); + if(start + 2 < size) reader->buffer |= (unsigned)(reader->data[start + 2] << 16u); + reader->buffer >>= (reader->bp & 7u); + return (rem >= nbits) ? 0 : (nbits - rem); + } + } +} + +/* Get bits without advancing the bit pointer. Must have enough bits available with ensureBits */ +static unsigned peekBits(LodePNGBitReader* reader, size_t nbits) { + return reader->buffer & ((1u << nbits) - 1u); +} + +/* Must have enough bits available with ensureBits */ +static void advanceBits(LodePNGBitReader* reader, size_t nbits) { + reader->buffer >>= nbits; + reader->bp += nbits; +} + +/* Must have enough bits available with ensureBits */ +static unsigned readBits(LodePNGBitReader* reader, size_t nbits) { + unsigned result = peekBits(reader, nbits); + advanceBits(reader, nbits); + return result; +} +#endif /*LODEPNG_COMPILE_DECODER*/ + +static unsigned reverseBits(unsigned bits, unsigned num) { + /*TODO: implement faster lookup table based version when needed*/ + unsigned i, result = 0; + for(i = 0; i < num; i++) result |= ((bits >> (num - i - 1u)) & 1u) << i; + return result; +} + +/* ////////////////////////////////////////////////////////////////////////// */ +/* / Deflate - Huffman / */ +/* ////////////////////////////////////////////////////////////////////////// */ + +#define FIRST_LENGTH_CODE_INDEX 257 +#define LAST_LENGTH_CODE_INDEX 285 +/*256 literals, the end code, some length codes, and 2 unused codes*/ +#define NUM_DEFLATE_CODE_SYMBOLS 288 +/*the distance codes have their own symbols, 30 used, 2 unused*/ +#define NUM_DISTANCE_SYMBOLS 32 +/*the code length codes. 0-15: code lengths, 16: copy previous 3-6 times, 17: 3-10 zeros, 18: 11-138 zeros*/ +#define NUM_CODE_LENGTH_CODES 19 + +/*the base lengths represented by codes 257-285*/ +static const unsigned LENGTHBASE[29] + = {3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, 35, 43, 51, 59, + 67, 83, 99, 115, 131, 163, 195, 227, 258}; + +/*the extra bits used by codes 257-285 (added to base length)*/ +static const unsigned LENGTHEXTRA[29] + = {0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, + 4, 4, 4, 4, 5, 5, 5, 5, 0}; + +/*the base backwards distances (the bits of distance codes appear after length codes and use their own huffman tree)*/ +static const unsigned DISTANCEBASE[30] + = {1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385, 513, + 769, 1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577}; + +/*the extra bits of backwards distances (added to base)*/ +static const unsigned DISTANCEEXTRA[30] + = {0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, + 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13}; + +/*the order in which "code length alphabet code lengths" are stored, out of this +the huffman tree of the dynamic huffman tree lengths is generated*/ +static const unsigned CLCL_ORDER[NUM_CODE_LENGTH_CODES] + = {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; + +/* ////////////////////////////////////////////////////////////////////////// */ + +/* +Huffman tree struct, containing multiple representations of the tree +*/ +typedef struct HuffmanTree { + unsigned* codes; /*the huffman codes (bit patterns representing the symbols)*/ + unsigned* lengths; /*the lengths of the huffman codes*/ + unsigned maxbitlen; /*maximum number of bits a single code can get*/ + unsigned numcodes; /*number of symbols in the alphabet = number of codes*/ + /* for reading only */ + unsigned* table_len; /*length of symbol from lookup table, or max length if secondary lookup needed*/ + unsigned* table_value; /*value of symbol from lookup table, or pointer to secondary table if needed*/ +} HuffmanTree; + +/*function used for debug purposes to draw the tree in ascii art with C++*/ +/* +static void HuffmanTree_draw(HuffmanTree* tree) { + std::cout << "tree. length: " << tree->numcodes << " maxbitlen: " << tree->maxbitlen << std::endl; + for(size_t i = 0; i != tree->codes.size; ++i) { + if(tree->lengths.data[i]) + std::cout << i << " " << tree->codes.data[i] << " " << tree->lengths.data[i] << std::endl; + } + std::cout << std::endl; +}*/ + +static void HuffmanTree_init(HuffmanTree* tree) { + tree->codes = 0; + tree->lengths = 0; + tree->table_len = 0; + tree->table_value = 0; +} + +static void HuffmanTree_cleanup(HuffmanTree* tree) { + lodepng_free(tree->codes); + lodepng_free(tree->lengths); + lodepng_free(tree->table_len); + lodepng_free(tree->table_value); +} + +/* amount of bits for first huffman table lookup, see HuffmanTree_makeTable and huffmanDecodeSymbol.*/ +#define FIRSTBITS 8u + +/* make table for huffman decoding */ +static unsigned HuffmanTree_makeTable(HuffmanTree* tree) { + static const unsigned headsize = 1u << FIRSTBITS; /*size of the first table*/ + static const unsigned mask = (1u << FIRSTBITS) /*headsize*/ - 1u; + size_t i, pointer, size; /*total table size*/ + unsigned* maxlens = (unsigned*)lodepng_malloc(headsize * sizeof(unsigned)); + if(!maxlens) return 83; /*alloc fail*/ + + /* compute maxlens: max total bit length of symbols sharing prefix in the first table*/ + for(i = 0; i < headsize; ++i) maxlens[i] = 0; + for(i = 0; i < tree->numcodes; i++) { + unsigned symbol = tree->codes[i]; + unsigned l = tree->lengths[i]; + unsigned index; + if(l <= FIRSTBITS) continue; /*symbols that fit in first table don't increase secondary table size*/ + /*get the FIRSTBITS MSBs, the MSBs of the symbol are encoded first. See later comment about the reversing*/ + index = reverseBits(symbol >> (l - FIRSTBITS), FIRSTBITS); + maxlens[index] = LODEPNG_MAX(maxlens[index], l); + } + /* compute total table size: size of first table plus all secondary tables for symbols longer than FIRSTBITS */ + size = headsize; + for(i = 0; i < headsize; ++i) { + unsigned l = maxlens[i]; + if(l > FIRSTBITS) size += (1u << (l - FIRSTBITS)); + } + tree->table_len = (unsigned*)lodepng_malloc(size * sizeof(unsigned)); + tree->table_value = (unsigned*)lodepng_malloc(size * sizeof(unsigned)); + if(!tree->table_len || !tree->table_value) { + lodepng_free(maxlens); + return 83; /*alloc fail*/ + } + /*initialize with an invalid length to indicate unused entries*/ + for(i = 0; i < size; ++i) tree->table_len[i] = 16; + + /*fill in the first table for long symbols: max prefix size and pointer to secondary tables*/ + pointer = headsize; + for(i = 0; i < headsize; ++i) { + unsigned l = maxlens[i]; + if(l <= FIRSTBITS) continue; + tree->table_len[i] = l; + tree->table_value[i] = pointer; + pointer += (1u << (l - FIRSTBITS)); + } + lodepng_free(maxlens); + + /*fill in the first table for short symbols, or secondary table for long symbols*/ + for(i = 0; i < tree->numcodes; ++i) { + unsigned l = tree->lengths[i]; + unsigned symbol = tree->codes[i]; /*the huffman bit pattern. i itself is the value.*/ + /*reverse bits, because the huffman bits are given in MSB first order but the bit reader reads LSB first*/ + unsigned reverse = reverseBits(symbol, l); + if(l == 0) { + continue; + } else if(l <= FIRSTBITS) { + /*short symbol, fully in first table, replicated num times if l < FIRSTBITS*/ + unsigned num = 1u << (FIRSTBITS - l); + unsigned j; + for(j = 0; j < num; ++j) { + /*bit reader will read the l bits of symbol first, the remaining FIRSTBITS - l bits go to the MSB's*/ + unsigned index = reverse | (j << l); + if(tree->table_len[index] != 16) return 55; /*invalid tree: long symbol shares prefix with short symbol*/ + tree->table_len[index] = l; + tree->table_value[index] = i; + } + } else { + /*long symbol, shares prefix with other long symbols in first lookup table, needs second lookup*/ + /*the FIRSTBITS MSBs of the symbol are the first table index*/ + unsigned index = reverse & mask; + unsigned maxlen = tree->table_len[index]; + /*log2 of secondary table length, should be >= l - FIRSTBITS*/ + unsigned tablelen = maxlen - FIRSTBITS; + unsigned start = tree->table_value[index]; /*starting index in secondary table*/ + unsigned num = 1u << (tablelen - (l - FIRSTBITS)); /*amount of entries of this symbol in secondary table*/ + unsigned j; + if(maxlen < l) return 55; /*invalid tree: long symbol shares prefix with short symbol*/ + for(j = 0; j < num; ++j) { + unsigned reverse2 = reverse >> FIRSTBITS; /* l - FIRSTBITS bits */ + unsigned index2 = start + (reverse2 | (j << (l - FIRSTBITS))); + tree->table_len[index2] = l; + tree->table_value[index2] = i; + } + } + } + + /* A good huffman tree has N * 2 - 1 nodes, of which N - 1 are internal nodes. + If that is not the case (due to too long length codes), the table will not + have been fully used, and this is an error (not all bit combinations can be + decoded): an oversubscribed huffman tree, indicated by error 55. */ + for(i = 0; i < size; ++i) { + if(tree->table_len[i] == 16) return 55; + } + + return 0; +} + +/* +Second step for the ...makeFromLengths and ...makeFromFrequencies functions. +numcodes, lengths and maxbitlen must already be filled in correctly. return +value is error. +*/ +static unsigned HuffmanTree_makeFromLengths2(HuffmanTree* tree) { + unsigned* blcount; + unsigned* nextcode; + unsigned error = 0; + unsigned bits, n; + + tree->codes = (unsigned*)lodepng_malloc(tree->numcodes * sizeof(unsigned)); + blcount = (unsigned*)lodepng_malloc((tree->maxbitlen + 1) * sizeof(unsigned)); + nextcode = (unsigned*)lodepng_malloc((tree->maxbitlen + 1) * sizeof(unsigned)); + if(!tree->codes || !blcount || !nextcode) error = 83; /*alloc fail*/ + + if(!error) { + for(n = 0; n != tree->maxbitlen + 1; n++) blcount[n] = nextcode[n] = 0; + /*step 1: count number of instances of each code length*/ + for(bits = 0; bits != tree->numcodes; ++bits) ++blcount[tree->lengths[bits]]; + /*step 2: generate the nextcode values*/ + for(bits = 1; bits <= tree->maxbitlen; ++bits) { + nextcode[bits] = (nextcode[bits - 1] + blcount[bits - 1]) << 1; + } + /*step 3: generate all the codes*/ + for(n = 0; n != tree->numcodes; ++n) { + if(tree->lengths[n] != 0) { + tree->codes[n] = nextcode[tree->lengths[n]]++; + /*remove superfluous bits from the code*/ + tree->codes[n] &= ((1u << tree->lengths[n]) - 1u); + } + } + } + + lodepng_free(blcount); + lodepng_free(nextcode); + + if(!error) error = HuffmanTree_makeTable(tree); + return error; +} + +/* +given the code lengths (as stored in the PNG file), generate the tree as defined +by Deflate. maxbitlen is the maximum bits that a code in the tree can have. +return value is error. +*/ +static unsigned HuffmanTree_makeFromLengths(HuffmanTree* tree, const unsigned* bitlen, + size_t numcodes, unsigned maxbitlen) { + unsigned i; + tree->lengths = (unsigned*)lodepng_malloc(numcodes * sizeof(unsigned)); + if(!tree->lengths) return 83; /*alloc fail*/ + for(i = 0; i != numcodes; ++i) tree->lengths[i] = bitlen[i]; + tree->numcodes = (unsigned)numcodes; /*number of symbols*/ + tree->maxbitlen = maxbitlen; + return HuffmanTree_makeFromLengths2(tree); +} + +#ifdef LODEPNG_COMPILE_ENCODER + +/*BPM: Boundary Package Merge, see "A Fast and Space-Economical Algorithm for Length-Limited Coding", +Jyrki Katajainen, Alistair Moffat, Andrew Turpin, 1995.*/ + +/*chain node for boundary package merge*/ +typedef struct BPMNode { + int weight; /*the sum of all weights in this chain*/ + unsigned index; /*index of this leaf node (called "count" in the paper)*/ + struct BPMNode* tail; /*the next nodes in this chain (null if last)*/ + int in_use; +} BPMNode; + +/*lists of chains*/ +typedef struct BPMLists { + /*memory pool*/ + unsigned memsize; + BPMNode* memory; + unsigned numfree; + unsigned nextfree; + BPMNode** freelist; + /*two heads of lookahead chains per list*/ + unsigned listsize; + BPMNode** chains0; + BPMNode** chains1; +} BPMLists; + +/*creates a new chain node with the given parameters, from the memory in the lists */ +static BPMNode* bpmnode_create(BPMLists* lists, int weight, unsigned index, BPMNode* tail) { + unsigned i; + BPMNode* result; + + /*memory full, so garbage collect*/ + if(lists->nextfree >= lists->numfree) { + /*mark only those that are in use*/ + for(i = 0; i != lists->memsize; ++i) lists->memory[i].in_use = 0; + for(i = 0; i != lists->listsize; ++i) { + BPMNode* node; + for(node = lists->chains0[i]; node != 0; node = node->tail) node->in_use = 1; + for(node = lists->chains1[i]; node != 0; node = node->tail) node->in_use = 1; + } + /*collect those that are free*/ + lists->numfree = 0; + for(i = 0; i != lists->memsize; ++i) { + if(!lists->memory[i].in_use) lists->freelist[lists->numfree++] = &lists->memory[i]; + } + lists->nextfree = 0; + } + + result = lists->freelist[lists->nextfree++]; + result->weight = weight; + result->index = index; + result->tail = tail; + return result; +} + +/*sort the leaves with stable mergesort*/ +static void bpmnode_sort(BPMNode* leaves, size_t num) { + BPMNode* mem = (BPMNode*)lodepng_malloc(sizeof(*leaves) * num); + size_t width, counter = 0; + for(width = 1; width < num; width *= 2) { + BPMNode* a = (counter & 1) ? mem : leaves; + BPMNode* b = (counter & 1) ? leaves : mem; + size_t p; + for(p = 0; p < num; p += 2 * width) { + size_t q = (p + width > num) ? num : (p + width); + size_t r = (p + 2 * width > num) ? num : (p + 2 * width); + size_t i = p, j = q, k; + for(k = p; k < r; k++) { + if(i < q && (j >= r || a[i].weight <= a[j].weight)) b[k] = a[i++]; + else b[k] = a[j++]; + } + } + counter++; + } + if(counter & 1) lodepng_memcpy(leaves, mem, sizeof(*leaves) * num); + lodepng_free(mem); +} + +/*Boundary Package Merge step, numpresent is the amount of leaves, and c is the current chain.*/ +static void boundaryPM(BPMLists* lists, BPMNode* leaves, size_t numpresent, int c, int num) { + unsigned lastindex = lists->chains1[c]->index; + + if(c == 0) { + if(lastindex >= numpresent) return; + lists->chains0[c] = lists->chains1[c]; + lists->chains1[c] = bpmnode_create(lists, leaves[lastindex].weight, lastindex + 1, 0); + } else { + /*sum of the weights of the head nodes of the previous lookahead chains.*/ + int sum = lists->chains0[c - 1]->weight + lists->chains1[c - 1]->weight; + lists->chains0[c] = lists->chains1[c]; + if(lastindex < numpresent && sum > leaves[lastindex].weight) { + lists->chains1[c] = bpmnode_create(lists, leaves[lastindex].weight, lastindex + 1, lists->chains1[c]->tail); + return; + } + lists->chains1[c] = bpmnode_create(lists, sum, lastindex, lists->chains1[c - 1]); + /*in the end we are only interested in the chain of the last list, so no + need to recurse if we're at the last one (this gives measurable speedup)*/ + if(num + 1 < (int)(2 * numpresent - 2)) { + boundaryPM(lists, leaves, numpresent, c - 1, num); + boundaryPM(lists, leaves, numpresent, c - 1, num); + } + } +} + +unsigned lodepng_huffman_code_lengths(unsigned* lengths, const unsigned* frequencies, + size_t numcodes, unsigned maxbitlen) { + unsigned error = 0; + unsigned i; + size_t numpresent = 0; /*number of symbols with non-zero frequency*/ + BPMNode* leaves; /*the symbols, only those with > 0 frequency*/ + + if(numcodes == 0) return 80; /*error: a tree of 0 symbols is not supposed to be made*/ + if((1u << maxbitlen) < (unsigned)numcodes) return 80; /*error: represent all symbols*/ + + leaves = (BPMNode*)lodepng_malloc(numcodes * sizeof(*leaves)); + if(!leaves) return 83; /*alloc fail*/ + + for(i = 0; i != numcodes; ++i) { + if(frequencies[i] > 0) { + leaves[numpresent].weight = (int)frequencies[i]; + leaves[numpresent].index = i; + ++numpresent; + } + } + + for(i = 0; i != numcodes; ++i) lengths[i] = 0; + + /*ensure at least two present symbols. There should be at least one symbol + according to RFC 1951 section 3.2.7. Some decoders incorrectly require two. To + make these work as well ensure there are at least two symbols. The + Package-Merge code below also doesn't work correctly if there's only one + symbol, it'd give it the theoritical 0 bits but in practice zlib wants 1 bit*/ + if(numpresent == 0) { + lengths[0] = lengths[1] = 1; /*note that for RFC 1951 section 3.2.7, only lengths[0] = 1 is needed*/ + } else if(numpresent == 1) { + lengths[leaves[0].index] = 1; + lengths[leaves[0].index == 0 ? 1 : 0] = 1; + } else { + BPMLists lists; + BPMNode* node; + + bpmnode_sort(leaves, numpresent); + + lists.listsize = maxbitlen; + lists.memsize = 2 * maxbitlen * (maxbitlen + 1); + lists.nextfree = 0; + lists.numfree = lists.memsize; + lists.memory = (BPMNode*)lodepng_malloc(lists.memsize * sizeof(*lists.memory)); + lists.freelist = (BPMNode**)lodepng_malloc(lists.memsize * sizeof(BPMNode*)); + lists.chains0 = (BPMNode**)lodepng_malloc(lists.listsize * sizeof(BPMNode*)); + lists.chains1 = (BPMNode**)lodepng_malloc(lists.listsize * sizeof(BPMNode*)); + if(!lists.memory || !lists.freelist || !lists.chains0 || !lists.chains1) error = 83; /*alloc fail*/ + + if(!error) { + for(i = 0; i != lists.memsize; ++i) lists.freelist[i] = &lists.memory[i]; + + bpmnode_create(&lists, leaves[0].weight, 1, 0); + bpmnode_create(&lists, leaves[1].weight, 2, 0); + + for(i = 0; i != lists.listsize; ++i) { + lists.chains0[i] = &lists.memory[0]; + lists.chains1[i] = &lists.memory[1]; + } + + /*each boundaryPM call adds one chain to the last list, and we need 2 * numpresent - 2 chains.*/ + for(i = 2; i != 2 * numpresent - 2; ++i) boundaryPM(&lists, leaves, numpresent, (int)maxbitlen - 1, (int)i); + + for(node = lists.chains1[maxbitlen - 1]; node; node = node->tail) { + for(i = 0; i != node->index; ++i) ++lengths[leaves[i].index]; + } + } + + lodepng_free(lists.memory); + lodepng_free(lists.freelist); + lodepng_free(lists.chains0); + lodepng_free(lists.chains1); + } + + lodepng_free(leaves); + return error; +} + +/*Create the Huffman tree given the symbol frequencies*/ +static unsigned HuffmanTree_makeFromFrequencies(HuffmanTree* tree, const unsigned* frequencies, + size_t mincodes, size_t numcodes, unsigned maxbitlen) { + size_t i; + unsigned error = 0; + while(!frequencies[numcodes - 1] && numcodes > mincodes) --numcodes; /*trim zeroes*/ + tree->maxbitlen = maxbitlen; + tree->numcodes = (unsigned)numcodes; /*number of symbols*/ + tree->lengths = (unsigned*)lodepng_realloc(tree->lengths, numcodes * sizeof(unsigned)); + if(!tree->lengths) return 83; /*alloc fail*/ + /*initialize all lengths to 0*/ + for(i = 0; i < numcodes; i++) tree->lengths[i] = 0; + + error = lodepng_huffman_code_lengths(tree->lengths, frequencies, numcodes, maxbitlen); + if(!error) error = HuffmanTree_makeFromLengths2(tree); + return error; +} + +static unsigned HuffmanTree_getCode(const HuffmanTree* tree, unsigned index) { + return tree->codes[index]; +} + +static unsigned HuffmanTree_getLength(const HuffmanTree* tree, unsigned index) { + return tree->lengths[index]; +} +#endif /*LODEPNG_COMPILE_ENCODER*/ + +/*get the literal and length code tree of a deflated block with fixed tree, as per the deflate specification*/ +static unsigned generateFixedLitLenTree(HuffmanTree* tree) { + unsigned i, error = 0; + unsigned* bitlen = (unsigned*)lodepng_malloc(NUM_DEFLATE_CODE_SYMBOLS * sizeof(unsigned)); + if(!bitlen) return 83; /*alloc fail*/ + + /*288 possible codes: 0-255=literals, 256=endcode, 257-285=lengthcodes, 286-287=unused*/ + for(i = 0; i <= 143; ++i) bitlen[i] = 8; + for(i = 144; i <= 255; ++i) bitlen[i] = 9; + for(i = 256; i <= 279; ++i) bitlen[i] = 7; + for(i = 280; i <= 287; ++i) bitlen[i] = 8; + + error = HuffmanTree_makeFromLengths(tree, bitlen, NUM_DEFLATE_CODE_SYMBOLS, 15); + + lodepng_free(bitlen); + return error; +} + +/*get the distance code tree of a deflated block with fixed tree, as specified in the deflate specification*/ +static unsigned generateFixedDistanceTree(HuffmanTree* tree) { + unsigned i, error = 0; + unsigned* bitlen = (unsigned*)lodepng_malloc(NUM_DISTANCE_SYMBOLS * sizeof(unsigned)); + if(!bitlen) return 83; /*alloc fail*/ + + /*there are 32 distance codes, but 30-31 are unused*/ + for(i = 0; i != NUM_DISTANCE_SYMBOLS; ++i) bitlen[i] = 5; + error = HuffmanTree_makeFromLengths(tree, bitlen, NUM_DISTANCE_SYMBOLS, 15); + + lodepng_free(bitlen); + return error; +} + +#ifdef LODEPNG_COMPILE_DECODER + +/* +returns the code, or (unsigned)(-1) if error happened +*/ +static unsigned huffmanDecodeSymbol(LodePNGBitReader* reader, const HuffmanTree* codetree) { + unsigned code, l, value; + if(ensureBits(reader, 15) > 1) return (unsigned)(-1); + code = peekBits(reader, FIRSTBITS); + l = codetree->table_len[code]; + value = codetree->table_value[code]; + if(l <= FIRSTBITS) { + advanceBits(reader, l); + return value; + } else { + unsigned index2; + advanceBits(reader, FIRSTBITS); + index2 = value + peekBits(reader, l - FIRSTBITS); + advanceBits(reader, codetree->table_len[index2] - FIRSTBITS); + return codetree->table_value[index2]; + } +} +#endif /*LODEPNG_COMPILE_DECODER*/ + +#ifdef LODEPNG_COMPILE_DECODER + +/* ////////////////////////////////////////////////////////////////////////// */ +/* / Inflator (Decompressor) / */ +/* ////////////////////////////////////////////////////////////////////////// */ + +/*get the tree of a deflated block with fixed tree, as specified in the deflate specification*/ +static void getTreeInflateFixed(HuffmanTree* tree_ll, HuffmanTree* tree_d) { + /*TODO: check for out of memory errors*/ + generateFixedLitLenTree(tree_ll); + generateFixedDistanceTree(tree_d); +} + +/*get the tree of a deflated block with dynamic tree, the tree itself is also Huffman compressed with a known tree*/ +static unsigned getTreeInflateDynamic(HuffmanTree* tree_ll, HuffmanTree* tree_d, + LodePNGBitReader* reader) { + /*make sure that length values that aren't filled in will be 0, or a wrong tree will be generated*/ + unsigned error = 0; + unsigned n, HLIT, HDIST, HCLEN, i; + + /*see comments in deflateDynamic for explanation of the context and these variables, it is analogous*/ + unsigned* bitlen_ll = 0; /*lit,len code lengths*/ + unsigned* bitlen_d = 0; /*dist code lengths*/ + /*code length code lengths ("clcl"), the bit lengths of the huffman tree used to compress bitlen_ll and bitlen_d*/ + unsigned* bitlen_cl = 0; + HuffmanTree tree_cl; /*the code tree for code length codes (the huffman tree for compressed huffman trees)*/ + + if(ensureBits(reader, 14)) return 49; /*error: the bit pointer is or will go past the memory*/ + + /*number of literal/length codes + 257. Unlike the spec, the value 257 is added to it here already*/ + HLIT = readBits(reader, 5) + 257; + /*number of distance codes. Unlike the spec, the value 1 is added to it here already*/ + HDIST = readBits(reader, 5) + 1; + /*number of code length codes. Unlike the spec, the value 4 is added to it here already*/ + HCLEN = readBits(reader, 4) + 4; + + bitlen_cl = (unsigned*)lodepng_malloc(NUM_CODE_LENGTH_CODES * sizeof(unsigned)); + if(!bitlen_cl) return 83 /*alloc fail*/; + + HuffmanTree_init(&tree_cl); + + while(!error) { + /*read the code length codes out of 3 * (amount of code length codes) bits*/ + if((reader->bp) + HCLEN * 3 > reader->bitsize) ERROR_BREAK(50); /*error: the bit pointer is or will go past the memory*/ + for(i = 0; i != HCLEN; ++i) { + ensureBits(reader, 3); + bitlen_cl[CLCL_ORDER[i]] = readBits(reader, 3); + } + for(i = HCLEN; i != NUM_CODE_LENGTH_CODES; ++i) { + bitlen_cl[CLCL_ORDER[i]] = 0; + } + + error = HuffmanTree_makeFromLengths(&tree_cl, bitlen_cl, NUM_CODE_LENGTH_CODES, 7); + if(error) break; + + /*now we can use this tree to read the lengths for the tree that this function will return*/ + bitlen_ll = (unsigned*)lodepng_malloc(NUM_DEFLATE_CODE_SYMBOLS * sizeof(unsigned)); + bitlen_d = (unsigned*)lodepng_malloc(NUM_DISTANCE_SYMBOLS * sizeof(unsigned)); + if(!bitlen_ll || !bitlen_d) ERROR_BREAK(83 /*alloc fail*/); + for(i = 0; i != NUM_DEFLATE_CODE_SYMBOLS; ++i) bitlen_ll[i] = 0; + for(i = 0; i != NUM_DISTANCE_SYMBOLS; ++i) bitlen_d[i] = 0; + + /*i is the current symbol we're reading in the part that contains the code lengths of lit/len and dist codes*/ + i = 0; + while(i < HLIT + HDIST) { + unsigned code = huffmanDecodeSymbol(reader, &tree_cl); + if(code <= 15) /*a length code*/ { + if(i < HLIT) bitlen_ll[i] = code; + else bitlen_d[i - HLIT] = code; + ++i; + } else if(code == 16) /*repeat previous*/ { + unsigned replength = 3; /*read in the 2 bits that indicate repeat length (3-6)*/ + unsigned value; /*set value to the previous code*/ + + if(i == 0) ERROR_BREAK(54); /*can't repeat previous if i is 0*/ + + if(ensureBits(reader, 2)) ERROR_BREAK(50); /*error, bit pointer jumps past memory*/ + replength += readBits(reader, 2); + + if(i < HLIT + 1) value = bitlen_ll[i - 1]; + else value = bitlen_d[i - HLIT - 1]; + /*repeat this value in the next lengths*/ + for(n = 0; n < replength; ++n) { + if(i >= HLIT + HDIST) ERROR_BREAK(13); /*error: i is larger than the amount of codes*/ + if(i < HLIT) bitlen_ll[i] = value; + else bitlen_d[i - HLIT] = value; + ++i; + } + } else if(code == 17) /*repeat "0" 3-10 times*/ { + unsigned replength = 3; /*read in the bits that indicate repeat length*/ + if(ensureBits(reader, 3)) ERROR_BREAK(50); /*error, bit pointer jumps past memory*/ + replength += readBits(reader, 3); + + /*repeat this value in the next lengths*/ + for(n = 0; n < replength; ++n) { + if(i >= HLIT + HDIST) ERROR_BREAK(14); /*error: i is larger than the amount of codes*/ + + if(i < HLIT) bitlen_ll[i] = 0; + else bitlen_d[i - HLIT] = 0; + ++i; + } + } else if(code == 18) /*repeat "0" 11-138 times*/ { + unsigned replength = 11; /*read in the bits that indicate repeat length*/ + if(ensureBits(reader, 7)) ERROR_BREAK(50); /*error, bit pointer jumps past memory*/ + replength += readBits(reader, 7); + + /*repeat this value in the next lengths*/ + for(n = 0; n < replength; ++n) { + if(i >= HLIT + HDIST) ERROR_BREAK(15); /*error: i is larger than the amount of codes*/ + + if(i < HLIT) bitlen_ll[i] = 0; + else bitlen_d[i - HLIT] = 0; + ++i; + } + } else /*if(code == (unsigned)(-1))*/ /*huffmanDecodeSymbol returns (unsigned)(-1) in case of error*/ { + if(code == (unsigned)(-1)) { + /*return error code 10 or 11 depending on the situation that happened in huffmanDecodeSymbol + (10=no endcode, 11=wrong jump outside of tree)*/ + error = (reader->bp) > reader->bitsize ? 10 : 11; + } + else error = 16; /*unexisting code, this can never happen*/ + break; + } + } + if(error) break; + + if(bitlen_ll[256] == 0) ERROR_BREAK(64); /*the length of the end code 256 must be larger than 0*/ + + /*now we've finally got HLIT and HDIST, so generate the code trees, and the function is done*/ + error = HuffmanTree_makeFromLengths(tree_ll, bitlen_ll, NUM_DEFLATE_CODE_SYMBOLS, 15); + if(error) break; + error = HuffmanTree_makeFromLengths(tree_d, bitlen_d, NUM_DISTANCE_SYMBOLS, 15); + + break; /*end of error-while*/ + } + + lodepng_free(bitlen_cl); + lodepng_free(bitlen_ll); + lodepng_free(bitlen_d); + HuffmanTree_cleanup(&tree_cl); + + return error; +} + +/*inflate a block with dynamic of fixed Huffman tree. btype must be 1 or 2.*/ +static unsigned inflateHuffmanBlock(ucvector* out, size_t* pos, LodePNGBitReader* reader, + unsigned btype) { + unsigned error = 0; + HuffmanTree tree_ll; /*the huffman tree for literal and length codes*/ + HuffmanTree tree_d; /*the huffman tree for distance codes*/ + + HuffmanTree_init(&tree_ll); + HuffmanTree_init(&tree_d); + + if(btype == 1) getTreeInflateFixed(&tree_ll, &tree_d); + else /*if(btype == 2)*/ error = getTreeInflateDynamic(&tree_ll, &tree_d, reader); + + while(!error) /*decode all symbols until end reached, breaks at end code*/ { + /*code_ll is literal, length or end code*/ + unsigned code_ll = huffmanDecodeSymbol(reader, &tree_ll); + if(code_ll <= 255) /*literal symbol*/ { + /*ucvector_push_back would do the same, but for some reason the two lines below run 10% faster*/ + if(!ucvector_resize(out, (*pos) + 1)) ERROR_BREAK(83 /*alloc fail*/); + out->data[*pos] = (unsigned char)code_ll; + ++(*pos); + } else if(code_ll >= FIRST_LENGTH_CODE_INDEX && code_ll <= LAST_LENGTH_CODE_INDEX) /*length code*/ { + unsigned code_d, distance; + unsigned numextrabits_l, numextrabits_d; /*extra bits for length and distance*/ + size_t start, backward, length; + + /*part 1: get length base*/ + length = LENGTHBASE[code_ll - FIRST_LENGTH_CODE_INDEX]; + + /*part 2: get extra bits and add the value of that to length*/ + numextrabits_l = LENGTHEXTRA[code_ll - FIRST_LENGTH_CODE_INDEX]; + if(ensureBits(reader, numextrabits_l)) ERROR_BREAK(51); /*error, bit pointer will jump past memory*/ + length += readBits(reader, numextrabits_l); + + /*part 3: get distance code*/ + code_d = huffmanDecodeSymbol(reader, &tree_d); + if(code_d > 29) { + if(code_d == (unsigned)(-1)) /*huffmanDecodeSymbol returns (unsigned)(-1) in case of error*/ { + /*return error code 10 or 11 depending on the situation that happened in huffmanDecodeSymbol + (10=no endcode, 11=wrong jump outside of tree)*/ + error = (reader->bp > reader->bitsize) ? 10 : 11; + } + else error = 18; /*error: invalid distance code (30-31 are never used)*/ + break; + } + distance = DISTANCEBASE[code_d]; + + /*part 4: get extra bits from distance*/ + numextrabits_d = DISTANCEEXTRA[code_d]; + if(ensureBits(reader, numextrabits_d)) ERROR_BREAK(51); /*error, bit pointer will jump past memory*/ + distance += readBits(reader, numextrabits_d); + + /*part 5: fill in all the out[n] values based on the length and dist*/ + start = (*pos); + if(distance > start) ERROR_BREAK(52); /*too long backward distance*/ + backward = start - distance; + + if(!ucvector_resize(out, (*pos) + length)) ERROR_BREAK(83 /*alloc fail*/); + if (distance < length) { + size_t forward; + for(forward = 0; forward < length; ++forward) { + out->data[(*pos)++] = out->data[backward++]; + } + } else { + lodepng_memcpy(out->data + *pos, out->data + backward, length); + *pos += length; + } + } else if(code_ll == 256) { + break; /*end code, break the loop*/ + } else /*if(code == (unsigned)(-1))*/ /*huffmanDecodeSymbol returns (unsigned)(-1) in case of error*/ { + /*return error code 10 or 11 depending on the situation that happened in huffmanDecodeSymbol + (10=no endcode, 11=wrong jump outside of tree)*/ + error = (reader->bp > reader->bitsize) ? 10 : 11; + break; + } + } + + HuffmanTree_cleanup(&tree_ll); + HuffmanTree_cleanup(&tree_d); + + return error; +} + +static unsigned inflateNoCompression(ucvector* out, size_t* pos, + LodePNGBitReader* reader, const LodePNGDecompressSettings* settings) { + size_t bytepos; + size_t size = reader->size; + unsigned LEN, NLEN, error = 0; + + /*go to first boundary of byte*/ + bytepos = (reader->bp + 7u) >> 3u; + + /*read LEN (2 bytes) and NLEN (2 bytes)*/ + if(bytepos + 4 >= size) return 52; /*error, bit pointer will jump past memory*/ + LEN = (unsigned)reader->data[bytepos] + (unsigned)(reader->data[bytepos + 1] << 8u); bytepos += 2; + NLEN = (unsigned)reader->data[bytepos] + (unsigned)(reader->data[bytepos + 1] << 8u); bytepos += 2; + + /*check if 16-bit NLEN is really the one's complement of LEN*/ + if(!settings->ignore_nlen && LEN + NLEN != 65535) { + return 21; /*error: NLEN is not one's complement of LEN*/ + } + + if(!ucvector_resize(out, (*pos) + LEN)) return 83; /*alloc fail*/ + + /*read the literal data: LEN bytes are now stored in the out buffer*/ + if(bytepos + LEN > size) return 23; /*error: reading outside of in buffer*/ + + lodepng_memcpy(out->data + *pos, reader->data + bytepos, LEN); + *pos += LEN; + bytepos += LEN; + + reader->bp = bytepos << 3u; + + return error; +} + +static unsigned lodepng_inflatev(ucvector* out, + const unsigned char* in, size_t insize, + const LodePNGDecompressSettings* settings) { + unsigned BFINAL = 0; + size_t pos = 0; /*byte position in the out buffer*/ + unsigned error = 0; + LodePNGBitReader reader; + LodePNGBitReader_init(&reader, in, insize); + + while(!BFINAL) { + unsigned BTYPE; + if(ensureBits(&reader, 3)) return 52; /*error, bit pointer will jump past memory*/ + BFINAL = readBits(&reader, 1); + BTYPE = readBits(&reader, 2); + + if(BTYPE == 3) return 20; /*error: invalid BTYPE*/ + else if(BTYPE == 0) error = inflateNoCompression(out, &pos, &reader, settings); /*no compression*/ + else error = inflateHuffmanBlock(out, &pos, &reader, BTYPE); /*compression, BTYPE 01 or 10*/ + + if(error) return error; + } + + return error; +} + +unsigned lodepng_inflate(unsigned char** out, size_t* outsize, + const unsigned char* in, size_t insize, + const LodePNGDecompressSettings* settings) { + unsigned error; + ucvector v; + ucvector_init_buffer(&v, *out, *outsize); + error = lodepng_inflatev(&v, in, insize, settings); + *out = v.data; + *outsize = v.size; + return error; +} + +static unsigned inflate(unsigned char** out, size_t* outsize, + const unsigned char* in, size_t insize, + const LodePNGDecompressSettings* settings) { + if(settings->custom_inflate) { + return settings->custom_inflate(out, outsize, in, insize, settings); + } else { + return lodepng_inflate(out, outsize, in, insize, settings); + } +} + +#endif /*LODEPNG_COMPILE_DECODER*/ + +#ifdef LODEPNG_COMPILE_ENCODER + +/* ////////////////////////////////////////////////////////////////////////// */ +/* / Deflator (Compressor) / */ +/* ////////////////////////////////////////////////////////////////////////// */ + +static const size_t MAX_SUPPORTED_DEFLATE_LENGTH = 258; + +/*search the index in the array, that has the largest value smaller than or equal to the given value, +given array must be sorted (if no value is smaller, it returns the size of the given array)*/ +static size_t searchCodeIndex(const unsigned* array, size_t array_size, size_t value) { + /*binary search (only small gain over linear). TODO: use CPU log2 instruction for getting symbols instead*/ + size_t left = 1; + size_t right = array_size - 1; + + while(left <= right) { + size_t mid = (left + right) >> 1; + if (array[mid] >= value) right = mid - 1; + else left = mid + 1; + } + if(left >= array_size || array[left] > value) left--; + return left; +} + +static void addLengthDistance(uivector* values, size_t length, size_t distance) { + /*values in encoded vector are those used by deflate: + 0-255: literal bytes + 256: end + 257-285: length/distance pair (length code, followed by extra length bits, distance code, extra distance bits) + 286-287: invalid*/ + + unsigned length_code = (unsigned)searchCodeIndex(LENGTHBASE, 29, length); + unsigned extra_length = (unsigned)(length - LENGTHBASE[length_code]); + unsigned dist_code = (unsigned)searchCodeIndex(DISTANCEBASE, 30, distance); + unsigned extra_distance = (unsigned)(distance - DISTANCEBASE[dist_code]); + + uivector_push_back(values, length_code + FIRST_LENGTH_CODE_INDEX); + uivector_push_back(values, extra_length); + uivector_push_back(values, dist_code); + uivector_push_back(values, extra_distance); +} + +/*3 bytes of data get encoded into two bytes. The hash cannot use more than 3 +bytes as input because 3 is the minimum match length for deflate*/ +static const unsigned HASH_NUM_VALUES = 65536; +static const unsigned HASH_BIT_MASK = 65535; /*HASH_NUM_VALUES - 1, but C90 does not like that as initializer*/ + +typedef struct Hash { + int* head; /*hash value to head circular pos - can be outdated if went around window*/ + /*circular pos to prev circular pos*/ + unsigned short* chain; + int* val; /*circular pos to hash value*/ + + /*TODO: do this not only for zeros but for any repeated byte. However for PNG + it's always going to be the zeros that dominate, so not important for PNG*/ + int* headz; /*similar to head, but for chainz*/ + unsigned short* chainz; /*those with same amount of zeros*/ + unsigned short* zeros; /*length of zeros streak, used as a second hash chain*/ +} Hash; + +static unsigned hash_init(Hash* hash, unsigned windowsize) { + unsigned i; + hash->head = (int*)lodepng_malloc(sizeof(int) * HASH_NUM_VALUES); + hash->val = (int*)lodepng_malloc(sizeof(int) * windowsize); + hash->chain = (unsigned short*)lodepng_malloc(sizeof(unsigned short) * windowsize); + + hash->zeros = (unsigned short*)lodepng_malloc(sizeof(unsigned short) * windowsize); + hash->headz = (int*)lodepng_malloc(sizeof(int) * (MAX_SUPPORTED_DEFLATE_LENGTH + 1)); + hash->chainz = (unsigned short*)lodepng_malloc(sizeof(unsigned short) * windowsize); + + if(!hash->head || !hash->chain || !hash->val || !hash->headz|| !hash->chainz || !hash->zeros) { + return 83; /*alloc fail*/ + } + + /*initialize hash table*/ + for(i = 0; i != HASH_NUM_VALUES; ++i) hash->head[i] = -1; + for(i = 0; i != windowsize; ++i) hash->val[i] = -1; + for(i = 0; i != windowsize; ++i) hash->chain[i] = i; /*same value as index indicates uninitialized*/ + + for(i = 0; i <= MAX_SUPPORTED_DEFLATE_LENGTH; ++i) hash->headz[i] = -1; + for(i = 0; i != windowsize; ++i) hash->chainz[i] = i; /*same value as index indicates uninitialized*/ + + return 0; +} + +static void hash_cleanup(Hash* hash) { + lodepng_free(hash->head); + lodepng_free(hash->val); + lodepng_free(hash->chain); + + lodepng_free(hash->zeros); + lodepng_free(hash->headz); + lodepng_free(hash->chainz); +} + + + +static unsigned getHash(const unsigned char* data, size_t size, size_t pos) { + unsigned result = 0; + if(pos + 2 < size) { + /*A simple shift and xor hash is used. Since the data of PNGs is dominated + by zeroes due to the filters, a better hash does not have a significant + effect on speed in traversing the chain, and causes more time spend on + calculating the hash.*/ + result ^= (unsigned)(data[pos + 0] << 0u); + result ^= (unsigned)(data[pos + 1] << 4u); + result ^= (unsigned)(data[pos + 2] << 8u); + } else { + size_t amount, i; + if(pos >= size) return 0; + amount = size - pos; + for(i = 0; i != amount; ++i) result ^= (unsigned)(data[pos + i] << (i * 8u)); + } + return result & HASH_BIT_MASK; +} + +static unsigned countZeros(const unsigned char* data, size_t size, size_t pos) { + const unsigned char* start = data + pos; + const unsigned char* end = start + MAX_SUPPORTED_DEFLATE_LENGTH; + if(end > data + size) end = data + size; + data = start; + while(data != end && *data == 0) ++data; + /*subtracting two addresses returned as 32-bit number (max value is MAX_SUPPORTED_DEFLATE_LENGTH)*/ + return (unsigned)(data - start); +} + +/*wpos = pos & (windowsize - 1)*/ +static void updateHashChain(Hash* hash, size_t wpos, unsigned hashval, unsigned short numzeros) { + hash->val[wpos] = (int)hashval; + if(hash->head[hashval] != -1) hash->chain[wpos] = hash->head[hashval]; + hash->head[hashval] = (int)wpos; + + hash->zeros[wpos] = numzeros; + if(hash->headz[numzeros] != -1) hash->chainz[wpos] = hash->headz[numzeros]; + hash->headz[numzeros] = (int)wpos; +} + +/* +LZ77-encode the data. Return value is error code. The input are raw bytes, the output +is in the form of unsigned integers with codes representing for example literal bytes, or +length/distance pairs. +It uses a hash table technique to let it encode faster. When doing LZ77 encoding, a +sliding window (of windowsize) is used, and all past bytes in that window can be used as +the "dictionary". A brute force search through all possible distances would be slow, and +this hash technique is one out of several ways to speed this up. +*/ +static unsigned encodeLZ77(uivector* out, Hash* hash, + const unsigned char* in, size_t inpos, size_t insize, unsigned windowsize, + unsigned minmatch, unsigned nicematch, unsigned lazymatching) { + size_t pos; + unsigned i, error = 0; + /*for large window lengths, assume the user wants no compression loss. Otherwise, max hash chain length speedup.*/ + unsigned maxchainlength = windowsize >= 8192 ? windowsize : windowsize / 8u; + unsigned maxlazymatch = windowsize >= 8192 ? MAX_SUPPORTED_DEFLATE_LENGTH : 64; + + unsigned usezeros = 1; /*not sure if setting it to false for windowsize < 8192 is better or worse*/ + unsigned numzeros = 0; + + unsigned offset; /*the offset represents the distance in LZ77 terminology*/ + unsigned length; + unsigned lazy = 0; + unsigned lazylength = 0, lazyoffset = 0; + unsigned hashval; + unsigned current_offset, current_length; + unsigned prev_offset; + const unsigned char *lastptr, *foreptr, *backptr; + unsigned hashpos; + + if(windowsize == 0 || windowsize > 32768) return 60; /*error: windowsize smaller/larger than allowed*/ + if((windowsize & (windowsize - 1)) != 0) return 90; /*error: must be power of two*/ + + if(nicematch > MAX_SUPPORTED_DEFLATE_LENGTH) nicematch = MAX_SUPPORTED_DEFLATE_LENGTH; + + for(pos = inpos; pos < insize; ++pos) { + size_t wpos = pos & (windowsize - 1); /*position for in 'circular' hash buffers*/ + unsigned chainlength = 0; + + hashval = getHash(in, insize, pos); + + if(usezeros && hashval == 0) { + if(numzeros == 0) numzeros = countZeros(in, insize, pos); + else if(pos + numzeros > insize || in[pos + numzeros - 1] != 0) --numzeros; + } else { + numzeros = 0; + } + + updateHashChain(hash, wpos, hashval, numzeros); + + /*the length and offset found for the current position*/ + length = 0; + offset = 0; + + hashpos = hash->chain[wpos]; + + lastptr = &in[insize < pos + MAX_SUPPORTED_DEFLATE_LENGTH ? insize : pos + MAX_SUPPORTED_DEFLATE_LENGTH]; + + /*search for the longest string*/ + prev_offset = 0; + for(;;) { + if(chainlength++ >= maxchainlength) break; + current_offset = (unsigned)(hashpos <= wpos ? wpos - hashpos : wpos - hashpos + windowsize); + + if(current_offset < prev_offset) break; /*stop when went completely around the circular buffer*/ + prev_offset = current_offset; + if(current_offset > 0) { + /*test the next characters*/ + foreptr = &in[pos]; + backptr = &in[pos - current_offset]; + + /*common case in PNGs is lots of zeros. Quickly skip over them as a speedup*/ + if(numzeros >= 3) { + unsigned skip = hash->zeros[hashpos]; + if(skip > numzeros) skip = numzeros; + backptr += skip; + foreptr += skip; + } + + while(foreptr != lastptr && *backptr == *foreptr) /*maximum supported length by deflate is max length*/ { + ++backptr; + ++foreptr; + } + current_length = (unsigned)(foreptr - &in[pos]); + + if(current_length > length) { + length = current_length; /*the longest length*/ + offset = current_offset; /*the offset that is related to this longest length*/ + /*jump out once a length of max length is found (speed gain). This also jumps + out if length is MAX_SUPPORTED_DEFLATE_LENGTH*/ + if(current_length >= nicematch) break; + } + } + + if(hashpos == hash->chain[hashpos]) break; + + if(numzeros >= 3 && length > numzeros) { + hashpos = hash->chainz[hashpos]; + if(hash->zeros[hashpos] != numzeros) break; + } else { + hashpos = hash->chain[hashpos]; + /*outdated hash value, happens if particular value was not encountered in whole last window*/ + if(hash->val[hashpos] != (int)hashval) break; + } + } + + if(lazymatching) { + if(!lazy && length >= 3 && length <= maxlazymatch && length < MAX_SUPPORTED_DEFLATE_LENGTH) { + lazy = 1; + lazylength = length; + lazyoffset = offset; + continue; /*try the next byte*/ + } + if(lazy) { + lazy = 0; + if(pos == 0) ERROR_BREAK(81); + if(length > lazylength + 1) { + /*push the previous character as literal*/ + if(!uivector_push_back(out, in[pos - 1])) ERROR_BREAK(83 /*alloc fail*/); + } else { + length = lazylength; + offset = lazyoffset; + hash->head[hashval] = -1; /*the same hashchain update will be done, this ensures no wrong alteration*/ + hash->headz[numzeros] = -1; /*idem*/ + --pos; + } + } + } + if(length >= 3 && offset > windowsize) ERROR_BREAK(86 /*too big (or overflown negative) offset*/); + + /*encode it as length/distance pair or literal value*/ + if(length < 3) /*only lengths of 3 or higher are supported as length/distance pair*/ { + if(!uivector_push_back(out, in[pos])) ERROR_BREAK(83 /*alloc fail*/); + } else if(length < minmatch || (length == 3 && offset > 4096)) { + /*compensate for the fact that longer offsets have more extra bits, a + length of only 3 may be not worth it then*/ + if(!uivector_push_back(out, in[pos])) ERROR_BREAK(83 /*alloc fail*/); + } else { + addLengthDistance(out, length, offset); + for(i = 1; i < length; ++i) { + ++pos; + wpos = pos & (windowsize - 1); + hashval = getHash(in, insize, pos); + if(usezeros && hashval == 0) { + if(numzeros == 0) numzeros = countZeros(in, insize, pos); + else if(pos + numzeros > insize || in[pos + numzeros - 1] != 0) --numzeros; + } else { + numzeros = 0; + } + updateHashChain(hash, wpos, hashval, numzeros); + } + } + } /*end of the loop through each character of input*/ + + return error; +} + +/* /////////////////////////////////////////////////////////////////////////// */ + +static unsigned deflateNoCompression(ucvector* out, const unsigned char* data, size_t datasize) { + /*non compressed deflate block data: 1 bit BFINAL,2 bits BTYPE,(5 bits): it jumps to start of next byte, + 2 bytes LEN, 2 bytes NLEN, LEN bytes literal DATA*/ + + size_t i, j, numdeflateblocks = (datasize + 65534u) / 65535u; + unsigned datapos = 0; + for(i = 0; i != numdeflateblocks; ++i) { + unsigned BFINAL, BTYPE, LEN, NLEN; + unsigned char firstbyte; + + BFINAL = (i == numdeflateblocks - 1); + BTYPE = 0; + + firstbyte = (unsigned char)(BFINAL + ((BTYPE & 1) << 1) + ((BTYPE & 2) << 1)); + ucvector_push_back(out, firstbyte); + + LEN = 65535; + if(datasize - datapos < 65535u) LEN = (unsigned)datasize - datapos; + NLEN = 65535 - LEN; + + ucvector_push_back(out, (unsigned char)(LEN & 255)); + ucvector_push_back(out, (unsigned char)(LEN >> 8u)); + ucvector_push_back(out, (unsigned char)(NLEN & 255)); + ucvector_push_back(out, (unsigned char)(NLEN >> 8u)); + + /*Decompressed data*/ + for(j = 0; j < 65535 && datapos < datasize; ++j) { + ucvector_push_back(out, data[datapos++]); + } + } + + return 0; +} + +/* +write the lz77-encoded data, which has lit, len and dist codes, to compressed stream using huffman trees. +tree_ll: the tree for lit and len codes. +tree_d: the tree for distance codes. +*/ +static void writeLZ77data(LodePNGBitWriter* writer, const uivector* lz77_encoded, + const HuffmanTree* tree_ll, const HuffmanTree* tree_d) { + size_t i = 0; + for(i = 0; i != lz77_encoded->size; ++i) { + unsigned val = lz77_encoded->data[i]; + writeBitsReversed(writer, HuffmanTree_getCode(tree_ll, val), HuffmanTree_getLength(tree_ll, val)); + if(val > 256) /*for a length code, 3 more things have to be added*/ { + unsigned length_index = val - FIRST_LENGTH_CODE_INDEX; + unsigned n_length_extra_bits = LENGTHEXTRA[length_index]; + unsigned length_extra_bits = lz77_encoded->data[++i]; + + unsigned distance_code = lz77_encoded->data[++i]; + + unsigned distance_index = distance_code; + unsigned n_distance_extra_bits = DISTANCEEXTRA[distance_index]; + unsigned distance_extra_bits = lz77_encoded->data[++i]; + + writeBits(writer, length_extra_bits, n_length_extra_bits); + writeBitsReversed(writer, HuffmanTree_getCode(tree_d, distance_code), + HuffmanTree_getLength(tree_d, distance_code)); + writeBits(writer, distance_extra_bits, n_distance_extra_bits); + } + } +} + +/*Deflate for a block of type "dynamic", that is, with freely, optimally, created huffman trees*/ +static unsigned deflateDynamic(LodePNGBitWriter* writer, Hash* hash, + const unsigned char* data, size_t datapos, size_t dataend, + const LodePNGCompressSettings* settings, unsigned final) { + unsigned error = 0; + + /* + A block is compressed as follows: The PNG data is lz77 encoded, resulting in + literal bytes and length/distance pairs. This is then huffman compressed with + two huffman trees. One huffman tree is used for the lit and len values ("ll"), + another huffman tree is used for the dist values ("d"). These two trees are + stored using their code lengths, and to compress even more these code lengths + are also run-length encoded and huffman compressed. This gives a huffman tree + of code lengths "cl". The code lenghts used to describe this third tree are + the code length code lengths ("clcl"). + */ + + /*The lz77 encoded data, represented with integers since there will also be length and distance codes in it*/ + uivector lz77_encoded; + HuffmanTree tree_ll; /*tree for lit,len values*/ + HuffmanTree tree_d; /*tree for distance codes*/ + HuffmanTree tree_cl; /*tree for encoding the code lengths representing tree_ll and tree_d*/ + uivector frequencies_ll; /*frequency of lit,len codes*/ + uivector frequencies_d; /*frequency of dist codes*/ + uivector frequencies_cl; /*frequency of code length codes*/ + uivector bitlen_lld; /*lit,len,dist code lenghts (int bits), literally (without repeat codes).*/ + uivector bitlen_lld_e; /*bitlen_lld encoded with repeat codes (this is a rudemtary run length compression)*/ + /*bitlen_cl is the code length code lengths ("clcl"). The bit lengths of codes to represent tree_cl + (these are written as is in the file, it would be crazy to compress these using yet another huffman + tree that needs to be represented by yet another set of code lengths)*/ + uivector bitlen_cl; + size_t datasize = dataend - datapos; + + /* + Due to the huffman compression of huffman tree representations ("two levels"), there are some anologies: + bitlen_lld is to tree_cl what data is to tree_ll and tree_d. + bitlen_lld_e is to bitlen_lld what lz77_encoded is to data. + bitlen_cl is to bitlen_lld_e what bitlen_lld is to lz77_encoded. + */ + + unsigned BFINAL = final; + size_t numcodes_ll, numcodes_d, i; + unsigned HLIT, HDIST, HCLEN; + + uivector_init(&lz77_encoded); + HuffmanTree_init(&tree_ll); + HuffmanTree_init(&tree_d); + HuffmanTree_init(&tree_cl); + uivector_init(&frequencies_ll); + uivector_init(&frequencies_d); + uivector_init(&frequencies_cl); + uivector_init(&bitlen_lld); + uivector_init(&bitlen_lld_e); + uivector_init(&bitlen_cl); + + /*This while loop never loops due to a break at the end, it is here to + allow breaking out of it to the cleanup phase on error conditions.*/ + while(!error) { + if(settings->use_lz77) { + error = encodeLZ77(&lz77_encoded, hash, data, datapos, dataend, settings->windowsize, + settings->minmatch, settings->nicematch, settings->lazymatching); + if(error) break; + } else { + if(!uivector_resize(&lz77_encoded, datasize)) ERROR_BREAK(83 /*alloc fail*/); + for(i = datapos; i < dataend; ++i) lz77_encoded.data[i - datapos] = data[i]; /*no LZ77, but still will be Huffman compressed*/ + } + + if(!uivector_resizev(&frequencies_ll, 286, 0)) ERROR_BREAK(83 /*alloc fail*/); + if(!uivector_resizev(&frequencies_d, 30, 0)) ERROR_BREAK(83 /*alloc fail*/); + + /*Count the frequencies of lit, len and dist codes*/ + for(i = 0; i != lz77_encoded.size; ++i) { + unsigned symbol = lz77_encoded.data[i]; + ++frequencies_ll.data[symbol]; + if(symbol > 256) { + unsigned dist = lz77_encoded.data[i + 2]; + ++frequencies_d.data[dist]; + i += 3; + } + } + frequencies_ll.data[256] = 1; /*there will be exactly 1 end code, at the end of the block*/ + + /*Make both huffman trees, one for the lit and len codes, one for the dist codes*/ + error = HuffmanTree_makeFromFrequencies(&tree_ll, frequencies_ll.data, 257, frequencies_ll.size, 15); + if(error) break; + /*2, not 1, is chosen for mincodes: some buggy PNG decoders require at least 2 symbols in the dist tree*/ + error = HuffmanTree_makeFromFrequencies(&tree_d, frequencies_d.data, 2, frequencies_d.size, 15); + if(error) break; + + numcodes_ll = tree_ll.numcodes; if(numcodes_ll > 286) numcodes_ll = 286; + numcodes_d = tree_d.numcodes; if(numcodes_d > 30) numcodes_d = 30; + /*store the code lengths of both generated trees in bitlen_lld*/ + for(i = 0; i != numcodes_ll; ++i) uivector_push_back(&bitlen_lld, HuffmanTree_getLength(&tree_ll, (unsigned)i)); + for(i = 0; i != numcodes_d; ++i) uivector_push_back(&bitlen_lld, HuffmanTree_getLength(&tree_d, (unsigned)i)); + + /*run-length compress bitlen_ldd into bitlen_lld_e by using repeat codes 16 (copy length 3-6 times), + 17 (3-10 zeroes), 18 (11-138 zeroes)*/ + for(i = 0; i != (unsigned)bitlen_lld.size; ++i) { + unsigned j = 0; /*amount of repititions*/ + while(i + j + 1 < (unsigned)bitlen_lld.size && bitlen_lld.data[i + j + 1] == bitlen_lld.data[i]) ++j; + + if(bitlen_lld.data[i] == 0 && j >= 2) /*repeat code for zeroes*/ { + ++j; /*include the first zero*/ + if(j <= 10) /*repeat code 17 supports max 10 zeroes*/ { + uivector_push_back(&bitlen_lld_e, 17); + uivector_push_back(&bitlen_lld_e, j - 3); + } else /*repeat code 18 supports max 138 zeroes*/ { + if(j > 138) j = 138; + uivector_push_back(&bitlen_lld_e, 18); + uivector_push_back(&bitlen_lld_e, j - 11); + } + i += (j - 1); + } else if(j >= 3) /*repeat code for value other than zero*/ { + size_t k; + unsigned num = j / 6u, rest = j % 6u; + uivector_push_back(&bitlen_lld_e, bitlen_lld.data[i]); + for(k = 0; k < num; ++k) { + uivector_push_back(&bitlen_lld_e, 16); + uivector_push_back(&bitlen_lld_e, 6 - 3); + } + if(rest >= 3) { + uivector_push_back(&bitlen_lld_e, 16); + uivector_push_back(&bitlen_lld_e, rest - 3); + } + else j -= rest; + i += j; + } else /*too short to benefit from repeat code*/ { + uivector_push_back(&bitlen_lld_e, bitlen_lld.data[i]); + } + } + + /*generate tree_cl, the huffmantree of huffmantrees*/ + + if(!uivector_resizev(&frequencies_cl, NUM_CODE_LENGTH_CODES, 0)) ERROR_BREAK(83 /*alloc fail*/); + for(i = 0; i != bitlen_lld_e.size; ++i) { + ++frequencies_cl.data[bitlen_lld_e.data[i]]; + /*after a repeat code come the bits that specify the number of repetitions, + those don't need to be in the frequencies_cl calculation*/ + if(bitlen_lld_e.data[i] >= 16) ++i; + } + + error = HuffmanTree_makeFromFrequencies(&tree_cl, frequencies_cl.data, + frequencies_cl.size, frequencies_cl.size, 7); + if(error) break; + + if(!uivector_resize(&bitlen_cl, tree_cl.numcodes)) ERROR_BREAK(83 /*alloc fail*/); + for(i = 0; i != tree_cl.numcodes; ++i) { + /*lenghts of code length tree is in the order as specified by deflate*/ + bitlen_cl.data[i] = HuffmanTree_getLength(&tree_cl, CLCL_ORDER[i]); + } + while(bitlen_cl.data[bitlen_cl.size - 1] == 0 && bitlen_cl.size > 4) { + /*remove zeros at the end, but minimum size must be 4*/ + if(!uivector_resize(&bitlen_cl, bitlen_cl.size - 1)) ERROR_BREAK(83 /*alloc fail*/); + } + if(error) break; + + /* + Write everything into the output + + After the BFINAL and BTYPE, the dynamic block consists out of the following: + - 5 bits HLIT, 5 bits HDIST, 4 bits HCLEN + - (HCLEN+4)*3 bits code lengths of code length alphabet + - HLIT + 257 code lenghts of lit/length alphabet (encoded using the code length + alphabet, + possible repetition codes 16, 17, 18) + - HDIST + 1 code lengths of distance alphabet (encoded using the code length + alphabet, + possible repetition codes 16, 17, 18) + - compressed data + - 256 (end code) + */ + + /*Write block type*/ + writeBits(writer, BFINAL, 1); + writeBits(writer, 0, 1); /*first bit of BTYPE "dynamic"*/ + writeBits(writer, 1, 1); /*second bit of BTYPE "dynamic"*/ + + /*write the HLIT, HDIST and HCLEN values*/ + HLIT = (unsigned)(numcodes_ll - 257); + HDIST = (unsigned)(numcodes_d - 1); + HCLEN = (unsigned)bitlen_cl.size - 4; + /*trim zeroes for HCLEN. HLIT and HDIST were already trimmed at tree creation*/ + while(!bitlen_cl.data[HCLEN + 4 - 1] && HCLEN > 0) --HCLEN; + writeBits(writer, HLIT, 5); + writeBits(writer, HDIST, 5); + writeBits(writer, HCLEN, 4); + + /*write the code lenghts of the code length alphabet*/ + for(i = 0; i != HCLEN + 4; ++i) writeBits(writer, bitlen_cl.data[i], 3); + + /*write the lenghts of the lit/len AND the dist alphabet*/ + for(i = 0; i != bitlen_lld_e.size; ++i) { + writeBitsReversed(writer, HuffmanTree_getCode(&tree_cl, bitlen_lld_e.data[i]), + HuffmanTree_getLength(&tree_cl, bitlen_lld_e.data[i])); + /*extra bits of repeat codes*/ + if(bitlen_lld_e.data[i] == 16) writeBits(writer, bitlen_lld_e.data[++i], 2); + else if(bitlen_lld_e.data[i] == 17) writeBits(writer, bitlen_lld_e.data[++i], 3); + else if(bitlen_lld_e.data[i] == 18) writeBits(writer, bitlen_lld_e.data[++i], 7); + } + + /*write the compressed data symbols*/ + writeLZ77data(writer, &lz77_encoded, &tree_ll, &tree_d); + /*error: the length of the end code 256 must be larger than 0*/ + if(HuffmanTree_getLength(&tree_ll, 256) == 0) ERROR_BREAK(64); + + /*write the end code*/ + writeBitsReversed(writer, HuffmanTree_getCode(&tree_ll, 256), HuffmanTree_getLength(&tree_ll, 256)); + + break; /*end of error-while*/ + } + + /*cleanup*/ + uivector_cleanup(&lz77_encoded); + HuffmanTree_cleanup(&tree_ll); + HuffmanTree_cleanup(&tree_d); + HuffmanTree_cleanup(&tree_cl); + uivector_cleanup(&frequencies_ll); + uivector_cleanup(&frequencies_d); + uivector_cleanup(&frequencies_cl); + uivector_cleanup(&bitlen_lld_e); + uivector_cleanup(&bitlen_lld); + uivector_cleanup(&bitlen_cl); + + return error; +} + +static unsigned deflateFixed(LodePNGBitWriter* writer, Hash* hash, + const unsigned char* data, + size_t datapos, size_t dataend, + const LodePNGCompressSettings* settings, unsigned final) { + HuffmanTree tree_ll; /*tree for literal values and length codes*/ + HuffmanTree tree_d; /*tree for distance codes*/ + + unsigned BFINAL = final; + unsigned error = 0; + size_t i; + + HuffmanTree_init(&tree_ll); + HuffmanTree_init(&tree_d); + + generateFixedLitLenTree(&tree_ll); + generateFixedDistanceTree(&tree_d); + + writeBits(writer, BFINAL, 1); + writeBits(writer, 1, 1); /*first bit of BTYPE*/ + writeBits(writer, 0, 1); /*second bit of BTYPE*/ + + if(settings->use_lz77) /*LZ77 encoded*/ { + uivector lz77_encoded; + uivector_init(&lz77_encoded); + error = encodeLZ77(&lz77_encoded, hash, data, datapos, dataend, settings->windowsize, + settings->minmatch, settings->nicematch, settings->lazymatching); + if(!error) writeLZ77data(writer, &lz77_encoded, &tree_ll, &tree_d); + uivector_cleanup(&lz77_encoded); + } else /*no LZ77, but still will be Huffman compressed*/ { + for(i = datapos; i < dataend; ++i) { + writeBitsReversed(writer, HuffmanTree_getCode(&tree_ll, data[i]), HuffmanTree_getLength(&tree_ll, data[i])); + } + } + /*add END code*/ + if(!error) writeBitsReversed(writer, HuffmanTree_getCode(&tree_ll, 256), HuffmanTree_getLength(&tree_ll, 256)); + + /*cleanup*/ + HuffmanTree_cleanup(&tree_ll); + HuffmanTree_cleanup(&tree_d); + + return error; +} + +static unsigned lodepng_deflatev(ucvector* out, const unsigned char* in, size_t insize, + const LodePNGCompressSettings* settings) { + unsigned error = 0; + size_t i, blocksize, numdeflateblocks; + Hash hash; + LodePNGBitWriter writer; + + LodePNGBitWriter_init(&writer, out); + + if(settings->btype > 2) return 61; + else if(settings->btype == 0) return deflateNoCompression(out, in, insize); + else if(settings->btype == 1) blocksize = insize; + else /*if(settings->btype == 2)*/ { + /*on PNGs, deflate blocks of 65-262k seem to give most dense encoding*/ + blocksize = insize / 8u + 8; + if(blocksize < 65536) blocksize = 65536; + if(blocksize > 262144) blocksize = 262144; + } + + numdeflateblocks = (insize + blocksize - 1) / blocksize; + if(numdeflateblocks == 0) numdeflateblocks = 1; + + error = hash_init(&hash, settings->windowsize); + if(error) return error; + + for(i = 0; i != numdeflateblocks && !error; ++i) { + unsigned final = (i == numdeflateblocks - 1); + size_t start = i * blocksize; + size_t end = start + blocksize; + if(end > insize) end = insize; + + if(settings->btype == 1) error = deflateFixed(&writer, &hash, in, start, end, settings, final); + else if(settings->btype == 2) error = deflateDynamic(&writer, &hash, in, start, end, settings, final); + } + + hash_cleanup(&hash); + + return error; +} + +unsigned lodepng_deflate(unsigned char** out, size_t* outsize, + const unsigned char* in, size_t insize, + const LodePNGCompressSettings* settings) { + unsigned error; + ucvector v; + ucvector_init_buffer(&v, *out, *outsize); + error = lodepng_deflatev(&v, in, insize, settings); + *out = v.data; + *outsize = v.size; + return error; +} + +static unsigned deflate(unsigned char** out, size_t* outsize, + const unsigned char* in, size_t insize, + const LodePNGCompressSettings* settings) { + if(settings->custom_deflate) { + return settings->custom_deflate(out, outsize, in, insize, settings); + } else { + return lodepng_deflate(out, outsize, in, insize, settings); + } +} + +#endif /*LODEPNG_COMPILE_DECODER*/ + +/* ////////////////////////////////////////////////////////////////////////// */ +/* / Adler32 / */ +/* ////////////////////////////////////////////////////////////////////////// */ + +static unsigned update_adler32(unsigned adler, const unsigned char* data, unsigned len) { + unsigned s1 = adler & 0xffff; + unsigned s2 = (adler >> 16) & 0xffff; + + while(len > 0) { + /*at least 5552 sums can be done before the sums overflow, saving a lot of module divisions*/ + unsigned amount = len > 5552 ? 5552 : len; + len -= amount; + while(amount > 0) { + s1 += (*data++); + s2 += s1; + --amount; + } + s1 %= 65521; + s2 %= 65521; + } + + return (s2 << 16) | s1; +} + +/*Return the adler32 of the bytes data[0..len-1]*/ +static unsigned adler32(const unsigned char* data, unsigned len) { + return update_adler32(1L, data, len); +} + +/* ////////////////////////////////////////////////////////////////////////// */ +/* / Zlib / */ +/* ////////////////////////////////////////////////////////////////////////// */ + +#ifdef LODEPNG_COMPILE_DECODER + +unsigned lodepng_zlib_decompress(unsigned char** out, size_t* outsize, const unsigned char* in, + size_t insize, const LodePNGDecompressSettings* settings) { + unsigned error = 0; + unsigned CM, CINFO, FDICT; + + if(insize < 2) return 53; /*error, size of zlib data too small*/ + /*read information from zlib header*/ + if((in[0] * 256 + in[1]) % 31 != 0) { + /*error: 256 * in[0] + in[1] must be a multiple of 31, the FCHECK value is supposed to be made that way*/ + return 24; + } + + CM = in[0] & 15; + CINFO = (in[0] >> 4) & 15; + /*FCHECK = in[1] & 31;*/ /*FCHECK is already tested above*/ + FDICT = (in[1] >> 5) & 1; + /*FLEVEL = (in[1] >> 6) & 3;*/ /*FLEVEL is not used here*/ + + if(CM != 8 || CINFO > 7) { + /*error: only compression method 8: inflate with sliding window of 32k is supported by the PNG spec*/ + return 25; + } + if(FDICT != 0) { + /*error: the specification of PNG says about the zlib stream: + "The additional flags shall not specify a preset dictionary."*/ + return 26; + } + + error = inflate(out, outsize, in + 2, insize - 2, settings); + if(error) return error; + + if(!settings->ignore_adler32) { + unsigned ADLER32 = lodepng_read32bitInt(&in[insize - 4]); + unsigned checksum = adler32(*out, (unsigned)(*outsize)); + if(checksum != ADLER32) return 58; /*error, adler checksum not correct, data must be corrupted*/ + } + + return 0; /*no error*/ +} + +static unsigned zlib_decompress(unsigned char** out, size_t* outsize, const unsigned char* in, + size_t insize, const LodePNGDecompressSettings* settings) { + if(settings->custom_zlib) { + return settings->custom_zlib(out, outsize, in, insize, settings); + } else { + return lodepng_zlib_decompress(out, outsize, in, insize, settings); + } +} + +#endif /*LODEPNG_COMPILE_DECODER*/ + +#ifdef LODEPNG_COMPILE_ENCODER + +unsigned lodepng_zlib_compress(unsigned char** out, size_t* outsize, const unsigned char* in, + size_t insize, const LodePNGCompressSettings* settings) { + size_t i; + unsigned error; + unsigned char* deflatedata = 0; + size_t deflatesize = 0; + + error = deflate(&deflatedata, &deflatesize, in, insize, settings); + + *out = NULL; + *outsize = 0; + if(!error) { + *outsize = deflatesize + 6; + *out = (unsigned char*)lodepng_malloc(*outsize); + if(!*out) error = 83; /*alloc fail*/ + } + + if(!error) { + unsigned ADLER32 = adler32(in, (unsigned)insize); + /*zlib data: 1 byte CMF (CM+CINFO), 1 byte FLG, deflate data, 4 byte ADLER32 checksum of the Decompressed data*/ + unsigned CMF = 120; /*0b01111000: CM 8, CINFO 7. With CINFO 7, any window size up to 32768 can be used.*/ + unsigned FLEVEL = 0; + unsigned FDICT = 0; + unsigned CMFFLG = 256 * CMF + FDICT * 32 + FLEVEL * 64; + unsigned FCHECK = 31 - CMFFLG % 31; + CMFFLG += FCHECK; + + (*out)[0] = (unsigned char)(CMFFLG >> 8); + (*out)[1] = (unsigned char)(CMFFLG & 255); + for(i = 0; i != deflatesize; ++i) (*out)[i + 2] = deflatedata[i]; + lodepng_set32bitInt(&(*out)[*outsize - 4], ADLER32); + } + + lodepng_free(deflatedata); + return error; +} + +/* compress using the default or custom zlib function */ +static unsigned zlib_compress(unsigned char** out, size_t* outsize, const unsigned char* in, + size_t insize, const LodePNGCompressSettings* settings) { + if(settings->custom_zlib) { + return settings->custom_zlib(out, outsize, in, insize, settings); + } else { + return lodepng_zlib_compress(out, outsize, in, insize, settings); + } +} + +#endif /*LODEPNG_COMPILE_ENCODER*/ + +#else /*no LODEPNG_COMPILE_ZLIB*/ + +#ifdef LODEPNG_COMPILE_DECODER +static unsigned zlib_decompress(unsigned char** out, size_t* outsize, const unsigned char* in, + size_t insize, const LodePNGDecompressSettings* settings) { + if(!settings->custom_zlib) return 87; /*no custom zlib function provided */ + return settings->custom_zlib(out, outsize, in, insize, settings); +} +#endif /*LODEPNG_COMPILE_DECODER*/ +#ifdef LODEPNG_COMPILE_ENCODER +static unsigned zlib_compress(unsigned char** out, size_t* outsize, const unsigned char* in, + size_t insize, const LodePNGCompressSettings* settings) { + if(!settings->custom_zlib) return 87; /*no custom zlib function provided */ + return settings->custom_zlib(out, outsize, in, insize, settings); +} +#endif /*LODEPNG_COMPILE_ENCODER*/ + +#endif /*LODEPNG_COMPILE_ZLIB*/ + +/* ////////////////////////////////////////////////////////////////////////// */ + +#ifdef LODEPNG_COMPILE_ENCODER + +/*this is a good tradeoff between speed and compression ratio*/ +#define DEFAULT_WINDOWSIZE 2048 + +void lodepng_compress_settings_init(LodePNGCompressSettings* settings) { + /*compress with dynamic huffman tree (not in the mathematical sense, just not the predefined one)*/ + settings->btype = 2; + settings->use_lz77 = 1; + settings->windowsize = DEFAULT_WINDOWSIZE; + settings->minmatch = 3; + settings->nicematch = 128; + settings->lazymatching = 1; + + settings->custom_zlib = 0; + settings->custom_deflate = 0; + settings->custom_context = 0; +} + +const LodePNGCompressSettings lodepng_default_compress_settings = {2, 1, DEFAULT_WINDOWSIZE, 3, 128, 1, 0, 0, 0}; + + +#endif /*LODEPNG_COMPILE_ENCODER*/ + +#ifdef LODEPNG_COMPILE_DECODER + +void lodepng_decompress_settings_init(LodePNGDecompressSettings* settings) { + settings->ignore_adler32 = 0; + settings->ignore_nlen = 0; + + settings->custom_zlib = 0; + settings->custom_inflate = 0; + settings->custom_context = 0; +} + +const LodePNGDecompressSettings lodepng_default_decompress_settings = {0, 0, 0, 0, 0}; + +#endif /*LODEPNG_COMPILE_DECODER*/ + +/* ////////////////////////////////////////////////////////////////////////// */ +/* ////////////////////////////////////////////////////////////////////////// */ +/* // End of Zlib related code. Begin of PNG related code. // */ +/* ////////////////////////////////////////////////////////////////////////// */ +/* ////////////////////////////////////////////////////////////////////////// */ + +#ifdef LODEPNG_COMPILE_PNG + +/* ////////////////////////////////////////////////////////////////////////// */ +/* / CRC32 / */ +/* ////////////////////////////////////////////////////////////////////////// */ + + +#ifndef LODEPNG_NO_COMPILE_CRC +/* CRC polynomial: 0xedb88320 */ +static unsigned lodepng_crc32_table[256] = { + 0u, 1996959894u, 3993919788u, 2567524794u, 124634137u, 1886057615u, 3915621685u, 2657392035u, + 249268274u, 2044508324u, 3772115230u, 2547177864u, 162941995u, 2125561021u, 3887607047u, 2428444049u, + 498536548u, 1789927666u, 4089016648u, 2227061214u, 450548861u, 1843258603u, 4107580753u, 2211677639u, + 325883990u, 1684777152u, 4251122042u, 2321926636u, 335633487u, 1661365465u, 4195302755u, 2366115317u, + 997073096u, 1281953886u, 3579855332u, 2724688242u, 1006888145u, 1258607687u, 3524101629u, 2768942443u, + 901097722u, 1119000684u, 3686517206u, 2898065728u, 853044451u, 1172266101u, 3705015759u, 2882616665u, + 651767980u, 1373503546u, 3369554304u, 3218104598u, 565507253u, 1454621731u, 3485111705u, 3099436303u, + 671266974u, 1594198024u, 3322730930u, 2970347812u, 795835527u, 1483230225u, 3244367275u, 3060149565u, + 1994146192u, 31158534u, 2563907772u, 4023717930u, 1907459465u, 112637215u, 2680153253u, 3904427059u, + 2013776290u, 251722036u, 2517215374u, 3775830040u, 2137656763u, 141376813u, 2439277719u, 3865271297u, + 1802195444u, 476864866u, 2238001368u, 4066508878u, 1812370925u, 453092731u, 2181625025u, 4111451223u, + 1706088902u, 314042704u, 2344532202u, 4240017532u, 1658658271u, 366619977u, 2362670323u, 4224994405u, + 1303535960u, 984961486u, 2747007092u, 3569037538u, 1256170817u, 1037604311u, 2765210733u, 3554079995u, + 1131014506u, 879679996u, 2909243462u, 3663771856u, 1141124467u, 855842277u, 2852801631u, 3708648649u, + 1342533948u, 654459306u, 3188396048u, 3373015174u, 1466479909u, 544179635u, 3110523913u, 3462522015u, + 1591671054u, 702138776u, 2966460450u, 3352799412u, 1504918807u, 783551873u, 3082640443u, 3233442989u, + 3988292384u, 2596254646u, 62317068u, 1957810842u, 3939845945u, 2647816111u, 81470997u, 1943803523u, + 3814918930u, 2489596804u, 225274430u, 2053790376u, 3826175755u, 2466906013u, 167816743u, 2097651377u, + 4027552580u, 2265490386u, 503444072u, 1762050814u, 4150417245u, 2154129355u, 426522225u, 1852507879u, + 4275313526u, 2312317920u, 282753626u, 1742555852u, 4189708143u, 2394877945u, 397917763u, 1622183637u, + 3604390888u, 2714866558u, 953729732u, 1340076626u, 3518719985u, 2797360999u, 1068828381u, 1219638859u, + 3624741850u, 2936675148u, 906185462u, 1090812512u, 3747672003u, 2825379669u, 829329135u, 1181335161u, + 3412177804u, 3160834842u, 628085408u, 1382605366u, 3423369109u, 3138078467u, 570562233u, 1426400815u, + 3317316542u, 2998733608u, 733239954u, 1555261956u, 3268935591u, 3050360625u, 752459403u, 1541320221u, + 2607071920u, 3965973030u, 1969922972u, 40735498u, 2617837225u, 3943577151u, 1913087877u, 83908371u, + 2512341634u, 3803740692u, 2075208622u, 213261112u, 2463272603u, 3855990285u, 2094854071u, 198958881u, + 2262029012u, 4057260610u, 1759359992u, 534414190u, 2176718541u, 4139329115u, 1873836001u, 414664567u, + 2282248934u, 4279200368u, 1711684554u, 285281116u, 2405801727u, 4167216745u, 1634467795u, 376229701u, + 2685067896u, 3608007406u, 1308918612u, 956543938u, 2808555105u, 3495958263u, 1231636301u, 1047427035u, + 2932959818u, 3654703836u, 1088359270u, 936918000u, 2847714899u, 3736837829u, 1202900863u, 817233897u, + 3183342108u, 3401237130u, 1404277552u, 615818150u, 3134207493u, 3453421203u, 1423857449u, 601450431u, + 3009837614u, 3294710456u, 1567103746u, 711928724u, 3020668471u, 3272380065u, 1510334235u, 755167117u +}; + +/*Return the CRC of the bytes buf[0..len-1].*/ +unsigned lodepng_crc32(const unsigned char* data, size_t length) { + unsigned r = 0xffffffffu; + size_t i; + for(i = 0; i < length; ++i) { + r = lodepng_crc32_table[(r ^ data[i]) & 0xffu] ^ (r >> 8u); + } + return r ^ 0xffffffffu; +} +#else /* !LODEPNG_NO_COMPILE_CRC */ +unsigned lodepng_crc32(const unsigned char* data, size_t length); +#endif /* !LODEPNG_NO_COMPILE_CRC */ + +/* ////////////////////////////////////////////////////////////////////////// */ +/* / Reading and writing PNG color channel bits / */ +/* ////////////////////////////////////////////////////////////////////////// */ + +/* The color channel bits of less-than-8-bit pixels are read with the MSB of bytes first, +so LodePNGBitWriter and LodePNGBitReader can't be used for those. */ + +static unsigned char readBitFromReversedStream(size_t* bitpointer, const unsigned char* bitstream) { + unsigned char result = (unsigned char)((bitstream[(*bitpointer) >> 3] >> (7 - ((*bitpointer) & 0x7))) & 1); + ++(*bitpointer); + return result; +} + +static unsigned readBitsFromReversedStream(size_t* bitpointer, const unsigned char* bitstream, size_t nbits) { + unsigned result = 0; + size_t i; + for(i = 0 ; i < nbits; ++i) { + result <<= 1; + result |= (unsigned)readBitFromReversedStream(bitpointer, bitstream); + } + return result; +} + +static void setBitOfReversedStream(size_t* bitpointer, unsigned char* bitstream, unsigned char bit) { + /*the current bit in bitstream may be 0 or 1 for this to work*/ + if(bit == 0) bitstream[(*bitpointer) >> 3] &= (unsigned char)(~(1 << (7 - ((*bitpointer) & 0x7)))); + else bitstream[(*bitpointer) >> 3] |= (1 << (7 - ((*bitpointer) & 0x7))); + ++(*bitpointer); +} + +/* ////////////////////////////////////////////////////////////////////////// */ +/* / PNG chunks / */ +/* ////////////////////////////////////////////////////////////////////////// */ + +unsigned lodepng_chunk_length(const unsigned char* chunk) { + return lodepng_read32bitInt(&chunk[0]); +} + +void lodepng_chunk_type(char type[5], const unsigned char* chunk) { + unsigned i; + for(i = 0; i != 4; ++i) type[i] = (char)chunk[4 + i]; + type[4] = 0; /*null termination char*/ +} + +unsigned char lodepng_chunk_type_equals(const unsigned char* chunk, const char* type) { + if(lodepng_strlen(type) != 4) return 0; + return (chunk[4] == type[0] && chunk[5] == type[1] && chunk[6] == type[2] && chunk[7] == type[3]); +} + +unsigned char lodepng_chunk_ancillary(const unsigned char* chunk) { + return((chunk[4] & 32) != 0); +} + +unsigned char lodepng_chunk_private(const unsigned char* chunk) { + return((chunk[6] & 32) != 0); +} + +unsigned char lodepng_chunk_safetocopy(const unsigned char* chunk) { + return((chunk[7] & 32) != 0); +} + +unsigned char* lodepng_chunk_data(unsigned char* chunk) { + return &chunk[8]; +} + +const unsigned char* lodepng_chunk_data_const(const unsigned char* chunk) { + return &chunk[8]; +} + +unsigned lodepng_chunk_check_crc(const unsigned char* chunk) { + unsigned length = lodepng_chunk_length(chunk); + unsigned CRC = lodepng_read32bitInt(&chunk[length + 8]); + /*the CRC is taken of the data and the 4 chunk type letters, not the length*/ + unsigned checksum = lodepng_crc32(&chunk[4], length + 4); + if(CRC != checksum) return 1; + else return 0; +} + +void lodepng_chunk_generate_crc(unsigned char* chunk) { + unsigned length = lodepng_chunk_length(chunk); + unsigned CRC = lodepng_crc32(&chunk[4], length + 4); + lodepng_set32bitInt(chunk + 8 + length, CRC); +} + +unsigned char* lodepng_chunk_next(unsigned char* chunk) { + if(chunk[0] == 0x89 && chunk[1] == 0x50 && chunk[2] == 0x4e && chunk[3] == 0x47 + && chunk[4] == 0x0d && chunk[5] == 0x0a && chunk[6] == 0x1a && chunk[7] == 0x0a) { + /* Is PNG magic header at start of PNG file. Jump to first actual chunk. */ + return chunk + 8; + } else { + unsigned total_chunk_length = lodepng_chunk_length(chunk) + 12; + return chunk + total_chunk_length; + } +} + +const unsigned char* lodepng_chunk_next_const(const unsigned char* chunk) { + if(chunk[0] == 0x89 && chunk[1] == 0x50 && chunk[2] == 0x4e && chunk[3] == 0x47 + && chunk[4] == 0x0d && chunk[5] == 0x0a && chunk[6] == 0x1a && chunk[7] == 0x0a) { + /* Is PNG magic header at start of PNG file. Jump to first actual chunk. */ + return chunk + 8; + } else { + unsigned total_chunk_length = lodepng_chunk_length(chunk) + 12; + return chunk + total_chunk_length; + } +} + +unsigned char* lodepng_chunk_find(unsigned char* chunk, const unsigned char* end, const char type[5]) { + for(;;) { + if(chunk + 12 >= end) return 0; + if(lodepng_chunk_type_equals(chunk, type)) return chunk; + chunk = lodepng_chunk_next(chunk); + } +} + +const unsigned char* lodepng_chunk_find_const(const unsigned char* chunk, const unsigned char* end, const char type[5]) { + for(;;) { + if(chunk + 12 >= end) return 0; + if(lodepng_chunk_type_equals(chunk, type)) return chunk; + chunk = lodepng_chunk_next_const(chunk); + } +} + +unsigned lodepng_chunk_append(unsigned char** out, size_t* outlength, const unsigned char* chunk) { + unsigned i; + unsigned total_chunk_length = lodepng_chunk_length(chunk) + 12; + unsigned char *chunk_start, *new_buffer; + size_t new_length = (*outlength) + total_chunk_length; + if(new_length < total_chunk_length || new_length < (*outlength)) return 77; /*integer overflow happened*/ + + new_buffer = (unsigned char*)lodepng_realloc(*out, new_length); + if(!new_buffer) return 83; /*alloc fail*/ + (*out) = new_buffer; + (*outlength) = new_length; + chunk_start = &(*out)[new_length - total_chunk_length]; + + for(i = 0; i != total_chunk_length; ++i) chunk_start[i] = chunk[i]; + + return 0; +} + +unsigned lodepng_chunk_create(unsigned char** out, size_t* outlength, unsigned length, + const char* type, const unsigned char* data) { + unsigned i; + unsigned char *chunk, *new_buffer; + size_t new_length = (*outlength) + length + 12; + if(new_length < length + 12 || new_length < (*outlength)) return 77; /*integer overflow happened*/ + new_buffer = (unsigned char*)lodepng_realloc(*out, new_length); + if(!new_buffer) return 83; /*alloc fail*/ + (*out) = new_buffer; + (*outlength) = new_length; + chunk = &(*out)[(*outlength) - length - 12]; + + /*1: length*/ + lodepng_set32bitInt(chunk, (unsigned)length); + + /*2: chunk name (4 letters)*/ + chunk[4] = (unsigned char)type[0]; + chunk[5] = (unsigned char)type[1]; + chunk[6] = (unsigned char)type[2]; + chunk[7] = (unsigned char)type[3]; + + /*3: the data*/ + for(i = 0; i != length; ++i) chunk[8 + i] = data[i]; + + /*4: CRC (of the chunkname characters and the data)*/ + lodepng_chunk_generate_crc(chunk); + + return 0; +} + +/* ////////////////////////////////////////////////////////////////////////// */ +/* / Color types, channels, bits / */ +/* ////////////////////////////////////////////////////////////////////////// */ + +/*checks if the colortype is valid and the bitdepth bd is allowed for this colortype. +Return value is a LodePNG error code.*/ +static unsigned checkColorValidity(LodePNGColorType colortype, unsigned bd) { + switch(colortype) { + case LCT_GREY: if(!(bd == 1 || bd == 2 || bd == 4 || bd == 8 || bd == 16)) return 37; break; + case LCT_RGB: if(!( bd == 8 || bd == 16)) return 37; break; + case LCT_PALETTE: if(!(bd == 1 || bd == 2 || bd == 4 || bd == 8 )) return 37; break; + case LCT_GREY_ALPHA: if(!( bd == 8 || bd == 16)) return 37; break; + case LCT_RGBA: if(!( bd == 8 || bd == 16)) return 37; break; + default: return 31; /* invalid color type */ + } + return 0; /*allowed color type / bits combination*/ +} + +static unsigned getNumColorChannels(LodePNGColorType colortype) { + switch(colortype) { + case LCT_GREY: return 1; + case LCT_RGB: return 3; + case LCT_PALETTE: return 1; + case LCT_GREY_ALPHA: return 2; + case LCT_RGBA: return 4; + default: return 0; /*invalid color type*/ + } +} + +static unsigned lodepng_get_bpp_lct(LodePNGColorType colortype, unsigned bitdepth) { + /*bits per pixel is amount of channels * bits per channel*/ + return getNumColorChannels(colortype) * bitdepth; +} + +/* ////////////////////////////////////////////////////////////////////////// */ + +void lodepng_color_mode_init(LodePNGColorMode* info) { + info->key_defined = 0; + info->key_r = info->key_g = info->key_b = 0; + info->colortype = LCT_RGBA; + info->bitdepth = 8; + info->palette = 0; + info->palettesize = 0; +} + +void lodepng_color_mode_cleanup(LodePNGColorMode* info) { + lodepng_palette_clear(info); +} + +unsigned lodepng_color_mode_copy(LodePNGColorMode* dest, const LodePNGColorMode* source) { + size_t i; + lodepng_color_mode_cleanup(dest); + *dest = *source; + if(source->palette) { + dest->palette = (unsigned char*)lodepng_malloc(1024); + if(!dest->palette && source->palettesize) return 83; /*alloc fail*/ + for(i = 0; i != source->palettesize * 4; ++i) dest->palette[i] = source->palette[i]; + } + return 0; +} + +LodePNGColorMode lodepng_color_mode_make(LodePNGColorType colortype, unsigned bitdepth) { + LodePNGColorMode result; + lodepng_color_mode_init(&result); + result.colortype = colortype; + result.bitdepth = bitdepth; + return result; +} + +static int lodepng_color_mode_equal(const LodePNGColorMode* a, const LodePNGColorMode* b) { + size_t i; + if(a->colortype != b->colortype) return 0; + if(a->bitdepth != b->bitdepth) return 0; + if(a->key_defined != b->key_defined) return 0; + if(a->key_defined) { + if(a->key_r != b->key_r) return 0; + if(a->key_g != b->key_g) return 0; + if(a->key_b != b->key_b) return 0; + } + if(a->palettesize != b->palettesize) return 0; + for(i = 0; i != a->palettesize * 4; ++i) { + if(a->palette[i] != b->palette[i]) return 0; + } + return 1; +} + +void lodepng_palette_clear(LodePNGColorMode* info) { + if(info->palette) lodepng_free(info->palette); + info->palette = 0; + info->palettesize = 0; +} + +unsigned lodepng_palette_add(LodePNGColorMode* info, + unsigned char r, unsigned char g, unsigned char b, unsigned char a) { + unsigned char* data; + /*the same resize technique as C++ std::vectors is used, and here it's made so that for a palette with + the max of 256 colors, it'll have the exact alloc size*/ + if(!info->palette) /*allocate palette if empty*/ { + /*room for 256 colors with 4 bytes each*/ + data = (unsigned char*)lodepng_realloc(info->palette, 1024); + if(!data) return 83; /*alloc fail*/ + else info->palette = data; + } + info->palette[4 * info->palettesize + 0] = r; + info->palette[4 * info->palettesize + 1] = g; + info->palette[4 * info->palettesize + 2] = b; + info->palette[4 * info->palettesize + 3] = a; + ++info->palettesize; + return 0; +} + +/*calculate bits per pixel out of colortype and bitdepth*/ +unsigned lodepng_get_bpp(const LodePNGColorMode* info) { + return lodepng_get_bpp_lct(info->colortype, info->bitdepth); +} + +unsigned lodepng_get_channels(const LodePNGColorMode* info) { + return getNumColorChannels(info->colortype); +} + +unsigned lodepng_is_greyscale_type(const LodePNGColorMode* info) { + return info->colortype == LCT_GREY || info->colortype == LCT_GREY_ALPHA; +} + +unsigned lodepng_is_alpha_type(const LodePNGColorMode* info) { + return (info->colortype & 4) != 0; /*4 or 6*/ +} + +unsigned lodepng_is_palette_type(const LodePNGColorMode* info) { + return info->colortype == LCT_PALETTE; +} + +unsigned lodepng_has_palette_alpha(const LodePNGColorMode* info) { + size_t i; + for(i = 0; i != info->palettesize; ++i) { + if(info->palette[i * 4 + 3] < 255) return 1; + } + return 0; +} + +unsigned lodepng_can_have_alpha(const LodePNGColorMode* info) { + return info->key_defined + || lodepng_is_alpha_type(info) + || lodepng_has_palette_alpha(info); +} + +static size_t lodepng_get_raw_size_lct(unsigned w, unsigned h, LodePNGColorType colortype, unsigned bitdepth) { + size_t bpp = lodepng_get_bpp_lct(colortype, bitdepth); + size_t n = (size_t)w * (size_t)h; + return ((n / 8u) * bpp) + ((n & 7u) * bpp + 7u) / 8u; +} + +size_t lodepng_get_raw_size(unsigned w, unsigned h, const LodePNGColorMode* color) { + return lodepng_get_raw_size_lct(w, h, color->colortype, color->bitdepth); +} + + +#ifdef LODEPNG_COMPILE_PNG +#ifdef LODEPNG_COMPILE_DECODER + +/*in an idat chunk, each scanline is a multiple of 8 bits, unlike the lodepng output buffer, +and in addition has one extra byte per line: the filter byte. So this gives a larger +result than lodepng_get_raw_size. */ +static size_t lodepng_get_raw_size_idat(unsigned w, unsigned h, const LodePNGColorMode* color) { + size_t bpp = lodepng_get_bpp(color); + /* + 1 for the filter byte, and possibly plus padding bits per line */ + size_t line = ((size_t)(w / 8u) * bpp) + 1u + ((w & 7u) * bpp + 7u) / 8u; + return (size_t)h * line; +} + +/* Safely check if multiplying two integers will overflow (no undefined +behavior, compiler removing the code, etc...) and output result. */ +static int lodepng_mulofl(size_t a, size_t b, size_t* result) { + *result = a * b; /* Unsigned multiplication is well defined and safe in C90 */ + return (a != 0 && *result / a != b); +} + +/* Safely check if adding two integers will overflow (no undefined +behavior, compiler removing the code, etc...) and output result. */ +static int lodepng_addofl(size_t a, size_t b, size_t* result) { + *result = a + b; /* Unsigned addition is well defined and safe in C90 */ + return *result < a; +} + +/*Safely checks whether size_t overflow can be caused due to amount of pixels. +This check is overcautious rather than precise. If this check indicates no overflow, +you can safely compute in a size_t (but not an unsigned): +-(size_t)w * (size_t)h * 8 +-amount of bytes in IDAT (including filter, padding and Adam7 bytes) +-amount of bytes in raw color model +Returns 1 if overflow possible, 0 if not. +*/ +static int lodepng_pixel_overflow(unsigned w, unsigned h, + const LodePNGColorMode* pngcolor, const LodePNGColorMode* rawcolor) { + size_t bpp = LODEPNG_MAX(lodepng_get_bpp(pngcolor), lodepng_get_bpp(rawcolor)); + size_t numpixels, total; + size_t line; /* bytes per line in worst case */ + + if(lodepng_mulofl((size_t)w, (size_t)h, &numpixels)) return 1; + if(lodepng_mulofl(numpixels, 8, &total)) return 1; /* bit pointer with 8-bit color, or 8 bytes per channel color */ + + /* Bytes per scanline with the expression "(w / 8u) * bpp) + ((w & 7u) * bpp + 7u) / 8u" */ + if(lodepng_mulofl((size_t)(w / 8u), bpp, &line)) return 1; + if(lodepng_addofl(line, ((w & 7u) * bpp + 7u) / 8u, &line)) return 1; + + if(lodepng_addofl(line, 5, &line)) return 1; /* 5 bytes overhead per line: 1 filterbyte, 4 for Adam7 worst case */ + if(lodepng_mulofl(line, h, &total)) return 1; /* Total bytes in worst case */ + + return 0; /* no overflow */ +} +#endif /*LODEPNG_COMPILE_DECODER*/ +#endif /*LODEPNG_COMPILE_PNG*/ + +#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS + +static void LodePNGUnknownChunks_init(LodePNGInfo* info) { + unsigned i; + for(i = 0; i != 3; ++i) info->unknown_chunks_data[i] = 0; + for(i = 0; i != 3; ++i) info->unknown_chunks_size[i] = 0; +} + +static void LodePNGUnknownChunks_cleanup(LodePNGInfo* info) { + unsigned i; + for(i = 0; i != 3; ++i) lodepng_free(info->unknown_chunks_data[i]); +} + +static unsigned LodePNGUnknownChunks_copy(LodePNGInfo* dest, const LodePNGInfo* src) { + unsigned i; + + LodePNGUnknownChunks_cleanup(dest); + + for(i = 0; i != 3; ++i) { + size_t j; + dest->unknown_chunks_size[i] = src->unknown_chunks_size[i]; + dest->unknown_chunks_data[i] = (unsigned char*)lodepng_malloc(src->unknown_chunks_size[i]); + if(!dest->unknown_chunks_data[i] && dest->unknown_chunks_size[i]) return 83; /*alloc fail*/ + for(j = 0; j < src->unknown_chunks_size[i]; ++j) { + dest->unknown_chunks_data[i][j] = src->unknown_chunks_data[i][j]; + } + } + + return 0; +} + +/******************************************************************************/ + +static void LodePNGText_init(LodePNGInfo* info) { + info->text_num = 0; + info->text_keys = NULL; + info->text_strings = NULL; +} + +static void LodePNGText_cleanup(LodePNGInfo* info) { + size_t i; + for(i = 0; i != info->text_num; ++i) { + string_cleanup(&info->text_keys[i]); + string_cleanup(&info->text_strings[i]); + } + lodepng_free(info->text_keys); + lodepng_free(info->text_strings); +} + +static unsigned LodePNGText_copy(LodePNGInfo* dest, const LodePNGInfo* source) { + size_t i = 0; + dest->text_keys = 0; + dest->text_strings = 0; + dest->text_num = 0; + for(i = 0; i != source->text_num; ++i) { + CERROR_TRY_RETURN(lodepng_add_text(dest, source->text_keys[i], source->text_strings[i])); + } + return 0; +} + +void lodepng_clear_text(LodePNGInfo* info) { + LodePNGText_cleanup(info); +} + +unsigned lodepng_add_text(LodePNGInfo* info, const char* key, const char* str) { + char** new_keys = (char**)(lodepng_realloc(info->text_keys, sizeof(char*) * (info->text_num + 1))); + char** new_strings = (char**)(lodepng_realloc(info->text_strings, sizeof(char*) * (info->text_num + 1))); + if(!new_keys || !new_strings) { + lodepng_free(new_keys); + lodepng_free(new_strings); + return 83; /*alloc fail*/ + } + + ++info->text_num; + info->text_keys = new_keys; + info->text_strings = new_strings; + + info->text_keys[info->text_num - 1] = alloc_string(key); + info->text_strings[info->text_num - 1] = alloc_string(str); + + return 0; +} + +/******************************************************************************/ + +static void LodePNGIText_init(LodePNGInfo* info) { + info->itext_num = 0; + info->itext_keys = NULL; + info->itext_langtags = NULL; + info->itext_transkeys = NULL; + info->itext_strings = NULL; +} + +static void LodePNGIText_cleanup(LodePNGInfo* info) { + size_t i; + for(i = 0; i != info->itext_num; ++i) { + string_cleanup(&info->itext_keys[i]); + string_cleanup(&info->itext_langtags[i]); + string_cleanup(&info->itext_transkeys[i]); + string_cleanup(&info->itext_strings[i]); + } + lodepng_free(info->itext_keys); + lodepng_free(info->itext_langtags); + lodepng_free(info->itext_transkeys); + lodepng_free(info->itext_strings); +} + +static unsigned LodePNGIText_copy(LodePNGInfo* dest, const LodePNGInfo* source) { + size_t i = 0; + dest->itext_keys = 0; + dest->itext_langtags = 0; + dest->itext_transkeys = 0; + dest->itext_strings = 0; + dest->itext_num = 0; + for(i = 0; i != source->itext_num; ++i) { + CERROR_TRY_RETURN(lodepng_add_itext(dest, source->itext_keys[i], source->itext_langtags[i], + source->itext_transkeys[i], source->itext_strings[i])); + } + return 0; +} + +void lodepng_clear_itext(LodePNGInfo* info) { + LodePNGIText_cleanup(info); +} + +unsigned lodepng_add_itext(LodePNGInfo* info, const char* key, const char* langtag, + const char* transkey, const char* str) { + char** new_keys = (char**)(lodepng_realloc(info->itext_keys, sizeof(char*) * (info->itext_num + 1))); + char** new_langtags = (char**)(lodepng_realloc(info->itext_langtags, sizeof(char*) * (info->itext_num + 1))); + char** new_transkeys = (char**)(lodepng_realloc(info->itext_transkeys, sizeof(char*) * (info->itext_num + 1))); + char** new_strings = (char**)(lodepng_realloc(info->itext_strings, sizeof(char*) * (info->itext_num + 1))); + if(!new_keys || !new_langtags || !new_transkeys || !new_strings) { + lodepng_free(new_keys); + lodepng_free(new_langtags); + lodepng_free(new_transkeys); + lodepng_free(new_strings); + return 83; /*alloc fail*/ + } + + ++info->itext_num; + info->itext_keys = new_keys; + info->itext_langtags = new_langtags; + info->itext_transkeys = new_transkeys; + info->itext_strings = new_strings; + + info->itext_keys[info->itext_num - 1] = alloc_string(key); + info->itext_langtags[info->itext_num - 1] = alloc_string(langtag); + info->itext_transkeys[info->itext_num - 1] = alloc_string(transkey); + info->itext_strings[info->itext_num - 1] = alloc_string(str); + + return 0; +} + +/* same as set but does not delete */ +static unsigned lodepng_assign_icc(LodePNGInfo* info, const char* name, const unsigned char* profile, unsigned profile_size) { + if(profile_size == 0) return 100; /*invalid ICC profile size*/ + + info->iccp_name = alloc_string(name); + info->iccp_profile = (unsigned char*)lodepng_malloc(profile_size); + + if(!info->iccp_name || !info->iccp_profile) return 83; /*alloc fail*/ + + lodepng_memcpy(info->iccp_profile, profile, profile_size); + info->iccp_profile_size = profile_size; + + return 0; /*ok*/ +} + +unsigned lodepng_set_icc(LodePNGInfo* info, const char* name, const unsigned char* profile, unsigned profile_size) { + if(info->iccp_name) lodepng_clear_icc(info); + info->iccp_defined = 1; + + return lodepng_assign_icc(info, name, profile, profile_size); +} + +void lodepng_clear_icc(LodePNGInfo* info) { + string_cleanup(&info->iccp_name); + lodepng_free(info->iccp_profile); + info->iccp_profile = NULL; + info->iccp_profile_size = 0; + info->iccp_defined = 0; +} +#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ + +void lodepng_info_init(LodePNGInfo* info) { + lodepng_color_mode_init(&info->color); + info->interlace_method = 0; + info->compression_method = 0; + info->filter_method = 0; +#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS + info->background_defined = 0; + info->background_r = info->background_g = info->background_b = 0; + + LodePNGText_init(info); + LodePNGIText_init(info); + + info->time_defined = 0; + info->phys_defined = 0; + + info->gama_defined = 0; + info->chrm_defined = 0; + info->srgb_defined = 0; + info->iccp_defined = 0; + info->iccp_name = NULL; + info->iccp_profile = NULL; + + LodePNGUnknownChunks_init(info); +#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ +} + +void lodepng_info_cleanup(LodePNGInfo* info) { + lodepng_color_mode_cleanup(&info->color); +#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS + LodePNGText_cleanup(info); + LodePNGIText_cleanup(info); + + lodepng_clear_icc(info); + + LodePNGUnknownChunks_cleanup(info); +#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ +} + +unsigned lodepng_info_copy(LodePNGInfo* dest, const LodePNGInfo* source) { + lodepng_info_cleanup(dest); + *dest = *source; + lodepng_color_mode_init(&dest->color); + CERROR_TRY_RETURN(lodepng_color_mode_copy(&dest->color, &source->color)); + +#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS + CERROR_TRY_RETURN(LodePNGText_copy(dest, source)); + CERROR_TRY_RETURN(LodePNGIText_copy(dest, source)); + if(source->iccp_defined) { + CERROR_TRY_RETURN(lodepng_assign_icc(dest, source->iccp_name, source->iccp_profile, source->iccp_profile_size)); + } + + LodePNGUnknownChunks_init(dest); + CERROR_TRY_RETURN(LodePNGUnknownChunks_copy(dest, source)); +#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ + return 0; +} + +/* ////////////////////////////////////////////////////////////////////////// */ + +/*index: bitgroup index, bits: bitgroup size(1, 2 or 4), in: bitgroup value, out: octet array to add bits to*/ +static void addColorBits(unsigned char* out, size_t index, unsigned bits, unsigned in) { + unsigned m = bits == 1 ? 7 : bits == 2 ? 3 : 1; /*8 / bits - 1*/ + /*p = the partial index in the byte, e.g. with 4 palettebits it is 0 for first half or 1 for second half*/ + unsigned p = index & m; + in &= (1u << bits) - 1u; /*filter out any other bits of the input value*/ + in = in << (bits * (m - p)); + if(p == 0) out[index * bits / 8u] = in; + else out[index * bits / 8u] |= in; +} + +typedef struct ColorTree ColorTree; + +/* +One node of a color tree +This is the data structure used to count the number of unique colors and to get a palette +index for a color. It's like an octree, but because the alpha channel is used too, each +node has 16 instead of 8 children. +*/ +struct ColorTree { + ColorTree* children[16]; /*up to 16 pointers to ColorTree of next level*/ + int index; /*the payload. Only has a meaningful value if this is in the last level*/ +}; + +static void color_tree_init(ColorTree* tree) { + int i; + for(i = 0; i != 16; ++i) tree->children[i] = 0; + tree->index = -1; +} + +static void color_tree_cleanup(ColorTree* tree) { + int i; + for(i = 0; i != 16; ++i) { + if(tree->children[i]) { + color_tree_cleanup(tree->children[i]); + lodepng_free(tree->children[i]); + } + } +} + +/*returns -1 if color not present, its index otherwise*/ +static int color_tree_get(ColorTree* tree, unsigned char r, unsigned char g, unsigned char b, unsigned char a) { + int bit = 0; + for(bit = 0; bit < 8; ++bit) { + int i = 8 * ((r >> bit) & 1) + 4 * ((g >> bit) & 1) + 2 * ((b >> bit) & 1) + 1 * ((a >> bit) & 1); + if(!tree->children[i]) return -1; + else tree = tree->children[i]; + } + return tree ? tree->index : -1; +} + +#ifdef LODEPNG_COMPILE_ENCODER +static int color_tree_has(ColorTree* tree, unsigned char r, unsigned char g, unsigned char b, unsigned char a) { + return color_tree_get(tree, r, g, b, a) >= 0; +} +#endif /*LODEPNG_COMPILE_ENCODER*/ + +/*color is not allowed to already exist. +Index should be >= 0 (it's signed to be compatible with using -1 for "doesn't exist")*/ +static void color_tree_add(ColorTree* tree, + unsigned char r, unsigned char g, unsigned char b, unsigned char a, unsigned index) { + int bit; + for(bit = 0; bit < 8; ++bit) { + int i = 8 * ((r >> bit) & 1) + 4 * ((g >> bit) & 1) + 2 * ((b >> bit) & 1) + 1 * ((a >> bit) & 1); + if(!tree->children[i]) { + tree->children[i] = (ColorTree*)lodepng_malloc(sizeof(ColorTree)); + color_tree_init(tree->children[i]); + } + tree = tree->children[i]; + } + tree->index = (int)index; +} + +/*put a pixel, given its RGBA color, into image of any color type*/ +static unsigned rgba8ToPixel(unsigned char* out, size_t i, + const LodePNGColorMode* mode, ColorTree* tree /*for palette*/, + unsigned char r, unsigned char g, unsigned char b, unsigned char a) { + if(mode->colortype == LCT_GREY) { + unsigned char gray = r; /*((unsigned short)r + g + b) / 3u;*/ + if(mode->bitdepth == 8) out[i] = gray; + else if(mode->bitdepth == 16) out[i * 2 + 0] = out[i * 2 + 1] = gray; + else { + /*take the most significant bits of gray*/ + gray = (gray >> (8 - mode->bitdepth)) & ((1 << mode->bitdepth) - 1); + addColorBits(out, i, mode->bitdepth, gray); + } + } else if(mode->colortype == LCT_RGB) { + if(mode->bitdepth == 8) { + out[i * 3 + 0] = r; + out[i * 3 + 1] = g; + out[i * 3 + 2] = b; + } else { + out[i * 6 + 0] = out[i * 6 + 1] = r; + out[i * 6 + 2] = out[i * 6 + 3] = g; + out[i * 6 + 4] = out[i * 6 + 5] = b; + } + } else if(mode->colortype == LCT_PALETTE) { + int index = color_tree_get(tree, r, g, b, a); + if(index < 0) return 82; /*color not in palette*/ + if(mode->bitdepth == 8) out[i] = index; + else addColorBits(out, i, mode->bitdepth, (unsigned)index); + } else if(mode->colortype == LCT_GREY_ALPHA) { + unsigned char gray = r; /*((unsigned short)r + g + b) / 3u;*/ + if(mode->bitdepth == 8) { + out[i * 2 + 0] = gray; + out[i * 2 + 1] = a; + } else if(mode->bitdepth == 16) { + out[i * 4 + 0] = out[i * 4 + 1] = gray; + out[i * 4 + 2] = out[i * 4 + 3] = a; + } + } else if(mode->colortype == LCT_RGBA) { + if(mode->bitdepth == 8) { + out[i * 4 + 0] = r; + out[i * 4 + 1] = g; + out[i * 4 + 2] = b; + out[i * 4 + 3] = a; + } else { + out[i * 8 + 0] = out[i * 8 + 1] = r; + out[i * 8 + 2] = out[i * 8 + 3] = g; + out[i * 8 + 4] = out[i * 8 + 5] = b; + out[i * 8 + 6] = out[i * 8 + 7] = a; + } + } + + return 0; /*no error*/ +} + +/*put a pixel, given its RGBA16 color, into image of any color 16-bitdepth type*/ +static void rgba16ToPixel(unsigned char* out, size_t i, + const LodePNGColorMode* mode, + unsigned short r, unsigned short g, unsigned short b, unsigned short a) { + if(mode->colortype == LCT_GREY) { + unsigned short gray = r; /*((unsigned)r + g + b) / 3u;*/ + out[i * 2 + 0] = (gray >> 8) & 255; + out[i * 2 + 1] = gray & 255; + } else if(mode->colortype == LCT_RGB) { + out[i * 6 + 0] = (r >> 8) & 255; + out[i * 6 + 1] = r & 255; + out[i * 6 + 2] = (g >> 8) & 255; + out[i * 6 + 3] = g & 255; + out[i * 6 + 4] = (b >> 8) & 255; + out[i * 6 + 5] = b & 255; + } else if(mode->colortype == LCT_GREY_ALPHA) { + unsigned short gray = r; /*((unsigned)r + g + b) / 3u;*/ + out[i * 4 + 0] = (gray >> 8) & 255; + out[i * 4 + 1] = gray & 255; + out[i * 4 + 2] = (a >> 8) & 255; + out[i * 4 + 3] = a & 255; + } else if(mode->colortype == LCT_RGBA) { + out[i * 8 + 0] = (r >> 8) & 255; + out[i * 8 + 1] = r & 255; + out[i * 8 + 2] = (g >> 8) & 255; + out[i * 8 + 3] = g & 255; + out[i * 8 + 4] = (b >> 8) & 255; + out[i * 8 + 5] = b & 255; + out[i * 8 + 6] = (a >> 8) & 255; + out[i * 8 + 7] = a & 255; + } +} + +/*Get RGBA8 color of pixel with index i (y * width + x) from the raw image with given color type.*/ +static void getPixelColorRGBA8(unsigned char* r, unsigned char* g, + unsigned char* b, unsigned char* a, + const unsigned char* in, size_t i, + const LodePNGColorMode* mode) { + if(mode->colortype == LCT_GREY) { + if(mode->bitdepth == 8) { + *r = *g = *b = in[i]; + if(mode->key_defined && *r == mode->key_r) *a = 0; + else *a = 255; + } else if(mode->bitdepth == 16) { + *r = *g = *b = in[i * 2 + 0]; + if(mode->key_defined && 256U * in[i * 2 + 0] + in[i * 2 + 1] == mode->key_r) *a = 0; + else *a = 255; + } else { + unsigned highest = ((1U << mode->bitdepth) - 1U); /*highest possible value for this bit depth*/ + size_t j = i * mode->bitdepth; + unsigned value = readBitsFromReversedStream(&j, in, mode->bitdepth); + *r = *g = *b = (value * 255) / highest; + if(mode->key_defined && value == mode->key_r) *a = 0; + else *a = 255; + } + } else if(mode->colortype == LCT_RGB) { + if(mode->bitdepth == 8) { + *r = in[i * 3 + 0]; *g = in[i * 3 + 1]; *b = in[i * 3 + 2]; + if(mode->key_defined && *r == mode->key_r && *g == mode->key_g && *b == mode->key_b) *a = 0; + else *a = 255; + } else { + *r = in[i * 6 + 0]; + *g = in[i * 6 + 2]; + *b = in[i * 6 + 4]; + if(mode->key_defined && 256U * in[i * 6 + 0] + in[i * 6 + 1] == mode->key_r + && 256U * in[i * 6 + 2] + in[i * 6 + 3] == mode->key_g + && 256U * in[i * 6 + 4] + in[i * 6 + 5] == mode->key_b) *a = 0; + else *a = 255; + } + } else if(mode->colortype == LCT_PALETTE) { + unsigned index; + if(mode->bitdepth == 8) index = in[i]; + else { + size_t j = i * mode->bitdepth; + index = readBitsFromReversedStream(&j, in, mode->bitdepth); + } + + if(index >= mode->palettesize) { + /*This is an error according to the PNG spec, but common PNG decoders make it black instead. + Done here too, slightly faster due to no error handling needed.*/ + *r = *g = *b = 0; + *a = 255; + } else { + *r = mode->palette[index * 4 + 0]; + *g = mode->palette[index * 4 + 1]; + *b = mode->palette[index * 4 + 2]; + *a = mode->palette[index * 4 + 3]; + } + } else if(mode->colortype == LCT_GREY_ALPHA) { + if(mode->bitdepth == 8) { + *r = *g = *b = in[i * 2 + 0]; + *a = in[i * 2 + 1]; + } else { + *r = *g = *b = in[i * 4 + 0]; + *a = in[i * 4 + 2]; + } + } else if(mode->colortype == LCT_RGBA) { + if(mode->bitdepth == 8) { + *r = in[i * 4 + 0]; + *g = in[i * 4 + 1]; + *b = in[i * 4 + 2]; + *a = in[i * 4 + 3]; + } else { + *r = in[i * 8 + 0]; + *g = in[i * 8 + 2]; + *b = in[i * 8 + 4]; + *a = in[i * 8 + 6]; + } + } +} + +/*Similar to getPixelColorRGBA8, but with all the for loops inside of the color +mode test cases, optimized to convert the colors much faster, when converting +to RGBA or RGB with 8 bit per cannel. buffer must be RGBA or RGB output with +enough memory, if has_alpha is true the output is RGBA. mode has the color mode +of the input buffer.*/ +static void getPixelColorsRGBA8(unsigned char* buffer, size_t numpixels, + unsigned has_alpha, const unsigned char* in, + const LodePNGColorMode* mode) { + unsigned num_channels = has_alpha ? 4 : 3; + size_t i; + if(mode->colortype == LCT_GREY) { + if(mode->bitdepth == 8) { + for(i = 0; i != numpixels; ++i, buffer += num_channels) { + buffer[0] = buffer[1] = buffer[2] = in[i]; + if(has_alpha) buffer[3] = mode->key_defined && in[i] == mode->key_r ? 0 : 255; + } + } else if(mode->bitdepth == 16) { + for(i = 0; i != numpixels; ++i, buffer += num_channels) { + buffer[0] = buffer[1] = buffer[2] = in[i * 2]; + if(has_alpha) buffer[3] = mode->key_defined && 256U * in[i * 2 + 0] + in[i * 2 + 1] == mode->key_r ? 0 : 255; + } + } else { + unsigned highest = ((1U << mode->bitdepth) - 1U); /*highest possible value for this bit depth*/ + size_t j = 0; + for(i = 0; i != numpixels; ++i, buffer += num_channels) { + unsigned value = readBitsFromReversedStream(&j, in, mode->bitdepth); + buffer[0] = buffer[1] = buffer[2] = (value * 255) / highest; + if(has_alpha) buffer[3] = mode->key_defined && value == mode->key_r ? 0 : 255; + } + } + } else if(mode->colortype == LCT_RGB) { + if(mode->bitdepth == 8) { + for(i = 0; i != numpixels; ++i, buffer += num_channels) { + buffer[0] = in[i * 3 + 0]; + buffer[1] = in[i * 3 + 1]; + buffer[2] = in[i * 3 + 2]; + if(has_alpha) buffer[3] = mode->key_defined && buffer[0] == mode->key_r + && buffer[1]== mode->key_g && buffer[2] == mode->key_b ? 0 : 255; + } + } else { + for(i = 0; i != numpixels; ++i, buffer += num_channels) { + buffer[0] = in[i * 6 + 0]; + buffer[1] = in[i * 6 + 2]; + buffer[2] = in[i * 6 + 4]; + if(has_alpha) buffer[3] = mode->key_defined + && 256U * in[i * 6 + 0] + in[i * 6 + 1] == mode->key_r + && 256U * in[i * 6 + 2] + in[i * 6 + 3] == mode->key_g + && 256U * in[i * 6 + 4] + in[i * 6 + 5] == mode->key_b ? 0 : 255; + } + } + } else if(mode->colortype == LCT_PALETTE) { + unsigned index; + size_t j = 0; + for(i = 0; i != numpixels; ++i, buffer += num_channels) { + if(mode->bitdepth == 8) index = in[i]; + else index = readBitsFromReversedStream(&j, in, mode->bitdepth); + + if(index >= mode->palettesize) { + /*This is an error according to the PNG spec, but most PNG decoders make it black instead. + Done here too, slightly faster due to no error handling needed.*/ + buffer[0] = buffer[1] = buffer[2] = 0; + if(has_alpha) buffer[3] = 255; + } else { + buffer[0] = mode->palette[index * 4 + 0]; + buffer[1] = mode->palette[index * 4 + 1]; + buffer[2] = mode->palette[index * 4 + 2]; + if(has_alpha) buffer[3] = mode->palette[index * 4 + 3]; + } + } + } else if(mode->colortype == LCT_GREY_ALPHA) { + if(mode->bitdepth == 8) { + for(i = 0; i != numpixels; ++i, buffer += num_channels) { + buffer[0] = buffer[1] = buffer[2] = in[i * 2 + 0]; + if(has_alpha) buffer[3] = in[i * 2 + 1]; + } + } else { + for(i = 0; i != numpixels; ++i, buffer += num_channels) { + buffer[0] = buffer[1] = buffer[2] = in[i * 4 + 0]; + if(has_alpha) buffer[3] = in[i * 4 + 2]; + } + } + } else if(mode->colortype == LCT_RGBA) { + if(mode->bitdepth == 8) { + for(i = 0; i != numpixels; ++i, buffer += num_channels) { + buffer[0] = in[i * 4 + 0]; + buffer[1] = in[i * 4 + 1]; + buffer[2] = in[i * 4 + 2]; + if(has_alpha) buffer[3] = in[i * 4 + 3]; + } + } else { + for(i = 0; i != numpixels; ++i, buffer += num_channels) { + buffer[0] = in[i * 8 + 0]; + buffer[1] = in[i * 8 + 2]; + buffer[2] = in[i * 8 + 4]; + if(has_alpha) buffer[3] = in[i * 8 + 6]; + } + } + } +} + +/*Get RGBA16 color of pixel with index i (y * width + x) from the raw image with +given color type, but the given color type must be 16-bit itself.*/ +static void getPixelColorRGBA16(unsigned short* r, unsigned short* g, unsigned short* b, unsigned short* a, + const unsigned char* in, size_t i, const LodePNGColorMode* mode) { + if(mode->colortype == LCT_GREY) { + *r = *g = *b = 256 * in[i * 2 + 0] + in[i * 2 + 1]; + if(mode->key_defined && 256U * in[i * 2 + 0] + in[i * 2 + 1] == mode->key_r) *a = 0; + else *a = 65535; + } else if(mode->colortype == LCT_RGB) { + *r = 256u * in[i * 6 + 0] + in[i * 6 + 1]; + *g = 256u * in[i * 6 + 2] + in[i * 6 + 3]; + *b = 256u * in[i * 6 + 4] + in[i * 6 + 5]; + if(mode->key_defined + && 256u * in[i * 6 + 0] + in[i * 6 + 1] == mode->key_r + && 256u * in[i * 6 + 2] + in[i * 6 + 3] == mode->key_g + && 256u * in[i * 6 + 4] + in[i * 6 + 5] == mode->key_b) *a = 0; + else *a = 65535; + } else if(mode->colortype == LCT_GREY_ALPHA) { + *r = *g = *b = 256u * in[i * 4 + 0] + in[i * 4 + 1]; + *a = 256u * in[i * 4 + 2] + in[i * 4 + 3]; + } else if(mode->colortype == LCT_RGBA) { + *r = 256u * in[i * 8 + 0] + in[i * 8 + 1]; + *g = 256u * in[i * 8 + 2] + in[i * 8 + 3]; + *b = 256u * in[i * 8 + 4] + in[i * 8 + 5]; + *a = 256u * in[i * 8 + 6] + in[i * 8 + 7]; + } +} + +unsigned lodepng_convert(unsigned char* out, const unsigned char* in, + const LodePNGColorMode* mode_out, const LodePNGColorMode* mode_in, + unsigned w, unsigned h) { + size_t i; + ColorTree tree; + size_t numpixels = (size_t)w * (size_t)h; + unsigned error = 0; + + if(lodepng_color_mode_equal(mode_out, mode_in)) { + size_t numbytes = lodepng_get_raw_size(w, h, mode_in); + for(i = 0; i != numbytes; ++i) out[i] = in[i]; + return 0; + } + + if(mode_out->colortype == LCT_PALETTE) { + size_t palettesize = mode_out->palettesize; + const unsigned char* palette = mode_out->palette; + size_t palsize = (size_t)1u << mode_out->bitdepth; + /*if the user specified output palette but did not give the values, assume + they want the values of the input color type (assuming that one is palette). + Note that we never create a new palette ourselves.*/ + if(palettesize == 0) { + palettesize = mode_in->palettesize; + palette = mode_in->palette; + /*if the input was also palette with same bitdepth, then the color types are also + equal, so copy literally. This to preserve the exact indices that were in the PNG + even in case there are duplicate colors in the palette.*/ + if (mode_in->colortype == LCT_PALETTE && mode_in->bitdepth == mode_out->bitdepth) { + size_t numbytes = lodepng_get_raw_size(w, h, mode_in); + for(i = 0; i != numbytes; ++i) out[i] = in[i]; + return 0; + } + } + if(palettesize < palsize) palsize = palettesize; + color_tree_init(&tree); + for(i = 0; i != palsize; ++i) { + const unsigned char* p = &palette[i * 4]; + color_tree_add(&tree, p[0], p[1], p[2], p[3], (unsigned)i); + } + } + + if(mode_in->bitdepth == 16 && mode_out->bitdepth == 16) { + for(i = 0; i != numpixels; ++i) { + unsigned short r = 0, g = 0, b = 0, a = 0; + getPixelColorRGBA16(&r, &g, &b, &a, in, i, mode_in); + rgba16ToPixel(out, i, mode_out, r, g, b, a); + } + } else if(mode_out->bitdepth == 8 && mode_out->colortype == LCT_RGBA) { + getPixelColorsRGBA8(out, numpixels, 1, in, mode_in); + } else if(mode_out->bitdepth == 8 && mode_out->colortype == LCT_RGB) { + getPixelColorsRGBA8(out, numpixels, 0, in, mode_in); + } else { + unsigned char r = 0, g = 0, b = 0, a = 0; + for(i = 0; i != numpixels; ++i) { + getPixelColorRGBA8(&r, &g, &b, &a, in, i, mode_in); + error = rgba8ToPixel(out, i, mode_out, &tree, r, g, b, a); + if (error) break; + } + } + + if(mode_out->colortype == LCT_PALETTE) { + color_tree_cleanup(&tree); + } + + return error; +} + + +/* Converts a single rgb color without alpha from one type to another, color bits truncated to +their bitdepth. In case of single channel (gray or palette), only the r channel is used. Slow +function, do not use to process all pixels of an image. Alpha channel not supported on purpose: +this is for bKGD, supporting alpha may prevent it from finding a color in the palette, from the +specification it looks like bKGD should ignore the alpha values of the palette since it can use +any palette index but doesn't have an alpha channel. Idem with ignoring color key. */ +unsigned lodepng_convert_rgb( + unsigned* r_out, unsigned* g_out, unsigned* b_out, + unsigned r_in, unsigned g_in, unsigned b_in, + const LodePNGColorMode* mode_out, const LodePNGColorMode* mode_in) { + unsigned r = 0, g = 0, b = 0; + unsigned mul = 65535 / ((1u << mode_in->bitdepth) - 1u); /*65535, 21845, 4369, 257, 1*/ + unsigned shift = 16 - mode_out->bitdepth; + + if(mode_in->colortype == LCT_GREY || mode_in->colortype == LCT_GREY_ALPHA) { + r = g = b = r_in * mul; + } else if(mode_in->colortype == LCT_RGB || mode_in->colortype == LCT_RGBA) { + r = r_in * mul; + g = g_in * mul; + b = b_in * mul; + } else if(mode_in->colortype == LCT_PALETTE) { + if(r_in >= mode_in->palettesize) return 82; + r = mode_in->palette[r_in * 4 + 0] * 257u; + g = mode_in->palette[r_in * 4 + 1] * 257u; + b = mode_in->palette[r_in * 4 + 2] * 257u; + } else { + return 31; + } + + /* now convert to output format */ + if(mode_out->colortype == LCT_GREY || mode_out->colortype == LCT_GREY_ALPHA) { + *r_out = r >> shift ; + } else if(mode_out->colortype == LCT_RGB || mode_out->colortype == LCT_RGBA) { + *r_out = r >> shift ; + *g_out = g >> shift ; + *b_out = b >> shift ; + } else if(mode_out->colortype == LCT_PALETTE) { + unsigned i; + /* a 16-bit color cannot be in the palette */ + if((r >> 8) != (r & 255) || (g >> 8) != (g & 255) || (b >> 8) != (b & 255)) return 82; + for(i = 0; i < mode_out->palettesize; i++) { + unsigned j = i * 4; + if((r >> 8) == mode_out->palette[j + 0] && (g >> 8) == mode_out->palette[j + 1] && + (b >> 8) == mode_out->palette[j + 2]) { + *r_out = i; + return 0; + } + } + return 82; + } else { + return 31; + } + + return 0; +} + +#ifdef LODEPNG_COMPILE_ENCODER + +void lodepng_color_stats_init(LodePNGColorStats* stats) { + /*stats*/ + stats->colored = 0; + stats->key = 0; + stats->key_r = stats->key_g = stats->key_b = 0; + stats->alpha = 0; + stats->numcolors = 0; + stats->bits = 1; + stats->numpixels = 0; + /*settings*/ + stats->allow_palette = 1; + stats->allow_greyscale = 1; +} + +/*function used for debug purposes with C++*/ +/*void printColorStats(LodePNGColorStats* p) { + std::cout << "colored: " << (int)p->colored << ", "; + std::cout << "key: " << (int)p->key << ", "; + std::cout << "key_r: " << (int)p->key_r << ", "; + std::cout << "key_g: " << (int)p->key_g << ", "; + std::cout << "key_b: " << (int)p->key_b << ", "; + std::cout << "alpha: " << (int)p->alpha << ", "; + std::cout << "numcolors: " << (int)p->numcolors << ", "; + std::cout << "bits: " << (int)p->bits << std::endl; +}*/ + +/*Returns how many bits needed to represent given value (max 8 bit)*/ +static unsigned getValueRequiredBits(unsigned char value) { + if(value == 0 || value == 255) return 1; + /*The scaling of 2-bit and 4-bit values uses multiples of 85 and 17*/ + if(value % 17 == 0) return value % 85 == 0 ? 2 : 4; + return 8; +} + +/*stats must already have been inited. */ +void lodepng_compute_color_stats(LodePNGColorStats* stats, + const unsigned char* in, unsigned w, unsigned h, + const LodePNGColorMode* mode_in) { + size_t i; + ColorTree tree; + size_t numpixels = (size_t)w * (size_t)h; + + /* mark things as done already if it would be impossible to have a more expensive case */ + unsigned colored_done = lodepng_is_greyscale_type(mode_in) ? 1 : 0; + unsigned alpha_done = lodepng_can_have_alpha(mode_in) ? 0 : 1; + unsigned numcolors_done = 0; + unsigned bpp = lodepng_get_bpp(mode_in); + unsigned bits_done = (stats->bits == 1 && bpp == 1) ? 1 : 0; + unsigned sixteen = 0; /* whether the input image is 16 bit */ + unsigned maxnumcolors = 257; + if(bpp <= 8) maxnumcolors = LODEPNG_MIN(257, stats->numcolors + (1u << bpp)); + + stats->numpixels += numpixels; + + /*if palette not allowed, no need to compute numcolors*/ + if(!stats->allow_palette) numcolors_done = 1; + + color_tree_init(&tree); + + /*If the stats was already filled in from previous data, fill its palette in tree + and mark things as done already if we know they are the most expensive case already*/ + if(stats->alpha) alpha_done = 1; + if(stats->colored) colored_done = 1; + if(stats->bits == 16) numcolors_done = 1; + if(stats->bits >= bpp) bits_done = 1; + if(stats->numcolors >= maxnumcolors) numcolors_done = 1; + + if(!numcolors_done) { + for(i = 0; i < stats->numcolors; i++) { + const unsigned char* color = &stats->palette[i * 4]; + color_tree_add(&tree, color[0], color[1], color[2], color[3], i); + } + } + + /*Check if the 16-bit input is truly 16-bit*/ + if(mode_in->bitdepth == 16 && !sixteen) { + unsigned short r, g, b, a; + for(i = 0; i != numpixels; ++i) { + getPixelColorRGBA16(&r, &g, &b, &a, in, i, mode_in); + if((r & 255) != ((r >> 8) & 255) || (g & 255) != ((g >> 8) & 255) || + (b & 255) != ((b >> 8) & 255) || (a & 255) != ((a >> 8) & 255)) /*first and second byte differ*/ { + stats->bits = 16; + sixteen = 1; + bits_done = 1; + numcolors_done = 1; /*counting colors no longer useful, palette doesn't support 16-bit*/ + break; + } + } + } + + if(sixteen) { + unsigned short r = 0, g = 0, b = 0, a = 0; + + for(i = 0; i != numpixels; ++i) { + getPixelColorRGBA16(&r, &g, &b, &a, in, i, mode_in); + + if(!colored_done && (r != g || r != b)) { + stats->colored = 1; + colored_done = 1; + } + + if(!alpha_done) { + unsigned matchkey = (r == stats->key_r && g == stats->key_g && b == stats->key_b); + if(a != 65535 && (a != 0 || (stats->key && !matchkey))) { + stats->alpha = 1; + stats->key = 0; + alpha_done = 1; + } else if(a == 0 && !stats->alpha && !stats->key) { + stats->key = 1; + stats->key_r = r; + stats->key_g = g; + stats->key_b = b; + } else if(a == 65535 && stats->key && matchkey) { + /* Color key cannot be used if an opaque pixel also has that RGB color. */ + stats->alpha = 1; + stats->key = 0; + alpha_done = 1; + } + } + if(alpha_done && numcolors_done && colored_done && bits_done) break; + } + + if(stats->key && !stats->alpha) { + for(i = 0; i != numpixels; ++i) { + getPixelColorRGBA16(&r, &g, &b, &a, in, i, mode_in); + if(a != 0 && r == stats->key_r && g == stats->key_g && b == stats->key_b) { + /* Color key cannot be used if an opaque pixel also has that RGB color. */ + stats->alpha = 1; + stats->key = 0; + alpha_done = 1; + } + } + } + } else /* < 16-bit */ { + unsigned char r = 0, g = 0, b = 0, a = 0; + for(i = 0; i != numpixels; ++i) { + getPixelColorRGBA8(&r, &g, &b, &a, in, i, mode_in); + + if(!bits_done && stats->bits < 8) { + /*only r is checked, < 8 bits is only relevant for grayscale*/ + unsigned bits = getValueRequiredBits(r); + if(bits > stats->bits) stats->bits = bits; + } + bits_done = (stats->bits >= bpp); + + if(!colored_done && (r != g || r != b)) { + stats->colored = 1; + colored_done = 1; + if(stats->bits < 8) stats->bits = 8; /*PNG has no colored modes with less than 8-bit per channel*/ + } + + if(!alpha_done) { + unsigned matchkey = (r == stats->key_r && g == stats->key_g && b == stats->key_b); + if(a != 255 && (a != 0 || (stats->key && !matchkey))) { + stats->alpha = 1; + stats->key = 0; + alpha_done = 1; + if(stats->bits < 8) stats->bits = 8; /*PNG has no alphachannel modes with less than 8-bit per channel*/ + } else if(a == 0 && !stats->alpha && !stats->key) { + stats->key = 1; + stats->key_r = r; + stats->key_g = g; + stats->key_b = b; + } else if(a == 255 && stats->key && matchkey) { + /* Color key cannot be used if an opaque pixel also has that RGB color. */ + stats->alpha = 1; + stats->key = 0; + alpha_done = 1; + if(stats->bits < 8) stats->bits = 8; /*PNG has no alphachannel modes with less than 8-bit per channel*/ + } + } + + if(!numcolors_done) { + if(!color_tree_has(&tree, r, g, b, a)) { + color_tree_add(&tree, r, g, b, a, stats->numcolors); + if(stats->numcolors < 256) { + unsigned char* p = stats->palette; + unsigned n = stats->numcolors; + p[n * 4 + 0] = r; + p[n * 4 + 1] = g; + p[n * 4 + 2] = b; + p[n * 4 + 3] = a; + } + ++stats->numcolors; + numcolors_done = stats->numcolors >= maxnumcolors; + } + } + + if(alpha_done && numcolors_done && colored_done && bits_done) break; + } + + if(stats->key && !stats->alpha) { + for(i = 0; i != numpixels; ++i) { + getPixelColorRGBA8(&r, &g, &b, &a, in, i, mode_in); + if(a != 0 && r == stats->key_r && g == stats->key_g && b == stats->key_b) { + /* Color key cannot be used if an opaque pixel also has that RGB color. */ + stats->alpha = 1; + stats->key = 0; + alpha_done = 1; + if(stats->bits < 8) stats->bits = 8; /*PNG has no alphachannel modes with less than 8-bit per channel*/ + } + } + } + + /*make the stats's key always 16-bit for consistency - repeat each byte twice*/ + stats->key_r += (stats->key_r << 8); + stats->key_g += (stats->key_g << 8); + stats->key_b += (stats->key_b << 8); + } + + color_tree_cleanup(&tree); +} + +#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS +/*Adds a single color to the color stats. The stats must already have been inited. The color must be given as 16-bit +(with 2 bytes repeating for 8-bit and 65535 for opaque alpha channel). This function is expensive, do not call it for +all pixels of an image but only for a few additional values. */ +static void lodepng_color_stats_add(LodePNGColorStats* stats, + unsigned r, unsigned g, unsigned b, unsigned a) { + unsigned char image[8]; + LodePNGColorMode mode; + lodepng_color_mode_init(&mode); + image[0] = r >> 8; image[1] = r; image[2] = g >> 8; image[3] = g; + image[4] = b >> 8; image[5] = b; image[6] = a >> 8; image[7] = a; + mode.bitdepth = 16; + mode.colortype = LCT_RGBA; + lodepng_compute_color_stats(stats, image, 1, 1, &mode); + lodepng_color_mode_cleanup(&mode); +} +#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ + +unsigned auto_choose_color(LodePNGColorMode* mode_out, + const LodePNGColorMode* mode_in, + const LodePNGColorStats* stats) { + unsigned error = 0; + unsigned palettebits; + size_t i, n; + size_t numpixels = stats->numpixels; + unsigned palette_ok, gray_ok; + + unsigned alpha = stats->alpha; + unsigned key = stats->key; + unsigned bits = stats->bits; + + mode_out->key_defined = 0; + + if(key && numpixels <= 16) { + alpha = 1; /*too few pixels to justify tRNS chunk overhead*/ + key = 0; + if(bits < 8) bits = 8; /*PNG has no alphachannel modes with less than 8-bit per channel*/ + } + + gray_ok = !stats->colored; + if(!stats->allow_greyscale) gray_ok = 0; + if(!gray_ok && bits < 8) bits = 8; + + n = stats->numcolors; + palettebits = n <= 2 ? 1 : (n <= 4 ? 2 : (n <= 16 ? 4 : 8)); + palette_ok = n <= 256 && bits <= 8 && n != 0; /*n==0 means likely numcolors wasn't computed*/ + if(numpixels < n * 2) palette_ok = 0; /*don't add palette overhead if image has only a few pixels*/ + if(gray_ok && bits <= palettebits) palette_ok = 0; /*gray is less overhead*/ + if(!stats->allow_palette) palette_ok = 0; + + if(palette_ok) { + const unsigned char* p = stats->palette; + lodepng_palette_clear(mode_out); /*remove potential earlier palette*/ + for(i = 0; i != stats->numcolors; ++i) { + error = lodepng_palette_add(mode_out, p[i * 4 + 0], p[i * 4 + 1], p[i * 4 + 2], p[i * 4 + 3]); + if(error) break; + } + + mode_out->colortype = LCT_PALETTE; + mode_out->bitdepth = palettebits; + + if(mode_in->colortype == LCT_PALETTE && mode_in->palettesize >= mode_out->palettesize + && mode_in->bitdepth == mode_out->bitdepth) { + /*If input should have same palette colors, keep original to preserve its order and prevent conversion*/ + lodepng_color_mode_cleanup(mode_out); + lodepng_color_mode_copy(mode_out, mode_in); + } + } else /*8-bit or 16-bit per channel*/ { + mode_out->bitdepth = bits; + mode_out->colortype = alpha ? (gray_ok ? LCT_GREY_ALPHA : LCT_RGBA) + : (gray_ok ? LCT_GREY : LCT_RGB); + if(key) { + unsigned mask = (1u << mode_out->bitdepth) - 1u; /*stats always uses 16-bit, mask converts it*/ + mode_out->key_r = stats->key_r & mask; + mode_out->key_g = stats->key_g & mask; + mode_out->key_b = stats->key_b & mask; + mode_out->key_defined = 1; + } + } + + return error; +} + +#endif /* #ifdef LODEPNG_COMPILE_ENCODER */ + +/* +Paeth predicter, used by PNG filter type 4 +The parameters are of type short, but should come from unsigned chars, the shorts +are only needed to make the paeth calculation correct. +*/ +static unsigned char paethPredictor(short a, short b, short c) { + short pa = LODEPNG_ABS(b - c); + short pb = LODEPNG_ABS(a - c); + short pc = LODEPNG_ABS(a + b - c - c); + /* return input value associated with smallest of pa, pb, pc (with certain priority if equal) */ + if(pb < pa) { a = b; pa = pb; } + return (pc < pa) ? c : a; +} + +/*shared values used by multiple Adam7 related functions*/ + +static const unsigned ADAM7_IX[7] = { 0, 4, 0, 2, 0, 1, 0 }; /*x start values*/ +static const unsigned ADAM7_IY[7] = { 0, 0, 4, 0, 2, 0, 1 }; /*y start values*/ +static const unsigned ADAM7_DX[7] = { 8, 8, 4, 4, 2, 2, 1 }; /*x delta values*/ +static const unsigned ADAM7_DY[7] = { 8, 8, 8, 4, 4, 2, 2 }; /*y delta values*/ + +/* +Outputs various dimensions and positions in the image related to the Adam7 reduced images. +passw: output containing the width of the 7 passes +passh: output containing the height of the 7 passes +filter_passstart: output containing the index of the start and end of each + reduced image with filter bytes +padded_passstart output containing the index of the start and end of each + reduced image when without filter bytes but with padded scanlines +passstart: output containing the index of the start and end of each reduced + image without padding between scanlines, but still padding between the images +w, h: width and height of non-interlaced image +bpp: bits per pixel +"padded" is only relevant if bpp is less than 8 and a scanline or image does not + end at a full byte +*/ +static void Adam7_getpassvalues(unsigned passw[7], unsigned passh[7], size_t filter_passstart[8], + size_t padded_passstart[8], size_t passstart[8], unsigned w, unsigned h, unsigned bpp) { + /*the passstart values have 8 values: the 8th one indicates the byte after the end of the 7th (= last) pass*/ + unsigned i; + + /*calculate width and height in pixels of each pass*/ + for(i = 0; i != 7; ++i) { + passw[i] = (w + ADAM7_DX[i] - ADAM7_IX[i] - 1) / ADAM7_DX[i]; + passh[i] = (h + ADAM7_DY[i] - ADAM7_IY[i] - 1) / ADAM7_DY[i]; + if(passw[i] == 0) passh[i] = 0; + if(passh[i] == 0) passw[i] = 0; + } + + filter_passstart[0] = padded_passstart[0] = passstart[0] = 0; + for(i = 0; i != 7; ++i) { + /*if passw[i] is 0, it's 0 bytes, not 1 (no filtertype-byte)*/ + filter_passstart[i + 1] = filter_passstart[i] + + ((passw[i] && passh[i]) ? passh[i] * (1u + (passw[i] * bpp + 7u) / 8u) : 0); + /*bits padded if needed to fill full byte at end of each scanline*/ + padded_passstart[i + 1] = padded_passstart[i] + passh[i] * ((passw[i] * bpp + 7u) / 8u); + /*only padded at end of reduced image*/ + passstart[i + 1] = passstart[i] + (passh[i] * passw[i] * bpp + 7u) / 8u; + } +} + +#ifdef LODEPNG_COMPILE_DECODER + +/* ////////////////////////////////////////////////////////////////////////// */ +/* / PNG Decoder / */ +/* ////////////////////////////////////////////////////////////////////////// */ + +/*read the information from the header and store it in the LodePNGInfo. return value is error*/ +unsigned lodepng_inspect(unsigned* w, unsigned* h, LodePNGState* state, + const unsigned char* in, size_t insize) { + unsigned width, height; + LodePNGInfo* info = &state->info_png; + if(insize == 0 || in == 0) { + CERROR_RETURN_ERROR(state->error, 48); /*error: the given data is empty*/ + } + if(insize < 33) { + CERROR_RETURN_ERROR(state->error, 27); /*error: the data length is smaller than the length of a PNG header*/ + } + + /*when decoding a new PNG image, make sure all parameters created after previous decoding are reset*/ + /* TODO: remove this. One should use a new LodePNGState for new sessions */ + lodepng_info_cleanup(info); + lodepng_info_init(info); + + if(in[0] != 137 || in[1] != 80 || in[2] != 78 || in[3] != 71 + || in[4] != 13 || in[5] != 10 || in[6] != 26 || in[7] != 10) { + CERROR_RETURN_ERROR(state->error, 28); /*error: the first 8 bytes are not the correct PNG signature*/ + } + if(lodepng_chunk_length(in + 8) != 13) { + CERROR_RETURN_ERROR(state->error, 94); /*error: header size must be 13 bytes*/ + } + if(!lodepng_chunk_type_equals(in + 8, "IHDR")) { + CERROR_RETURN_ERROR(state->error, 29); /*error: it doesn't start with a IHDR chunk!*/ + } + + /*read the values given in the header*/ + width = lodepng_read32bitInt(&in[16]); + height = lodepng_read32bitInt(&in[20]); + /*TODO: remove the undocumented feature that allows to give null pointers to width or height*/ + if(w) *w = width; + if(h) *h = height; + info->color.bitdepth = in[24]; + info->color.colortype = (LodePNGColorType)in[25]; + info->compression_method = in[26]; + info->filter_method = in[27]; + info->interlace_method = in[28]; + + /*errors returned only after the parsing so other values are still output*/ + + /*error: invalid image size*/ + if(width == 0 || height == 0) CERROR_RETURN_ERROR(state->error, 93); + /*error: invalid colortype or bitdepth combination*/ + state->error = checkColorValidity(info->color.colortype, info->color.bitdepth); + if(state->error) return state->error; + /*error: only compression method 0 is allowed in the specification*/ + if(info->compression_method != 0) CERROR_RETURN_ERROR(state->error, 32); + /*error: only filter method 0 is allowed in the specification*/ + if(info->filter_method != 0) CERROR_RETURN_ERROR(state->error, 33); + /*error: only interlace methods 0 and 1 exist in the specification*/ + if(info->interlace_method > 1) CERROR_RETURN_ERROR(state->error, 34); + + if(!state->decoder.ignore_crc) { + unsigned CRC = lodepng_read32bitInt(&in[29]); + unsigned checksum = lodepng_crc32(&in[12], 17); + if(CRC != checksum) { + CERROR_RETURN_ERROR(state->error, 57); /*invalid CRC*/ + } + } + + return state->error; +} + +static unsigned unfilterScanline(unsigned char* recon, const unsigned char* scanline, const unsigned char* precon, + size_t bytewidth, unsigned char filterType, size_t length) { + /* + For PNG filter method 0 + unfilter a PNG image scanline by scanline. when the pixels are smaller than 1 byte, + the filter works byte per byte (bytewidth = 1) + precon is the previous unfiltered scanline, recon the result, scanline the current one + the incoming scanlines do NOT include the filtertype byte, that one is given in the parameter filterType instead + recon and scanline MAY be the same memory address! precon must be disjoint. + */ + + size_t i; + switch(filterType) { + case 0: + for(i = 0; i != length; ++i) recon[i] = scanline[i]; + break; + case 1: + for(i = 0; i != bytewidth; ++i) recon[i] = scanline[i]; + for(i = bytewidth; i < length; ++i) recon[i] = scanline[i] + recon[i - bytewidth]; + break; + case 2: + if(precon) { + for(i = 0; i != length; ++i) recon[i] = scanline[i] + precon[i]; + } else { + for(i = 0; i != length; ++i) recon[i] = scanline[i]; + } + break; + case 3: + if(precon) { + for(i = 0; i != bytewidth; ++i) recon[i] = scanline[i] + (precon[i] >> 1u); + for(i = bytewidth; i < length; ++i) recon[i] = scanline[i] + ((recon[i - bytewidth] + precon[i]) >> 1u); + } else { + for(i = 0; i != bytewidth; ++i) recon[i] = scanline[i]; + for(i = bytewidth; i < length; ++i) recon[i] = scanline[i] + (recon[i - bytewidth] >> 1u); + } + break; + case 4: + if(precon) { + for(i = 0; i != bytewidth; ++i) { + recon[i] = (scanline[i] + precon[i]); /*paethPredictor(0, precon[i], 0) is always precon[i]*/ + } + for(i = bytewidth; i < length; ++i) { + recon[i] = (scanline[i] + paethPredictor(recon[i - bytewidth], precon[i], precon[i - bytewidth])); + } + } else { + for(i = 0; i != bytewidth; ++i) { + recon[i] = scanline[i]; + } + for(i = bytewidth; i < length; ++i) { + /*paethPredictor(recon[i - bytewidth], 0, 0) is always recon[i - bytewidth]*/ + recon[i] = (scanline[i] + recon[i - bytewidth]); + } + } + break; + default: return 36; /*error: unexisting filter type given*/ + } + return 0; +} + +static unsigned unfilter(unsigned char* out, const unsigned char* in, unsigned w, unsigned h, unsigned bpp) { + /* + For PNG filter method 0 + this function unfilters a single image (e.g. without interlacing this is called once, with Adam7 seven times) + out must have enough bytes allocated already, in must have the scanlines + 1 filtertype byte per scanline + w and h are image dimensions or dimensions of reduced image, bpp is bits per pixel + in and out are allowed to be the same memory address (but aren't the same size since in has the extra filter bytes) + */ + + unsigned y; + unsigned char* prevline = 0; + + /*bytewidth is used for filtering, is 1 when bpp < 8, number of bytes per pixel otherwise*/ + size_t bytewidth = (bpp + 7u) / 8u; + size_t linebytes = (w * bpp + 7u) / 8u; + + for(y = 0; y < h; ++y) { + size_t outindex = linebytes * y; + size_t inindex = (1 + linebytes) * y; /*the extra filterbyte added to each row*/ + unsigned char filterType = in[inindex]; + + CERROR_TRY_RETURN(unfilterScanline(&out[outindex], &in[inindex + 1], prevline, bytewidth, filterType, linebytes)); + + prevline = &out[outindex]; + } + + return 0; +} + +/* +in: Adam7 interlaced image, with no padding bits between scanlines, but between + reduced images so that each reduced image starts at a byte. +out: the same pixels, but re-ordered so that they're now a non-interlaced image with size w*h +bpp: bits per pixel +out has the following size in bits: w * h * bpp. +in is possibly bigger due to padding bits between reduced images. +out must be big enough AND must be 0 everywhere if bpp < 8 in the current implementation +(because that's likely a little bit faster) +NOTE: comments about padding bits are only relevant if bpp < 8 +*/ +static void Adam7_deinterlace(unsigned char* out, const unsigned char* in, unsigned w, unsigned h, unsigned bpp) { + unsigned passw[7], passh[7]; + size_t filter_passstart[8], padded_passstart[8], passstart[8]; + unsigned i; + + Adam7_getpassvalues(passw, passh, filter_passstart, padded_passstart, passstart, w, h, bpp); + + if(bpp >= 8) { + for(i = 0; i != 7; ++i) { + unsigned x, y, b; + size_t bytewidth = bpp / 8u; + for(y = 0; y < passh[i]; ++y) + for(x = 0; x < passw[i]; ++x) { + size_t pixelinstart = passstart[i] + (y * passw[i] + x) * bytewidth; + size_t pixeloutstart = ((ADAM7_IY[i] + y * ADAM7_DY[i]) * w + ADAM7_IX[i] + x * ADAM7_DX[i]) * bytewidth; + for(b = 0; b < bytewidth; ++b) { + out[pixeloutstart + b] = in[pixelinstart + b]; + } + } + } + } else /*bpp < 8: Adam7 with pixels < 8 bit is a bit trickier: with bit pointers*/ { + for(i = 0; i != 7; ++i) { + unsigned x, y, b; + unsigned ilinebits = bpp * passw[i]; + unsigned olinebits = bpp * w; + size_t obp, ibp; /*bit pointers (for out and in buffer)*/ + for(y = 0; y < passh[i]; ++y) + for(x = 0; x < passw[i]; ++x) { + ibp = (8 * passstart[i]) + (y * ilinebits + x * bpp); + obp = (ADAM7_IY[i] + y * ADAM7_DY[i]) * olinebits + (ADAM7_IX[i] + x * ADAM7_DX[i]) * bpp; + for(b = 0; b < bpp; ++b) { + unsigned char bit = readBitFromReversedStream(&ibp, in); + setBitOfReversedStream(&obp, out, bit); + } + } + } + } +} + +static void removePaddingBits(unsigned char* out, const unsigned char* in, + size_t olinebits, size_t ilinebits, unsigned h) { + /* + After filtering there are still padding bits if scanlines have non multiple of 8 bit amounts. They need + to be removed (except at last scanline of (Adam7-reduced) image) before working with pure image buffers + for the Adam7 code, the color convert code and the output to the user. + in and out are allowed to be the same buffer, in may also be higher but still overlapping; in must + have >= ilinebits*h bits, out must have >= olinebits*h bits, olinebits must be <= ilinebits + also used to move bits after earlier such operations happened, e.g. in a sequence of reduced images from Adam7 + only useful if (ilinebits - olinebits) is a value in the range 1..7 + */ + unsigned y; + size_t diff = ilinebits - olinebits; + size_t ibp = 0, obp = 0; /*input and output bit pointers*/ + for(y = 0; y < h; ++y) { + size_t x; + for(x = 0; x < olinebits; ++x) { + unsigned char bit = readBitFromReversedStream(&ibp, in); + setBitOfReversedStream(&obp, out, bit); + } + ibp += diff; + } +} + +/*out must be buffer big enough to contain full image, and in must contain the full decompressed data from +the IDAT chunks (with filter index bytes and possible padding bits) +return value is error*/ +static unsigned postProcessScanlines(unsigned char* out, unsigned char* in, + unsigned w, unsigned h, const LodePNGInfo* info_png) { + /* + This function converts the filtered-padded-interlaced data into pure 2D image buffer with the PNG's colortype. + Steps: + *) if no Adam7: 1) unfilter 2) remove padding bits (= posible extra bits per scanline if bpp < 8) + *) if adam7: 1) 7x unfilter 2) 7x remove padding bits 3) Adam7_deinterlace + NOTE: the in buffer will be overwritten with intermediate data! + */ + unsigned bpp = lodepng_get_bpp(&info_png->color); + if(bpp == 0) return 31; /*error: invalid colortype*/ + + if(info_png->interlace_method == 0) { + if(bpp < 8 && w * bpp != ((w * bpp + 7u) / 8u) * 8u) { + CERROR_TRY_RETURN(unfilter(in, in, w, h, bpp)); + removePaddingBits(out, in, w * bpp, ((w * bpp + 7u) / 8u) * 8u, h); + } + /*we can immediately filter into the out buffer, no other steps needed*/ + else CERROR_TRY_RETURN(unfilter(out, in, w, h, bpp)); + } else /*interlace_method is 1 (Adam7)*/ { + unsigned passw[7], passh[7]; size_t filter_passstart[8], padded_passstart[8], passstart[8]; + unsigned i; + + Adam7_getpassvalues(passw, passh, filter_passstart, padded_passstart, passstart, w, h, bpp); + + for(i = 0; i != 7; ++i) { + CERROR_TRY_RETURN(unfilter(&in[padded_passstart[i]], &in[filter_passstart[i]], passw[i], passh[i], bpp)); + /*TODO: possible efficiency improvement: if in this reduced image the bits fit nicely in 1 scanline, + move bytes instead of bits or move not at all*/ + if(bpp < 8) { + /*remove padding bits in scanlines; after this there still may be padding + bits between the different reduced images: each reduced image still starts nicely at a byte*/ + removePaddingBits(&in[passstart[i]], &in[padded_passstart[i]], passw[i] * bpp, + ((passw[i] * bpp + 7u) / 8u) * 8u, passh[i]); + } + } + + Adam7_deinterlace(out, in, w, h, bpp); + } + + return 0; +} + +static unsigned readChunk_PLTE(LodePNGColorMode* color, const unsigned char* data, size_t chunkLength) { + unsigned pos = 0, i; + if(color->palette) lodepng_free(color->palette); + color->palettesize = chunkLength / 3u; + color->palette = (unsigned char*)lodepng_malloc(4 * color->palettesize); + if(!color->palette && color->palettesize) { + color->palettesize = 0; + return 83; /*alloc fail*/ + } + if(color->palettesize > 256) return 38; /*error: palette too big*/ + + for(i = 0; i != color->palettesize; ++i) { + color->palette[4 * i + 0] = data[pos++]; /*R*/ + color->palette[4 * i + 1] = data[pos++]; /*G*/ + color->palette[4 * i + 2] = data[pos++]; /*B*/ + color->palette[4 * i + 3] = 255; /*alpha*/ + } + + return 0; /* OK */ +} + +static unsigned readChunk_tRNS(LodePNGColorMode* color, const unsigned char* data, size_t chunkLength) { + unsigned i; + if(color->colortype == LCT_PALETTE) { + /*error: more alpha values given than there are palette entries*/ + if(chunkLength > color->palettesize) return 39; + + for(i = 0; i != chunkLength; ++i) color->palette[4 * i + 3] = data[i]; + } else if(color->colortype == LCT_GREY) { + /*error: this chunk must be 2 bytes for grayscale image*/ + if(chunkLength != 2) return 30; + + color->key_defined = 1; + color->key_r = color->key_g = color->key_b = 256u * data[0] + data[1]; + } else if(color->colortype == LCT_RGB) { + /*error: this chunk must be 6 bytes for RGB image*/ + if(chunkLength != 6) return 41; + + color->key_defined = 1; + color->key_r = 256u * data[0] + data[1]; + color->key_g = 256u * data[2] + data[3]; + color->key_b = 256u * data[4] + data[5]; + } + else return 42; /*error: tRNS chunk not allowed for other color models*/ + + return 0; /* OK */ +} + + +#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS +/*background color chunk (bKGD)*/ +static unsigned readChunk_bKGD(LodePNGInfo* info, const unsigned char* data, size_t chunkLength) { + if(info->color.colortype == LCT_PALETTE) { + /*error: this chunk must be 1 byte for indexed color image*/ + if(chunkLength != 1) return 43; + + /*error: invalid palette index, or maybe this chunk appeared before PLTE*/ + if(data[0] >= info->color.palettesize) return 103; + + info->background_defined = 1; + info->background_r = info->background_g = info->background_b = data[0]; + } else if(info->color.colortype == LCT_GREY || info->color.colortype == LCT_GREY_ALPHA) { + /*error: this chunk must be 2 bytes for grayscale image*/ + if(chunkLength != 2) return 44; + + /*the values are truncated to bitdepth in the PNG file*/ + info->background_defined = 1; + info->background_r = info->background_g = info->background_b = 256u * data[0] + data[1]; + } else if(info->color.colortype == LCT_RGB || info->color.colortype == LCT_RGBA) { + /*error: this chunk must be 6 bytes for grayscale image*/ + if(chunkLength != 6) return 45; + + /*the values are truncated to bitdepth in the PNG file*/ + info->background_defined = 1; + info->background_r = 256u * data[0] + data[1]; + info->background_g = 256u * data[2] + data[3]; + info->background_b = 256u * data[4] + data[5]; + } + + return 0; /* OK */ +} + +/*text chunk (tEXt)*/ +static unsigned readChunk_tEXt(LodePNGInfo* info, const unsigned char* data, size_t chunkLength) { + unsigned error = 0; + char *key = 0, *str = 0; + unsigned i; + + while(!error) /*not really a while loop, only used to break on error*/ { + unsigned length, string2_begin; + + length = 0; + while(length < chunkLength && data[length] != 0) ++length; + /*even though it's not allowed by the standard, no error is thrown if + there's no null termination char, if the text is empty*/ + if(length < 1 || length > 79) CERROR_BREAK(error, 89); /*keyword too short or long*/ + + key = (char*)lodepng_malloc(length + 1); + if(!key) CERROR_BREAK(error, 83); /*alloc fail*/ + + key[length] = 0; + for(i = 0; i != length; ++i) key[i] = (char)data[i]; + + string2_begin = length + 1; /*skip keyword null terminator*/ + + length = (unsigned)(chunkLength < string2_begin ? 0 : chunkLength - string2_begin); + str = (char*)lodepng_malloc(length + 1); + if(!str) CERROR_BREAK(error, 83); /*alloc fail*/ + + str[length] = 0; + for(i = 0; i != length; ++i) str[i] = (char)data[string2_begin + i]; + + error = lodepng_add_text(info, key, str); + + break; + } + + lodepng_free(key); + lodepng_free(str); + + return error; +} + +/*compressed text chunk (zTXt)*/ +static unsigned readChunk_zTXt(LodePNGInfo* info, const LodePNGDecompressSettings* zlibsettings, + const unsigned char* data, size_t chunkLength) { + unsigned error = 0; + unsigned i; + + unsigned length, string2_begin; + char *key = 0; + ucvector decoded; + + ucvector_init(&decoded); + + while(!error) /*not really a while loop, only used to break on error*/ { + for(length = 0; length < chunkLength && data[length] != 0; ++length) ; + if(length + 2 >= chunkLength) CERROR_BREAK(error, 75); /*no null termination, corrupt?*/ + if(length < 1 || length > 79) CERROR_BREAK(error, 89); /*keyword too short or long*/ + + key = (char*)lodepng_malloc(length + 1); + if(!key) CERROR_BREAK(error, 83); /*alloc fail*/ + + key[length] = 0; + for(i = 0; i != length; ++i) key[i] = (char)data[i]; + + if(data[length + 1] != 0) CERROR_BREAK(error, 72); /*the 0 byte indicating compression must be 0*/ + + string2_begin = length + 2; + if(string2_begin > chunkLength) CERROR_BREAK(error, 75); /*no null termination, corrupt?*/ + + length = (unsigned)chunkLength - string2_begin; + /*will fail if zlib error, e.g. if length is too small*/ + error = zlib_decompress(&decoded.data, &decoded.size, + &data[string2_begin], + length, zlibsettings); + if(error) break; + ucvector_push_back(&decoded, 0); + + error = lodepng_add_text(info, key, (char*)decoded.data); + + break; + } + + lodepng_free(key); + ucvector_cleanup(&decoded); + + return error; +} + +/*international text chunk (iTXt)*/ +static unsigned readChunk_iTXt(LodePNGInfo* info, const LodePNGDecompressSettings* zlibsettings, + const unsigned char* data, size_t chunkLength) { + unsigned error = 0; + unsigned i; + + unsigned length, begin, compressed; + char *key = 0, *langtag = 0, *transkey = 0; + ucvector decoded; + ucvector_init(&decoded); /* TODO: only use in case of compressed text */ + + while(!error) /*not really a while loop, only used to break on error*/ { + /*Quick check if the chunk length isn't too small. Even without check + it'd still fail with other error checks below if it's too short. This just gives a different error code.*/ + if(chunkLength < 5) CERROR_BREAK(error, 30); /*iTXt chunk too short*/ + + /*read the key*/ + for(length = 0; length < chunkLength && data[length] != 0; ++length) ; + if(length + 3 >= chunkLength) CERROR_BREAK(error, 75); /*no null termination char, corrupt?*/ + if(length < 1 || length > 79) CERROR_BREAK(error, 89); /*keyword too short or long*/ + + key = (char*)lodepng_malloc(length + 1); + if(!key) CERROR_BREAK(error, 83); /*alloc fail*/ + + key[length] = 0; + for(i = 0; i != length; ++i) key[i] = (char)data[i]; + + /*read the compression method*/ + compressed = data[length + 1]; + if(data[length + 2] != 0) CERROR_BREAK(error, 72); /*the 0 byte indicating compression must be 0*/ + + /*even though it's not allowed by the standard, no error is thrown if + there's no null termination char, if the text is empty for the next 3 texts*/ + + /*read the langtag*/ + begin = length + 3; + length = 0; + for(i = begin; i < chunkLength && data[i] != 0; ++i) ++length; + + langtag = (char*)lodepng_malloc(length + 1); + if(!langtag) CERROR_BREAK(error, 83); /*alloc fail*/ + + langtag[length] = 0; + for(i = 0; i != length; ++i) langtag[i] = (char)data[begin + i]; + + /*read the transkey*/ + begin += length + 1; + length = 0; + for(i = begin; i < chunkLength && data[i] != 0; ++i) ++length; + + transkey = (char*)lodepng_malloc(length + 1); + if(!transkey) CERROR_BREAK(error, 83); /*alloc fail*/ + + transkey[length] = 0; + for(i = 0; i != length; ++i) transkey[i] = (char)data[begin + i]; + + /*read the actual text*/ + begin += length + 1; + + length = (unsigned)chunkLength < begin ? 0 : (unsigned)chunkLength - begin; + + if(compressed) { + /*will fail if zlib error, e.g. if length is too small*/ + error = zlib_decompress(&decoded.data, &decoded.size, + &data[begin], + length, zlibsettings); + if(error) break; + if(decoded.allocsize < decoded.size) decoded.allocsize = decoded.size; + ucvector_push_back(&decoded, 0); + } else { + if(!ucvector_resize(&decoded, length + 1)) CERROR_BREAK(error, 83 /*alloc fail*/); + + decoded.data[length] = 0; + for(i = 0; i != length; ++i) decoded.data[i] = data[begin + i]; + } + + error = lodepng_add_itext(info, key, langtag, transkey, (char*)decoded.data); + + break; + } + + lodepng_free(key); + lodepng_free(langtag); + lodepng_free(transkey); + ucvector_cleanup(&decoded); + + return error; +} + +static unsigned readChunk_tIME(LodePNGInfo* info, const unsigned char* data, size_t chunkLength) { + if(chunkLength != 7) return 73; /*invalid tIME chunk size*/ + + info->time_defined = 1; + info->time.year = 256u * data[0] + data[1]; + info->time.month = data[2]; + info->time.day = data[3]; + info->time.hour = data[4]; + info->time.minute = data[5]; + info->time.second = data[6]; + + return 0; /* OK */ +} + +static unsigned readChunk_pHYs(LodePNGInfo* info, const unsigned char* data, size_t chunkLength) { + if(chunkLength != 9) return 74; /*invalid pHYs chunk size*/ + + info->phys_defined = 1; + info->phys_x = 16777216u * data[0] + 65536u * data[1] + 256u * data[2] + data[3]; + info->phys_y = 16777216u * data[4] + 65536u * data[5] + 256u * data[6] + data[7]; + info->phys_unit = data[8]; + + return 0; /* OK */ +} + +static unsigned readChunk_gAMA(LodePNGInfo* info, const unsigned char* data, size_t chunkLength) { + if(chunkLength != 4) return 96; /*invalid gAMA chunk size*/ + + info->gama_defined = 1; + info->gama_gamma = 16777216u * data[0] + 65536u * data[1] + 256u * data[2] + data[3]; + + return 0; /* OK */ +} + +static unsigned readChunk_cHRM(LodePNGInfo* info, const unsigned char* data, size_t chunkLength) { + if(chunkLength != 32) return 97; /*invalid cHRM chunk size*/ + + info->chrm_defined = 1; + info->chrm_white_x = 16777216u * data[ 0] + 65536u * data[ 1] + 256u * data[ 2] + data[ 3]; + info->chrm_white_y = 16777216u * data[ 4] + 65536u * data[ 5] + 256u * data[ 6] + data[ 7]; + info->chrm_red_x = 16777216u * data[ 8] + 65536u * data[ 9] + 256u * data[10] + data[11]; + info->chrm_red_y = 16777216u * data[12] + 65536u * data[13] + 256u * data[14] + data[15]; + info->chrm_green_x = 16777216u * data[16] + 65536u * data[17] + 256u * data[18] + data[19]; + info->chrm_green_y = 16777216u * data[20] + 65536u * data[21] + 256u * data[22] + data[23]; + info->chrm_blue_x = 16777216u * data[24] + 65536u * data[25] + 256u * data[26] + data[27]; + info->chrm_blue_y = 16777216u * data[28] + 65536u * data[29] + 256u * data[30] + data[31]; + + return 0; /* OK */ +} + +static unsigned readChunk_sRGB(LodePNGInfo* info, const unsigned char* data, size_t chunkLength) { + if(chunkLength != 1) return 98; /*invalid sRGB chunk size (this one is never ignored)*/ + + info->srgb_defined = 1; + info->srgb_intent = data[0]; + + return 0; /* OK */ +} + +static unsigned readChunk_iCCP(LodePNGInfo* info, const LodePNGDecompressSettings* zlibsettings, + const unsigned char* data, size_t chunkLength) { + unsigned error = 0; + unsigned i; + + unsigned length, string2_begin; + ucvector decoded; + + info->iccp_defined = 1; + if(info->iccp_name) lodepng_clear_icc(info); + + for(length = 0; length < chunkLength && data[length] != 0; ++length) ; + if(length + 2 >= chunkLength) return 75; /*no null termination, corrupt?*/ + if(length < 1 || length > 79) return 89; /*keyword too short or long*/ + + info->iccp_name = (char*)lodepng_malloc(length + 1); + if(!info->iccp_name) return 83; /*alloc fail*/ + + info->iccp_name[length] = 0; + for(i = 0; i != length; ++i) info->iccp_name[i] = (char)data[i]; + + if(data[length + 1] != 0) return 72; /*the 0 byte indicating compression must be 0*/ + + string2_begin = length + 2; + if(string2_begin > chunkLength) return 75; /*no null termination, corrupt?*/ + + length = (unsigned)chunkLength - string2_begin; + ucvector_init(&decoded); + error = zlib_decompress(&decoded.data, &decoded.size, + &data[string2_begin], + length, zlibsettings); + if(!error) { + if(decoded.size) { + info->iccp_profile_size = decoded.size; + info->iccp_profile = (unsigned char*)lodepng_malloc(decoded.size); + if(info->iccp_profile) { + lodepng_memcpy(info->iccp_profile, decoded.data, decoded.size); + } else { + error = 83; /* alloc fail */ + } + } else { + error = 100; /*invalid ICC profile size*/ + } + } + ucvector_cleanup(&decoded); + return error; +} +#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ + +unsigned lodepng_inspect_chunk(LodePNGState* state, size_t pos, + const unsigned char* in, size_t insize) { + const unsigned char* chunk = in + pos; + unsigned chunkLength; + const unsigned char* data; + unsigned unhandled = 0; + unsigned error = 0; + + if (pos + 4 > insize) return 30; + chunkLength = lodepng_chunk_length(chunk); + if(chunkLength > 2147483647) return 63; + data = lodepng_chunk_data_const(chunk); + if(data + chunkLength + 4 > in + insize) return 30; + + if(lodepng_chunk_type_equals(chunk, "PLTE")) { + error = readChunk_PLTE(&state->info_png.color, data, chunkLength); + } else if(lodepng_chunk_type_equals(chunk, "tRNS")) { + error = readChunk_tRNS(&state->info_png.color, data, chunkLength); +#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS + } else if(lodepng_chunk_type_equals(chunk, "bKGD")) { + error = readChunk_bKGD(&state->info_png, data, chunkLength); + } else if(lodepng_chunk_type_equals(chunk, "tEXt")) { + error = readChunk_tEXt(&state->info_png, data, chunkLength); + } else if(lodepng_chunk_type_equals(chunk, "zTXt")) { + error = readChunk_zTXt(&state->info_png, &state->decoder.zlibsettings, data, chunkLength); + } else if(lodepng_chunk_type_equals(chunk, "iTXt")) { + error = readChunk_iTXt(&state->info_png, &state->decoder.zlibsettings, data, chunkLength); + } else if(lodepng_chunk_type_equals(chunk, "tIME")) { + error = readChunk_tIME(&state->info_png, data, chunkLength); + } else if(lodepng_chunk_type_equals(chunk, "pHYs")) { + error = readChunk_pHYs(&state->info_png, data, chunkLength); + } else if(lodepng_chunk_type_equals(chunk, "gAMA")) { + error = readChunk_gAMA(&state->info_png, data, chunkLength); + } else if(lodepng_chunk_type_equals(chunk, "cHRM")) { + error = readChunk_cHRM(&state->info_png, data, chunkLength); + } else if(lodepng_chunk_type_equals(chunk, "sRGB")) { + error = readChunk_sRGB(&state->info_png, data, chunkLength); + } else if(lodepng_chunk_type_equals(chunk, "iCCP")) { + error = readChunk_iCCP(&state->info_png, &state->decoder.zlibsettings, data, chunkLength); +#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ + } else { + /* unhandled chunk is ok (is not an error) */ + unhandled = 1; + } + + if(!error && !unhandled && !state->decoder.ignore_crc) { + if(lodepng_chunk_check_crc(chunk)) return 57; /*invalid CRC*/ + } + + return error; +} + +/*read a PNG, the result will be in the same color type as the PNG (hence "generic")*/ +static void decodeGeneric(unsigned char** out, unsigned* w, unsigned* h, + LodePNGState* state, + const unsigned char* in, size_t insize) { + unsigned char IEND = 0; + const unsigned char* chunk; + size_t i; + ucvector idat; /*the data from idat chunks*/ + unsigned char* scanlines = 0; + size_t scanlines_size = 0, expected_size = 0; + size_t outsize = 0; + + /*for unknown chunk order*/ + unsigned unknown = 0; +#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS + unsigned critical_pos = 1; /*1 = after IHDR, 2 = after PLTE, 3 = after IDAT*/ +#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ + + + /* safe output values in case error happens */ + *out = 0; + *w = *h = 0; + + state->error = lodepng_inspect(w, h, state, in, insize); /*reads header and resets other parameters in state->info_png*/ + if(state->error) return; + + if(lodepng_pixel_overflow(*w, *h, &state->info_png.color, &state->info_raw)) { + CERROR_RETURN(state->error, 92); /*overflow possible due to amount of pixels*/ + } + + ucvector_init(&idat); + chunk = &in[33]; /*first byte of the first chunk after the header*/ + + /*loop through the chunks, ignoring unknown chunks and stopping at IEND chunk. + IDAT data is put at the start of the in buffer*/ + while(!IEND && !state->error) { + unsigned chunkLength; + const unsigned char* data; /*the data in the chunk*/ + + /*error: size of the in buffer too small to contain next chunk*/ + if((size_t)((chunk - in) + 12) > insize || chunk < in) { + if(state->decoder.ignore_end) break; /*other errors may still happen though*/ + CERROR_BREAK(state->error, 30); + } + + /*length of the data of the chunk, excluding the length bytes, chunk type and CRC bytes*/ + chunkLength = lodepng_chunk_length(chunk); + /*error: chunk length larger than the max PNG chunk size*/ + if(chunkLength > 2147483647) { + if(state->decoder.ignore_end) break; /*other errors may still happen though*/ + CERROR_BREAK(state->error, 63); + } + + if((size_t)((chunk - in) + chunkLength + 12) > insize || (chunk + chunkLength + 12) < in) { + CERROR_BREAK(state->error, 64); /*error: size of the in buffer too small to contain next chunk*/ + } + + data = lodepng_chunk_data_const(chunk); + + unknown = 0; + + /*IDAT chunk, containing compressed image data*/ + if(lodepng_chunk_type_equals(chunk, "IDAT")) { + size_t oldsize = idat.size; + size_t newsize; + if(lodepng_addofl(oldsize, chunkLength, &newsize)) CERROR_BREAK(state->error, 95); + if(!ucvector_resize(&idat, newsize)) CERROR_BREAK(state->error, 83 /*alloc fail*/); + for(i = 0; i != chunkLength; ++i) idat.data[oldsize + i] = data[i]; +#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS + critical_pos = 3; +#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ + } else if(lodepng_chunk_type_equals(chunk, "IEND")) { + /*IEND chunk*/ + IEND = 1; + } else if(lodepng_chunk_type_equals(chunk, "PLTE")) { + /*palette chunk (PLTE)*/ + state->error = readChunk_PLTE(&state->info_png.color, data, chunkLength); + if(state->error) break; +#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS + critical_pos = 2; +#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ + } else if(lodepng_chunk_type_equals(chunk, "tRNS")) { + /*palette transparency chunk (tRNS). Even though this one is an ancillary chunk , it is still compiled + in without 'LODEPNG_COMPILE_ANCILLARY_CHUNKS' because it contains essential color information that + affects the alpha channel of pixels. */ + state->error = readChunk_tRNS(&state->info_png.color, data, chunkLength); + if(state->error) break; +#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS + /*background color chunk (bKGD)*/ + } else if(lodepng_chunk_type_equals(chunk, "bKGD")) { + state->error = readChunk_bKGD(&state->info_png, data, chunkLength); + if(state->error) break; + } else if(lodepng_chunk_type_equals(chunk, "tEXt")) { + /*text chunk (tEXt)*/ + if(state->decoder.read_text_chunks) { + state->error = readChunk_tEXt(&state->info_png, data, chunkLength); + if(state->error) break; + } + } else if(lodepng_chunk_type_equals(chunk, "zTXt")) { + /*compressed text chunk (zTXt)*/ + if(state->decoder.read_text_chunks) { + state->error = readChunk_zTXt(&state->info_png, &state->decoder.zlibsettings, data, chunkLength); + if(state->error) break; + } + } else if(lodepng_chunk_type_equals(chunk, "iTXt")) { + /*international text chunk (iTXt)*/ + if(state->decoder.read_text_chunks) { + state->error = readChunk_iTXt(&state->info_png, &state->decoder.zlibsettings, data, chunkLength); + if(state->error) break; + } + } else if(lodepng_chunk_type_equals(chunk, "tIME")) { + state->error = readChunk_tIME(&state->info_png, data, chunkLength); + if(state->error) break; + } else if(lodepng_chunk_type_equals(chunk, "pHYs")) { + state->error = readChunk_pHYs(&state->info_png, data, chunkLength); + if(state->error) break; + } else if(lodepng_chunk_type_equals(chunk, "gAMA")) { + state->error = readChunk_gAMA(&state->info_png, data, chunkLength); + if(state->error) break; + } else if(lodepng_chunk_type_equals(chunk, "cHRM")) { + state->error = readChunk_cHRM(&state->info_png, data, chunkLength); + if(state->error) break; + } else if(lodepng_chunk_type_equals(chunk, "sRGB")) { + state->error = readChunk_sRGB(&state->info_png, data, chunkLength); + if(state->error) break; + } else if(lodepng_chunk_type_equals(chunk, "iCCP")) { + state->error = readChunk_iCCP(&state->info_png, &state->decoder.zlibsettings, data, chunkLength); + if(state->error) break; +#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ + } else /*it's not an implemented chunk type, so ignore it: skip over the data*/ { + /*error: unknown critical chunk (5th bit of first byte of chunk type is 0)*/ + if(!state->decoder.ignore_critical && !lodepng_chunk_ancillary(chunk)) { + CERROR_BREAK(state->error, 69); + } + + unknown = 1; +#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS + if(state->decoder.remember_unknown_chunks) { + state->error = lodepng_chunk_append(&state->info_png.unknown_chunks_data[critical_pos - 1], + &state->info_png.unknown_chunks_size[critical_pos - 1], chunk); + if(state->error) break; + } +#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ + } + + if(!state->decoder.ignore_crc && !unknown) /*check CRC if wanted, only on known chunk types*/ { + if(lodepng_chunk_check_crc(chunk)) CERROR_BREAK(state->error, 57); /*invalid CRC*/ + } + + if(!IEND) chunk = lodepng_chunk_next_const(chunk); + } + + /*predict output size, to allocate exact size for output buffer to avoid more dynamic allocation. + If the decompressed size does not match the prediction, the image must be corrupt.*/ + if(state->info_png.interlace_method == 0) { + expected_size = lodepng_get_raw_size_idat(*w, *h, &state->info_png.color); + } else { + /*Adam-7 interlaced: expected size is the sum of the 7 sub-images sizes*/ + const LodePNGColorMode* color = &state->info_png.color; + expected_size = 0; + expected_size += lodepng_get_raw_size_idat((*w + 7) >> 3, (*h + 7) >> 3, color); + if(*w > 4) expected_size += lodepng_get_raw_size_idat((*w + 3) >> 3, (*h + 7) >> 3, color); + expected_size += lodepng_get_raw_size_idat((*w + 3) >> 2, (*h + 3) >> 3, color); + if(*w > 2) expected_size += lodepng_get_raw_size_idat((*w + 1) >> 2, (*h + 3) >> 2, color); + expected_size += lodepng_get_raw_size_idat((*w + 1) >> 1, (*h + 1) >> 2, color); + if(*w > 1) expected_size += lodepng_get_raw_size_idat((*w + 0) >> 1, (*h + 1) >> 1, color); + expected_size += lodepng_get_raw_size_idat((*w + 0), (*h + 0) >> 1, color); + } + if(!state->error) { + /* This allocated data will be realloced by zlib_decompress, initially at + smaller size again. But the fact that it's already allocated at full size + here speeds the multiple reallocs up. TODO: make zlib_decompress support + receiving already allocated buffer with expected size instead. */ + scanlines = (unsigned char*)lodepng_malloc(expected_size); + if(!scanlines) state->error = 83; /*alloc fail*/ + scanlines_size = 0; + } + if(!state->error) { + state->error = zlib_decompress(&scanlines, &scanlines_size, idat.data, + idat.size, &state->decoder.zlibsettings); + if(!state->error && scanlines_size != expected_size) state->error = 91; /*decompressed size doesn't match prediction*/ + } + ucvector_cleanup(&idat); + + if(!state->error) { + outsize = lodepng_get_raw_size(*w, *h, &state->info_png.color); + *out = (unsigned char*)lodepng_malloc(outsize); + if(!*out) state->error = 83; /*alloc fail*/ + } + if(!state->error) { + for(i = 0; i < outsize; i++) (*out)[i] = 0; + state->error = postProcessScanlines(*out, scanlines, *w, *h, &state->info_png); + } + lodepng_free(scanlines); +} + +unsigned lodepng_decode(unsigned char** out, unsigned* w, unsigned* h, + LodePNGState* state, + const unsigned char* in, size_t insize) { + *out = 0; + decodeGeneric(out, w, h, state, in, insize); + if(state->error) return state->error; + if(!state->decoder.color_convert || lodepng_color_mode_equal(&state->info_raw, &state->info_png.color)) { + /*same color type, no copying or converting of data needed*/ + /*store the info_png color settings on the info_raw so that the info_raw still reflects what colortype + the raw image has to the end user*/ + if(!state->decoder.color_convert) { + state->error = lodepng_color_mode_copy(&state->info_raw, &state->info_png.color); + if(state->error) return state->error; + } + } else { + /*color conversion needed; sort of copy of the data*/ + unsigned char* data = *out; + size_t outsize; + + /*TODO: check if this works according to the statement in the documentation: "The converter can convert + from grayscale input color type, to 8-bit grayscale or grayscale with alpha"*/ + if(!(state->info_raw.colortype == LCT_RGB || state->info_raw.colortype == LCT_RGBA) + && !(state->info_raw.bitdepth == 8)) { + return 56; /*unsupported color mode conversion*/ + } + + outsize = lodepng_get_raw_size(*w, *h, &state->info_raw); + *out = (unsigned char*)lodepng_malloc(outsize); + if(!(*out)) { + state->error = 83; /*alloc fail*/ + } + else state->error = lodepng_convert(*out, data, &state->info_raw, + &state->info_png.color, *w, *h); + lodepng_free(data); + } + return state->error; +} + +unsigned lodepng_decode_memory(unsigned char** out, unsigned* w, unsigned* h, const unsigned char* in, + size_t insize, LodePNGColorType colortype, unsigned bitdepth) { + unsigned error; + LodePNGState state; + lodepng_state_init(&state); + state.info_raw.colortype = colortype; + state.info_raw.bitdepth = bitdepth; + error = lodepng_decode(out, w, h, &state, in, insize); + lodepng_state_cleanup(&state); + return error; +} + +unsigned lodepng_decode32(unsigned char** out, unsigned* w, unsigned* h, const unsigned char* in, size_t insize) { + return lodepng_decode_memory(out, w, h, in, insize, LCT_RGBA, 8); +} + +unsigned lodepng_decode24(unsigned char** out, unsigned* w, unsigned* h, const unsigned char* in, size_t insize) { + return lodepng_decode_memory(out, w, h, in, insize, LCT_RGB, 8); +} + +#ifdef LODEPNG_COMPILE_DISK +unsigned lodepng_decode_file(unsigned char** out, unsigned* w, unsigned* h, const char* filename, + LodePNGColorType colortype, unsigned bitdepth) { + unsigned char* buffer = 0; + size_t buffersize; + unsigned error; + /* safe output values in case error happens */ + *out = 0; + *w = *h = 0; + error = lodepng_load_file(&buffer, &buffersize, filename); + if(!error) error = lodepng_decode_memory(out, w, h, buffer, buffersize, colortype, bitdepth); + lodepng_free(buffer); + return error; +} + +unsigned lodepng_decode32_file(unsigned char** out, unsigned* w, unsigned* h, const char* filename) { + return lodepng_decode_file(out, w, h, filename, LCT_RGBA, 8); +} + +unsigned lodepng_decode24_file(unsigned char** out, unsigned* w, unsigned* h, const char* filename) { + return lodepng_decode_file(out, w, h, filename, LCT_RGB, 8); +} +#endif /*LODEPNG_COMPILE_DISK*/ + +void lodepng_decoder_settings_init(LodePNGDecoderSettings* settings) { + settings->color_convert = 1; +#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS + settings->read_text_chunks = 1; + settings->remember_unknown_chunks = 0; +#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ + settings->ignore_crc = 0; + settings->ignore_critical = 0; + settings->ignore_end = 0; + lodepng_decompress_settings_init(&settings->zlibsettings); +} + +#endif /*LODEPNG_COMPILE_DECODER*/ + +#if defined(LODEPNG_COMPILE_DECODER) || defined(LODEPNG_COMPILE_ENCODER) + +void lodepng_state_init(LodePNGState* state) { +#ifdef LODEPNG_COMPILE_DECODER + lodepng_decoder_settings_init(&state->decoder); +#endif /*LODEPNG_COMPILE_DECODER*/ +#ifdef LODEPNG_COMPILE_ENCODER + lodepng_encoder_settings_init(&state->encoder); +#endif /*LODEPNG_COMPILE_ENCODER*/ + lodepng_color_mode_init(&state->info_raw); + lodepng_info_init(&state->info_png); + state->error = 1; +} + +void lodepng_state_cleanup(LodePNGState* state) { + lodepng_color_mode_cleanup(&state->info_raw); + lodepng_info_cleanup(&state->info_png); +} + +void lodepng_state_copy(LodePNGState* dest, const LodePNGState* source) { + lodepng_state_cleanup(dest); + *dest = *source; + lodepng_color_mode_init(&dest->info_raw); + lodepng_info_init(&dest->info_png); + dest->error = lodepng_color_mode_copy(&dest->info_raw, &source->info_raw); if(dest->error) return; + dest->error = lodepng_info_copy(&dest->info_png, &source->info_png); if(dest->error) return; +} + +#endif /* defined(LODEPNG_COMPILE_DECODER) || defined(LODEPNG_COMPILE_ENCODER) */ + +#ifdef LODEPNG_COMPILE_ENCODER + +/* ////////////////////////////////////////////////////////////////////////// */ +/* / PNG Encoder / */ +/* ////////////////////////////////////////////////////////////////////////// */ + +/*chunkName must be string of 4 characters*/ +static unsigned addChunk(ucvector* out, const char* chunkName, const unsigned char* data, size_t length) { + CERROR_TRY_RETURN(lodepng_chunk_create(&out->data, &out->size, (unsigned)length, chunkName, data)); + out->allocsize = out->size; /*fix the allocsize again*/ + return 0; +} + +static void writeSignature(ucvector* out) { + /*8 bytes PNG signature, aka the magic bytes*/ + ucvector_push_back(out, 137); + ucvector_push_back(out, 80); + ucvector_push_back(out, 78); + ucvector_push_back(out, 71); + ucvector_push_back(out, 13); + ucvector_push_back(out, 10); + ucvector_push_back(out, 26); + ucvector_push_back(out, 10); +} + +static unsigned addChunk_IHDR(ucvector* out, unsigned w, unsigned h, + LodePNGColorType colortype, unsigned bitdepth, unsigned interlace_method) { + unsigned char data[13]; + + lodepng_set32bitInt(data + 0, w); /*width*/ + lodepng_set32bitInt(data + 4, h); /*height*/ + data[8] = (unsigned char)bitdepth; /*bit depth*/ + data[9] = (unsigned char)colortype; /*color type*/ + data[10] = 0; /*compression method*/ + data[11] = 0; /*filter method*/ + data[12] = interlace_method; /*interlace method*/ + + return addChunk(out, "IHDR", data, sizeof(data)); +} + +static unsigned addChunk_PLTE(ucvector* out, const LodePNGColorMode* info) { + unsigned error = 0; + size_t i; + ucvector PLTE; + ucvector_init(&PLTE); + for(i = 0; i != info->palettesize * 4; ++i) { + /*add all channels except alpha channel*/ + if(i % 4 != 3) ucvector_push_back(&PLTE, info->palette[i]); + } + error = addChunk(out, "PLTE", PLTE.data, PLTE.size); + ucvector_cleanup(&PLTE); + + return error; +} + +static unsigned addChunk_tRNS(ucvector* out, const LodePNGColorMode* info) { + unsigned error = 0; + size_t i; + ucvector tRNS; + ucvector_init(&tRNS); + if(info->colortype == LCT_PALETTE) { + size_t amount = info->palettesize; + /*the tail of palette values that all have 255 as alpha, does not have to be encoded*/ + for(i = info->palettesize; i != 0; --i) { + if(info->palette[4 * (i - 1) + 3] == 255) --amount; + else break; + } + /*add only alpha channel*/ + for(i = 0; i != amount; ++i) ucvector_push_back(&tRNS, info->palette[4 * i + 3]); + } else if(info->colortype == LCT_GREY) { + if(info->key_defined) { + ucvector_push_back(&tRNS, (unsigned char)(info->key_r >> 8)); + ucvector_push_back(&tRNS, (unsigned char)(info->key_r & 255)); + } + } else if(info->colortype == LCT_RGB) { + if(info->key_defined) { + ucvector_push_back(&tRNS, (unsigned char)(info->key_r >> 8)); + ucvector_push_back(&tRNS, (unsigned char)(info->key_r & 255)); + ucvector_push_back(&tRNS, (unsigned char)(info->key_g >> 8)); + ucvector_push_back(&tRNS, (unsigned char)(info->key_g & 255)); + ucvector_push_back(&tRNS, (unsigned char)(info->key_b >> 8)); + ucvector_push_back(&tRNS, (unsigned char)(info->key_b & 255)); + } + } + + error = addChunk(out, "tRNS", tRNS.data, tRNS.size); + ucvector_cleanup(&tRNS); + + return error; +} + +static unsigned addChunk_IDAT(ucvector* out, const unsigned char* data, size_t datasize, + LodePNGCompressSettings* zlibsettings) { + ucvector zlibdata; + unsigned error = 0; + + /*compress with the Zlib compressor*/ + ucvector_init(&zlibdata); + error = zlib_compress(&zlibdata.data, &zlibdata.size, data, datasize, zlibsettings); + if(!error) error = addChunk(out, "IDAT", zlibdata.data, zlibdata.size); + ucvector_cleanup(&zlibdata); + + return error; +} + +static unsigned addChunk_IEND(ucvector* out) { + unsigned error = 0; + error = addChunk(out, "IEND", 0, 0); + return error; +} + +#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS + +static unsigned addChunk_tEXt(ucvector* out, const char* keyword, const char* textstring) { + unsigned error = 0; + size_t i; + ucvector text; + ucvector_init(&text); + for(i = 0; keyword[i] != 0; ++i) ucvector_push_back(&text, (unsigned char)keyword[i]); + if(i < 1 || i > 79) return 89; /*error: invalid keyword size*/ + ucvector_push_back(&text, 0); /*0 termination char*/ + for(i = 0; textstring[i] != 0; ++i) ucvector_push_back(&text, (unsigned char)textstring[i]); + error = addChunk(out, "tEXt", text.data, text.size); + ucvector_cleanup(&text); + + return error; +} + +static unsigned addChunk_zTXt(ucvector* out, const char* keyword, const char* textstring, + LodePNGCompressSettings* zlibsettings) { + unsigned error = 0; + ucvector data, compressed; + size_t i, textsize = lodepng_strlen(textstring); + + ucvector_init(&data); + ucvector_init(&compressed); + for(i = 0; keyword[i] != 0; ++i) ucvector_push_back(&data, (unsigned char)keyword[i]); + if(i < 1 || i > 79) return 89; /*error: invalid keyword size*/ + ucvector_push_back(&data, 0); /*0 termination char*/ + ucvector_push_back(&data, 0); /*compression method: 0*/ + + error = zlib_compress(&compressed.data, &compressed.size, + (const unsigned char*)textstring, textsize, zlibsettings); + if(!error) { + for(i = 0; i != compressed.size; ++i) ucvector_push_back(&data, compressed.data[i]); + error = addChunk(out, "zTXt", data.data, data.size); + } + + ucvector_cleanup(&compressed); + ucvector_cleanup(&data); + return error; +} + +static unsigned addChunk_iTXt(ucvector* out, unsigned compressed, const char* keyword, const char* langtag, + const char* transkey, const char* textstring, LodePNGCompressSettings* zlibsettings) { + unsigned error = 0; + ucvector data; + size_t i, textsize = lodepng_strlen(textstring); + + ucvector_init(&data); + + for(i = 0; keyword[i] != 0; ++i) ucvector_push_back(&data, (unsigned char)keyword[i]); + if(i < 1 || i > 79) return 89; /*error: invalid keyword size*/ + ucvector_push_back(&data, 0); /*null termination char*/ + ucvector_push_back(&data, compressed ? 1 : 0); /*compression flag*/ + ucvector_push_back(&data, 0); /*compression method*/ + for(i = 0; langtag[i] != 0; ++i) ucvector_push_back(&data, (unsigned char)langtag[i]); + ucvector_push_back(&data, 0); /*null termination char*/ + for(i = 0; transkey[i] != 0; ++i) ucvector_push_back(&data, (unsigned char)transkey[i]); + ucvector_push_back(&data, 0); /*null termination char*/ + + if(compressed) { + ucvector compressed_data; + ucvector_init(&compressed_data); + error = zlib_compress(&compressed_data.data, &compressed_data.size, + (const unsigned char*)textstring, textsize, zlibsettings); + if(!error) { + for(i = 0; i != compressed_data.size; ++i) ucvector_push_back(&data, compressed_data.data[i]); + } + ucvector_cleanup(&compressed_data); + } else /*not compressed*/ { + for(i = 0; textstring[i] != 0; ++i) ucvector_push_back(&data, (unsigned char)textstring[i]); + } + + if(!error) error = addChunk(out, "iTXt", data.data, data.size); + ucvector_cleanup(&data); + return error; +} + +static unsigned addChunk_bKGD(ucvector* out, const LodePNGInfo* info) { + unsigned char data[6]; + size_t size = 0; + if(info->color.colortype == LCT_GREY || info->color.colortype == LCT_GREY_ALPHA) { + data[0] = (unsigned char)(info->background_r >> 8); + data[1] = (unsigned char)(info->background_r & 255); + size = 2; + } else if(info->color.colortype == LCT_RGB || info->color.colortype == LCT_RGBA) { + data[0] = (unsigned char)(info->background_r >> 8); + data[1] = (unsigned char)(info->background_r & 255); + data[2] = (unsigned char)(info->background_g >> 8); + data[3] = (unsigned char)(info->background_g & 255); + data[4] = (unsigned char)(info->background_b >> 8); + data[5] = (unsigned char)(info->background_b & 255); + size = 6; + } else if(info->color.colortype == LCT_PALETTE) { + data[0] =(unsigned char)(info->background_r & 255); /*palette index*/ + size = 1; + } + return addChunk(out, "bKGD", data, size); +} + +static unsigned addChunk_tIME(ucvector* out, const LodePNGTime* time) { + unsigned char data[7]; + data[0] = (unsigned char)(time->year >> 8); + data[1] = (unsigned char)(time->year & 255); + data[2] = (unsigned char)time->month; + data[3] = (unsigned char)time->day; + data[4] = (unsigned char)time->hour; + data[5] = (unsigned char)time->minute; + data[6] = (unsigned char)time->second; + return addChunk(out, "tIME", data, sizeof(data)); +} + +static unsigned addChunk_pHYs(ucvector* out, const LodePNGInfo* info) { + unsigned char data[9]; + lodepng_set32bitInt(data + 0, info->phys_x); + lodepng_set32bitInt(data + 4, info->phys_y); data[8] = info->phys_unit; + return addChunk(out, "pHYs", data, sizeof(data)); +} + +static unsigned addChunk_gAMA(ucvector* out, const LodePNGInfo* info) { + unsigned char data[4]; + lodepng_set32bitInt(data, info->gama_gamma); + return addChunk(out, "gAMA", data, sizeof(data)); +} + +static unsigned addChunk_cHRM(ucvector* out, const LodePNGInfo* info) { + unsigned char data[32]; + lodepng_set32bitInt(data + 0, info->chrm_white_x); + lodepng_set32bitInt(data + 4, info->chrm_white_y); + lodepng_set32bitInt(data + 8, info->chrm_red_x); + lodepng_set32bitInt(data + 12, info->chrm_red_y); + lodepng_set32bitInt(data + 16, info->chrm_green_x); + lodepng_set32bitInt(data + 20, info->chrm_green_y); + lodepng_set32bitInt(data + 24, info->chrm_blue_x); + lodepng_set32bitInt(data + 28, info->chrm_blue_y); + return addChunk(out, "cHRM", data, sizeof(data)); +} + +static unsigned addChunk_sRGB(ucvector* out, const LodePNGInfo* info) { + unsigned char data = info->srgb_intent; + return addChunk(out, "sRGB", &data, 1); +} + +static unsigned addChunk_iCCP(ucvector* out, const LodePNGInfo* info, LodePNGCompressSettings* zlibsettings) { + unsigned error = 0; + ucvector data, compressed; + size_t i; + + ucvector_init(&data); + ucvector_init(&compressed); + for(i = 0; info->iccp_name[i] != 0; ++i) ucvector_push_back(&data, (unsigned char)info->iccp_name[i]); + if(i < 1 || i > 79) return 89; /*error: invalid keyword size*/ + ucvector_push_back(&data, 0); /*0 termination char*/ + ucvector_push_back(&data, 0); /*compression method: 0*/ + + error = zlib_compress(&compressed.data, &compressed.size, + info->iccp_profile, info->iccp_profile_size, zlibsettings); + if(!error) { + for(i = 0; i != compressed.size; ++i) ucvector_push_back(&data, compressed.data[i]); + error = addChunk(out, "iCCP", data.data, data.size); + } + + ucvector_cleanup(&compressed); + ucvector_cleanup(&data); + return error; +} + +#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ + +static void filterScanline(unsigned char* out, const unsigned char* scanline, const unsigned char* prevline, + size_t length, size_t bytewidth, unsigned char filterType) { + size_t i; + switch(filterType) { + case 0: /*None*/ + for(i = 0; i != length; ++i) out[i] = scanline[i]; + break; + case 1: /*Sub*/ + for(i = 0; i != bytewidth; ++i) out[i] = scanline[i]; + for(i = bytewidth; i < length; ++i) out[i] = scanline[i] - scanline[i - bytewidth]; + break; + case 2: /*Up*/ + if(prevline) { + for(i = 0; i != length; ++i) out[i] = scanline[i] - prevline[i]; + } else { + for(i = 0; i != length; ++i) out[i] = scanline[i]; + } + break; + case 3: /*Average*/ + if(prevline) { + for(i = 0; i != bytewidth; ++i) out[i] = scanline[i] - (prevline[i] >> 1); + for(i = bytewidth; i < length; ++i) out[i] = scanline[i] - ((scanline[i - bytewidth] + prevline[i]) >> 1); + } else { + for(i = 0; i != bytewidth; ++i) out[i] = scanline[i]; + for(i = bytewidth; i < length; ++i) out[i] = scanline[i] - (scanline[i - bytewidth] >> 1); + } + break; + case 4: /*Paeth*/ + if(prevline) { + /*paethPredictor(0, prevline[i], 0) is always prevline[i]*/ + for(i = 0; i != bytewidth; ++i) out[i] = (scanline[i] - prevline[i]); + for(i = bytewidth; i < length; ++i) { + out[i] = (scanline[i] - paethPredictor(scanline[i - bytewidth], prevline[i], prevline[i - bytewidth])); + } + } else { + for(i = 0; i != bytewidth; ++i) out[i] = scanline[i]; + /*paethPredictor(scanline[i - bytewidth], 0, 0) is always scanline[i - bytewidth]*/ + for(i = bytewidth; i < length; ++i) out[i] = (scanline[i] - scanline[i - bytewidth]); + } + break; + default: return; /*unexisting filter type given*/ + } +} + +/* TODO: remove the usage of float */ +/* log2 approximation. A slight bit faster than std::log. */ +static float flog2(float f) { + float result = 0; + while(f > 32) { result += 4; f /= 16; } + while(f > 2) { ++result; f /= 2; } + return result + 1.442695f * (f * f * f / 3 - 3 * f * f / 2 + 3 * f - 1.83333f); +} + +static unsigned filter(unsigned char* out, const unsigned char* in, unsigned w, unsigned h, + const LodePNGColorMode* info, const LodePNGEncoderSettings* settings) { + /* + For PNG filter method 0 + out must be a buffer with as size: h + (w * h * bpp + 7u) / 8u, because there are + the scanlines with 1 extra byte per scanline + */ + + unsigned bpp = lodepng_get_bpp(info); + /*the width of a scanline in bytes, not including the filter type*/ + size_t linebytes = (w * bpp + 7u) / 8u; + /*bytewidth is used for filtering, is 1 when bpp < 8, number of bytes per pixel otherwise*/ + size_t bytewidth = (bpp + 7u) / 8u; + const unsigned char* prevline = 0; + unsigned x, y; + unsigned error = 0; + LodePNGFilterStrategy strategy = settings->filter_strategy; + + /* + There is a heuristic called the minimum sum of absolute differences heuristic, suggested by the PNG standard: + * If the image type is Palette, or the bit depth is smaller than 8, then do not filter the image (i.e. + use fixed filtering, with the filter None). + * (The other case) If the image type is Grayscale or RGB (with or without Alpha), and the bit depth is + not smaller than 8, then use adaptive filtering heuristic as follows: independently for each row, apply + all five filters and select the filter that produces the smallest sum of absolute values per row. + This heuristic is used if filter strategy is LFS_MINSUM and filter_palette_zero is true. + + If filter_palette_zero is true and filter_strategy is not LFS_MINSUM, the above heuristic is followed, + but for "the other case", whatever strategy filter_strategy is set to instead of the minimum sum + heuristic is used. + */ + if(settings->filter_palette_zero && + (info->colortype == LCT_PALETTE || info->bitdepth < 8)) strategy = LFS_ZERO; + + if(bpp == 0) return 31; /*error: invalid color type*/ + + if(strategy >= LFS_ZERO && strategy <= LFS_FOUR) { + unsigned char type = (unsigned char)strategy; + for(y = 0; y != h; ++y) { + size_t outindex = (1 + linebytes) * y; /*the extra filterbyte added to each row*/ + size_t inindex = linebytes * y; + out[outindex] = type; /*filter type byte*/ + filterScanline(&out[outindex + 1], &in[inindex], prevline, linebytes, bytewidth, type); + prevline = &in[inindex]; + } + } else if(strategy == LFS_MINSUM) { + /*adaptive filtering*/ + size_t sum[5]; + unsigned char* attempt[5]; /*five filtering attempts, one for each filter type*/ + size_t smallest = 0; + unsigned char type, bestType = 0; + + for(type = 0; type != 5; ++type) { + attempt[type] = (unsigned char*)lodepng_malloc(linebytes); + if(!attempt[type]) return 83; /*alloc fail*/ + } + + if(!error) { + for(y = 0; y != h; ++y) { + /*try the 5 filter types*/ + for(type = 0; type != 5; ++type) { + filterScanline(attempt[type], &in[y * linebytes], prevline, linebytes, bytewidth, type); + + /*calculate the sum of the result*/ + sum[type] = 0; + if(type == 0) { + for(x = 0; x != linebytes; ++x) sum[type] += (unsigned char)(attempt[type][x]); + } else { + for(x = 0; x != linebytes; ++x) { + /*For differences, each byte should be treated as signed, values above 127 are negative + (converted to signed char). Filtertype 0 isn't a difference though, so use unsigned there. + This means filtertype 0 is almost never chosen, but that is justified.*/ + unsigned char s = attempt[type][x]; + sum[type] += s < 128 ? s : (255U - s); + } + } + + /*check if this is smallest sum (or if type == 0 it's the first case so always store the values)*/ + if(type == 0 || sum[type] < smallest) { + bestType = type; + smallest = sum[type]; + } + } + + prevline = &in[y * linebytes]; + + /*now fill the out values*/ + out[y * (linebytes + 1)] = bestType; /*the first byte of a scanline will be the filter type*/ + for(x = 0; x != linebytes; ++x) out[y * (linebytes + 1) + 1 + x] = attempt[bestType][x]; + } + } + + for(type = 0; type != 5; ++type) lodepng_free(attempt[type]); + } else if(strategy == LFS_ENTROPY) { + float sum[5]; + unsigned char* attempt[5]; /*five filtering attempts, one for each filter type*/ + float smallest = 0; + unsigned type, bestType = 0; + unsigned count[256]; + + for(type = 0; type != 5; ++type) { + attempt[type] = (unsigned char*)lodepng_malloc(linebytes); + if(!attempt[type]) return 83; /*alloc fail*/ + } + + for(y = 0; y != h; ++y) { + /*try the 5 filter types*/ + for(type = 0; type != 5; ++type) { + filterScanline(attempt[type], &in[y * linebytes], prevline, linebytes, bytewidth, type); + for(x = 0; x != 256; ++x) count[x] = 0; + for(x = 0; x != linebytes; ++x) ++count[attempt[type][x]]; + ++count[type]; /*the filter type itself is part of the scanline*/ + sum[type] = 0; + for(x = 0; x != 256; ++x) { + float p = count[x] / (float)(linebytes + 1); + sum[type] += count[x] == 0 ? 0 : flog2(1 / p) * p; + } + /*check if this is smallest sum (or if type == 0 it's the first case so always store the values)*/ + if(type == 0 || sum[type] < smallest) { + bestType = type; + smallest = sum[type]; + } + } + + prevline = &in[y * linebytes]; + + /*now fill the out values*/ + out[y * (linebytes + 1)] = bestType; /*the first byte of a scanline will be the filter type*/ + for(x = 0; x != linebytes; ++x) out[y * (linebytes + 1) + 1 + x] = attempt[bestType][x]; + } + + for(type = 0; type != 5; ++type) lodepng_free(attempt[type]); + } else if(strategy == LFS_PREDEFINED) { + for(y = 0; y != h; ++y) { + size_t outindex = (1 + linebytes) * y; /*the extra filterbyte added to each row*/ + size_t inindex = linebytes * y; + unsigned char type = settings->predefined_filters[y]; + out[outindex] = type; /*filter type byte*/ + filterScanline(&out[outindex + 1], &in[inindex], prevline, linebytes, bytewidth, type); + prevline = &in[inindex]; + } + } else if(strategy == LFS_BRUTE_FORCE) { + /*brute force filter chooser. + deflate the scanline after every filter attempt to see which one deflates best. + This is very slow and gives only slightly smaller, sometimes even larger, result*/ + size_t size[5]; + unsigned char* attempt[5]; /*five filtering attempts, one for each filter type*/ + size_t smallest = 0; + unsigned type = 0, bestType = 0; + unsigned char* dummy; + LodePNGCompressSettings zlibsettings = settings->zlibsettings; + /*use fixed tree on the attempts so that the tree is not adapted to the filtertype on purpose, + to simulate the true case where the tree is the same for the whole image. Sometimes it gives + better result with dynamic tree anyway. Using the fixed tree sometimes gives worse, but in rare + cases better compression. It does make this a bit less slow, so it's worth doing this.*/ + zlibsettings.btype = 1; + /*a custom encoder likely doesn't read the btype setting and is optimized for complete PNG + images only, so disable it*/ + zlibsettings.custom_zlib = 0; + zlibsettings.custom_deflate = 0; + for(type = 0; type != 5; ++type) { + attempt[type] = (unsigned char*)lodepng_malloc(linebytes); + if(!attempt[type]) return 83; /*alloc fail*/ + } + for(y = 0; y != h; ++y) /*try the 5 filter types*/ { + for(type = 0; type != 5; ++type) { + unsigned testsize = (unsigned)linebytes; + /*if(testsize > 8) testsize /= 8;*/ /*it already works good enough by testing a part of the row*/ + + filterScanline(attempt[type], &in[y * linebytes], prevline, linebytes, bytewidth, type); + size[type] = 0; + dummy = 0; + zlib_compress(&dummy, &size[type], attempt[type], testsize, &zlibsettings); + lodepng_free(dummy); + /*check if this is smallest size (or if type == 0 it's the first case so always store the values)*/ + if(type == 0 || size[type] < smallest) { + bestType = type; + smallest = size[type]; + } + } + prevline = &in[y * linebytes]; + out[y * (linebytes + 1)] = bestType; /*the first byte of a scanline will be the filter type*/ + for(x = 0; x != linebytes; ++x) out[y * (linebytes + 1) + 1 + x] = attempt[bestType][x]; + } + for(type = 0; type != 5; ++type) lodepng_free(attempt[type]); + } + else return 88; /* unknown filter strategy */ + + return error; +} + +static void addPaddingBits(unsigned char* out, const unsigned char* in, + size_t olinebits, size_t ilinebits, unsigned h) { + /*The opposite of the removePaddingBits function + olinebits must be >= ilinebits*/ + unsigned y; + size_t diff = olinebits - ilinebits; + size_t obp = 0, ibp = 0; /*bit pointers*/ + for(y = 0; y != h; ++y) { + size_t x; + for(x = 0; x < ilinebits; ++x) { + unsigned char bit = readBitFromReversedStream(&ibp, in); + setBitOfReversedStream(&obp, out, bit); + } + /*obp += diff; --> no, fill in some value in the padding bits too, to avoid + "Use of uninitialised value of size ###" warning from valgrind*/ + for(x = 0; x != diff; ++x) setBitOfReversedStream(&obp, out, 0); + } +} + +/* +in: non-interlaced image with size w*h +out: the same pixels, but re-ordered according to PNG's Adam7 interlacing, with + no padding bits between scanlines, but between reduced images so that each + reduced image starts at a byte. +bpp: bits per pixel +there are no padding bits, not between scanlines, not between reduced images +in has the following size in bits: w * h * bpp. +out is possibly bigger due to padding bits between reduced images +NOTE: comments about padding bits are only relevant if bpp < 8 +*/ +static void Adam7_interlace(unsigned char* out, const unsigned char* in, unsigned w, unsigned h, unsigned bpp) { + unsigned passw[7], passh[7]; + size_t filter_passstart[8], padded_passstart[8], passstart[8]; + unsigned i; + + Adam7_getpassvalues(passw, passh, filter_passstart, padded_passstart, passstart, w, h, bpp); + + if(bpp >= 8) { + for(i = 0; i != 7; ++i) { + unsigned x, y, b; + size_t bytewidth = bpp / 8u; + for(y = 0; y < passh[i]; ++y) + for(x = 0; x < passw[i]; ++x) { + size_t pixelinstart = ((ADAM7_IY[i] + y * ADAM7_DY[i]) * w + ADAM7_IX[i] + x * ADAM7_DX[i]) * bytewidth; + size_t pixeloutstart = passstart[i] + (y * passw[i] + x) * bytewidth; + for(b = 0; b < bytewidth; ++b) { + out[pixeloutstart + b] = in[pixelinstart + b]; + } + } + } + } else /*bpp < 8: Adam7 with pixels < 8 bit is a bit trickier: with bit pointers*/ { + for(i = 0; i != 7; ++i) { + unsigned x, y, b; + unsigned ilinebits = bpp * passw[i]; + unsigned olinebits = bpp * w; + size_t obp, ibp; /*bit pointers (for out and in buffer)*/ + for(y = 0; y < passh[i]; ++y) + for(x = 0; x < passw[i]; ++x) { + ibp = (ADAM7_IY[i] + y * ADAM7_DY[i]) * olinebits + (ADAM7_IX[i] + x * ADAM7_DX[i]) * bpp; + obp = (8 * passstart[i]) + (y * ilinebits + x * bpp); + for(b = 0; b < bpp; ++b) { + unsigned char bit = readBitFromReversedStream(&ibp, in); + setBitOfReversedStream(&obp, out, bit); + } + } + } + } +} + +/*out must be buffer big enough to contain uncompressed IDAT chunk data, and in must contain the full image. +return value is error**/ +static unsigned preProcessScanlines(unsigned char** out, size_t* outsize, const unsigned char* in, + unsigned w, unsigned h, + const LodePNGInfo* info_png, const LodePNGEncoderSettings* settings) { + /* + This function converts the pure 2D image with the PNG's colortype, into filtered-padded-interlaced data. Steps: + *) if no Adam7: 1) add padding bits (= posible extra bits per scanline if bpp < 8) 2) filter + *) if adam7: 1) Adam7_interlace 2) 7x add padding bits 3) 7x filter + */ + unsigned bpp = lodepng_get_bpp(&info_png->color); + unsigned error = 0; + + if(info_png->interlace_method == 0) { + *outsize = h + (h * ((w * bpp + 7u) / 8u)); /*image size plus an extra byte per scanline + possible padding bits*/ + *out = (unsigned char*)lodepng_malloc(*outsize); + if(!(*out) && (*outsize)) error = 83; /*alloc fail*/ + + if(!error) { + /*non multiple of 8 bits per scanline, padding bits needed per scanline*/ + if(bpp < 8 && w * bpp != ((w * bpp + 7u) / 8u) * 8u) { + unsigned char* padded = (unsigned char*)lodepng_malloc(h * ((w * bpp + 7u) / 8u)); + if(!padded) error = 83; /*alloc fail*/ + if(!error) { + addPaddingBits(padded, in, ((w * bpp + 7u) / 8u) * 8u, w * bpp, h); + error = filter(*out, padded, w, h, &info_png->color, settings); + } + lodepng_free(padded); + } else { + /*we can immediately filter into the out buffer, no other steps needed*/ + error = filter(*out, in, w, h, &info_png->color, settings); + } + } + } else /*interlace_method is 1 (Adam7)*/ { + unsigned passw[7], passh[7]; + size_t filter_passstart[8], padded_passstart[8], passstart[8]; + unsigned char* adam7; + + Adam7_getpassvalues(passw, passh, filter_passstart, padded_passstart, passstart, w, h, bpp); + + *outsize = filter_passstart[7]; /*image size plus an extra byte per scanline + possible padding bits*/ + *out = (unsigned char*)lodepng_malloc(*outsize); + if(!(*out)) error = 83; /*alloc fail*/ + + adam7 = (unsigned char*)lodepng_malloc(passstart[7]); + if(!adam7 && passstart[7]) error = 83; /*alloc fail*/ + + if(!error) { + unsigned i; + + Adam7_interlace(adam7, in, w, h, bpp); + for(i = 0; i != 7; ++i) { + if(bpp < 8) { + unsigned char* padded = (unsigned char*)lodepng_malloc(padded_passstart[i + 1] - padded_passstart[i]); + if(!padded) ERROR_BREAK(83); /*alloc fail*/ + addPaddingBits(padded, &adam7[passstart[i]], + ((passw[i] * bpp + 7u) / 8u) * 8u, passw[i] * bpp, passh[i]); + error = filter(&(*out)[filter_passstart[i]], padded, + passw[i], passh[i], &info_png->color, settings); + lodepng_free(padded); + } else { + error = filter(&(*out)[filter_passstart[i]], &adam7[padded_passstart[i]], + passw[i], passh[i], &info_png->color, settings); + } + + if(error) break; + } + } + + lodepng_free(adam7); + } + + return error; +} + +/* +palette must have 4 * palettesize bytes allocated, and given in format RGBARGBARGBARGBA... +returns 0 if the palette is opaque, +returns 1 if the palette has a single color with alpha 0 ==> color key +returns 2 if the palette is semi-translucent. +*/ +static unsigned getPaletteTranslucency(const unsigned char* palette, size_t palettesize) { + size_t i; + unsigned key = 0; + unsigned r = 0, g = 0, b = 0; /*the value of the color with alpha 0, so long as color keying is possible*/ + for(i = 0; i != palettesize; ++i) { + if(!key && palette[4 * i + 3] == 0) { + r = palette[4 * i + 0]; g = palette[4 * i + 1]; b = palette[4 * i + 2]; + key = 1; + i = (size_t)(-1); /*restart from beginning, to detect earlier opaque colors with key's value*/ + } + else if(palette[4 * i + 3] != 255) return 2; + /*when key, no opaque RGB may have key's RGB*/ + else if(key && r == palette[i * 4 + 0] && g == palette[i * 4 + 1] && b == palette[i * 4 + 2]) return 2; + } + return key; +} + +#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS +static unsigned addUnknownChunks(ucvector* out, unsigned char* data, size_t datasize) { + unsigned char* inchunk = data; + while((size_t)(inchunk - data) < datasize) { + CERROR_TRY_RETURN(lodepng_chunk_append(&out->data, &out->size, inchunk)); + out->allocsize = out->size; /*fix the allocsize again*/ + inchunk = lodepng_chunk_next(inchunk); + } + return 0; +} + +static unsigned isGrayICCProfile(const unsigned char* profile, unsigned size) { + /* + It is a gray profile if bytes 16-19 are "GRAY", rgb profile if bytes 16-19 + are "RGB ". We do not perform any full parsing of the ICC profile here, other + than check those 4 bytes to grayscale profile. Other than that, validity of + the profile is not checked. This is needed only because the PNG specification + requires using a non-gray color model if there is an ICC profile with "RGB " + (sadly limiting compression opportunities if the input data is grayscale RGB + data), and requires using a gray color model if it is "GRAY". + */ + if(size < 20) return 0; + return profile[16] == 'G' && profile[17] == 'R' && profile[18] == 'A' && profile[19] == 'Y'; +} + +static unsigned isRGBICCProfile(const unsigned char* profile, unsigned size) { + /* See comment in isGrayICCProfile*/ + if(size < 20) return 0; + return profile[16] == 'R' && profile[17] == 'G' && profile[18] == 'B' && profile[19] == ' '; +} +#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ + +unsigned lodepng_encode(unsigned char** out, size_t* outsize, + const unsigned char* image, unsigned w, unsigned h, + LodePNGState* state) { + unsigned char* data = 0; /*uncompressed version of the IDAT chunk data*/ + size_t datasize = 0; + ucvector outv; + LodePNGInfo info; + const LodePNGInfo* info_png = &state->info_png; + + ucvector_init(&outv); + lodepng_info_init(&info); + + /*provide some proper output values if error will happen*/ + *out = 0; + *outsize = 0; + state->error = 0; + + /*check input values validity*/ + if((info_png->color.colortype == LCT_PALETTE || state->encoder.force_palette) + && (info_png->color.palettesize == 0 || info_png->color.palettesize > 256)) { + state->error = 68; /*invalid palette size, it is only allowed to be 1-256*/ + goto cleanup; + } + if(state->encoder.zlibsettings.btype > 2) { + state->error = 61; /*error: unexisting btype*/ + goto cleanup; + } + if(info_png->interlace_method > 1) { + state->error = 71; /*error: unexisting interlace mode*/ + goto cleanup; + } + state->error = checkColorValidity(info_png->color.colortype, info_png->color.bitdepth); + if(state->error) goto cleanup; /*error: unexisting color type given*/ + state->error = checkColorValidity(state->info_raw.colortype, state->info_raw.bitdepth); + if(state->error) goto cleanup; /*error: unexisting color type given*/ + + /* color convert and compute scanline filter types */ + lodepng_info_copy(&info, &state->info_png); + if(state->encoder.auto_convert) { + LodePNGColorStats stats; + lodepng_color_stats_init(&stats); +#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS + if(info_png->iccp_defined && + isGrayICCProfile(info_png->iccp_profile, info_png->iccp_profile_size)) { + /*the PNG specification does not allow to use palette with a GRAY ICC profile, even + if the palette has only gray colors, so disallow it.*/ + stats.allow_palette = 0; + } + if(info_png->iccp_defined && + isRGBICCProfile(info_png->iccp_profile, info_png->iccp_profile_size)) { + /*the PNG specification does not allow to use grayscale color with RGB ICC profile, so disallow gray.*/ + stats.allow_greyscale = 0; + } +#endif /* LODEPNG_COMPILE_ANCILLARY_CHUNKS */ + lodepng_compute_color_stats(&stats, image, w, h, &state->info_raw); +#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS + if(info_png->background_defined) { + /*the background chunk's color must be taken into account as well*/ + unsigned r = 0, g = 0, b = 0; + LodePNGColorMode mode16 = lodepng_color_mode_make(LCT_RGB, 16); + lodepng_convert_rgb(&r, &g, &b, info_png->background_r, info_png->background_g, info_png->background_b, &mode16, &info_png->color); + lodepng_color_stats_add(&stats, r, g, b, 65535); + } +#endif /* LODEPNG_COMPILE_ANCILLARY_CHUNKS */ + state->error = auto_choose_color(&info.color, &state->info_raw, &stats); + if(state->error) goto cleanup; +#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS + /*also convert the background chunk*/ + if(info_png->background_defined) { + if(lodepng_convert_rgb(&info.background_r, &info.background_g, &info.background_b, + info_png->background_r, info_png->background_g, info_png->background_b, &info.color, &info_png->color)) { + state->error = 104; + goto cleanup; + } + } +#endif /* LODEPNG_COMPILE_ANCILLARY_CHUNKS */ + } +#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS + if(info_png->iccp_defined) { + unsigned gray_icc = isGrayICCProfile(info_png->iccp_profile, info_png->iccp_profile_size); + unsigned rgb_icc = isRGBICCProfile(info_png->iccp_profile, info_png->iccp_profile_size); + unsigned gray_png = info.color.colortype == LCT_GREY || info.color.colortype == LCT_GREY_ALPHA; + if(!gray_icc && !rgb_icc) { + state->error = 100; /* Disallowed profile color type for PNG */ + goto cleanup; + } + if(gray_icc != gray_png) { + /*Not allowed to use RGB/RGBA/palette with GRAY ICC profile or vice versa, + or in case of auto_convert, it wasn't possible to find appropriate model*/ + state->error = state->encoder.auto_convert ? 102 : 101; + goto cleanup; + } + } +#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ + if(!lodepng_color_mode_equal(&state->info_raw, &info.color)) { + unsigned char* converted; + size_t size = ((size_t)w * (size_t)h * (size_t)lodepng_get_bpp(&info.color) + 7u) / 8u; + + converted = (unsigned char*)lodepng_malloc(size); + if(!converted && size) state->error = 83; /*alloc fail*/ + if(!state->error) { + state->error = lodepng_convert(converted, image, &info.color, &state->info_raw, w, h); + } + if(!state->error) preProcessScanlines(&data, &datasize, converted, w, h, &info, &state->encoder); + lodepng_free(converted); + if(state->error) goto cleanup; + } + else preProcessScanlines(&data, &datasize, image, w, h, &info, &state->encoder); + + /* output all PNG chunks */ { +#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS + size_t i; +#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ + /*write signature and chunks*/ + writeSignature(&outv); + /*IHDR*/ + addChunk_IHDR(&outv, w, h, info.color.colortype, info.color.bitdepth, info.interlace_method); +#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS + /*unknown chunks between IHDR and PLTE*/ + if(info.unknown_chunks_data[0]) { + state->error = addUnknownChunks(&outv, info.unknown_chunks_data[0], info.unknown_chunks_size[0]); + if(state->error) goto cleanup; + } + /*color profile chunks must come before PLTE */ + if(info.iccp_defined) addChunk_iCCP(&outv, &info, &state->encoder.zlibsettings); + if(info.srgb_defined) addChunk_sRGB(&outv, &info); + if(info.gama_defined) addChunk_gAMA(&outv, &info); + if(info.chrm_defined) addChunk_cHRM(&outv, &info); +#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ + /*PLTE*/ + if(info.color.colortype == LCT_PALETTE) { + addChunk_PLTE(&outv, &info.color); + } + if(state->encoder.force_palette && (info.color.colortype == LCT_RGB || info.color.colortype == LCT_RGBA)) { + addChunk_PLTE(&outv, &info.color); + } + /*tRNS*/ + if(info.color.colortype == LCT_PALETTE && getPaletteTranslucency(info.color.palette, info.color.palettesize) != 0) { + addChunk_tRNS(&outv, &info.color); + } + if((info.color.colortype == LCT_GREY || info.color.colortype == LCT_RGB) && info.color.key_defined) { + addChunk_tRNS(&outv, &info.color); + } +#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS + /*bKGD (must come between PLTE and the IDAt chunks*/ + if(info.background_defined) { + state->error = addChunk_bKGD(&outv, &info); + if(state->error) goto cleanup; + } + /*pHYs (must come before the IDAT chunks)*/ + if(info.phys_defined) addChunk_pHYs(&outv, &info); + + /*unknown chunks between PLTE and IDAT*/ + if(info.unknown_chunks_data[1]) { + state->error = addUnknownChunks(&outv, info.unknown_chunks_data[1], info.unknown_chunks_size[1]); + if(state->error) goto cleanup; + } +#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ + /*IDAT (multiple IDAT chunks must be consecutive)*/ + state->error = addChunk_IDAT(&outv, data, datasize, &state->encoder.zlibsettings); + if(state->error) goto cleanup; +#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS + /*tIME*/ + if(info.time_defined) addChunk_tIME(&outv, &info.time); + /*tEXt and/or zTXt*/ + for(i = 0; i != info.text_num; ++i) { + if(lodepng_strlen(info.text_keys[i]) > 79) { + state->error = 66; /*text chunk too large*/ + goto cleanup; + } + if(lodepng_strlen(info.text_keys[i]) < 1) { + state->error = 67; /*text chunk too small*/ + goto cleanup; + } + if(state->encoder.text_compression) { + addChunk_zTXt(&outv, info.text_keys[i], info.text_strings[i], &state->encoder.zlibsettings); + } else { + addChunk_tEXt(&outv, info.text_keys[i], info.text_strings[i]); + } + } + /*LodePNG version id in text chunk*/ + if(state->encoder.add_id) { + unsigned already_added_id_text = 0; + for(i = 0; i != info.text_num; ++i) { + const char* k = info.text_keys[i]; + /* Could use strcmp, but we're not calling or reimplementing this C library function for this use only */ + if(k[0] == 'L' && k[1] == 'o' && k[2] == 'd' && k[3] == 'e' && + k[4] == 'P' && k[5] == 'N' && k[6] == 'G' && k[7] == '\0') { + already_added_id_text = 1; + break; + } + } + if(already_added_id_text == 0) { + addChunk_tEXt(&outv, "LodePNG", LODEPNG_VERSION_STRING); /*it's shorter as tEXt than as zTXt chunk*/ + } + } + /*iTXt*/ + for(i = 0; i != info.itext_num; ++i) { + if(lodepng_strlen(info.itext_keys[i]) > 79) { + state->error = 66; /*text chunk too large*/ + goto cleanup; + } + if(lodepng_strlen(info.itext_keys[i]) < 1) { + state->error = 67; /*text chunk too small*/ + goto cleanup; + } + addChunk_iTXt(&outv, state->encoder.text_compression, + info.itext_keys[i], info.itext_langtags[i], info.itext_transkeys[i], info.itext_strings[i], + &state->encoder.zlibsettings); + } + + /*unknown chunks between IDAT and IEND*/ + if(info.unknown_chunks_data[2]) { + state->error = addUnknownChunks(&outv, info.unknown_chunks_data[2], info.unknown_chunks_size[2]); + if(state->error) goto cleanup; + } +#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ + addChunk_IEND(&outv); + } + +cleanup: + lodepng_info_cleanup(&info); + lodepng_free(data); + + /*instead of cleaning the vector up, give it to the output*/ + *out = outv.data; + *outsize = outv.size; + + return state->error; +} + +unsigned lodepng_encode_memory(unsigned char** out, size_t* outsize, const unsigned char* image, + unsigned w, unsigned h, LodePNGColorType colortype, unsigned bitdepth) { + unsigned error; + LodePNGState state; + lodepng_state_init(&state); + state.info_raw.colortype = colortype; + state.info_raw.bitdepth = bitdepth; + state.info_png.color.colortype = colortype; + state.info_png.color.bitdepth = bitdepth; + lodepng_encode(out, outsize, image, w, h, &state); + error = state.error; + lodepng_state_cleanup(&state); + return error; +} + +unsigned lodepng_encode32(unsigned char** out, size_t* outsize, const unsigned char* image, unsigned w, unsigned h) { + return lodepng_encode_memory(out, outsize, image, w, h, LCT_RGBA, 8); +} + +unsigned lodepng_encode24(unsigned char** out, size_t* outsize, const unsigned char* image, unsigned w, unsigned h) { + return lodepng_encode_memory(out, outsize, image, w, h, LCT_RGB, 8); +} + +#ifdef LODEPNG_COMPILE_DISK +unsigned lodepng_encode_file(const char* filename, const unsigned char* image, unsigned w, unsigned h, + LodePNGColorType colortype, unsigned bitdepth) { + unsigned char* buffer; + size_t buffersize; + unsigned error = lodepng_encode_memory(&buffer, &buffersize, image, w, h, colortype, bitdepth); + if(!error) error = lodepng_save_file(buffer, buffersize, filename); + lodepng_free(buffer); + return error; +} + +unsigned lodepng_encode32_file(const char* filename, const unsigned char* image, unsigned w, unsigned h) { + return lodepng_encode_file(filename, image, w, h, LCT_RGBA, 8); +} + +unsigned lodepng_encode24_file(const char* filename, const unsigned char* image, unsigned w, unsigned h) { + return lodepng_encode_file(filename, image, w, h, LCT_RGB, 8); +} +#endif /*LODEPNG_COMPILE_DISK*/ + +void lodepng_encoder_settings_init(LodePNGEncoderSettings* settings) { + lodepng_compress_settings_init(&settings->zlibsettings); + settings->filter_palette_zero = 1; + settings->filter_strategy = LFS_MINSUM; + settings->auto_convert = 1; + settings->force_palette = 0; + settings->predefined_filters = 0; +#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS + settings->add_id = 0; + settings->text_compression = 1; +#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ +} + +#endif /*LODEPNG_COMPILE_ENCODER*/ +#endif /*LODEPNG_COMPILE_PNG*/ + +#ifdef LODEPNG_COMPILE_ERROR_TEXT +/* +This returns the description of a numerical error code in English. This is also +the documentation of all the error codes. +*/ +const char* lodepng_error_text(unsigned code) { + switch(code) { + case 0: return "no error, everything went ok"; + case 1: return "nothing done yet"; /*the Encoder/Decoder has done nothing yet, error checking makes no sense yet*/ + case 10: return "end of input memory reached without huffman end code"; /*while huffman decoding*/ + case 11: return "error in code tree made it jump outside of huffman tree"; /*while huffman decoding*/ + case 13: return "problem while processing dynamic deflate block"; + case 14: return "problem while processing dynamic deflate block"; + case 15: return "problem while processing dynamic deflate block"; + case 16: return "unexisting code while processing dynamic deflate block"; + case 17: return "end of out buffer memory reached while inflating"; + case 18: return "invalid distance code while inflating"; + case 19: return "end of out buffer memory reached while inflating"; + case 20: return "invalid deflate block BTYPE encountered while decoding"; + case 21: return "NLEN is not ones complement of LEN in a deflate block"; + + /*end of out buffer memory reached while inflating: + This can happen if the inflated deflate data is longer than the amount of bytes required to fill up + all the pixels of the image, given the color depth and image dimensions. Something that doesn't + happen in a normal, well encoded, PNG image.*/ + case 22: return "end of out buffer memory reached while inflating"; + case 23: return "end of in buffer memory reached while inflating"; + case 24: return "invalid FCHECK in zlib header"; + case 25: return "invalid compression method in zlib header"; + case 26: return "FDICT encountered in zlib header while it's not used for PNG"; + case 27: return "PNG file is smaller than a PNG header"; + /*Checks the magic file header, the first 8 bytes of the PNG file*/ + case 28: return "incorrect PNG signature, it's no PNG or corrupted"; + case 29: return "first chunk is not the header chunk"; + case 30: return "chunk length too large, chunk broken off at end of file"; + case 31: return "illegal PNG color type or bpp"; + case 32: return "illegal PNG compression method"; + case 33: return "illegal PNG filter method"; + case 34: return "illegal PNG interlace method"; + case 35: return "chunk length of a chunk is too large or the chunk too small"; + case 36: return "illegal PNG filter type encountered"; + case 37: return "illegal bit depth for this color type given"; + case 38: return "the palette is too big"; /*more than 256 colors*/ + case 39: return "tRNS chunk before PLTE or has more entries than palette size"; + case 40: return "tRNS chunk has wrong size for grayscale image"; + case 41: return "tRNS chunk has wrong size for RGB image"; + case 42: return "tRNS chunk appeared while it was not allowed for this color type"; + case 43: return "bKGD chunk has wrong size for palette image"; + case 44: return "bKGD chunk has wrong size for grayscale image"; + case 45: return "bKGD chunk has wrong size for RGB image"; + case 48: return "empty input buffer given to decoder. Maybe caused by non-existing file?"; + case 49: return "jumped past memory while generating dynamic huffman tree"; + case 50: return "jumped past memory while generating dynamic huffman tree"; + case 51: return "jumped past memory while inflating huffman block"; + case 52: return "jumped past memory while inflating"; + case 53: return "size of zlib data too small"; + case 54: return "repeat symbol in tree while there was no value symbol yet"; + /*jumped past tree while generating huffman tree, this could be when the + tree will have more leaves than symbols after generating it out of the + given lenghts. They call this an oversubscribed dynamic bit lengths tree in zlib.*/ + case 55: return "jumped past tree while generating huffman tree"; + case 56: return "given output image colortype or bitdepth not supported for color conversion"; + case 57: return "invalid CRC encountered (checking CRC can be disabled)"; + case 58: return "invalid ADLER32 encountered (checking ADLER32 can be disabled)"; + case 59: return "requested color conversion not supported"; + case 60: return "invalid window size given in the settings of the encoder (must be 0-32768)"; + case 61: return "invalid BTYPE given in the settings of the encoder (only 0, 1 and 2 are allowed)"; + /*LodePNG leaves the choice of RGB to grayscale conversion formula to the user.*/ + case 62: return "conversion from color to grayscale not supported"; + /*(2^31-1)*/ + case 63: return "length of a chunk too long, max allowed for PNG is 2147483647 bytes per chunk"; + /*this would result in the inability of a deflated block to ever contain an end code. It must be at least 1.*/ + case 64: return "the length of the END symbol 256 in the Huffman tree is 0"; + case 66: return "the length of a text chunk keyword given to the encoder is longer than the maximum of 79 bytes"; + case 67: return "the length of a text chunk keyword given to the encoder is smaller than the minimum of 1 byte"; + case 68: return "tried to encode a PLTE chunk with a palette that has less than 1 or more than 256 colors"; + case 69: return "unknown chunk type with 'critical' flag encountered by the decoder"; + case 71: return "unexisting interlace mode given to encoder (must be 0 or 1)"; + case 72: return "while decoding, unexisting compression method encountering in zTXt or iTXt chunk (it must be 0)"; + case 73: return "invalid tIME chunk size"; + case 74: return "invalid pHYs chunk size"; + /*length could be wrong, or data chopped off*/ + case 75: return "no null termination char found while decoding text chunk"; + case 76: return "iTXt chunk too short to contain required bytes"; + case 77: return "integer overflow in buffer size"; + case 78: return "failed to open file for reading"; /*file doesn't exist or couldn't be opened for reading*/ + case 79: return "failed to open file for writing"; + case 80: return "tried creating a tree of 0 symbols"; + case 81: return "lazy matching at pos 0 is impossible"; + case 82: return "color conversion to palette requested while a color isn't in palette, or index out of bounds"; + case 83: return "memory allocation failed"; + case 84: return "given image too small to contain all pixels to be encoded"; + case 86: return "impossible offset in lz77 encoding (internal bug)"; + case 87: return "must provide custom zlib function pointer if LODEPNG_COMPILE_ZLIB is not defined"; + case 88: return "invalid filter strategy given for LodePNGEncoderSettings.filter_strategy"; + case 89: return "text chunk keyword too short or long: must have size 1-79"; + /*the windowsize in the LodePNGCompressSettings. Requiring POT(==> & instead of %) makes encoding 12% faster.*/ + case 90: return "windowsize must be a power of two"; + case 91: return "invalid decompressed idat size"; + case 92: return "integer overflow due to too many pixels"; + case 93: return "zero width or height is invalid"; + case 94: return "header chunk must have a size of 13 bytes"; + case 95: return "integer overflow with combined idat chunk size"; + case 96: return "invalid gAMA chunk size"; + case 97: return "invalid cHRM chunk size"; + case 98: return "invalid sRGB chunk size"; + case 99: return "invalid sRGB rendering intent"; + case 100: return "invalid ICC profile color type, the PNG specification only allows RGB or GRAY"; + case 101: return "PNG specification does not allow RGB ICC profile on gray color types and vice versa"; + case 102: return "not allowed to set grayscale ICC profile with colored pixels by PNG specification"; + case 103: return "invalid palette index in bKGD chunk. Maybe it came before PLTE chunk?"; + case 104: return "invalid bKGD color while encoding (e.g. palette index out of range)"; + } + return "unknown error code"; +} +#endif /*LODEPNG_COMPILE_ERROR_TEXT*/ + +/* ////////////////////////////////////////////////////////////////////////// */ +/* ////////////////////////////////////////////////////////////////////////// */ +/* // C++ Wrapper // */ +/* ////////////////////////////////////////////////////////////////////////// */ +/* ////////////////////////////////////////////////////////////////////////// */ + +#ifdef LODEPNG_COMPILE_CPP +namespace lodepng { + +#ifdef LODEPNG_COMPILE_DISK +#ifdef LODEPNG_COMPILE_DECODER +unsigned load_file(std::vector& buffer, const std::string& filename) { + long size = lodepng_filesize(filename.c_str()); + if(size < 0) return 78; + buffer.resize((size_t)size); + return size == 0 ? 0 : lodepng_buffer_file(&buffer[0], (size_t)size, filename.c_str()); +} +#endif /*LODEPNG_COMPILE_DECODER*/ + +/*write given buffer to the file, overwriting the file, it doesn't append to it.*/ +unsigned save_file(const std::vector& buffer, const std::string& filename) { + return lodepng_save_file(buffer.empty() ? 0 : &buffer[0], buffer.size(), filename.c_str()); +} +#endif /* LODEPNG_COMPILE_DISK */ + +#ifdef LODEPNG_COMPILE_ZLIB +#ifdef LODEPNG_COMPILE_DECODER +unsigned decompress(std::vector& out, const unsigned char* in, size_t insize, + const LodePNGDecompressSettings& settings) { + unsigned char* buffer = 0; + size_t buffersize = 0; + unsigned error = zlib_decompress(&buffer, &buffersize, in, insize, &settings); + if(buffer) { + out.insert(out.end(), &buffer[0], &buffer[buffersize]); + lodepng_free(buffer); + } + return error; +} + +unsigned decompress(std::vector& out, const std::vector& in, + const LodePNGDecompressSettings& settings) { + return decompress(out, in.empty() ? 0 : &in[0], in.size(), settings); +} +#endif /* LODEPNG_COMPILE_DECODER */ + +#ifdef LODEPNG_COMPILE_ENCODER +unsigned compress(std::vector& out, const unsigned char* in, size_t insize, + const LodePNGCompressSettings& settings) { + unsigned char* buffer = 0; + size_t buffersize = 0; + unsigned error = zlib_compress(&buffer, &buffersize, in, insize, &settings); + if(buffer) { + out.insert(out.end(), &buffer[0], &buffer[buffersize]); + lodepng_free(buffer); + } + return error; +} + +unsigned compress(std::vector& out, const std::vector& in, + const LodePNGCompressSettings& settings) { + return compress(out, in.empty() ? 0 : &in[0], in.size(), settings); +} +#endif /* LODEPNG_COMPILE_ENCODER */ +#endif /* LODEPNG_COMPILE_ZLIB */ + + +#ifdef LODEPNG_COMPILE_PNG + +State::State() { + lodepng_state_init(this); +} + +State::State(const State& other) { + lodepng_state_init(this); + lodepng_state_copy(this, &other); +} + +State::~State() { + lodepng_state_cleanup(this); +} + +State& State::operator=(const State& other) { + lodepng_state_copy(this, &other); + return *this; +} + +#ifdef LODEPNG_COMPILE_DECODER + +unsigned decode(std::vector& out, unsigned& w, unsigned& h, const unsigned char* in, + size_t insize, LodePNGColorType colortype, unsigned bitdepth) { + unsigned char* buffer; + unsigned error = lodepng_decode_memory(&buffer, &w, &h, in, insize, colortype, bitdepth); + if(buffer && !error) { + State state; + state.info_raw.colortype = colortype; + state.info_raw.bitdepth = bitdepth; + size_t buffersize = lodepng_get_raw_size(w, h, &state.info_raw); + out.insert(out.end(), &buffer[0], &buffer[buffersize]); + lodepng_free(buffer); + } + return error; +} + +unsigned decode(std::vector& out, unsigned& w, unsigned& h, + const std::vector& in, LodePNGColorType colortype, unsigned bitdepth) { + return decode(out, w, h, in.empty() ? 0 : &in[0], (unsigned)in.size(), colortype, bitdepth); +} + +unsigned decode(std::vector& out, unsigned& w, unsigned& h, + State& state, + const unsigned char* in, size_t insize) { + unsigned char* buffer = NULL; + unsigned error = lodepng_decode(&buffer, &w, &h, &state, in, insize); + if(buffer && !error) { + size_t buffersize = lodepng_get_raw_size(w, h, &state.info_raw); + out.insert(out.end(), &buffer[0], &buffer[buffersize]); + } + lodepng_free(buffer); + return error; +} + +unsigned decode(std::vector& out, unsigned& w, unsigned& h, + State& state, + const std::vector& in) { + return decode(out, w, h, state, in.empty() ? 0 : &in[0], in.size()); +} + +#ifdef LODEPNG_COMPILE_DISK +unsigned decode(std::vector& out, unsigned& w, unsigned& h, const std::string& filename, + LodePNGColorType colortype, unsigned bitdepth) { + std::vector buffer; + /* safe output values in case error happens */ + w = h = 0; + unsigned error = load_file(buffer, filename); + if(error) return error; + return decode(out, w, h, buffer, colortype, bitdepth); +} +#endif /* LODEPNG_COMPILE_DECODER */ +#endif /* LODEPNG_COMPILE_DISK */ + +#ifdef LODEPNG_COMPILE_ENCODER +unsigned encode(std::vector& out, const unsigned char* in, unsigned w, unsigned h, + LodePNGColorType colortype, unsigned bitdepth) { + unsigned char* buffer; + size_t buffersize; + unsigned error = lodepng_encode_memory(&buffer, &buffersize, in, w, h, colortype, bitdepth); + if(buffer) { + out.insert(out.end(), &buffer[0], &buffer[buffersize]); + lodepng_free(buffer); + } + return error; +} + +unsigned encode(std::vector& out, + const std::vector& in, unsigned w, unsigned h, + LodePNGColorType colortype, unsigned bitdepth) { + if(lodepng_get_raw_size_lct(w, h, colortype, bitdepth) > in.size()) return 84; + return encode(out, in.empty() ? 0 : &in[0], w, h, colortype, bitdepth); +} + +unsigned encode(std::vector& out, + const unsigned char* in, unsigned w, unsigned h, + State& state) { + unsigned char* buffer; + size_t buffersize; + unsigned error = lodepng_encode(&buffer, &buffersize, in, w, h, &state); + if(buffer) { + out.insert(out.end(), &buffer[0], &buffer[buffersize]); + lodepng_free(buffer); + } + return error; +} + +unsigned encode(std::vector& out, + const std::vector& in, unsigned w, unsigned h, + State& state) { + if(lodepng_get_raw_size(w, h, &state.info_raw) > in.size()) return 84; + return encode(out, in.empty() ? 0 : &in[0], w, h, state); +} + +#ifdef LODEPNG_COMPILE_DISK +unsigned encode(const std::string& filename, + const unsigned char* in, unsigned w, unsigned h, + LodePNGColorType colortype, unsigned bitdepth) { + std::vector buffer; + unsigned error = encode(buffer, in, w, h, colortype, bitdepth); + if(!error) error = save_file(buffer, filename); + return error; +} + +unsigned encode(const std::string& filename, + const std::vector& in, unsigned w, unsigned h, + LodePNGColorType colortype, unsigned bitdepth) { + if(lodepng_get_raw_size_lct(w, h, colortype, bitdepth) > in.size()) return 84; + return encode(filename, in.empty() ? 0 : &in[0], w, h, colortype, bitdepth); +} +#endif /* LODEPNG_COMPILE_DISK */ +#endif /* LODEPNG_COMPILE_ENCODER */ +#endif /* LODEPNG_COMPILE_PNG */ +} /* namespace lodepng */ +#endif /*LODEPNG_COMPILE_CPP*/ diff --git a/engine/Quake/lodepng.h b/engine/Quake/lodepng.h new file mode 100644 index 0000000..558ff1b --- /dev/null +++ b/engine/Quake/lodepng.h @@ -0,0 +1,1949 @@ +/* +LodePNG version 20190824 + +Copyright (c) 2005-2019 Lode Vandevenne + +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any damages +arising from the use of this software. + +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it +freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + + 3. This notice may not be removed or altered from any source + distribution. +*/ + +#ifndef LODEPNG_H +#define LODEPNG_H + +#include /*for size_t*/ + +extern const char* LODEPNG_VERSION_STRING; + +/* +The following #defines are used to create code sections. They can be disabled +to disable code sections, which can give faster compile time and smaller binary. +The "NO_COMPILE" defines are designed to be used to pass as defines to the +compiler command to disable them without modifying this header, e.g. +-DLODEPNG_NO_COMPILE_ZLIB for gcc. +In addition to those below, you can also define LODEPNG_NO_COMPILE_CRC to +allow implementing a custom lodepng_crc32. +*/ +/*deflate & zlib. If disabled, you must specify alternative zlib functions in +the custom_zlib field of the compress and decompress settings*/ +#ifndef LODEPNG_NO_COMPILE_ZLIB +#define LODEPNG_COMPILE_ZLIB +#endif + +/*png encoder and png decoder*/ +#ifndef LODEPNG_NO_COMPILE_PNG +#define LODEPNG_COMPILE_PNG +#endif + +/*deflate&zlib decoder and png decoder*/ +#ifndef LODEPNG_NO_COMPILE_DECODER +#define LODEPNG_COMPILE_DECODER +#endif + +/*deflate&zlib encoder and png encoder*/ +#ifndef LODEPNG_NO_COMPILE_ENCODER +#define LODEPNG_COMPILE_ENCODER +#endif + +/*the optional built in harddisk file loading and saving functions*/ +#ifndef LODEPNG_NO_COMPILE_DISK +#define LODEPNG_COMPILE_DISK +#endif + +/*support for chunks other than IHDR, IDAT, PLTE, tRNS, IEND: ancillary and unknown chunks*/ +#ifndef LODEPNG_NO_COMPILE_ANCILLARY_CHUNKS +#define LODEPNG_COMPILE_ANCILLARY_CHUNKS +#endif + +/*ability to convert error numerical codes to English text string*/ +#ifndef LODEPNG_NO_COMPILE_ERROR_TEXT +#define LODEPNG_COMPILE_ERROR_TEXT +#endif + +/*Compile the default allocators (C's free, malloc and realloc). If you disable this, +you can define the functions lodepng_free, lodepng_malloc and lodepng_realloc in your +source files with custom allocators.*/ +#ifndef LODEPNG_NO_COMPILE_ALLOCATORS +#define LODEPNG_COMPILE_ALLOCATORS +#endif + +/*compile the C++ version (you can disable the C++ wrapper here even when compiling for C++)*/ +#ifdef __cplusplus +#ifndef LODEPNG_NO_COMPILE_CPP +#define LODEPNG_COMPILE_CPP +#endif +#endif + +#ifdef LODEPNG_COMPILE_CPP +#include +#include +#endif /*LODEPNG_COMPILE_CPP*/ + +#ifdef LODEPNG_COMPILE_PNG +/*The PNG color types (also used for raw image).*/ +typedef enum LodePNGColorType { + LCT_GREY = 0, /*grayscale: 1,2,4,8,16 bit*/ + LCT_RGB = 2, /*RGB: 8,16 bit*/ + LCT_PALETTE = 3, /*palette: 1,2,4,8 bit*/ + LCT_GREY_ALPHA = 4, /*grayscale with alpha: 8,16 bit*/ + LCT_RGBA = 6, /*RGB with alpha: 8,16 bit*/ + /*LCT_MAX_OCTET_VALUE lets the compiler allow this enum to represent any invalid + byte value from 0 to 255 that could be present in an invalid PNG file header. Do + not use, compare with or set the name LCT_MAX_OCTET_VALUE, instead either use + the valid color type names above, or numeric values like 1 or 7 when checking for + particular disallowed color type byte values, or cast to integer to print it.*/ + LCT_MAX_OCTET_VALUE = 255 +} LodePNGColorType; + +#ifdef LODEPNG_COMPILE_DECODER +/* +Converts PNG data in memory to raw pixel data. +out: Output parameter. Pointer to buffer that will contain the raw pixel data. + After decoding, its size is w * h * (bytes per pixel) bytes larger than + initially. Bytes per pixel depends on colortype and bitdepth. + Must be freed after usage with free(*out). + Note: for 16-bit per channel colors, uses big endian format like PNG does. +w: Output parameter. Pointer to width of pixel data. +h: Output parameter. Pointer to height of pixel data. +in: Memory buffer with the PNG file. +insize: size of the in buffer. +colortype: the desired color type for the raw output image. See explanation on PNG color types. +bitdepth: the desired bit depth for the raw output image. See explanation on PNG color types. +Return value: LodePNG error code (0 means no error). +*/ +unsigned lodepng_decode_memory(unsigned char** out, unsigned* w, unsigned* h, + const unsigned char* in, size_t insize, + LodePNGColorType colortype, unsigned bitdepth); + +/*Same as lodepng_decode_memory, but always decodes to 32-bit RGBA raw image*/ +unsigned lodepng_decode32(unsigned char** out, unsigned* w, unsigned* h, + const unsigned char* in, size_t insize); + +/*Same as lodepng_decode_memory, but always decodes to 24-bit RGB raw image*/ +unsigned lodepng_decode24(unsigned char** out, unsigned* w, unsigned* h, + const unsigned char* in, size_t insize); + +#ifdef LODEPNG_COMPILE_DISK +/* +Load PNG from disk, from file with given name. +Same as the other decode functions, but instead takes a filename as input. +*/ +unsigned lodepng_decode_file(unsigned char** out, unsigned* w, unsigned* h, + const char* filename, + LodePNGColorType colortype, unsigned bitdepth); + +/*Same as lodepng_decode_file, but always decodes to 32-bit RGBA raw image.*/ +unsigned lodepng_decode32_file(unsigned char** out, unsigned* w, unsigned* h, + const char* filename); + +/*Same as lodepng_decode_file, but always decodes to 24-bit RGB raw image.*/ +unsigned lodepng_decode24_file(unsigned char** out, unsigned* w, unsigned* h, + const char* filename); +#endif /*LODEPNG_COMPILE_DISK*/ +#endif /*LODEPNG_COMPILE_DECODER*/ + + +#ifdef LODEPNG_COMPILE_ENCODER +/* +Converts raw pixel data into a PNG image in memory. The colortype and bitdepth + of the output PNG image cannot be chosen, they are automatically determined + by the colortype, bitdepth and content of the input pixel data. + Note: for 16-bit per channel colors, needs big endian format like PNG does. +out: Output parameter. Pointer to buffer that will contain the PNG image data. + Must be freed after usage with free(*out). +outsize: Output parameter. Pointer to the size in bytes of the out buffer. +image: The raw pixel data to encode. The size of this buffer should be + w * h * (bytes per pixel), bytes per pixel depends on colortype and bitdepth. +w: width of the raw pixel data in pixels. +h: height of the raw pixel data in pixels. +colortype: the color type of the raw input image. See explanation on PNG color types. +bitdepth: the bit depth of the raw input image. See explanation on PNG color types. +Return value: LodePNG error code (0 means no error). +*/ +unsigned lodepng_encode_memory(unsigned char** out, size_t* outsize, + const unsigned char* image, unsigned w, unsigned h, + LodePNGColorType colortype, unsigned bitdepth); + +/*Same as lodepng_encode_memory, but always encodes from 32-bit RGBA raw image.*/ +unsigned lodepng_encode32(unsigned char** out, size_t* outsize, + const unsigned char* image, unsigned w, unsigned h); + +/*Same as lodepng_encode_memory, but always encodes from 24-bit RGB raw image.*/ +unsigned lodepng_encode24(unsigned char** out, size_t* outsize, + const unsigned char* image, unsigned w, unsigned h); + +#ifdef LODEPNG_COMPILE_DISK +/* +Converts raw pixel data into a PNG file on disk. +Same as the other encode functions, but instead takes a filename as output. +NOTE: This overwrites existing files without warning! +*/ +unsigned lodepng_encode_file(const char* filename, + const unsigned char* image, unsigned w, unsigned h, + LodePNGColorType colortype, unsigned bitdepth); + +/*Same as lodepng_encode_file, but always encodes from 32-bit RGBA raw image.*/ +unsigned lodepng_encode32_file(const char* filename, + const unsigned char* image, unsigned w, unsigned h); + +/*Same as lodepng_encode_file, but always encodes from 24-bit RGB raw image.*/ +unsigned lodepng_encode24_file(const char* filename, + const unsigned char* image, unsigned w, unsigned h); +#endif /*LODEPNG_COMPILE_DISK*/ +#endif /*LODEPNG_COMPILE_ENCODER*/ + + +#ifdef LODEPNG_COMPILE_CPP +namespace lodepng { +#ifdef LODEPNG_COMPILE_DECODER +/*Same as lodepng_decode_memory, but decodes to an std::vector. The colortype +is the format to output the pixels to. Default is RGBA 8-bit per channel.*/ +unsigned decode(std::vector& out, unsigned& w, unsigned& h, + const unsigned char* in, size_t insize, + LodePNGColorType colortype = LCT_RGBA, unsigned bitdepth = 8); +unsigned decode(std::vector& out, unsigned& w, unsigned& h, + const std::vector& in, + LodePNGColorType colortype = LCT_RGBA, unsigned bitdepth = 8); +#ifdef LODEPNG_COMPILE_DISK +/* +Converts PNG file from disk to raw pixel data in memory. +Same as the other decode functions, but instead takes a filename as input. +*/ +unsigned decode(std::vector& out, unsigned& w, unsigned& h, + const std::string& filename, + LodePNGColorType colortype = LCT_RGBA, unsigned bitdepth = 8); +#endif /* LODEPNG_COMPILE_DISK */ +#endif /* LODEPNG_COMPILE_DECODER */ + +#ifdef LODEPNG_COMPILE_ENCODER +/*Same as lodepng_encode_memory, but encodes to an std::vector. colortype +is that of the raw input data. The output PNG color type will be auto chosen.*/ +unsigned encode(std::vector& out, + const unsigned char* in, unsigned w, unsigned h, + LodePNGColorType colortype = LCT_RGBA, unsigned bitdepth = 8); +unsigned encode(std::vector& out, + const std::vector& in, unsigned w, unsigned h, + LodePNGColorType colortype = LCT_RGBA, unsigned bitdepth = 8); +#ifdef LODEPNG_COMPILE_DISK +/* +Converts 32-bit RGBA raw pixel data into a PNG file on disk. +Same as the other encode functions, but instead takes a filename as output. +NOTE: This overwrites existing files without warning! +*/ +unsigned encode(const std::string& filename, + const unsigned char* in, unsigned w, unsigned h, + LodePNGColorType colortype = LCT_RGBA, unsigned bitdepth = 8); +unsigned encode(const std::string& filename, + const std::vector& in, unsigned w, unsigned h, + LodePNGColorType colortype = LCT_RGBA, unsigned bitdepth = 8); +#endif /* LODEPNG_COMPILE_DISK */ +#endif /* LODEPNG_COMPILE_ENCODER */ +} /* namespace lodepng */ +#endif /*LODEPNG_COMPILE_CPP*/ +#endif /*LODEPNG_COMPILE_PNG*/ + +#ifdef LODEPNG_COMPILE_ERROR_TEXT +/*Returns an English description of the numerical error code.*/ +const char* lodepng_error_text(unsigned code); +#endif /*LODEPNG_COMPILE_ERROR_TEXT*/ + +#ifdef LODEPNG_COMPILE_DECODER +/*Settings for zlib decompression*/ +typedef struct LodePNGDecompressSettings LodePNGDecompressSettings; +struct LodePNGDecompressSettings { + /* Check LodePNGDecoderSettings for more ignorable errors such as ignore_crc */ + unsigned ignore_adler32; /*if 1, continue and don't give an error message if the Adler32 checksum is corrupted*/ + unsigned ignore_nlen; /*ignore complement of len checksum in uncompressed blocks*/ + + /*use custom zlib decoder instead of built in one (default: null)*/ + unsigned (*custom_zlib)(unsigned char**, size_t*, + const unsigned char*, size_t, + const LodePNGDecompressSettings*); + /*use custom deflate decoder instead of built in one (default: null) + if custom_zlib is not null, custom_inflate is ignored (the zlib format uses deflate)*/ + unsigned (*custom_inflate)(unsigned char**, size_t*, + const unsigned char*, size_t, + const LodePNGDecompressSettings*); + + const void* custom_context; /*optional custom settings for custom functions*/ +}; + +extern const LodePNGDecompressSettings lodepng_default_decompress_settings; +void lodepng_decompress_settings_init(LodePNGDecompressSettings* settings); +#endif /*LODEPNG_COMPILE_DECODER*/ + +#ifdef LODEPNG_COMPILE_ENCODER +/* +Settings for zlib compression. Tweaking these settings tweaks the balance +between speed and compression ratio. +*/ +typedef struct LodePNGCompressSettings LodePNGCompressSettings; +struct LodePNGCompressSettings /*deflate = compress*/ { + /*LZ77 related settings*/ + unsigned btype; /*the block type for LZ (0, 1, 2 or 3, see zlib standard). Should be 2 for proper compression.*/ + unsigned use_lz77; /*whether or not to use LZ77. Should be 1 for proper compression.*/ + unsigned windowsize; /*must be a power of two <= 32768. higher compresses more but is slower. Default value: 2048.*/ + unsigned minmatch; /*mininum lz77 length. 3 is normally best, 6 can be better for some PNGs. Default: 0*/ + unsigned nicematch; /*stop searching if >= this length found. Set to 258 for best compression. Default: 128*/ + unsigned lazymatching; /*use lazy matching: better compression but a bit slower. Default: true*/ + + /*use custom zlib encoder instead of built in one (default: null)*/ + unsigned (*custom_zlib)(unsigned char**, size_t*, + const unsigned char*, size_t, + const LodePNGCompressSettings*); + /*use custom deflate encoder instead of built in one (default: null) + if custom_zlib is used, custom_deflate is ignored since only the built in + zlib function will call custom_deflate*/ + unsigned (*custom_deflate)(unsigned char**, size_t*, + const unsigned char*, size_t, + const LodePNGCompressSettings*); + + const void* custom_context; /*optional custom settings for custom functions*/ +}; + +extern const LodePNGCompressSettings lodepng_default_compress_settings; +void lodepng_compress_settings_init(LodePNGCompressSettings* settings); +#endif /*LODEPNG_COMPILE_ENCODER*/ + +#ifdef LODEPNG_COMPILE_PNG +/* +Color mode of an image. Contains all information required to decode the pixel +bits to RGBA colors. This information is the same as used in the PNG file +format, and is used both for PNG and raw image data in LodePNG. +*/ +typedef struct LodePNGColorMode { + /*header (IHDR)*/ + LodePNGColorType colortype; /*color type, see PNG standard or documentation further in this header file*/ + unsigned bitdepth; /*bits per sample, see PNG standard or documentation further in this header file*/ + + /* + palette (PLTE and tRNS) + + Dynamically allocated with the colors of the palette, including alpha. + When encoding a PNG, to store your colors in the palette of the LodePNGColorMode, first use + lodepng_palette_clear, then for each color use lodepng_palette_add. + If you encode an image without alpha with palette, don't forget to put value 255 in each A byte of the palette. + + When decoding, by default you can ignore this palette, since LodePNG already + fills the palette colors in the pixels of the raw RGBA output. + + The palette is only supported for color type 3. + */ + unsigned char* palette; /*palette in RGBARGBA... order. When allocated, must be either 0, or have size 1024*/ + size_t palettesize; /*palette size in number of colors (amount of bytes is 4 * palettesize)*/ + + /* + transparent color key (tRNS) + + This color uses the same bit depth as the bitdepth value in this struct, which can be 1-bit to 16-bit. + For grayscale PNGs, r, g and b will all 3 be set to the same. + + When decoding, by default you can ignore this information, since LodePNG sets + pixels with this key to transparent already in the raw RGBA output. + + The color key is only supported for color types 0 and 2. + */ + unsigned key_defined; /*is a transparent color key given? 0 = false, 1 = true*/ + unsigned key_r; /*red/grayscale component of color key*/ + unsigned key_g; /*green component of color key*/ + unsigned key_b; /*blue component of color key*/ +} LodePNGColorMode; + +/*init, cleanup and copy functions to use with this struct*/ +void lodepng_color_mode_init(LodePNGColorMode* info); +void lodepng_color_mode_cleanup(LodePNGColorMode* info); +/*return value is error code (0 means no error)*/ +unsigned lodepng_color_mode_copy(LodePNGColorMode* dest, const LodePNGColorMode* source); +/* Makes a temporary LodePNGColorMode that does not need cleanup (no palette) */ +LodePNGColorMode lodepng_color_mode_make(LodePNGColorType colortype, unsigned bitdepth); + +void lodepng_palette_clear(LodePNGColorMode* info); +/*add 1 color to the palette*/ +unsigned lodepng_palette_add(LodePNGColorMode* info, + unsigned char r, unsigned char g, unsigned char b, unsigned char a); + +/*get the total amount of bits per pixel, based on colortype and bitdepth in the struct*/ +unsigned lodepng_get_bpp(const LodePNGColorMode* info); +/*get the amount of color channels used, based on colortype in the struct. +If a palette is used, it counts as 1 channel.*/ +unsigned lodepng_get_channels(const LodePNGColorMode* info); +/*is it a grayscale type? (only colortype 0 or 4)*/ +unsigned lodepng_is_greyscale_type(const LodePNGColorMode* info); +/*has it got an alpha channel? (only colortype 2 or 6)*/ +unsigned lodepng_is_alpha_type(const LodePNGColorMode* info); +/*has it got a palette? (only colortype 3)*/ +unsigned lodepng_is_palette_type(const LodePNGColorMode* info); +/*only returns true if there is a palette and there is a value in the palette with alpha < 255. +Loops through the palette to check this.*/ +unsigned lodepng_has_palette_alpha(const LodePNGColorMode* info); +/* +Check if the given color info indicates the possibility of having non-opaque pixels in the PNG image. +Returns true if the image can have translucent or invisible pixels (it still be opaque if it doesn't use such pixels). +Returns false if the image can only have opaque pixels. +In detail, it returns true only if it's a color type with alpha, or has a palette with non-opaque values, +or if "key_defined" is true. +*/ +unsigned lodepng_can_have_alpha(const LodePNGColorMode* info); +/*Returns the byte size of a raw image buffer with given width, height and color mode*/ +size_t lodepng_get_raw_size(unsigned w, unsigned h, const LodePNGColorMode* color); + +#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS +/*The information of a Time chunk in PNG.*/ +typedef struct LodePNGTime { + unsigned year; /*2 bytes used (0-65535)*/ + unsigned month; /*1-12*/ + unsigned day; /*1-31*/ + unsigned hour; /*0-23*/ + unsigned minute; /*0-59*/ + unsigned second; /*0-60 (to allow for leap seconds)*/ +} LodePNGTime; +#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ + +/*Information about the PNG image, except pixels, width and height.*/ +typedef struct LodePNGInfo { + /*header (IHDR), palette (PLTE) and transparency (tRNS) chunks*/ + unsigned compression_method;/*compression method of the original file. Always 0.*/ + unsigned filter_method; /*filter method of the original file*/ + unsigned interlace_method; /*interlace method of the original file: 0=none, 1=Adam7*/ + LodePNGColorMode color; /*color type and bits, palette and transparency of the PNG file*/ + +#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS + /* + Suggested background color chunk (bKGD) + + This uses the same color mode and bit depth as the PNG (except no alpha channel), + with values truncated to the bit depth in the unsigned integer. + + For grayscale and palette PNGs, the value is stored in background_r. The values + in background_g and background_b are then unused. + + So when decoding, you may get these in a different color mode than the one you requested + for the raw pixels. + + When encoding with auto_convert, you must use the color model defined in info_png.color for + these values. The encoder normally ignores info_png.color when auto_convert is on, but will + use it to interpret these values (and convert copies of them to its chosen color model). + + When encoding, avoid setting this to an expensive color, such as a non-gray value + when the image is gray, or the compression will be worse since it will be forced to + write the PNG with a more expensive color mode (when auto_convert is on). + + The decoder does not use this background color to edit the color of pixels. This is a + completely optional metadata feature. + */ + unsigned background_defined; /*is a suggested background color given?*/ + unsigned background_r; /*red/gray/palette component of suggested background color*/ + unsigned background_g; /*green component of suggested background color*/ + unsigned background_b; /*blue component of suggested background color*/ + + /* + non-international text chunks (tEXt and zTXt) + + The char** arrays each contain num strings. The actual messages are in + text_strings, while text_keys are keywords that give a short description what + the actual text represents, e.g. Title, Author, Description, or anything else. + + All the string fields below including keys, names and language tags are null terminated. + The PNG specification uses null characters for the keys, names and tags, and forbids null + characters to appear in the main text which is why we can use null termination everywhere here. + + A keyword is minimum 1 character and maximum 79 characters long. It's + discouraged to use a single line length longer than 79 characters for texts. + + Don't allocate these text buffers yourself. Use the init/cleanup functions + correctly and use lodepng_add_text and lodepng_clear_text. + */ + size_t text_num; /*the amount of texts in these char** buffers (there may be more texts in itext)*/ + char** text_keys; /*the keyword of a text chunk (e.g. "Comment")*/ + char** text_strings; /*the actual text*/ + + /* + international text chunks (iTXt) + Similar to the non-international text chunks, but with additional strings + "langtags" and "transkeys". + */ + size_t itext_num; /*the amount of international texts in this PNG*/ + char** itext_keys; /*the English keyword of the text chunk (e.g. "Comment")*/ + char** itext_langtags; /*language tag for this text's language, ISO/IEC 646 string, e.g. ISO 639 language tag*/ + char** itext_transkeys; /*keyword translated to the international language - UTF-8 string*/ + char** itext_strings; /*the actual international text - UTF-8 string*/ + + /*time chunk (tIME)*/ + unsigned time_defined; /*set to 1 to make the encoder generate a tIME chunk*/ + LodePNGTime time; + + /*phys chunk (pHYs)*/ + unsigned phys_defined; /*if 0, there is no pHYs chunk and the values below are undefined, if 1 else there is one*/ + unsigned phys_x; /*pixels per unit in x direction*/ + unsigned phys_y; /*pixels per unit in y direction*/ + unsigned phys_unit; /*may be 0 (unknown unit) or 1 (metre)*/ + + /* + Color profile related chunks: gAMA, cHRM, sRGB, iCPP + + LodePNG does not apply any color conversions on pixels in the encoder or decoder and does not interpret these color + profile values. It merely passes on the information. If you wish to use color profiles and convert colors, please + use these values with a color management library. + + See the PNG, ICC and sRGB specifications for more information about the meaning of these values. + */ + + /* gAMA chunk: optional, overridden by sRGB or iCCP if those are present. */ + unsigned gama_defined; /* Whether a gAMA chunk is present (0 = not present, 1 = present). */ + unsigned gama_gamma; /* Gamma exponent times 100000 */ + + /* cHRM chunk: optional, overridden by sRGB or iCCP if those are present. */ + unsigned chrm_defined; /* Whether a cHRM chunk is present (0 = not present, 1 = present). */ + unsigned chrm_white_x; /* White Point x times 100000 */ + unsigned chrm_white_y; /* White Point y times 100000 */ + unsigned chrm_red_x; /* Red x times 100000 */ + unsigned chrm_red_y; /* Red y times 100000 */ + unsigned chrm_green_x; /* Green x times 100000 */ + unsigned chrm_green_y; /* Green y times 100000 */ + unsigned chrm_blue_x; /* Blue x times 100000 */ + unsigned chrm_blue_y; /* Blue y times 100000 */ + + /* + sRGB chunk: optional. May not appear at the same time as iCCP. + If gAMA is also present gAMA must contain value 45455. + If cHRM is also present cHRM must contain respectively 31270,32900,64000,33000,30000,60000,15000,6000. + */ + unsigned srgb_defined; /* Whether an sRGB chunk is present (0 = not present, 1 = present). */ + unsigned srgb_intent; /* Rendering intent: 0=perceptual, 1=rel. colorimetric, 2=saturation, 3=abs. colorimetric */ + + /* + iCCP chunk: optional. May not appear at the same time as sRGB. + + LodePNG does not parse or use the ICC profile (except its color space header field for an edge case), a + separate library to handle the ICC data (not included in LodePNG) format is needed to use it for color + management and conversions. + + For encoding, if iCCP is present, gAMA and cHRM are recommended to be added as well with values that match the ICC + profile as closely as possible, if you wish to do this you should provide the correct values for gAMA and cHRM and + enable their '_defined' flags since LodePNG will not automatically compute them from the ICC profile. + + For encoding, the ICC profile is required by the PNG specification to be an "RGB" profile for non-gray + PNG color types and a "GRAY" profile for gray PNG color types. If you disable auto_convert, you must ensure + the ICC profile type matches your requested color type, else the encoder gives an error. If auto_convert is + enabled (the default), and the ICC profile is not a good match for the pixel data, this will result in an encoder + error if the pixel data has non-gray pixels for a GRAY profile, or a silent less-optimal compression of the pixel + data if the pixels could be encoded as grayscale but the ICC profile is RGB. + + To avoid this do not set an ICC profile in the image unless there is a good reason for it, and when doing so + make sure you compute it carefully to avoid the above problems. + */ + unsigned iccp_defined; /* Whether an iCCP chunk is present (0 = not present, 1 = present). */ + char* iccp_name; /* Null terminated string with profile name, 1-79 bytes */ + /* + The ICC profile in iccp_profile_size bytes. + Don't allocate this buffer yourself. Use the init/cleanup functions + correctly and use lodepng_set_icc and lodepng_clear_icc. + */ + unsigned char* iccp_profile; + unsigned iccp_profile_size; /* The size of iccp_profile in bytes */ + + /* End of color profile related chunks */ + + + /* + unknown chunks: chunks not known by LodePNG, passed on byte for byte. + + There are 3 buffers, one for each position in the PNG where unknown chunks can appear. + Each buffer contains all unknown chunks for that position consecutively. + The 3 positions are: + 0: between IHDR and PLTE, 1: between PLTE and IDAT, 2: between IDAT and IEND. + + For encoding, do not store critical chunks or known chunks that are enabled with a "_defined" flag + above in here, since the encoder will blindly follow this and could then encode an invalid PNG file + (such as one with two IHDR chunks or the disallowed combination of sRGB with iCCP). But do use + this if you wish to store an ancillary chunk that is not supported by LodePNG (such as sPLT or hIST), + or any non-standard PNG chunk. + + Do not allocate or traverse this data yourself. Use the chunk traversing functions declared + later, such as lodepng_chunk_next and lodepng_chunk_append, to read/write this struct. + */ + unsigned char* unknown_chunks_data[3]; + size_t unknown_chunks_size[3]; /*size in bytes of the unknown chunks, given for protection*/ +#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ +} LodePNGInfo; + +/*init, cleanup and copy functions to use with this struct*/ +void lodepng_info_init(LodePNGInfo* info); +void lodepng_info_cleanup(LodePNGInfo* info); +/*return value is error code (0 means no error)*/ +unsigned lodepng_info_copy(LodePNGInfo* dest, const LodePNGInfo* source); + +#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS +unsigned lodepng_add_text(LodePNGInfo* info, const char* key, const char* str); /*push back both texts at once*/ +void lodepng_clear_text(LodePNGInfo* info); /*use this to clear the texts again after you filled them in*/ + +unsigned lodepng_add_itext(LodePNGInfo* info, const char* key, const char* langtag, + const char* transkey, const char* str); /*push back the 4 texts of 1 chunk at once*/ +void lodepng_clear_itext(LodePNGInfo* info); /*use this to clear the itexts again after you filled them in*/ + +/*replaces if exists*/ +unsigned lodepng_set_icc(LodePNGInfo* info, const char* name, const unsigned char* profile, unsigned profile_size); +void lodepng_clear_icc(LodePNGInfo* info); /*use this to clear the texts again after you filled them in*/ +#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ + +/* +Converts raw buffer from one color type to another color type, based on +LodePNGColorMode structs to describe the input and output color type. +See the reference manual at the end of this header file to see which color conversions are supported. +return value = LodePNG error code (0 if all went ok, an error if the conversion isn't supported) +The out buffer must have size (w * h * bpp + 7) / 8, where bpp is the bits per pixel +of the output color type (lodepng_get_bpp). +For < 8 bpp images, there should not be padding bits at the end of scanlines. +For 16-bit per channel colors, uses big endian format like PNG does. +Return value is LodePNG error code +*/ +unsigned lodepng_convert(unsigned char* out, const unsigned char* in, + const LodePNGColorMode* mode_out, const LodePNGColorMode* mode_in, + unsigned w, unsigned h); + +#ifdef LODEPNG_COMPILE_DECODER +/* +Settings for the decoder. This contains settings for the PNG and the Zlib +decoder, but not the Info settings from the Info structs. +*/ +typedef struct LodePNGDecoderSettings { + LodePNGDecompressSettings zlibsettings; /*in here is the setting to ignore Adler32 checksums*/ + + /* Check LodePNGDecompressSettings for more ignorable errors such as ignore_adler32 */ + unsigned ignore_crc; /*ignore CRC checksums*/ + unsigned ignore_critical; /*ignore unknown critical chunks*/ + unsigned ignore_end; /*ignore issues at end of file if possible (missing IEND chunk, too large chunk, ...)*/ + /* TODO: make a system involving warnings with levels and a strict mode instead. Other potentially recoverable + errors: srgb rendering intent value, size of content of ancillary chunks, more than 79 characters for some + strings, placement/combination rules for ancillary chunks, crc of unknown chunks, allowed characters + in string keys, etc... */ + + unsigned color_convert; /*whether to convert the PNG to the color type you want. Default: yes*/ + +#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS + unsigned read_text_chunks; /*if false but remember_unknown_chunks is true, they're stored in the unknown chunks*/ + /*store all bytes from unknown chunks in the LodePNGInfo (off by default, useful for a png editor)*/ + unsigned remember_unknown_chunks; +#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ +} LodePNGDecoderSettings; + +void lodepng_decoder_settings_init(LodePNGDecoderSettings* settings); +#endif /*LODEPNG_COMPILE_DECODER*/ + +#ifdef LODEPNG_COMPILE_ENCODER +/*automatically use color type with less bits per pixel if losslessly possible. Default: AUTO*/ +typedef enum LodePNGFilterStrategy { + /*every filter at zero*/ + LFS_ZERO = 0, + /*every filter at 1, 2, 3 or 4 (paeth), unlike LFS_ZERO not a good choice, but for testing*/ + LFS_ONE = 1, + LFS_TWO = 2, + LFS_THREE = 3, + LFS_FOUR = 4, + /*Use filter that gives minimum sum, as described in the official PNG filter heuristic.*/ + LFS_MINSUM, + /*Use the filter type that gives smallest Shannon entropy for this scanline. Depending + on the image, this is better or worse than minsum.*/ + LFS_ENTROPY, + /* + Brute-force-search PNG filters by compressing each filter for each scanline. + Experimental, very slow, and only rarely gives better compression than MINSUM. + */ + LFS_BRUTE_FORCE, + /*use predefined_filters buffer: you specify the filter type for each scanline*/ + LFS_PREDEFINED +} LodePNGFilterStrategy; + +/*Gives characteristics about the integer RGBA colors of the image (count, alpha channel usage, bit depth, ...), +which helps decide which color model to use for encoding. +Used internally by default if "auto_convert" is enabled. Public because it's useful for custom algorithms.*/ +typedef struct LodePNGColorStats { + unsigned colored; /*not grayscale*/ + unsigned key; /*image is not opaque and color key is possible instead of full alpha*/ + unsigned short key_r; /*key values, always as 16-bit, in 8-bit case the byte is duplicated, e.g. 65535 means 255*/ + unsigned short key_g; + unsigned short key_b; + unsigned alpha; /*image is not opaque and alpha channel or alpha palette required*/ + unsigned numcolors; /*amount of colors, up to 257. Not valid if bits == 16 or allow_palette is disabled.*/ + unsigned char palette[1024]; /*Remembers up to the first 256 RGBA colors, in no particular order, only valid when numcolors is valid*/ + unsigned bits; /*bits per channel (not for palette). 1,2 or 4 for grayscale only. 16 if 16-bit per channel required.*/ + size_t numpixels; + + /*user settings for computing/using the stats*/ + unsigned allow_palette; /*default 1. if 0, disallow choosing palette colortype in auto_choose_color, and don't count numcolors*/ + unsigned allow_greyscale; /*default 1. if 0, choose RGB or RGBA even if the image only has gray colors*/ +} LodePNGColorStats; + +void lodepng_color_stats_init(LodePNGColorStats* stats); + +/*Get a LodePNGColorStats of the image. The stats must already have been inited.*/ +void lodepng_compute_color_stats(LodePNGColorStats* stats, + const unsigned char* image, unsigned w, unsigned h, + const LodePNGColorMode* mode_in); +/*Computes a minimal PNG color model that can contain all colors as indicated by the stats and it settings. +The stats should be computed with lodepng_compute_color_stats. +mode_in is raw color profile of the image the stats were computed on, to copy palette order from when relevant. +Minimal PNG color model means the color type and bit depth that gives smallest amount of bits in the output image, +e.g. gray if only grayscale pixels, palette if less than 256 colors, color key if only single transparent color, ... +LodePNG uses this function internally if auto_convert is enabled (it is by default). +*/ +unsigned lodepng_auto_choose_color(LodePNGColorMode* mode_out, + const LodePNGColorMode* mode_in, + const LodePNGColorMode* stats); + +/*Settings for the encoder.*/ +typedef struct LodePNGEncoderSettings { + LodePNGCompressSettings zlibsettings; /*settings for the zlib encoder, such as window size, ...*/ + + unsigned auto_convert; /*automatically choose output PNG color type. Default: true*/ + + /*If true, follows the official PNG heuristic: if the PNG uses a palette or lower than + 8 bit depth, set all filters to zero. Otherwise use the filter_strategy. Note that to + completely follow the official PNG heuristic, filter_palette_zero must be true and + filter_strategy must be LFS_MINSUM*/ + unsigned filter_palette_zero; + /*Which filter strategy to use when not using zeroes due to filter_palette_zero. + Set filter_palette_zero to 0 to ensure always using your chosen strategy. Default: LFS_MINSUM*/ + LodePNGFilterStrategy filter_strategy; + /*used if filter_strategy is LFS_PREDEFINED. In that case, this must point to a buffer with + the same length as the amount of scanlines in the image, and each value must <= 5. You + have to cleanup this buffer, LodePNG will never free it. Don't forget that filter_palette_zero + must be set to 0 to ensure this is also used on palette or low bitdepth images.*/ + const unsigned char* predefined_filters; + + /*force creating a PLTE chunk if colortype is 2 or 6 (= a suggested palette). + If colortype is 3, PLTE is _always_ created.*/ + unsigned force_palette; +#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS + /*add LodePNG identifier and version as a text chunk, for debugging*/ + unsigned add_id; + /*encode text chunks as zTXt chunks instead of tEXt chunks, and use compression in iTXt chunks*/ + unsigned text_compression; +#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ +} LodePNGEncoderSettings; + +void lodepng_encoder_settings_init(LodePNGEncoderSettings* settings); +#endif /*LODEPNG_COMPILE_ENCODER*/ + + +#if defined(LODEPNG_COMPILE_DECODER) || defined(LODEPNG_COMPILE_ENCODER) +/*The settings, state and information for extended encoding and decoding.*/ +typedef struct LodePNGState { +#ifdef LODEPNG_COMPILE_DECODER + LodePNGDecoderSettings decoder; /*the decoding settings*/ +#endif /*LODEPNG_COMPILE_DECODER*/ +#ifdef LODEPNG_COMPILE_ENCODER + LodePNGEncoderSettings encoder; /*the encoding settings*/ +#endif /*LODEPNG_COMPILE_ENCODER*/ + LodePNGColorMode info_raw; /*specifies the format in which you would like to get the raw pixel buffer*/ + LodePNGInfo info_png; /*info of the PNG image obtained after decoding*/ + unsigned error; +#ifdef LODEPNG_COMPILE_CPP + /* For the lodepng::State subclass. */ + virtual ~LodePNGState(){} +#endif +} LodePNGState; + +/*init, cleanup and copy functions to use with this struct*/ +void lodepng_state_init(LodePNGState* state); +void lodepng_state_cleanup(LodePNGState* state); +void lodepng_state_copy(LodePNGState* dest, const LodePNGState* source); +#endif /* defined(LODEPNG_COMPILE_DECODER) || defined(LODEPNG_COMPILE_ENCODER) */ + +#ifdef LODEPNG_COMPILE_DECODER +/* +Same as lodepng_decode_memory, but uses a LodePNGState to allow custom settings and +getting much more information about the PNG image and color mode. +*/ +unsigned lodepng_decode(unsigned char** out, unsigned* w, unsigned* h, + LodePNGState* state, + const unsigned char* in, size_t insize); + +/* +Read the PNG header, but not the actual data. This returns only the information +that is in the IHDR chunk of the PNG, such as width, height and color type. The +information is placed in the info_png field of the LodePNGState. +*/ +unsigned lodepng_inspect(unsigned* w, unsigned* h, + LodePNGState* state, + const unsigned char* in, size_t insize); +#endif /*LODEPNG_COMPILE_DECODER*/ + +/* +Reads one metadata chunk (other than IHDR) of the PNG file and outputs what it +read in the state. Returns error code on failure. +Use lodepng_inspect first with a new state, then e.g. lodepng_chunk_find_const +to find the desired chunk type, and if non null use lodepng_inspect_chunk (with +chunk_pointer - start_of_file as pos). +Supports most metadata chunks from the PNG standard (gAMA, bKGD, tEXt, ...). +Ignores unsupported, unknown, non-metadata or IHDR chunks (without error). +Requirements: &in[pos] must point to start of a chunk, must use regular +lodepng_inspect first since format of most other chunks depends on IHDR, and if +there is a PLTE chunk, that one must be inspected before tRNS or bKGD. +*/ +unsigned lodepng_inspect_chunk(LodePNGState* state, size_t pos, + const unsigned char* in, size_t insize); + +#ifdef LODEPNG_COMPILE_ENCODER +/*This function allocates the out buffer with standard malloc and stores the size in *outsize.*/ +unsigned lodepng_encode(unsigned char** out, size_t* outsize, + const unsigned char* image, unsigned w, unsigned h, + LodePNGState* state); +#endif /*LODEPNG_COMPILE_ENCODER*/ + +/* +The lodepng_chunk functions are normally not needed, except to traverse the +unknown chunks stored in the LodePNGInfo struct, or add new ones to it. +It also allows traversing the chunks of an encoded PNG file yourself. + +The chunk pointer always points to the beginning of the chunk itself, that is +the first byte of the 4 length bytes. + +In the PNG file format, chunks have the following format: +-4 bytes length: length of the data of the chunk in bytes (chunk itself is 12 bytes longer) +-4 bytes chunk type (ASCII a-z,A-Z only, see below) +-length bytes of data (may be 0 bytes if length was 0) +-4 bytes of CRC, computed on chunk name + data + +The first chunk starts at the 8th byte of the PNG file, the entire rest of the file +exists out of concatenated chunks with the above format. + +PNG standard chunk ASCII naming conventions: +-First byte: uppercase = critical, lowercase = ancillary +-Second byte: uppercase = public, lowercase = private +-Third byte: must be uppercase +-Fourth byte: uppercase = unsafe to copy, lowercase = safe to copy +*/ + +/* +Gets the length of the data of the chunk. Total chunk length has 12 bytes more. +There must be at least 4 bytes to read from. If the result value is too large, +it may be corrupt data. +*/ +unsigned lodepng_chunk_length(const unsigned char* chunk); + +/*puts the 4-byte type in null terminated string*/ +void lodepng_chunk_type(char type[5], const unsigned char* chunk); + +/*check if the type is the given type*/ +unsigned char lodepng_chunk_type_equals(const unsigned char* chunk, const char* type); + +/*0: it's one of the critical chunk types, 1: it's an ancillary chunk (see PNG standard)*/ +unsigned char lodepng_chunk_ancillary(const unsigned char* chunk); + +/*0: public, 1: private (see PNG standard)*/ +unsigned char lodepng_chunk_private(const unsigned char* chunk); + +/*0: the chunk is unsafe to copy, 1: the chunk is safe to copy (see PNG standard)*/ +unsigned char lodepng_chunk_safetocopy(const unsigned char* chunk); + +/*get pointer to the data of the chunk, where the input points to the header of the chunk*/ +unsigned char* lodepng_chunk_data(unsigned char* chunk); +const unsigned char* lodepng_chunk_data_const(const unsigned char* chunk); + +/*returns 0 if the crc is correct, 1 if it's incorrect (0 for OK as usual!)*/ +unsigned lodepng_chunk_check_crc(const unsigned char* chunk); + +/*generates the correct CRC from the data and puts it in the last 4 bytes of the chunk*/ +void lodepng_chunk_generate_crc(unsigned char* chunk); + +/* +Iterate to next chunks, allows iterating through all chunks of the PNG file. +Input must be at the beginning of a chunk (result of a previous lodepng_chunk_next call, +or the 8th byte of a PNG file which always has the first chunk), or alternatively may +point to the first byte of the PNG file (which is not a chunk but the magic header, the +function will then skip over it and return the first real chunk). +Expects at least 8 readable bytes of memory in the input pointer. +Will output pointer to the start of the next chunk or the end of the file if there +is no more chunk after this. Start this process at the 8th byte of the PNG file. +In a non-corrupt PNG file, the last chunk should have name "IEND". +*/ +unsigned char* lodepng_chunk_next(unsigned char* chunk); +const unsigned char* lodepng_chunk_next_const(const unsigned char* chunk); + +/*Finds the first chunk with the given type in the range [chunk, end), or returns NULL if not found.*/ +unsigned char* lodepng_chunk_find(unsigned char* chunk, const unsigned char* end, const char type[5]); +const unsigned char* lodepng_chunk_find_const(const unsigned char* chunk, const unsigned char* end, const char type[5]); + +/* +Appends chunk to the data in out. The given chunk should already have its chunk header. +The out variable and outlength are updated to reflect the new reallocated buffer. +Returns error code (0 if it went ok) +*/ +unsigned lodepng_chunk_append(unsigned char** out, size_t* outlength, const unsigned char* chunk); + +/* +Appends new chunk to out. The chunk to append is given by giving its length, type +and data separately. The type is a 4-letter string. +The out variable and outlength are updated to reflect the new reallocated buffer. +Returne error code (0 if it went ok) +*/ +unsigned lodepng_chunk_create(unsigned char** out, size_t* outlength, unsigned length, + const char* type, const unsigned char* data); + + +/*Calculate CRC32 of buffer*/ +unsigned lodepng_crc32(const unsigned char* buf, size_t len); +#endif /*LODEPNG_COMPILE_PNG*/ + + +#ifdef LODEPNG_COMPILE_ZLIB +/* +This zlib part can be used independently to zlib compress and decompress a +buffer. It cannot be used to create gzip files however, and it only supports the +part of zlib that is required for PNG, it does not support dictionaries. +*/ + +#ifdef LODEPNG_COMPILE_DECODER +/*Inflate a buffer. Inflate is the decompression step of deflate. Out buffer must be freed after use.*/ +unsigned lodepng_inflate(unsigned char** out, size_t* outsize, + const unsigned char* in, size_t insize, + const LodePNGDecompressSettings* settings); + +/* +Decompresses Zlib data. Reallocates the out buffer and appends the data. The +data must be according to the zlib specification. +Either, *out must be NULL and *outsize must be 0, or, *out must be a valid +buffer and *outsize its size in bytes. out must be freed by user after usage. +*/ +unsigned lodepng_zlib_decompress(unsigned char** out, size_t* outsize, + const unsigned char* in, size_t insize, + const LodePNGDecompressSettings* settings); +#endif /*LODEPNG_COMPILE_DECODER*/ + +#ifdef LODEPNG_COMPILE_ENCODER +/* +Compresses data with Zlib. Reallocates the out buffer and appends the data. +Zlib adds a small header and trailer around the deflate data. +The data is output in the format of the zlib specification. +Either, *out must be NULL and *outsize must be 0, or, *out must be a valid +buffer and *outsize its size in bytes. out must be freed by user after usage. +*/ +unsigned lodepng_zlib_compress(unsigned char** out, size_t* outsize, + const unsigned char* in, size_t insize, + const LodePNGCompressSettings* settings); + +/* +Find length-limited Huffman code for given frequencies. This function is in the +public interface only for tests, it's used internally by lodepng_deflate. +*/ +unsigned lodepng_huffman_code_lengths(unsigned* lengths, const unsigned* frequencies, + size_t numcodes, unsigned maxbitlen); + +/*Compress a buffer with deflate. See RFC 1951. Out buffer must be freed after use.*/ +unsigned lodepng_deflate(unsigned char** out, size_t* outsize, + const unsigned char* in, size_t insize, + const LodePNGCompressSettings* settings); + +#endif /*LODEPNG_COMPILE_ENCODER*/ +#endif /*LODEPNG_COMPILE_ZLIB*/ + +#ifdef LODEPNG_COMPILE_DISK +/* +Load a file from disk into buffer. The function allocates the out buffer, and +after usage you should free it. +out: output parameter, contains pointer to loaded buffer. +outsize: output parameter, size of the allocated out buffer +filename: the path to the file to load +return value: error code (0 means ok) +*/ +unsigned lodepng_load_file(unsigned char** out, size_t* outsize, const char* filename); + +/* +Save a file from buffer to disk. Warning, if it exists, this function overwrites +the file without warning! +buffer: the buffer to write +buffersize: size of the buffer to write +filename: the path to the file to save to +return value: error code (0 means ok) +*/ +unsigned lodepng_save_file(const unsigned char* buffer, size_t buffersize, const char* filename); +#endif /*LODEPNG_COMPILE_DISK*/ + +#ifdef LODEPNG_COMPILE_CPP +/* The LodePNG C++ wrapper uses std::vectors instead of manually allocated memory buffers. */ +namespace lodepng { +#ifdef LODEPNG_COMPILE_PNG +class State : public LodePNGState { + public: + State(); + State(const State& other); + virtual ~State(); + State& operator=(const State& other); +}; + +#ifdef LODEPNG_COMPILE_DECODER +/* Same as other lodepng::decode, but using a State for more settings and information. */ +unsigned decode(std::vector& out, unsigned& w, unsigned& h, + State& state, + const unsigned char* in, size_t insize); +unsigned decode(std::vector& out, unsigned& w, unsigned& h, + State& state, + const std::vector& in); +#endif /*LODEPNG_COMPILE_DECODER*/ + +#ifdef LODEPNG_COMPILE_ENCODER +/* Same as other lodepng::encode, but using a State for more settings and information. */ +unsigned encode(std::vector& out, + const unsigned char* in, unsigned w, unsigned h, + State& state); +unsigned encode(std::vector& out, + const std::vector& in, unsigned w, unsigned h, + State& state); +#endif /*LODEPNG_COMPILE_ENCODER*/ + +#ifdef LODEPNG_COMPILE_DISK +/* +Load a file from disk into an std::vector. +return value: error code (0 means ok) +*/ +unsigned load_file(std::vector& buffer, const std::string& filename); + +/* +Save the binary data in an std::vector to a file on disk. The file is overwritten +without warning. +*/ +unsigned save_file(const std::vector& buffer, const std::string& filename); +#endif /* LODEPNG_COMPILE_DISK */ +#endif /* LODEPNG_COMPILE_PNG */ + +#ifdef LODEPNG_COMPILE_ZLIB +#ifdef LODEPNG_COMPILE_DECODER +/* Zlib-decompress an unsigned char buffer */ +unsigned decompress(std::vector& out, const unsigned char* in, size_t insize, + const LodePNGDecompressSettings& settings = lodepng_default_decompress_settings); + +/* Zlib-decompress an std::vector */ +unsigned decompress(std::vector& out, const std::vector& in, + const LodePNGDecompressSettings& settings = lodepng_default_decompress_settings); +#endif /* LODEPNG_COMPILE_DECODER */ + +#ifdef LODEPNG_COMPILE_ENCODER +/* Zlib-compress an unsigned char buffer */ +unsigned compress(std::vector& out, const unsigned char* in, size_t insize, + const LodePNGCompressSettings& settings = lodepng_default_compress_settings); + +/* Zlib-compress an std::vector */ +unsigned compress(std::vector& out, const std::vector& in, + const LodePNGCompressSettings& settings = lodepng_default_compress_settings); +#endif /* LODEPNG_COMPILE_ENCODER */ +#endif /* LODEPNG_COMPILE_ZLIB */ +} /* namespace lodepng */ +#endif /*LODEPNG_COMPILE_CPP*/ + +/* +TODO: +[.] test if there are no memory leaks or security exploits - done a lot but needs to be checked often +[.] check compatibility with various compilers - done but needs to be redone for every newer version +[X] converting color to 16-bit per channel types +[X] support color profile chunk types (but never let them touch RGB values by default) +[ ] support all public PNG chunk types (almost done except sBIT, sPLT and hIST) +[ ] make sure encoder generates no chunks with size > (2^31)-1 +[ ] partial decoding (stream processing) +[X] let the "isFullyOpaque" function check color keys and transparent palettes too +[X] better name for the variables "codes", "codesD", "codelengthcodes", "clcl" and "lldl" +[ ] allow treating some errors like warnings, when image is recoverable (e.g. 69, 57, 58) +[ ] make warnings like: oob palette, checksum fail, data after iend, wrong/unknown crit chunk, no null terminator in text, ... +[ ] error messages with line numbers (and version) +[ ] errors in state instead of as return code? +[ ] new errors/warnings like suspiciously big decompressed ztxt or iccp chunk +[ ] let the C++ wrapper catch exceptions coming from the standard library and return LodePNG error codes +[ ] allow user to provide custom color conversion functions, e.g. for premultiplied alpha, padding bits or not, ... +[ ] allow user to give data (void*) to custom allocator +[ ] provide alternatives for C library functions not present on some platforms (memcpy, ...) +[ ] rename "grey" to "gray" everywhere since "color" also uses US spelling (keep "grey" copies for backwards compatibility) +*/ + +#endif /*LODEPNG_H inclusion guard*/ + +/* +LodePNG Documentation +--------------------- + +0. table of contents +-------------------- + + 1. about + 1.1. supported features + 1.2. features not supported + 2. C and C++ version + 3. security + 4. decoding + 5. encoding + 6. color conversions + 6.1. PNG color types + 6.2. color conversions + 6.3. padding bits + 6.4. A note about 16-bits per channel and endianness + 7. error values + 8. chunks and PNG editing + 9. compiler support + 10. examples + 10.1. decoder C++ example + 10.2. decoder C example + 11. state settings reference + 12. changes + 13. contact information + + +1. about +-------- + +PNG is a file format to store raster images losslessly with good compression, +supporting different color types and alpha channel. + +LodePNG is a PNG codec according to the Portable Network Graphics (PNG) +Specification (Second Edition) - W3C Recommendation 10 November 2003. + +The specifications used are: + +*) Portable Network Graphics (PNG) Specification (Second Edition): + http://www.w3.org/TR/2003/REC-PNG-20031110 +*) RFC 1950 ZLIB Compressed Data Format version 3.3: + http://www.gzip.org/zlib/rfc-zlib.html +*) RFC 1951 DEFLATE Compressed Data Format Specification ver 1.3: + http://www.gzip.org/zlib/rfc-deflate.html + +The most recent version of LodePNG can currently be found at +http://lodev.org/lodepng/ + +LodePNG works both in C (ISO C90) and C++, with a C++ wrapper that adds +extra functionality. + +LodePNG exists out of two files: +-lodepng.h: the header file for both C and C++ +-lodepng.c(pp): give it the name lodepng.c or lodepng.cpp (or .cc) depending on your usage + +If you want to start using LodePNG right away without reading this doc, get the +examples from the LodePNG website to see how to use it in code, or check the +smaller examples in chapter 13 here. + +LodePNG is simple but only supports the basic requirements. To achieve +simplicity, the following design choices were made: There are no dependencies +on any external library. There are functions to decode and encode a PNG with +a single function call, and extended versions of these functions taking a +LodePNGState struct allowing to specify or get more information. By default +the colors of the raw image are always RGB or RGBA, no matter what color type +the PNG file uses. To read and write files, there are simple functions to +convert the files to/from buffers in memory. + +This all makes LodePNG suitable for loading textures in games, demos and small +programs, ... It's less suitable for full fledged image editors, loading PNGs +over network (it requires all the image data to be available before decoding can +begin), life-critical systems, ... + +1.1. supported features +----------------------- + +The following features are supported by the decoder: + +*) decoding of PNGs with any color type, bit depth and interlace mode, to a 24- or 32-bit color raw image, + or the same color type as the PNG +*) encoding of PNGs, from any raw image to 24- or 32-bit color, or the same color type as the raw image +*) Adam7 interlace and deinterlace for any color type +*) loading the image from harddisk or decoding it from a buffer from other sources than harddisk +*) support for alpha channels, including RGBA color model, translucent palettes and color keying +*) zlib decompression (inflate) +*) zlib compression (deflate) +*) CRC32 and ADLER32 checksums +*) colorimetric color profile conversions: currently experimentally available in lodepng_util.cpp only, + plus alternatively ability to pass on chroma/gamma/ICC profile information to other color management system. +*) handling of unknown chunks, allowing making a PNG editor that stores custom and unknown chunks. +*) the following chunks are supported by both encoder and decoder: + IHDR: header information + PLTE: color palette + IDAT: pixel data + IEND: the final chunk + tRNS: transparency for palettized images + tEXt: textual information + zTXt: compressed textual information + iTXt: international textual information + bKGD: suggested background color + pHYs: physical dimensions + tIME: modification time + cHRM: RGB chromaticities + gAMA: RGB gamma correction + iCCP: ICC color profile + sRGB: rendering intent + +1.2. features not supported +--------------------------- + +The following features are _not_ supported: + +*) some features needed to make a conformant PNG-Editor might be still missing. +*) partial loading/stream processing. All data must be available and is processed in one call. +*) The following public chunks are not (yet) supported but treated as unknown chunks by LodePNG: + sBIT + hIST + sPLT + + +2. C and C++ version +-------------------- + +The C version uses buffers allocated with alloc that you need to free() +yourself. You need to use init and cleanup functions for each struct whenever +using a struct from the C version to avoid exploits and memory leaks. + +The C++ version has extra functions with std::vectors in the interface and the +lodepng::State class which is a LodePNGState with constructor and destructor. + +These files work without modification for both C and C++ compilers because all +the additional C++ code is in "#ifdef __cplusplus" blocks that make C-compilers +ignore it, and the C code is made to compile both with strict ISO C90 and C++. + +To use the C++ version, you need to rename the source file to lodepng.cpp +(instead of lodepng.c), and compile it with a C++ compiler. + +To use the C version, you need to rename the source file to lodepng.c (instead +of lodepng.cpp), and compile it with a C compiler. + + +3. Security +----------- + +Even if carefully designed, it's always possible that LodePNG contains possible +exploits. If you discover one, please let me know, and it will be fixed. + +When using LodePNG, care has to be taken with the C version of LodePNG, as well +as the C-style structs when working with C++. The following conventions are used +for all C-style structs: + +-if a struct has a corresponding init function, always call the init function when making a new one +-if a struct has a corresponding cleanup function, call it before the struct disappears to avoid memory leaks +-if a struct has a corresponding copy function, use the copy function instead of "=". + The destination must also be inited already. + + +4. Decoding +----------- + +Decoding converts a PNG compressed image to a raw pixel buffer. + +Most documentation on using the decoder is at its declarations in the header +above. For C, simple decoding can be done with functions such as +lodepng_decode32, and more advanced decoding can be done with the struct +LodePNGState and lodepng_decode. For C++, all decoding can be done with the +various lodepng::decode functions, and lodepng::State can be used for advanced +features. + +When using the LodePNGState, it uses the following fields for decoding: +*) LodePNGInfo info_png: it stores extra information about the PNG (the input) in here +*) LodePNGColorMode info_raw: here you can say what color mode of the raw image (the output) you want to get +*) LodePNGDecoderSettings decoder: you can specify a few extra settings for the decoder to use + +LodePNGInfo info_png +-------------------- + +After decoding, this contains extra information of the PNG image, except the actual +pixels, width and height because these are already gotten directly from the decoder +functions. + +It contains for example the original color type of the PNG image, text comments, +suggested background color, etc... More details about the LodePNGInfo struct are +at its declaration documentation. + +LodePNGColorMode info_raw +------------------------- + +When decoding, here you can specify which color type you want +the resulting raw image to be. If this is different from the colortype of the +PNG, then the decoder will automatically convert the result. This conversion +always works, except if you want it to convert a color PNG to grayscale or to +a palette with missing colors. + +By default, 32-bit color is used for the result. + +LodePNGDecoderSettings decoder +------------------------------ + +The settings can be used to ignore the errors created by invalid CRC and Adler32 +chunks, and to disable the decoding of tEXt chunks. + +There's also a setting color_convert, true by default. If false, no conversion +is done, the resulting data will be as it was in the PNG (after decompression) +and you'll have to puzzle the colors of the pixels together yourself using the +color type information in the LodePNGInfo. + + +5. Encoding +----------- + +Encoding converts a raw pixel buffer to a PNG compressed image. + +Most documentation on using the encoder is at its declarations in the header +above. For C, simple encoding can be done with functions such as +lodepng_encode32, and more advanced decoding can be done with the struct +LodePNGState and lodepng_encode. For C++, all encoding can be done with the +various lodepng::encode functions, and lodepng::State can be used for advanced +features. + +Like the decoder, the encoder can also give errors. However it gives less errors +since the encoder input is trusted, the decoder input (a PNG image that could +be forged by anyone) is not trusted. + +When using the LodePNGState, it uses the following fields for encoding: +*) LodePNGInfo info_png: here you specify how you want the PNG (the output) to be. +*) LodePNGColorMode info_raw: here you say what color type of the raw image (the input) has +*) LodePNGEncoderSettings encoder: you can specify a few settings for the encoder to use + +LodePNGInfo info_png +-------------------- + +When encoding, you use this the opposite way as when decoding: for encoding, +you fill in the values you want the PNG to have before encoding. By default it's +not needed to specify a color type for the PNG since it's automatically chosen, +but it's possible to choose it yourself given the right settings. + +The encoder will not always exactly match the LodePNGInfo struct you give, +it tries as close as possible. Some things are ignored by the encoder. The +encoder uses, for example, the following settings from it when applicable: +colortype and bitdepth, text chunks, time chunk, the color key, the palette, the +background color, the interlace method, unknown chunks, ... + +When encoding to a PNG with colortype 3, the encoder will generate a PLTE chunk. +If the palette contains any colors for which the alpha channel is not 255 (so +there are translucent colors in the palette), it'll add a tRNS chunk. + +LodePNGColorMode info_raw +------------------------- + +You specify the color type of the raw image that you give to the input here, +including a possible transparent color key and palette you happen to be using in +your raw image data. + +By default, 32-bit color is assumed, meaning your input has to be in RGBA +format with 4 bytes (unsigned chars) per pixel. + +LodePNGEncoderSettings encoder +------------------------------ + +The following settings are supported (some are in sub-structs): +*) auto_convert: when this option is enabled, the encoder will +automatically choose the smallest possible color mode (including color key) that +can encode the colors of all pixels without information loss. +*) btype: the block type for LZ77. 0 = uncompressed, 1 = fixed huffman tree, + 2 = dynamic huffman tree (best compression). Should be 2 for proper + compression. +*) use_lz77: whether or not to use LZ77 for compressed block types. Should be + true for proper compression. +*) windowsize: the window size used by the LZ77 encoder (1 - 32768). Has value + 2048 by default, but can be set to 32768 for better, but slow, compression. +*) force_palette: if colortype is 2 or 6, you can make the encoder write a PLTE + chunk if force_palette is true. This can used as suggested palette to convert + to by viewers that don't support more than 256 colors (if those still exist) +*) add_id: add text chunk "Encoder: LodePNG " to the image. +*) text_compression: default 1. If 1, it'll store texts as zTXt instead of tEXt chunks. + zTXt chunks use zlib compression on the text. This gives a smaller result on + large texts but a larger result on small texts (such as a single program name). + It's all tEXt or all zTXt though, there's no separate setting per text yet. + + +6. color conversions +-------------------- + +An important thing to note about LodePNG, is that the color type of the PNG, and +the color type of the raw image, are completely independent. By default, when +you decode a PNG, you get the result as a raw image in the color type you want, +no matter whether the PNG was encoded with a palette, grayscale or RGBA color. +And if you encode an image, by default LodePNG will automatically choose the PNG +color type that gives good compression based on the values of colors and amount +of colors in the image. It can be configured to let you control it instead as +well, though. + +To be able to do this, LodePNG does conversions from one color mode to another. +It can convert from almost any color type to any other color type, except the +following conversions: RGB to grayscale is not supported, and converting to a +palette when the palette doesn't have a required color is not supported. This is +not supported on purpose: this is information loss which requires a color +reduction algorithm that is beyong the scope of a PNG encoder (yes, RGB to gray +is easy, but there are multiple ways if you want to give some channels more +weight). + +By default, when decoding, you get the raw image in 32-bit RGBA or 24-bit RGB +color, no matter what color type the PNG has. And by default when encoding, +LodePNG automatically picks the best color model for the output PNG, and expects +the input image to be 32-bit RGBA or 24-bit RGB. So, unless you want to control +the color format of the images yourself, you can skip this chapter. + +6.1. PNG color types +-------------------- + +A PNG image can have many color types, ranging from 1-bit color to 64-bit color, +as well as palettized color modes. After the zlib decompression and unfiltering +in the PNG image is done, the raw pixel data will have that color type and thus +a certain amount of bits per pixel. If you want the output raw image after +decoding to have another color type, a conversion is done by LodePNG. + +The PNG specification gives the following color types: + +0: grayscale, bit depths 1, 2, 4, 8, 16 +2: RGB, bit depths 8 and 16 +3: palette, bit depths 1, 2, 4 and 8 +4: grayscale with alpha, bit depths 8 and 16 +6: RGBA, bit depths 8 and 16 + +Bit depth is the amount of bits per pixel per color channel. So the total amount +of bits per pixel is: amount of channels * bitdepth. + +6.2. color conversions +---------------------- + +As explained in the sections about the encoder and decoder, you can specify +color types and bit depths in info_png and info_raw to change the default +behaviour. + +If, when decoding, you want the raw image to be something else than the default, +you need to set the color type and bit depth you want in the LodePNGColorMode, +or the parameters colortype and bitdepth of the simple decoding function. + +If, when encoding, you use another color type than the default in the raw input +image, you need to specify its color type and bit depth in the LodePNGColorMode +of the raw image, or use the parameters colortype and bitdepth of the simple +encoding function. + +If, when encoding, you don't want LodePNG to choose the output PNG color type +but control it yourself, you need to set auto_convert in the encoder settings +to false, and specify the color type you want in the LodePNGInfo of the +encoder (including palette: it can generate a palette if auto_convert is true, +otherwise not). + +If the input and output color type differ (whether user chosen or auto chosen), +LodePNG will do a color conversion, which follows the rules below, and may +sometimes result in an error. + +To avoid some confusion: +-the decoder converts from PNG to raw image +-the encoder converts from raw image to PNG +-the colortype and bitdepth in LodePNGColorMode info_raw, are those of the raw image +-the colortype and bitdepth in the color field of LodePNGInfo info_png, are those of the PNG +-when encoding, the color type in LodePNGInfo is ignored if auto_convert + is enabled, it is automatically generated instead +-when decoding, the color type in LodePNGInfo is set by the decoder to that of the original + PNG image, but it can be ignored since the raw image has the color type you requested instead +-if the color type of the LodePNGColorMode and PNG image aren't the same, a conversion + between the color types is done if the color types are supported. If it is not + supported, an error is returned. If the types are the same, no conversion is done. +-even though some conversions aren't supported, LodePNG supports loading PNGs from any + colortype and saving PNGs to any colortype, sometimes it just requires preparing + the raw image correctly before encoding. +-both encoder and decoder use the same color converter. + +The function lodepng_convert does the color conversion. It is available in the +interface but normally isn't needed since the encoder and decoder already call +it. + +Non supported color conversions: +-color to grayscale when non-gray pixels are present: no error is thrown, but +the result will look ugly because only the red channel is taken (it assumes all +three channels are the same in this case so ignores green and blue). The reason +no error is given is to allow converting from three-channel grayscale images to +one-channel even if there are numerical imprecisions. +-anything to palette when the palette does not have an exact match for a from-color +in it: in this case an error is thrown + +Supported color conversions: +-anything to 8-bit RGB, 8-bit RGBA, 16-bit RGB, 16-bit RGBA +-any gray or gray+alpha, to gray or gray+alpha +-anything to a palette, as long as the palette has the requested colors in it +-removing alpha channel +-higher to smaller bitdepth, and vice versa + +If you want no color conversion to be done (e.g. for speed or control): +-In the encoder, you can make it save a PNG with any color type by giving the +raw color mode and LodePNGInfo the same color mode, and setting auto_convert to +false. +-In the decoder, you can make it store the pixel data in the same color type +as the PNG has, by setting the color_convert setting to false. Settings in +info_raw are then ignored. + +6.3. padding bits +----------------- + +In the PNG file format, if a less than 8-bit per pixel color type is used and the scanlines +have a bit amount that isn't a multiple of 8, then padding bits are used so that each +scanline starts at a fresh byte. But that is NOT true for the LodePNG raw input and output. +The raw input image you give to the encoder, and the raw output image you get from the decoder +will NOT have these padding bits, e.g. in the case of a 1-bit image with a width +of 7 pixels, the first pixel of the second scanline will the the 8th bit of the first byte, +not the first bit of a new byte. + +6.4. A note about 16-bits per channel and endianness +---------------------------------------------------- + +LodePNG uses unsigned char arrays for 16-bit per channel colors too, just like +for any other color format. The 16-bit values are stored in big endian (most +significant byte first) in these arrays. This is the opposite order of the +little endian used by x86 CPU's. + +LodePNG always uses big endian because the PNG file format does so internally. +Conversions to other formats than PNG uses internally are not supported by +LodePNG on purpose, there are myriads of formats, including endianness of 16-bit +colors, the order in which you store R, G, B and A, and so on. Supporting and +converting to/from all that is outside the scope of LodePNG. + +This may mean that, depending on your use case, you may want to convert the big +endian output of LodePNG to little endian with a for loop. This is certainly not +always needed, many applications and libraries support big endian 16-bit colors +anyway, but it means you cannot simply cast the unsigned char* buffer to an +unsigned short* buffer on x86 CPUs. + + +7. error values +--------------- + +All functions in LodePNG that return an error code, return 0 if everything went +OK, or a non-zero code if there was an error. + +The meaning of the LodePNG error values can be retrieved with the function +lodepng_error_text: given the numerical error code, it returns a description +of the error in English as a string. + +Check the implementation of lodepng_error_text to see the meaning of each code. + + +8. chunks and PNG editing +------------------------- + +If you want to add extra chunks to a PNG you encode, or use LodePNG for a PNG +editor that should follow the rules about handling of unknown chunks, or if your +program is able to read other types of chunks than the ones handled by LodePNG, +then that's possible with the chunk functions of LodePNG. + +A PNG chunk has the following layout: + +4 bytes length +4 bytes type name +length bytes data +4 bytes CRC + +8.1. iterating through chunks +----------------------------- + +If you have a buffer containing the PNG image data, then the first chunk (the +IHDR chunk) starts at byte number 8 of that buffer. The first 8 bytes are the +signature of the PNG and are not part of a chunk. But if you start at byte 8 +then you have a chunk, and can check the following things of it. + +NOTE: none of these functions check for memory buffer boundaries. To avoid +exploits, always make sure the buffer contains all the data of the chunks. +When using lodepng_chunk_next, make sure the returned value is within the +allocated memory. + +unsigned lodepng_chunk_length(const unsigned char* chunk): + +Get the length of the chunk's data. The total chunk length is this length + 12. + +void lodepng_chunk_type(char type[5], const unsigned char* chunk): +unsigned char lodepng_chunk_type_equals(const unsigned char* chunk, const char* type): + +Get the type of the chunk or compare if it's a certain type + +unsigned char lodepng_chunk_critical(const unsigned char* chunk): +unsigned char lodepng_chunk_private(const unsigned char* chunk): +unsigned char lodepng_chunk_safetocopy(const unsigned char* chunk): + +Check if the chunk is critical in the PNG standard (only IHDR, PLTE, IDAT and IEND are). +Check if the chunk is private (public chunks are part of the standard, private ones not). +Check if the chunk is safe to copy. If it's not, then, when modifying data in a critical +chunk, unsafe to copy chunks of the old image may NOT be saved in the new one if your +program doesn't handle that type of unknown chunk. + +unsigned char* lodepng_chunk_data(unsigned char* chunk): +const unsigned char* lodepng_chunk_data_const(const unsigned char* chunk): + +Get a pointer to the start of the data of the chunk. + +unsigned lodepng_chunk_check_crc(const unsigned char* chunk): +void lodepng_chunk_generate_crc(unsigned char* chunk): + +Check if the crc is correct or generate a correct one. + +unsigned char* lodepng_chunk_next(unsigned char* chunk): +const unsigned char* lodepng_chunk_next_const(const unsigned char* chunk): + +Iterate to the next chunk. This works if you have a buffer with consecutive chunks. Note that these +functions do no boundary checking of the allocated data whatsoever, so make sure there is enough +data available in the buffer to be able to go to the next chunk. + +unsigned lodepng_chunk_append(unsigned char** out, size_t* outlength, const unsigned char* chunk): +unsigned lodepng_chunk_create(unsigned char** out, size_t* outlength, unsigned length, + const char* type, const unsigned char* data): + +These functions are used to create new chunks that are appended to the data in *out that has +length *outlength. The append function appends an existing chunk to the new data. The create +function creates a new chunk with the given parameters and appends it. Type is the 4-letter +name of the chunk. + +8.2. chunks in info_png +----------------------- + +The LodePNGInfo struct contains fields with the unknown chunk in it. It has 3 +buffers (each with size) to contain 3 types of unknown chunks: +the ones that come before the PLTE chunk, the ones that come between the PLTE +and the IDAT chunks, and the ones that come after the IDAT chunks. +It's necessary to make the distionction between these 3 cases because the PNG +standard forces to keep the ordering of unknown chunks compared to the critical +chunks, but does not force any other ordering rules. + +info_png.unknown_chunks_data[0] is the chunks before PLTE +info_png.unknown_chunks_data[1] is the chunks after PLTE, before IDAT +info_png.unknown_chunks_data[2] is the chunks after IDAT + +The chunks in these 3 buffers can be iterated through and read by using the same +way described in the previous subchapter. + +When using the decoder to decode a PNG, you can make it store all unknown chunks +if you set the option settings.remember_unknown_chunks to 1. By default, this +option is off (0). + +The encoder will always encode unknown chunks that are stored in the info_png. +If you need it to add a particular chunk that isn't known by LodePNG, you can +use lodepng_chunk_append or lodepng_chunk_create to the chunk data in +info_png.unknown_chunks_data[x]. + +Chunks that are known by LodePNG should not be added in that way. E.g. to make +LodePNG add a bKGD chunk, set background_defined to true and add the correct +parameters there instead. + + +9. compiler support +------------------- + +No libraries other than the current standard C library are needed to compile +LodePNG. For the C++ version, only the standard C++ library is needed on top. +Add the files lodepng.c(pp) and lodepng.h to your project, include +lodepng.h where needed, and your program can read/write PNG files. + +It is compatible with C90 and up, and C++03 and up. + +If performance is important, use optimization when compiling! For both the +encoder and decoder, this makes a large difference. + +Make sure that LodePNG is compiled with the same compiler of the same version +and with the same settings as the rest of the program, or the interfaces with +std::vectors and std::strings in C++ can be incompatible. + +CHAR_BITS must be 8 or higher, because LodePNG uses unsigned chars for octets. + +*) gcc and g++ + +LodePNG is developed in gcc so this compiler is natively supported. It gives no +warnings with compiler options "-Wall -Wextra -pedantic -ansi", with gcc and g++ +version 4.7.1 on Linux, 32-bit and 64-bit. + +*) Clang + +Fully supported and warning-free. + +*) Mingw + +The Mingw compiler (a port of gcc for Windows) should be fully supported by +LodePNG. + +*) Visual Studio and Visual C++ Express Edition + +LodePNG should be warning-free with warning level W4. Two warnings were disabled +with pragmas though: warning 4244 about implicit conversions, and warning 4996 +where it wants to use a non-standard function fopen_s instead of the standard C +fopen. + +Visual Studio may want "stdafx.h" files to be included in each source file and +give an error "unexpected end of file while looking for precompiled header". +This is not standard C++ and will not be added to the stock LodePNG. You can +disable it for lodepng.cpp only by right clicking it, Properties, C/C++, +Precompiled Headers, and set it to Not Using Precompiled Headers there. + +NOTE: Modern versions of VS should be fully supported, but old versions, e.g. +VS6, are not guaranteed to work. + +*) Compilers on Macintosh + +LodePNG has been reported to work both with gcc and LLVM for Macintosh, both for +C and C++. + +*) Other Compilers + +If you encounter problems on any compilers, feel free to let me know and I may +try to fix it if the compiler is modern and standards complient. + + +10. examples +------------ + +This decoder example shows the most basic usage of LodePNG. More complex +examples can be found on the LodePNG website. + +10.1. decoder C++ example +------------------------- + +#include "lodepng.h" +#include + +int main(int argc, char *argv[]) { + const char* filename = argc > 1 ? argv[1] : "test.png"; + + //load and decode + std::vector image; + unsigned width, height; + unsigned error = lodepng::decode(image, width, height, filename); + + //if there's an error, display it + if(error) std::cout << "decoder error " << error << ": " << lodepng_error_text(error) << std::endl; + + //the pixels are now in the vector "image", 4 bytes per pixel, ordered RGBARGBA..., use it as texture, draw it, ... +} + +10.2. decoder C example +----------------------- + +#include "lodepng.h" + +int main(int argc, char *argv[]) { + unsigned error; + unsigned char* image; + size_t width, height; + const char* filename = argc > 1 ? argv[1] : "test.png"; + + error = lodepng_decode32_file(&image, &width, &height, filename); + + if(error) printf("decoder error %u: %s\n", error, lodepng_error_text(error)); + + / * use image here * / + + free(image); + return 0; +} + +11. state settings reference +---------------------------- + +A quick reference of some settings to set on the LodePNGState + +For decoding: + +state.decoder.zlibsettings.ignore_adler32: ignore ADLER32 checksums +state.decoder.zlibsettings.custom_...: use custom inflate function +state.decoder.ignore_crc: ignore CRC checksums +state.decoder.ignore_critical: ignore unknown critical chunks +state.decoder.ignore_end: ignore missing IEND chunk. May fail if this corruption causes other errors +state.decoder.color_convert: convert internal PNG color to chosen one +state.decoder.read_text_chunks: whether to read in text metadata chunks +state.decoder.remember_unknown_chunks: whether to read in unknown chunks +state.info_raw.colortype: desired color type for decoded image +state.info_raw.bitdepth: desired bit depth for decoded image +state.info_raw....: more color settings, see struct LodePNGColorMode +state.info_png....: no settings for decoder but ouput, see struct LodePNGInfo + +For encoding: + +state.encoder.zlibsettings.btype: disable compression by setting it to 0 +state.encoder.zlibsettings.use_lz77: use LZ77 in compression +state.encoder.zlibsettings.windowsize: tweak LZ77 windowsize +state.encoder.zlibsettings.minmatch: tweak min LZ77 length to match +state.encoder.zlibsettings.nicematch: tweak LZ77 match where to stop searching +state.encoder.zlibsettings.lazymatching: try one more LZ77 matching +state.encoder.zlibsettings.custom_...: use custom deflate function +state.encoder.auto_convert: choose optimal PNG color type, if 0 uses info_png +state.encoder.filter_palette_zero: PNG filter strategy for palette +state.encoder.filter_strategy: PNG filter strategy to encode with +state.encoder.force_palette: add palette even if not encoding to one +state.encoder.add_id: add LodePNG identifier and version as a text chunk +state.encoder.text_compression: use compressed text chunks for metadata +state.info_raw.colortype: color type of raw input image you provide +state.info_raw.bitdepth: bit depth of raw input image you provide +state.info_raw: more color settings, see struct LodePNGColorMode +state.info_png.color.colortype: desired color type if auto_convert is false +state.info_png.color.bitdepth: desired bit depth if auto_convert is false +state.info_png.color....: more color settings, see struct LodePNGColorMode +state.info_png....: more PNG related settings, see struct LodePNGInfo + + +12. changes +----------- + +The version number of LodePNG is the date of the change given in the format +yyyymmdd. + +Some changes aren't backwards compatible. Those are indicated with a (!) +symbol. + +*) 14 aug 2019: around 25% faster decoding thanks to huffman lookup tables. +*) 15 jun 2019 (!): auto_choose_color API changed (for bugfix: don't use palette + if gray ICC profile) and non-ICC LodePNGColorProfile renamed to LodePNGColorStats. +*) 30 dec 2018: code style changes only: removed newlines before opening braces. +*) 10 sep 2018: added way to inspect metadata chunks without full decoding. +*) 19 aug 2018 (!): fixed color mode bKGD is encoded with and made it use + palette index in case of palette. +*) 10 aug 2018 (!): added support for gAMA, cHRM, sRGB and iCCP chunks. This + change is backwards compatible unless you relied on unknown_chunks for those. +*) 11 jun 2018: less restrictive check for pixel size integer overflow +*) 14 jan 2018: allow optionally ignoring a few more recoverable errors +*) 17 sep 2017: fix memory leak for some encoder input error cases +*) 27 nov 2016: grey+alpha auto color model detection bugfix +*) 18 apr 2016: Changed qsort to custom stable sort (for platforms w/o qsort). +*) 09 apr 2016: Fixed colorkey usage detection, and better file loading (within + the limits of pure C90). +*) 08 dec 2015: Made load_file function return error if file can't be opened. +*) 24 okt 2015: Bugfix with decoding to palette output. +*) 18 apr 2015: Boundary PM instead of just package-merge for faster encoding. +*) 23 aug 2014: Reduced needless memory usage of decoder. +*) 28 jun 2014: Removed fix_png setting, always support palette OOB for + simplicity. Made ColorProfile public. +*) 09 jun 2014: Faster encoder by fixing hash bug and more zeros optimization. +*) 22 dec 2013: Power of two windowsize required for optimization. +*) 15 apr 2013: Fixed bug with LAC_ALPHA and color key. +*) 25 mar 2013: Added an optional feature to ignore some PNG errors (fix_png). +*) 11 mar 2013 (!): Bugfix with custom free. Changed from "my" to "lodepng_" + prefix for the custom allocators and made it possible with a new #define to + use custom ones in your project without needing to change lodepng's code. +*) 28 jan 2013: Bugfix with color key. +*) 27 okt 2012: Tweaks in text chunk keyword length error handling. +*) 8 okt 2012 (!): Added new filter strategy (entropy) and new auto color mode. + (no palette). Better deflate tree encoding. New compression tweak settings. + Faster color conversions while decoding. Some internal cleanups. +*) 23 sep 2012: Reduced warnings in Visual Studio a little bit. +*) 1 sep 2012 (!): Removed #define's for giving custom (de)compression functions + and made it work with function pointers instead. +*) 23 jun 2012: Added more filter strategies. Made it easier to use custom alloc + and free functions and toggle #defines from compiler flags. Small fixes. +*) 6 may 2012 (!): Made plugging in custom zlib/deflate functions more flexible. +*) 22 apr 2012 (!): Made interface more consistent, renaming a lot. Removed + redundant C++ codec classes. Reduced amount of structs. Everything changed, + but it is cleaner now imho and functionality remains the same. Also fixed + several bugs and shrunk the implementation code. Made new samples. +*) 6 nov 2011 (!): By default, the encoder now automatically chooses the best + PNG color model and bit depth, based on the amount and type of colors of the + raw image. For this, autoLeaveOutAlphaChannel replaced by auto_choose_color. +*) 9 okt 2011: simpler hash chain implementation for the encoder. +*) 8 sep 2011: lz77 encoder lazy matching instead of greedy matching. +*) 23 aug 2011: tweaked the zlib compression parameters after benchmarking. + A bug with the PNG filtertype heuristic was fixed, so that it chooses much + better ones (it's quite significant). A setting to do an experimental, slow, + brute force search for PNG filter types is added. +*) 17 aug 2011 (!): changed some C zlib related function names. +*) 16 aug 2011: made the code less wide (max 120 characters per line). +*) 17 apr 2011: code cleanup. Bugfixes. Convert low to 16-bit per sample colors. +*) 21 feb 2011: fixed compiling for C90. Fixed compiling with sections disabled. +*) 11 dec 2010: encoding is made faster, based on suggestion by Peter Eastman + to optimize long sequences of zeros. +*) 13 nov 2010: added LodePNG_InfoColor_hasPaletteAlpha and + LodePNG_InfoColor_canHaveAlpha functions for convenience. +*) 7 nov 2010: added LodePNG_error_text function to get error code description. +*) 30 okt 2010: made decoding slightly faster +*) 26 okt 2010: (!) changed some C function and struct names (more consistent). + Reorganized the documentation and the declaration order in the header. +*) 08 aug 2010: only changed some comments and external samples. +*) 05 jul 2010: fixed bug thanks to warnings in the new gcc version. +*) 14 mar 2010: fixed bug where too much memory was allocated for char buffers. +*) 02 sep 2008: fixed bug where it could create empty tree that linux apps could + read by ignoring the problem but windows apps couldn't. +*) 06 jun 2008: added more error checks for out of memory cases. +*) 26 apr 2008: added a few more checks here and there to ensure more safety. +*) 06 mar 2008: crash with encoding of strings fixed +*) 02 feb 2008: support for international text chunks added (iTXt) +*) 23 jan 2008: small cleanups, and #defines to divide code in sections +*) 20 jan 2008: support for unknown chunks allowing using LodePNG for an editor. +*) 18 jan 2008: support for tIME and pHYs chunks added to encoder and decoder. +*) 17 jan 2008: ability to encode and decode compressed zTXt chunks added + Also various fixes, such as in the deflate and the padding bits code. +*) 13 jan 2008: Added ability to encode Adam7-interlaced images. Improved + filtering code of encoder. +*) 07 jan 2008: (!) changed LodePNG to use ISO C90 instead of C++. A + C++ wrapper around this provides an interface almost identical to before. + Having LodePNG be pure ISO C90 makes it more portable. The C and C++ code + are together in these files but it works both for C and C++ compilers. +*) 29 dec 2007: (!) changed most integer types to unsigned int + other tweaks +*) 30 aug 2007: bug fixed which makes this Borland C++ compatible +*) 09 aug 2007: some VS2005 warnings removed again +*) 21 jul 2007: deflate code placed in new namespace separate from zlib code +*) 08 jun 2007: fixed bug with 2- and 4-bit color, and small interlaced images +*) 04 jun 2007: improved support for Visual Studio 2005: crash with accessing + invalid std::vector element [0] fixed, and level 3 and 4 warnings removed +*) 02 jun 2007: made the encoder add a tag with version by default +*) 27 may 2007: zlib and png code separated (but still in the same file), + simple encoder/decoder functions added for more simple usage cases +*) 19 may 2007: minor fixes, some code cleaning, new error added (error 69), + moved some examples from here to lodepng_examples.cpp +*) 12 may 2007: palette decoding bug fixed +*) 24 apr 2007: changed the license from BSD to the zlib license +*) 11 mar 2007: very simple addition: ability to encode bKGD chunks. +*) 04 mar 2007: (!) tEXt chunk related fixes, and support for encoding + palettized PNG images. Plus little interface change with palette and texts. +*) 03 mar 2007: Made it encode dynamic Huffman shorter with repeat codes. + Fixed a bug where the end code of a block had length 0 in the Huffman tree. +*) 26 feb 2007: Huffman compression with dynamic trees (BTYPE 2) now implemented + and supported by the encoder, resulting in smaller PNGs at the output. +*) 27 jan 2007: Made the Adler-32 test faster so that a timewaste is gone. +*) 24 jan 2007: gave encoder an error interface. Added color conversion from any + greyscale type to 8-bit greyscale with or without alpha. +*) 21 jan 2007: (!) Totally changed the interface. It allows more color types + to convert to and is more uniform. See the manual for how it works now. +*) 07 jan 2007: Some cleanup & fixes, and a few changes over the last days: + encode/decode custom tEXt chunks, separate classes for zlib & deflate, and + at last made the decoder give errors for incorrect Adler32 or Crc. +*) 01 jan 2007: Fixed bug with encoding PNGs with less than 8 bits per channel. +*) 29 dec 2006: Added support for encoding images without alpha channel, and + cleaned out code as well as making certain parts faster. +*) 28 dec 2006: Added "Settings" to the encoder. +*) 26 dec 2006: The encoder now does LZ77 encoding and produces much smaller files now. + Removed some code duplication in the decoder. Fixed little bug in an example. +*) 09 dec 2006: (!) Placed output parameters of public functions as first parameter. + Fixed a bug of the decoder with 16-bit per color. +*) 15 okt 2006: Changed documentation structure +*) 09 okt 2006: Encoder class added. It encodes a valid PNG image from the + given image buffer, however for now it's not compressed. +*) 08 sep 2006: (!) Changed to interface with a Decoder class +*) 30 jul 2006: (!) LodePNG_InfoPng , width and height are now retrieved in different + way. Renamed decodePNG to decodePNGGeneric. +*) 29 jul 2006: (!) Changed the interface: image info is now returned as a + struct of type LodePNG::LodePNG_Info, instead of a vector, which was a bit clumsy. +*) 28 jul 2006: Cleaned the code and added new error checks. + Corrected terminology "deflate" into "inflate". +*) 23 jun 2006: Added SDL example in the documentation in the header, this + example allows easy debugging by displaying the PNG and its transparency. +*) 22 jun 2006: (!) Changed way to obtain error value. Added + loadFile function for convenience. Made decodePNG32 faster. +*) 21 jun 2006: (!) Changed type of info vector to unsigned. + Changed position of palette in info vector. Fixed an important bug that + happened on PNGs with an uncompressed block. +*) 16 jun 2006: Internally changed unsigned into unsigned where + needed, and performed some optimizations. +*) 07 jun 2006: (!) Renamed functions to decodePNG and placed them + in LodePNG namespace. Changed the order of the parameters. Rewrote the + documentation in the header. Renamed files to lodepng.cpp and lodepng.h +*) 22 apr 2006: Optimized and improved some code +*) 07 sep 2005: (!) Changed to std::vector interface +*) 12 aug 2005: Initial release (C++, decoder only) + + +13. contact information +----------------------- + +Feel free to contact me with suggestions, problems, comments, ... concerning +LodePNG. If you encounter a PNG image that doesn't work properly with this +decoder, feel free to send it and I'll use it to find and fix the problem. + +My email address is (puzzle the account and domain together with an @ symbol): +Domain: gmail dot com. +Account: lode dot vandevenne. + + +Copyright (c) 2005-2019 Lode Vandevenne +*/ diff --git a/engine/Quake/main_sdl.c b/engine/Quake/main_sdl.c new file mode 100644 index 0000000..04d8683 --- /dev/null +++ b/engine/Quake/main_sdl.c @@ -0,0 +1,193 @@ +/* +Copyright (C) 1996-2001 Id Software, Inc. +Copyright (C) 2002-2005 John Fitzgibbons and others +Copyright (C) 2007-2008 Kristian Duske +Copyright (C) 2010-2014 QuakeSpasm developers + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#include "quakedef.h" +#if defined(SDL_FRAMEWORK) || defined(NO_SDL_CONFIG) +#if defined(USE_SDL2) +#include +#else +#include +#endif +#else +#include "SDL.h" +#endif +#include + +#if defined(USE_SDL2) + +/* need at least SDL_2.0.0 */ +#define SDL_MIN_X 2 +#define SDL_MIN_Y 0 +#define SDL_MIN_Z 0 +#define SDL_REQUIREDVERSION (SDL_VERSIONNUM(SDL_MIN_X,SDL_MIN_Y,SDL_MIN_Z)) +#define SDL_NEW_VERSION_REJECT (SDL_VERSIONNUM(3,0,0)) + +#else + +/* need at least SDL_1.2.10 */ +#define SDL_MIN_X 1 +#define SDL_MIN_Y 2 +#define SDL_MIN_Z 10 +#define SDL_REQUIREDVERSION (SDL_VERSIONNUM(SDL_MIN_X,SDL_MIN_Y,SDL_MIN_Z)) +/* reject 1.3.0 and newer at runtime. */ +#define SDL_NEW_VERSION_REJECT (SDL_VERSIONNUM(1,3,0)) + +#endif + +void Sys_AtExit (void) +{ + SDL_Quit(); +} + +void Sys_InitSDL (void) +{ +#if defined(USE_SDL2) + SDL_version v; + SDL_version *sdl_version = &v; + SDL_GetVersion(&v); +#else + const SDL_version *sdl_version = SDL_Linked_Version(); +#endif + + Sys_Printf("Found SDL version %i.%i.%i\n",sdl_version->major,sdl_version->minor,sdl_version->patch); + if (SDL_VERSIONNUM(sdl_version->major,sdl_version->minor,sdl_version->patch) < SDL_REQUIREDVERSION) + { /*reject running under older SDL versions */ + Sys_Error("You need at least v%d.%d.%d of SDL to run this game.", SDL_MIN_X,SDL_MIN_Y,SDL_MIN_Z); + } + if (SDL_VERSIONNUM(sdl_version->major,sdl_version->minor,sdl_version->patch) >= SDL_NEW_VERSION_REJECT) + { /*reject running under newer (1.3.x) SDL */ + Sys_Error("Your version of SDL library is incompatible with me.\n" + "You need a library version in the line of %d.%d.%d\n", SDL_MIN_X,SDL_MIN_Y,SDL_MIN_Z); + } + + if (SDL_Init(0) < 0) + { + Sys_Error("Couldn't init SDL: %s", SDL_GetError()); + } + atexit(Sys_AtExit); +} + +#define DEFAULT_MEMORY (256 * 1024 * 1024) // ericw -- was 72MB (64-bit) / 64MB (32-bit) + +static quakeparms_t parms; + +// On OS X we call SDL_main from the launcher, but SDL2 doesn't redefine main +// as SDL_main on OS X anymore, so we do it ourselves. +#if defined(USE_SDL2) && defined(__APPLE__) +#define main SDL_main +#endif + +int main(int argc, char *argv[]) +{ + int t; + double time, oldtime, newtime; + + host_parms = &parms; + parms.basedir = "."; + + parms.argc = argc; + parms.argv = argv; + + parms.errstate = 0; + + COM_InitArgv(parms.argc, parms.argv); + + isDedicated = (COM_CheckParm("-dedicated") != 0); + + Sys_InitSDL (); + + Sys_Init(); + + parms.memsize = DEFAULT_MEMORY; + if (COM_CheckParm("-heapsize")) + { + t = COM_CheckParm("-heapsize") + 1; + if (t < com_argc) + parms.memsize = Q_atoi(com_argv[t]) * 1024; + } + + parms.membase = malloc (parms.memsize); + + if (!parms.membase) + Sys_Error ("Not enough memory free; check disk space\n"); + + Sys_Printf("Quake %1.2f (c) id Software\n", VERSION); + Sys_Printf("GLQuake %1.2f (c) id Software\n", GLQUAKE_VERSION); + Sys_Printf("FitzQuake %1.2f (c) John Fitzgibbons\n", FITZQUAKE_VERSION); + Sys_Printf("FitzQuake SDL port (c) SleepwalkR, Baker\n"); + Sys_Printf("QuakeSpasm " QUAKESPASM_VER_STRING " (c) Ozkan Sezer, Eric Wasylishen & others\n"); + + Sys_Printf("Host_Init\n"); + Host_Init(); + + oldtime = Sys_DoubleTime(); + if (isDedicated) + { + while (1) + { + newtime = Sys_DoubleTime (); + time = newtime - oldtime; + + while (time < sys_ticrate.value ) + { + SDL_Delay(1); + newtime = Sys_DoubleTime (); + time = newtime - oldtime; + } + + Host_Frame (time); + oldtime = newtime; + } + } + else + while (1) + { + /* If we have no input focus at all, sleep a bit */ + if (!VID_HasMouseOrInputFocus() || cl.paused) + { + SDL_Delay(16); + } + /* If we're minimised, sleep a bit more */ + if (VID_IsMinimized()) + { + scr_skipupdate = 1; + SDL_Delay(32); + } + else + { + scr_skipupdate = 0; + } + newtime = Sys_DoubleTime (); + time = newtime - oldtime; + + Host_Frame (time); + + if (time < sys_throttle.value && !cls.timedemo) + SDL_Delay(1); + + oldtime = newtime; + } + + return 0; +} + diff --git a/engine/code/mathlib.c b/engine/Quake/mathlib.c similarity index 72% rename from engine/code/mathlib.c rename to engine/Quake/mathlib.c index 0598eef..c98008e 100644 --- a/engine/code/mathlib.c +++ b/engine/Quake/mathlib.c @@ -1,5 +1,8 @@ /* -Copyright (C) 1996-1997 Id Software, Inc. +Copyright (C) 1996-2001 Id Software, Inc. +Copyright (C) 2002-2009 John Fitzgibbons and others +Copyright (C) 2007-2008 Kristian Duske +Copyright (C) 2010-2014 QuakeSpasm developers This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -8,7 +11,7 @@ of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. @@ -19,19 +22,15 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ // mathlib.c -- math primitives -#include #include "quakedef.h" -void Sys_Error (char *error, ...); - vec3_t vec3_origin = {0,0,0}; -int nanmask = 255<<23; /*-----------------------------------------------------------------*/ -// jkrige - quake2 warps + //#define DEG2RAD( a ) ( a * M_PI ) / 180.0F -// jkrige - quake2 warps +#define DEG2RAD( a ) ( (a) * M_PI_DIV_180 ) //johnfitz void ProjectPointOnPlane( vec3_t dst, const vec3_t p, const vec3_t normal ) { @@ -87,69 +86,7 @@ void PerpendicularVector( vec3_t dst, const vec3_t src ) VectorNormalize( dst ); } -#ifdef _WIN32 -#pragma optimize( "", off ) -#endif - - -void RotatePointAroundVector( vec3_t dst, const vec3_t dir, const vec3_t point, float degrees ) -{ - float m[3][3]; - float im[3][3]; - float zrot[3][3]; - float tmpmat[3][3]; - float rot[3][3]; - int i; - vec3_t vr, vup, vf; - - vf[0] = dir[0]; - vf[1] = dir[1]; - vf[2] = dir[2]; - - PerpendicularVector( vr, dir ); - CrossProduct( vr, vf, vup ); - - m[0][0] = vr[0]; - m[1][0] = vr[1]; - m[2][0] = vr[2]; - - m[0][1] = vup[0]; - m[1][1] = vup[1]; - m[2][1] = vup[2]; - - m[0][2] = vf[0]; - m[1][2] = vf[1]; - m[2][2] = vf[2]; - - memcpy( im, m, sizeof( im ) ); - - im[0][1] = m[1][0]; - im[0][2] = m[2][0]; - im[1][0] = m[0][1]; - im[1][2] = m[2][1]; - im[2][0] = m[0][2]; - im[2][1] = m[1][2]; - - memset( zrot, 0, sizeof( zrot ) ); - zrot[0][0] = zrot[1][1] = zrot[2][2] = 1.0F; - - zrot[0][0] = cos( DEG2RAD( degrees ) ); - zrot[0][1] = sin( DEG2RAD( degrees ) ); - zrot[1][0] = -sin( DEG2RAD( degrees ) ); - zrot[1][1] = cos( DEG2RAD( degrees ) ); - - R_ConcatRotations( m, zrot, tmpmat ); - R_ConcatRotations( tmpmat, im, rot ); - - for ( i = 0; i < 3; i++ ) - { - dst[i] = rot[i][0] * point[0] + rot[i][1] * point[1] + rot[i][2] * point[2]; - } -} - -#ifdef _WIN32 -#pragma optimize( "", on ) -#endif +//johnfitz -- removed RotatePointAroundVector() becuase it's no longer used and my compiler fucked it up anyway /*-----------------------------------------------------------------*/ @@ -166,20 +103,6 @@ float anglemod(float a) return a; } -/* -================== -BOPS_Error - -Split out like this for ASM to call. -================== -*/ -void BOPS_Error (void) -{ - Sys_Error ("BoxOnPlaneSide: Bad signbits"); -} - - -#if !id386 /* ================== @@ -205,45 +128,45 @@ int BoxOnPlaneSide (vec3_t emins, vec3_t emaxs, mplane_t *p) return 3; } #endif - + // general case switch (p->signbits) { case 0: -dist1 = p->normal[0]*emaxs[0] + p->normal[1]*emaxs[1] + p->normal[2]*emaxs[2]; -dist2 = p->normal[0]*emins[0] + p->normal[1]*emins[1] + p->normal[2]*emins[2]; + dist1 = p->normal[0]*emaxs[0] + p->normal[1]*emaxs[1] + p->normal[2]*emaxs[2]; + dist2 = p->normal[0]*emins[0] + p->normal[1]*emins[1] + p->normal[2]*emins[2]; break; case 1: -dist1 = p->normal[0]*emins[0] + p->normal[1]*emaxs[1] + p->normal[2]*emaxs[2]; -dist2 = p->normal[0]*emaxs[0] + p->normal[1]*emins[1] + p->normal[2]*emins[2]; + dist1 = p->normal[0]*emins[0] + p->normal[1]*emaxs[1] + p->normal[2]*emaxs[2]; + dist2 = p->normal[0]*emaxs[0] + p->normal[1]*emins[1] + p->normal[2]*emins[2]; break; case 2: -dist1 = p->normal[0]*emaxs[0] + p->normal[1]*emins[1] + p->normal[2]*emaxs[2]; -dist2 = p->normal[0]*emins[0] + p->normal[1]*emaxs[1] + p->normal[2]*emins[2]; + dist1 = p->normal[0]*emaxs[0] + p->normal[1]*emins[1] + p->normal[2]*emaxs[2]; + dist2 = p->normal[0]*emins[0] + p->normal[1]*emaxs[1] + p->normal[2]*emins[2]; break; case 3: -dist1 = p->normal[0]*emins[0] + p->normal[1]*emins[1] + p->normal[2]*emaxs[2]; -dist2 = p->normal[0]*emaxs[0] + p->normal[1]*emaxs[1] + p->normal[2]*emins[2]; + dist1 = p->normal[0]*emins[0] + p->normal[1]*emins[1] + p->normal[2]*emaxs[2]; + dist2 = p->normal[0]*emaxs[0] + p->normal[1]*emaxs[1] + p->normal[2]*emins[2]; break; case 4: -dist1 = p->normal[0]*emaxs[0] + p->normal[1]*emaxs[1] + p->normal[2]*emins[2]; -dist2 = p->normal[0]*emins[0] + p->normal[1]*emins[1] + p->normal[2]*emaxs[2]; + dist1 = p->normal[0]*emaxs[0] + p->normal[1]*emaxs[1] + p->normal[2]*emins[2]; + dist2 = p->normal[0]*emins[0] + p->normal[1]*emins[1] + p->normal[2]*emaxs[2]; break; case 5: -dist1 = p->normal[0]*emins[0] + p->normal[1]*emaxs[1] + p->normal[2]*emins[2]; -dist2 = p->normal[0]*emaxs[0] + p->normal[1]*emins[1] + p->normal[2]*emaxs[2]; + dist1 = p->normal[0]*emins[0] + p->normal[1]*emaxs[1] + p->normal[2]*emins[2]; + dist2 = p->normal[0]*emaxs[0] + p->normal[1]*emins[1] + p->normal[2]*emaxs[2]; break; case 6: -dist1 = p->normal[0]*emaxs[0] + p->normal[1]*emins[1] + p->normal[2]*emins[2]; -dist2 = p->normal[0]*emins[0] + p->normal[1]*emaxs[1] + p->normal[2]*emaxs[2]; + dist1 = p->normal[0]*emaxs[0] + p->normal[1]*emins[1] + p->normal[2]*emins[2]; + dist2 = p->normal[0]*emins[0] + p->normal[1]*emaxs[1] + p->normal[2]*emaxs[2]; break; case 7: -dist1 = p->normal[0]*emins[0] + p->normal[1]*emins[1] + p->normal[2]*emins[2]; -dist2 = p->normal[0]*emaxs[0] + p->normal[1]*emaxs[1] + p->normal[2]*emaxs[2]; + dist1 = p->normal[0]*emins[0] + p->normal[1]*emins[1] + p->normal[2]*emins[2]; + dist2 = p->normal[0]*emaxs[0] + p->normal[1]*emaxs[1] + p->normal[2]*emaxs[2]; break; default: dist1 = dist2 = 0; // shut up compiler - BOPS_Error (); + Sys_Error ("BoxOnPlaneSide: Bad signbits"); break; } @@ -271,7 +194,6 @@ dist2 = p->normal[0]*emaxs[0] + p->normal[1]*emaxs[1] + p->normal[2]*emaxs[2]; sides = 1; if (dist2 < 0) sides |= 2; - #endif sides = 0; @@ -281,21 +203,32 @@ dist2 = p->normal[0]*emaxs[0] + p->normal[1]*emaxs[1] + p->normal[2]*emaxs[2]; sides |= 2; #ifdef PARANOID -if (sides == 0) - Sys_Error ("BoxOnPlaneSide: sides==0"); + if (sides == 0) + Sys_Error ("BoxOnPlaneSide: sides==0"); #endif return sides; } -#endif - +//johnfitz -- the opposite of AngleVectors. this takes forward and generates pitch yaw roll +//TODO: take right and up vectors to properly set yaw and roll +void VectorAngles (const vec3_t forward, vec3_t angles) +{ + vec3_t temp; + + temp[0] = forward[0]; + temp[1] = forward[1]; + temp[2] = 0; + angles[PITCH] = -atan2(forward[2], VectorLength(temp)) / M_PI_DIV_180; + angles[YAW] = atan2(forward[1], forward[0]) / M_PI_DIV_180; + angles[ROLL] = 0; +} void AngleVectors (vec3_t angles, vec3_t forward, vec3_t right, vec3_t up) { float angle; float sr, sp, sy, cr, cp, cy; - + angle = angles[YAW] * (M_PI*2 / 360); sy = sin(angle); cy = cos(angle); @@ -320,11 +253,11 @@ void AngleVectors (vec3_t angles, vec3_t forward, vec3_t right, vec3_t up) int VectorCompare (vec3_t v1, vec3_t v2) { int i; - + for (i=0 ; i<3 ; i++) if (v1[i] != v2[i]) return 0; - + return 1; } @@ -369,27 +302,16 @@ void CrossProduct (vec3_t v1, vec3_t v2, vec3_t cross) cross[2] = v1[0]*v2[1] - v1[1]*v2[0]; } -double sqrt(double x); - -vec_t Length(vec3_t v) +vec_t VectorLength(vec3_t v) { - int i; - float length; - - length = 0; - for (i=0 ; i< 3 ; i++) - length += v[i]*v[i]; - length = sqrt (length); // FIXME - - return length; + return sqrt(DotProduct(v,v)); } float VectorNormalize (vec3_t v) { float length, ilength; - length = v[0]*v[0] + v[1]*v[1] + v[2]*v[2]; - length = sqrt (length); // FIXME + length = sqrt(DotProduct(v,v)); if (length) { @@ -398,7 +320,7 @@ float VectorNormalize (vec3_t v) v[1] *= ilength; v[2] *= ilength; } - + return length; } @@ -507,7 +429,7 @@ void FloorDivMod (double numer, double denom, int *quotient, #ifndef PARANOID if (denom <= 0.0) - Sys_Error ("FloorDivMod: bad denominator %d\n", denom); + Sys_Error ("FloorDivMod: bad denominator %f\n", denom); // if ((floor(numer) != numer) || (floor(denom) != denom)) // Sys_Error ("FloorDivMod: non-integer numer or denom %f %f\n", @@ -563,10 +485,6 @@ int GreatestCommonDivisor (int i1, int i2) } -#if !id386 - -// TODO: move to nonintel.c - /* =================== Invert24To16 @@ -584,4 +502,3 @@ fixed16_t Invert24To16(fixed16_t val) (((double)0x10000 * (double)0x1000000 / (double)val) + 0.5); } -#endif diff --git a/engine/code/mathlib.h b/engine/Quake/mathlib.h similarity index 62% rename from engine/code/mathlib.h rename to engine/Quake/mathlib.h index 81e420c..a607905 100644 --- a/engine/code/mathlib.h +++ b/engine/Quake/mathlib.h @@ -1,5 +1,8 @@ /* -Copyright (C) 1996-1997 Id Software, Inc. +Copyright (C) 1996-2001 Id Software, Inc. +Copyright (C) 2002-2009 John Fitzgibbons and others +Copyright (C) 2007-2008 Kristian Duske +Copyright (C) 2010-2014 QuakeSpasm developers This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -8,7 +11,7 @@ of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. @@ -17,49 +20,59 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -// mathlib.h -typedef float vec_t; -typedef vec_t vec3_t[3]; -typedef vec_t vec5_t[5]; +#ifndef __MATHLIB_H +#define __MATHLIB_H + +// mathlib.h -typedef int fixed4_t; -typedef int fixed8_t; -typedef int fixed16_t; +#include #ifndef M_PI #define M_PI 3.14159265358979323846 // matches value in gcc v2 math.h #endif -// jkrige - quake2 warps -#ifndef DEG2RAD -#define DEG2RAD( a ) ( a * M_PI ) / 180.0F -#endif -// jkrige - quake2 warps +#define M_PI_DIV_180 (M_PI / 180.0) //johnfitz struct mplane_s; extern vec3_t vec3_origin; -extern int nanmask; -#define IS_NAN(x) (((*(int *)&x)&nanmask)==nanmask) +#define nanmask (255 << 23) /* 7F800000 */ +#if 0 /* macro is violating strict aliasing rules */ +#define IS_NAN(x) (((*(int *) (char *) &x) & nanmask) == nanmask) +#else +static inline int IS_NAN (float x) { + union { float f; int i; } num; + num.f = x; + return ((num.i & nanmask) == nanmask); +} +#endif + +#define Q_rint(x) ((x) > 0 ? (int)((x) + 0.5) : (int)((x) - 0.5)) //johnfitz -- from joequake #define DotProduct(x,y) (x[0]*y[0]+x[1]*y[1]+x[2]*y[2]) +#define DoublePrecisionDotProduct(x,y) ((double)x[0]*y[0]+(double)x[1]*y[1]+(double)x[2]*y[2]) #define VectorSubtract(a,b,c) {c[0]=a[0]-b[0];c[1]=a[1]-b[1];c[2]=a[2]-b[2];} #define VectorAdd(a,b,c) {c[0]=a[0]+b[0];c[1]=a[1]+b[1];c[2]=a[2]+b[2];} #define VectorCopy(a,b) {b[0]=a[0];b[1]=a[1];b[2]=a[2];} -// jkrige - quake2 warps -#define VectorClear(a) (a[0]=a[1]=a[2]=0) -#define VectorNegate(a,b) (b[0]=-a[0],b[1]=-a[1],b[2]=-a[2]) -#define VectorSet(v, x, y, z) (v[0]=(x), v[1]=(y), v[2]=(z)) -// jkrige - quake2 warps - - -// jkrige - field of view (fov) fix -void RotatePointAroundVector( vec3_t dst, const vec3_t dir, const vec3_t point, float degrees ); -// jkrige - field of view (fov) fix - +//johnfitz -- courtesy of lordhavoc +// QuakeSpasm: To avoid strict aliasing violations, use a float/int union instead of type punning. +#define VectorNormalizeFast(_v)\ +{\ + union { float f; int i; } _y, _number;\ + _number.f = DotProduct(_v, _v);\ + if (_number.f != 0.0)\ + {\ + _y.i = 0x5f3759df - (_number.i >> 1);\ + _y.f = _y.f * (1.5f - (_number.f * 0.5f * _y.f * _y.f));\ + VectorScale(_v, _y.f, _v);\ + }\ +} + +void TurnVector (vec3_t out, const vec3_t forward, const vec3_t side, float angle); //johnfitz +void VectorAngles (const vec3_t forward, vec3_t angles); //johnfitz void VectorMA (vec3_t veca, float scale, vec3_t vecb, vec3_t vecc); @@ -69,7 +82,7 @@ void _VectorAdd (vec3_t veca, vec3_t vecb, vec3_t out); void _VectorCopy (vec3_t in, vec3_t out); int VectorCompare (vec3_t v1, vec3_t v2); -vec_t Length (vec3_t v); +vec_t VectorLength (vec3_t v); void CrossProduct (vec3_t v1, vec3_t v2, vec3_t cross); float VectorNormalize (vec3_t v); // returns vector length void VectorInverse (vec3_t v); @@ -89,7 +102,6 @@ int BoxOnPlaneSide (vec3_t emins, vec3_t emaxs, struct mplane_s *plane); float anglemod(float a); - #define BOX_ON_PLANE_SIDE(emins, emaxs, p) \ (((p)->type < 3)? \ ( \ @@ -105,3 +117,6 @@ float anglemod(float a); ) \ : \ BoxOnPlaneSide( (emins), (emaxs), (p))) + +#endif /* __MATHLIB_H */ + diff --git a/engine/code/menu.c b/engine/Quake/menu.c similarity index 56% rename from engine/code/menu.c rename to engine/Quake/menu.c index d06f682..5548b7e 100644 --- a/engine/code/menu.c +++ b/engine/Quake/menu.c @@ -1,5 +1,7 @@ /* -Copyright (C) 1996-1997 Id Software, Inc. +Copyright (C) 1996-2001 Id Software, Inc. +Copyright (C) 2002-2009 John Fitzgibbons and others +Copyright (C) 2010-2014 QuakeSpasm developers This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -8,7 +10,7 @@ of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. @@ -17,17 +19,15 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#include "quakedef.h" - -#ifdef _WIN32 -#include "winquake.h" -#endif +#include "quakedef.h" +#include "bgmusic.h" +void (*vid_menucmdfn)(void); //johnfitz void (*vid_menudrawfn)(void); void (*vid_menukeyfn)(int key); -enum {m_none, m_main, m_singleplayer, m_load, m_save, m_multiplayer, m_setup, m_net, m_options, m_video, m_keys, m_help, m_quit, m_serialconfig, m_modemconfig, m_lanconfig, m_gameoptions, m_search, m_slist} m_state; +enum m_state_e m_state; void M_Menu_Main_f (void); void M_Menu_SinglePlayer_f (void); @@ -36,17 +36,15 @@ void M_Menu_Main_f (void); void M_Menu_MultiPlayer_f (void); void M_Menu_Setup_f (void); void M_Menu_Net_f (void); + void M_Menu_LanConfig_f (void); + void M_Menu_GameOptions_f (void); + void M_Menu_Search_f (void); + void M_Menu_ServerList_f (void); void M_Menu_Options_f (void); void M_Menu_Keys_f (void); void M_Menu_Video_f (void); void M_Menu_Help_f (void); void M_Menu_Quit_f (void); -void M_Menu_SerialConfig_f (void); - void M_Menu_ModemConfig_f (void); -void M_Menu_LanConfig_f (void); -void M_Menu_GameOptions_f (void); -void M_Menu_Search_f (void); -void M_Menu_ServerList_f (void); void M_Main_Draw (void); void M_SinglePlayer_Draw (void); @@ -55,17 +53,15 @@ void M_Main_Draw (void); void M_MultiPlayer_Draw (void); void M_Setup_Draw (void); void M_Net_Draw (void); + void M_LanConfig_Draw (void); + void M_GameOptions_Draw (void); + void M_Search_Draw (void); + void M_ServerList_Draw (void); void M_Options_Draw (void); void M_Keys_Draw (void); void M_Video_Draw (void); void M_Help_Draw (void); void M_Quit_Draw (void); -void M_SerialConfig_Draw (void); - void M_ModemConfig_Draw (void); -void M_LanConfig_Draw (void); -void M_GameOptions_Draw (void); -void M_Search_Draw (void); -void M_ServerList_Draw (void); void M_Main_Key (int key); void M_SinglePlayer_Key (int key); @@ -74,32 +70,28 @@ void M_Main_Key (int key); void M_MultiPlayer_Key (int key); void M_Setup_Key (int key); void M_Net_Key (int key); + void M_LanConfig_Key (int key); + void M_GameOptions_Key (int key); + void M_Search_Key (int key); + void M_ServerList_Key (int key); void M_Options_Key (int key); void M_Keys_Key (int key); void M_Video_Key (int key); void M_Help_Key (int key); void M_Quit_Key (int key); -void M_SerialConfig_Key (int key); - void M_ModemConfig_Key (int key); -void M_LanConfig_Key (int key); -void M_GameOptions_Key (int key); -void M_Search_Key (int key); -void M_ServerList_Key (int key); qboolean m_entersound; // play after drawing a frame, so caching // won't disrupt the sound qboolean m_recursiveDraw; -int m_return_state; +enum m_state_e m_return_state; qboolean m_return_onerror; char m_return_reason [32]; #define StartingGame (m_multiplayer_cursor == 1) #define JoiningGame (m_multiplayer_cursor == 0) -#define SerialConfig (m_net_cursor == 0) -#define DirectConfig (m_net_cursor == 1) -#define IPXConfig (m_net_cursor == 2) -#define TCPIPConfig (m_net_cursor == 3) +#define IPXConfig (m_net_cursor == 0) +#define TCPIPConfig (m_net_cursor == 1) void M_ConfigureNetSubsystem(void); @@ -112,10 +104,10 @@ Draws one solid graphics character */ void M_DrawCharacter (int cx, int line, int num) { - Draw_Character ( cx + ((vid.width - 320)>>1), line, num); + Draw_Character (cx, line, num); } -void M_Print (int cx, int cy, char *str) +void M_Print (int cx, int cy, const char *str) { while (*str) { @@ -125,7 +117,7 @@ void M_Print (int cx, int cy, char *str) } } -void M_PrintWhite (int cx, int cy, char *str) +void M_PrintWhite (int cx, int cy, const char *str) { while (*str) { @@ -137,48 +129,19 @@ void M_PrintWhite (int cx, int cy, char *str) void M_DrawTransPic (int x, int y, qpic_t *pic) { - Draw_TransPic (x + ((vid.width - 320)>>1), y, pic); + Draw_Pic (x, y, pic); //johnfitz -- simplified becuase centering is handled elsewhere } void M_DrawPic (int x, int y, qpic_t *pic) { - Draw_Pic (x + ((vid.width - 320)>>1), y, pic); -} - -byte identityTable[256]; -byte translationTable[256]; - -void M_BuildTranslationTable(int top, int bottom) -{ - int j; - byte *dest, *source; - - for (j = 0; j < 256; j++) - identityTable[j] = j; - dest = translationTable; - source = identityTable; - memcpy (dest, source, 256); - - if (top < 128) // the artists made some backwards ranges. sigh. - memcpy (dest + TOP_RANGE, source + top, 16); - else - for (j=0 ; j<16 ; j++) - dest[TOP_RANGE+j] = source[top+15-j]; - - if (bottom < 128) - memcpy (dest + BOTTOM_RANGE, source + bottom, 16); - else - for (j=0 ; j<16 ; j++) - dest[BOTTOM_RANGE+j] = source[bottom+15-j]; + Draw_Pic (x, y, pic); //johnfitz -- simplified becuase centering is handled elsewhere } - -void M_DrawTransPicTranslate (int x, int y, qpic_t *pic) +void M_DrawTransPicTranslate (int x, int y, qpic_t *pic, int top, int bottom) //johnfitz -- more parameters { - Draw_TransPicTranslate (x + ((vid.width - 320)>>1), y, pic, translationTable); + Draw_TransPicTranslate (x, y, pic, top, bottom); //johnfitz -- simplified becuase centering is handled elsewhere } - void M_DrawTextBox (int x, int y, int width, int lines) { qpic_t *p; @@ -254,6 +217,8 @@ void M_ToggleMenu_f (void) M_Menu_Main_f (); return; } + + IN_Activate(); key_dest = key_game; m_state = m_none; return; @@ -283,6 +248,7 @@ void M_Menu_Main_f (void) m_save_demonum = cls.demonum; cls.demonum = -1; } + IN_Deactivate(modestate == MS_WINDOWED); key_dest = key_menu; m_state = m_main; m_entersound = true; @@ -299,7 +265,7 @@ void M_Main_Draw (void) M_DrawPic ( (320-p->width)/2, 4, p); M_DrawTransPic (72, 32, Draw_CachePic ("gfx/mainmenu.lmp") ); - f = (int)(host_time * 10)%6; + f = (int)(realtime * 10)%6; M_DrawTransPic (54, 32 + m_main_cursor * 20,Draw_CachePic( va("gfx/menudot%i.lmp", f+1 ) ) ); } @@ -310,9 +276,13 @@ void M_Main_Key (int key) switch (key) { case K_ESCAPE: + case K_BBUTTON: + IN_Activate(); key_dest = key_game; m_state = m_none; cls.demonum = m_save_demonum; + if (!fitzmode) /* QuakeSpasm customization: */ + break; if (cls.demonum != -1 && !cls.demoplayback && cls.state != ca_connected) CL_NextDemo (); break; @@ -330,6 +300,8 @@ void M_Main_Key (int key) break; case K_ENTER: + case K_KP_ENTER: + case K_ABUTTON: m_entersound = true; switch (m_main_cursor) @@ -366,6 +338,7 @@ int m_singleplayer_cursor; void M_Menu_SinglePlayer_f (void) { + IN_Deactivate(modestate == MS_WINDOWED); key_dest = key_menu; m_state = m_singleplayer; m_entersound = true; @@ -382,7 +355,7 @@ void M_SinglePlayer_Draw (void) M_DrawPic ( (320-p->width)/2, 4, p); M_DrawTransPic (72, 32, Draw_CachePic ("gfx/sp_menu.lmp") ); - f = (int)(host_time * 10)%6; + f = (int)(realtime * 10)%6; M_DrawTransPic (54, 32 + m_singleplayer_cursor * 20,Draw_CachePic( va("gfx/menudot%i.lmp", f+1 ) ) ); } @@ -393,6 +366,7 @@ void M_SinglePlayer_Key (int key) switch (key) { case K_ESCAPE: + case K_BBUTTON: M_Menu_Main_f (); break; @@ -409,18 +383,23 @@ void M_SinglePlayer_Key (int key) break; case K_ENTER: + case K_KP_ENTER: + case K_ABUTTON: m_entersound = true; switch (m_singleplayer_cursor) { case 0: if (sv.active) - if (!SCR_ModalMessage("Are you sure you want to\nstart a new game?\n")) + if (!SCR_ModalMessage("Are you sure you want to\nstart a new game?\n", 0.0f)) break; + IN_Activate(); key_dest = key_game; if (sv.active) Cbuf_AddText ("disconnect\n"); Cbuf_AddText ("maxplayers 1\n"); + Cbuf_AddText ("deathmatch 0\n"); //johnfitz + Cbuf_AddText ("coop 0\n"); //johnfitz Cbuf_AddText ("map start\n"); break; @@ -440,36 +419,35 @@ void M_SinglePlayer_Key (int key) int load_cursor; // 0 < load_cursor < MAX_SAVEGAMES -#define MAX_SAVEGAMES 12 +#define MAX_SAVEGAMES 20 /* johnfitz -- increased from 12 */ char m_filenames[MAX_SAVEGAMES][SAVEGAME_COMMENT_LENGTH+1]; int loadable[MAX_SAVEGAMES]; void M_ScanSaves (void) { - int i, j; + int i, j; char name[MAX_OSPATH]; FILE *f; - int version; + int version; - for (i=0 ; iwidth)/2, 4, p); - for (i=0 ; i< MAX_SAVEGAMES; i++) + for (i = 0; i < MAX_SAVEGAMES; i++) M_Print (16, 32 + 8*i, m_filenames[i]); // line cursor @@ -523,7 +505,7 @@ void M_Save_Draw (void) p = Draw_CachePic ("gfx/p_save.lmp"); M_DrawPic ( (320-p->width)/2, 4, p); - for (i=0 ; iwidth)/2, 4, p); M_DrawTransPic (72, 32, Draw_CachePic ("gfx/mp_menu.lmp") ); - f = (int)(host_time * 10)%6; + f = (int)(realtime * 10)%6; M_DrawTransPic (54, 32 + m_multiplayer_cursor * 20,Draw_CachePic( va("gfx/menudot%i.lmp", f+1 ) ) ); - if (serialAvailable || ipxAvailable || tcpipAvailable) + if (ipxAvailable || tcpipAvailable) return; M_PrintWhite ((320/2) - ((27*8)/2), 148, "No Communications Available"); } @@ -645,6 +636,7 @@ void M_MultiPlayer_Key (int key) switch (key) { case K_ESCAPE: + case K_BBUTTON: M_Menu_Main_f (); break; @@ -661,16 +653,18 @@ void M_MultiPlayer_Key (int key) break; case K_ENTER: + case K_KP_ENTER: + case K_ABUTTON: m_entersound = true; switch (m_multiplayer_cursor) { case 0: - if (serialAvailable || ipxAvailable || tcpipAvailable) + if (ipxAvailable || tcpipAvailable) M_Menu_Net_f (); break; case 1: - if (serialAvailable || ipxAvailable || tcpipAvailable) + if (ipxAvailable || tcpipAvailable) M_Menu_Net_f (); break; @@ -698,6 +692,7 @@ int setup_bottom; void M_Menu_Setup_f (void) { + IN_Deactivate(modestate == MS_WINDOWED); key_dest = key_menu; m_state = m_setup; m_entersound = true; @@ -733,8 +728,7 @@ void M_Setup_Draw (void) p = Draw_CachePic ("gfx/bigbox.lmp"); M_DrawTransPic (160, 64, p); p = Draw_CachePic ("gfx/menuplyr.lmp"); - M_BuildTranslationTable(setup_top*16, setup_bottom*16); - M_DrawTransPicTranslate (172, 72, p); + M_DrawTransPicTranslate (172, 72, p, setup_top, setup_bottom); M_DrawCharacter (56, setup_cursor_table [setup_cursor], 12+((int)(realtime*4)&1)); @@ -748,11 +742,10 @@ void M_Setup_Draw (void) void M_Setup_Key (int k) { - int l; - switch (k) { case K_ESCAPE: + case K_BBUTTON: M_Menu_MultiPlayer_f (); break; @@ -791,6 +784,8 @@ forward: break; case K_ENTER: + case K_KP_ENTER: + case K_ABUTTON: if (setup_cursor == 0 || setup_cursor == 1) return; @@ -821,28 +816,6 @@ forward: setup_myname[strlen(setup_myname)-1] = 0; } break; - - default: - if (k < 32 || k > 127) - break; - if (setup_cursor == 0) - { - l = strlen(setup_hostname); - if (l < 15) - { - setup_hostname[l+1] = 0; - setup_hostname[l] = k; - } - } - if (setup_cursor == 1) - { - l = strlen(setup_myname); - if (l < 15) - { - setup_myname[l+1] = 0; - setup_myname[l] = k; - } - } } if (setup_top > 13) @@ -855,26 +828,47 @@ forward: setup_bottom = 13; } + +void M_Setup_Char (int k) +{ + int l; + + switch (setup_cursor) + { + case 0: + l = strlen(setup_hostname); + if (l < 15) + { + setup_hostname[l+1] = 0; + setup_hostname[l] = k; + } + break; + case 1: + l = strlen(setup_myname); + if (l < 15) + { + setup_myname[l+1] = 0; + setup_myname[l] = k; + } + break; + } +} + + +qboolean M_Setup_TextEntry (void) +{ + return (setup_cursor == 0 || setup_cursor == 1); +} + //============================================================================= /* NET MENU */ int m_net_cursor; int m_net_items; -int m_net_saveHeight; -char *net_helpMessage [] = +const char *net_helpMessage [] = { /* .........1.........2.... */ - " ", - " Two computers connected", - " through two modems. ", - " ", - - " ", - " Two computers connected", - " by a null-modem cable. ", - " ", - " Novell network LANs ", " or Windows 95 DOS-box. ", " ", @@ -888,10 +882,11 @@ char *net_helpMessage [] = void M_Menu_Net_f (void) { + IN_Deactivate(modestate == MS_WINDOWED); key_dest = key_menu; m_state = m_net; m_entersound = true; - m_net_items = 4; + m_net_items = 2; if (m_net_cursor >= m_net_items) m_net_cursor = 0; @@ -911,41 +906,6 @@ void M_Net_Draw (void) f = 32; - if (serialAvailable) - { - p = Draw_CachePic ("gfx/netmen1.lmp"); - } - else - { -#ifdef _WIN32 - p = NULL; -#else - p = Draw_CachePic ("gfx/dim_modm.lmp"); -#endif - } - - if (p) - M_DrawTransPic (72, f, p); - - f += 19; - - if (serialAvailable) - { - p = Draw_CachePic ("gfx/netmen2.lmp"); - } - else - { -#ifdef _WIN32 - p = NULL; -#else - p = Draw_CachePic ("gfx/dim_drct.lmp"); -#endif - } - - if (p) - M_DrawTransPic (72, f, p); - - f += 19; if (ipxAvailable) p = Draw_CachePic ("gfx/netmen3.lmp"); else @@ -959,22 +919,15 @@ void M_Net_Draw (void) p = Draw_CachePic ("gfx/dim_tcp.lmp"); M_DrawTransPic (72, f, p); - if (m_net_items == 5) // JDC, could just be removed - { - f += 19; - p = Draw_CachePic ("gfx/netmen5.lmp"); - M_DrawTransPic (72, f, p); - } - f = (320-26*8)/2; - M_DrawTextBox (f, 134, 24, 4); + M_DrawTextBox (f, 96, 24, 4); f += 8; - M_Print (f, 142, net_helpMessage[m_net_cursor*4+0]); - M_Print (f, 150, net_helpMessage[m_net_cursor*4+1]); - M_Print (f, 158, net_helpMessage[m_net_cursor*4+2]); - M_Print (f, 166, net_helpMessage[m_net_cursor*4+3]); + M_Print (f, 104, net_helpMessage[m_net_cursor*4+0]); + M_Print (f, 112, net_helpMessage[m_net_cursor*4+1]); + M_Print (f, 120, net_helpMessage[m_net_cursor*4+2]); + M_Print (f, 128, net_helpMessage[m_net_cursor*4+3]); - f = (int)(host_time * 10)%6; + f = (int)(realtime * 10)%6; M_DrawTransPic (54, 32 + m_net_cursor * 20,Draw_CachePic( va("gfx/menudot%i.lmp", f+1 ) ) ); } @@ -985,6 +938,7 @@ again: switch (k) { case K_ESCAPE: + case K_BBUTTON: M_Menu_MultiPlayer_f (); break; @@ -1001,58 +955,55 @@ again: break; case K_ENTER: + case K_KP_ENTER: + case K_ABUTTON: m_entersound = true; - - switch (m_net_cursor) - { - case 0: - M_Menu_SerialConfig_f (); - break; - - case 1: - M_Menu_SerialConfig_f (); - break; - - case 2: - M_Menu_LanConfig_f (); - break; - - case 3: - M_Menu_LanConfig_f (); - break; - - case 4: -// multiprotocol - break; - } + M_Menu_LanConfig_f (); + break; } - if (m_net_cursor == 0 && !serialAvailable) - goto again; - if (m_net_cursor == 1 && !serialAvailable) + if (m_net_cursor == 0 && !ipxAvailable) goto again; - if (m_net_cursor == 2 && !ipxAvailable) - goto again; - if (m_net_cursor == 3 && !tcpipAvailable) + if (m_net_cursor == 1 && !tcpipAvailable) goto again; } //============================================================================= /* OPTIONS MENU */ -/*#ifdef _WIN32 -#define OPTIONS_ITEMS 14 -#else -#define OPTIONS_ITEMS 13 -#endif*/ - -// jkrige - menu items -#ifdef _WIN32 -#define OPTIONS_ITEMS 16 -#else -#define OPTIONS_ITEMS 15 -#endif -// jkrige - menu items +enum +{ + OPT_CUSTOMIZE = 0, + OPT_CONSOLE, // 1 + OPT_DEFAULTS, // 2 + OPT_SCALE, + OPT_SCRSIZE, + OPT_GAMMA, + OPT_CONTRAST, + OPT_MOUSESPEED, + OPT_SBALPHA, + OPT_SNDVOL, + OPT_MUSICVOL, + OPT_MUSICEXT, + OPT_ALWAYRUN, + OPT_INVMOUSE, + OPT_ALWAYSMLOOK, + OPT_LOOKSPRING, + OPT_LOOKSTRAFE, +//#ifdef _WIN32 +// OPT_USEMOUSE, +//#endif + OPT_VIDEO, // This is the last before OPTIONS_ITEMS + OPTIONS_ITEMS +}; + +enum +{ + ALWAYSRUN_OFF = 0, + ALWAYSRUN_VANILLA, + ALWAYSRUN_QUAKESPASM, + ALWAYSRUN_ITEMS +}; #define SLIDER_RANGE 10 @@ -1060,165 +1011,125 @@ int options_cursor; void M_Menu_Options_f (void) { + IN_Deactivate(modestate == MS_WINDOWED); key_dest = key_menu; m_state = m_options; m_entersound = true; - -#ifdef _WIN32 - if ((options_cursor == 16) && (modestate != MS_WINDOWED)) - { - options_cursor = 0; - } -#endif } void M_AdjustSliders (int dir) { + int curr_alwaysrun, target_alwaysrun; + float f, l; + S_LocalSound ("misc/menu3.wav"); switch (options_cursor) { - // jkrige - scr_viewsize removal - /*case 2: // screen size - scr_viewsize.value += dir * 10; - // jkrige - viewsize decreased - //if (scr_viewsize.value < 30) - // scr_viewsize.value = 30; - //if (scr_viewsize.value > 120) - // scr_viewsize.value = 120; - if (scr_viewsize.value < 10) - scr_viewsize.value = 10; - if (scr_viewsize.value > 100) - scr_viewsize.value = 100; - // jkrige - viewsize decreased - Cvar_SetValue ("viewsize", scr_viewsize.value); - break;*/ - // jkrige - scr_viewsize removal - - // jkrige - change brightness slider for opengl -#ifdef GLQUAKE - case 2: // gamma - // jkrige - gamma - gl_gamma.value -= dir * 0.05; - if (gl_gamma.value < 0.5) - gl_gamma.value = 0.5; - if (gl_gamma.value > 2.75) - gl_gamma.value = 2.75; - Cvar_SetValue ("gamma", gl_gamma.value); - // jkrige - gamma - break; -#else - case 2: // gamma - v_gamma.value -= dir * 0.05; - if (v_gamma.value < 0.5) - v_gamma.value = 0.5; - if (v_gamma.value > 1) - v_gamma.value = 1; - Cvar_SetValue ("gamma", v_gamma.value); - break; -#endif - // jkrige - change brightness slider for opengl - - // jkrige - anisotropic filtering -#ifdef GLQUAKE - case 3: // texture mode - gl_texturemode.value += dir * 1; - if(anisotropic_ext == false) - { - if (gl_texturemode.value < 0.0f) - gl_texturemode.value = 0.0f; - if (gl_texturemode.value > 2.0f) - gl_texturemode.value = 2.0f; - } - if(anisotropic_ext == true) - { - if (gl_texturemode.value < 0.0f) - gl_texturemode.value = 0.0f; - if (gl_texturemode.value > ((int)2.0f + (int)floor((log(maximumAnisotrophy)/log(2.0f)) + 0.5f))) - gl_texturemode.value = ((int)2.0f + (int)floor((log(maximumAnisotrophy)/log(2.0f)) + 0.5f)); - } - Cvar_SetValue ("gl_texturemode", gl_texturemode.value); - break; -#endif - // jkrige - anisotropic filtering - - case 4: // mouse speed - sensitivity.value += dir * 0.5; - if (sensitivity.value < 1) - sensitivity.value = 1; - if (sensitivity.value > 11) - sensitivity.value = 11; - Cvar_SetValue ("sensitivity", sensitivity.value); - break; - - case 5: // music volume - // jkrige - cd audio volume fix -//#ifdef _WIN32 -// bgmvolume.value += dir * 1.0; -//#else - bgmvolume.value += dir * 0.1; -//#endif - // jkrige - cd audio volume fix - - if (bgmvolume.value < 0) - bgmvolume.value = 0; - if (bgmvolume.value > 1) - bgmvolume.value = 1; - Cvar_SetValue ("bgmvolume", bgmvolume.value); - break; - - case 6: // sfx volume - volume.value += dir * 0.1; - if (volume.value < 0) - volume.value = 0; - if (volume.value > 1) - volume.value = 1; - Cvar_SetValue ("volume", volume.value); - break; - - case 7: // allways run - if (cl_forwardspeed.value > 200) + case OPT_SCALE: // console and menu scale + l = ((vid.width + 31) / 32) / 10.0; + f = scr_conscale.value + dir * .1; + if (f < 1) f = 1; + else if(f > l) f = l; + Cvar_SetValue ("scr_conscale", f); + Cvar_SetValue ("scr_menuscale", f); + Cvar_SetValue ("scr_sbarscale", f); + break; + case OPT_SCRSIZE: // screen size + f = scr_viewsize.value + dir * 10; + if (f > 120) f = 120; + else if(f < 30) f = 30; + Cvar_SetValue ("viewsize", f); + break; + case OPT_GAMMA: // gamma + f = vid_gamma.value - dir * 0.05; + if (f < 0.5) f = 0.5; + else if (f > 1) f = 1; + Cvar_SetValue ("gamma", f); + break; + case OPT_CONTRAST: // contrast + f = vid_contrast.value + dir * 0.1; + if (f < 1) f = 1; + else if (f > 2) f = 2; + Cvar_SetValue ("contrast", f); + break; + case OPT_MOUSESPEED: // mouse speed + f = sensitivity.value + dir * 0.5; + if (f > 11) f = 11; + else if (f < 1) f = 1; + Cvar_SetValue ("sensitivity", f); + break; + case OPT_SBALPHA: // statusbar alpha + f = scr_sbaralpha.value - dir * 0.05; + if (f < 0) f = 0; + else if (f > 1) f = 1; + Cvar_SetValue ("scr_sbaralpha", f); + break; + case OPT_MUSICVOL: // music volume + f = bgmvolume.value + dir * 0.1; + if (f < 0) f = 0; + else if (f > 1) f = 1; + Cvar_SetValue ("bgmvolume", f); + break; + case OPT_MUSICEXT: // enable external music vs cdaudio + Cvar_Set ("bgm_extmusic", bgm_extmusic.value ? "0" : "1"); + break; + case OPT_SNDVOL: // sfx volume + f = sfxvolume.value + dir * 0.1; + if (f < 0) f = 0; + else if (f > 1) f = 1; + Cvar_SetValue ("volume", f); + break; + + case OPT_ALWAYRUN: // always run + if (cl_alwaysrun.value) + curr_alwaysrun = ALWAYSRUN_QUAKESPASM; + else if (cl_forwardspeed.value > 200) + curr_alwaysrun = ALWAYSRUN_VANILLA; + else + curr_alwaysrun = ALWAYSRUN_OFF; + + target_alwaysrun = (ALWAYSRUN_ITEMS + curr_alwaysrun + dir) % ALWAYSRUN_ITEMS; + + if (target_alwaysrun == ALWAYSRUN_VANILLA) + { + Cvar_SetValue ("cl_alwaysrun", 0); + Cvar_SetValue ("cl_forwardspeed", 400); + Cvar_SetValue ("cl_backspeed", 400); + } + else if (target_alwaysrun == ALWAYSRUN_QUAKESPASM) { + Cvar_SetValue ("cl_alwaysrun", 1); Cvar_SetValue ("cl_forwardspeed", 200); Cvar_SetValue ("cl_backspeed", 200); } - else + else // ALWAYSRUN_OFF { - Cvar_SetValue ("cl_forwardspeed", 400); - Cvar_SetValue ("cl_backspeed", 400); + Cvar_SetValue ("cl_alwaysrun", 0); + Cvar_SetValue ("cl_forwardspeed", 200); + Cvar_SetValue ("cl_backspeed", 200); } break; - case 8: // invert mouse + case OPT_INVMOUSE: // invert mouse Cvar_SetValue ("m_pitch", -m_pitch.value); break; - case 9: // lookspring - Cvar_SetValue ("lookspring", !lookspring.value); - break; - - case 10: // lookstrafe - Cvar_SetValue ("lookstrafe", !lookstrafe.value); - break; - - case 11: // crosshair - Cvar_SetValue ("crosshair", !crosshair.value); // jkrige - crosshair - break; - - case 12: - Cvar_SetValue ("cl_mlook", !cl_mlook.value); // jkrige - mlook cvar + case OPT_ALWAYSMLOOK: + if (in_mlook.state & 1) + Cbuf_AddText("-mlook"); + else + Cbuf_AddText("+mlook"); break; - case 13: - Cvar_SetValue ("cl_slook", !cl_slook.value); // jkrige - slook cvar + case OPT_LOOKSPRING: // lookspring + Cvar_Set ("lookspring", lookspring.value ? "0" : "1"); break; -#ifdef _WIN32 - case 15: // _windowed_mouse - Cvar_SetValue ("_windowed_mouse", !_windowed_mouse.value); + case OPT_LOOKSTRAFE: // lookstrafe + Cvar_Set ("lookstrafe", lookstrafe.value ? "0" : "1"); break; -#endif } } @@ -1232,7 +1143,7 @@ void M_DrawSlider (int x, int y, float range) if (range > 1) range = 1; M_DrawCharacter (x-8, y, 128); - for (i=0 ; iwidth)/2, 4, p); - M_Print (16, 32, " Customize controls"); - //M_Print (16, 40, " Go to console"); - M_Print (16, 40, " Reset to defaults"); - - // jkrige - scr_viewsize removal - /*M_Print (16, 48, " Screen size"); - // jkrige - viewsize decreased - //r = (scr_viewsize.value - 30) / (120 - 30); - r = (scr_viewsize.value - 10) / (100 - 10); - // jkrige - viewsize decreased - M_DrawSlider (220, 48, r);*/ - // jkrige - scr_viewsize removal - - // jkrige - change brightness slider for opengl - M_Print (16, 48, " Brightness"); -#ifdef GLQUAKE - r = (2.75 - gl_gamma.value) / 2.25; -#else - r = (1.0 - v_gamma.value) / 0.5; -#endif - M_DrawSlider (220, 48, r); - // jkrige - change brightness slider for opengl - - - // jkrige - anisotropic filtering - M_Print (16, 56, " Texture Mode"); -#ifdef GLQUAKE - if (gl_texturemode.value == 0.0f) - M_Print (220, 56, "Point"); - else if (gl_texturemode.value == 1.0f) - M_Print (220, 56, "Bilinear"); - else if (gl_texturemode.value == 2.0f) - M_Print (220, 56, "Trilinear"); + // Draw the items in the order of the enum defined above: + // OPT_CUSTOMIZE: + M_Print (16, 32, " Controls"); + // OPT_CONSOLE: + M_Print (16, 32 + 8*OPT_CONSOLE, " Goto console"); + // OPT_DEFAULTS: + M_Print (16, 32 + 8*OPT_DEFAULTS, " Reset config"); + + // OPT_SCALE: + M_Print (16, 32 + 8*OPT_SCALE, " Scale"); + l = (vid.width / 320.0) - 1; + r = l > 0 ? (scr_conscale.value - 1) / l : 0; + M_DrawSlider (220, 32 + 8*OPT_SCALE, r); + + // OPT_SCRSIZE: + M_Print (16, 32 + 8*OPT_SCRSIZE, " Screen size"); + r = (scr_viewsize.value - 30) / (120 - 30); + M_DrawSlider (220, 32 + 8*OPT_SCRSIZE, r); + + // OPT_GAMMA: + M_Print (16, 32 + 8*OPT_GAMMA, " Brightness"); + r = (1.0 - vid_gamma.value) / 0.5; + M_DrawSlider (220, 32 + 8*OPT_GAMMA, r); + + // OPT_CONTRAST: + M_Print (16, 32 + 8*OPT_CONTRAST, " Contrast"); + r = vid_contrast.value - 1.0; + M_DrawSlider (220, 32 + 8*OPT_CONTRAST, r); + + // OPT_MOUSESPEED: + M_Print (16, 32 + 8*OPT_MOUSESPEED, " Mouse Speed"); + r = (sensitivity.value - 1)/10; + M_DrawSlider (220, 32 + 8*OPT_MOUSESPEED, r); + + // OPT_SBALPHA: + M_Print (16, 32 + 8*OPT_SBALPHA, " Statusbar alpha"); + r = (1.0 - scr_sbaralpha.value) ; // scr_sbaralpha range is 1.0 to 0.0 + M_DrawSlider (220, 32 + 8*OPT_SBALPHA, r); + + // OPT_SNDVOL: + M_Print (16, 32 + 8*OPT_SNDVOL, " Sound Volume"); + r = sfxvolume.value; + M_DrawSlider (220, 32 + 8*OPT_SNDVOL, r); + + // OPT_MUSICVOL: + M_Print (16, 32 + 8*OPT_MUSICVOL, " Music Volume"); + r = bgmvolume.value; + M_DrawSlider (220, 32 + 8*OPT_MUSICVOL, r); + + // OPT_MUSICEXT: + M_Print (16, 32 + 8*OPT_MUSICEXT, " External Music"); + M_DrawCheckbox (220, 32 + 8*OPT_MUSICEXT, bgm_extmusic.value); + + // OPT_ALWAYRUN: + M_Print (16, 32 + 8*OPT_ALWAYRUN, " Always Run"); + if (cl_alwaysrun.value) + M_Print (220, 32 + 8*OPT_ALWAYRUN, "quakespasm"); + else if (cl_forwardspeed.value > 200.0) + M_Print (220, 32 + 8*OPT_ALWAYRUN, "vanilla"); else - { - if (modelist[(int)vid_mode.value].width > 640) - M_Print (220, 56, va("Anisotropic %.0fx", pow(2.0f, gl_texturemode.value - 2.0f))); - else - M_Print (220, 56, va("AF %.0fx", pow(2.0f, gl_texturemode.value - 2.0f))); - } -#else - M_Print (220, 56, "Point"); -#endif - // jkrige - anisotropic filtering - - - M_Print (16, 64, " Mouse Speed"); - M_DrawSlider (220, 64, (float)((sensitivity.value - 1) / 10)); - - M_Print (16, 72, " Music Volume"); - M_DrawSlider (220, 72, bgmvolume.value); + M_Print (220, 32 + 8*OPT_ALWAYRUN, "off"); - M_Print (16, 80, " Sound Volume"); - M_DrawSlider (220, 80, volume.value); + // OPT_INVMOUSE: + M_Print (16, 32 + 8*OPT_INVMOUSE, " Invert Mouse"); + M_DrawCheckbox (220, 32 + 8*OPT_INVMOUSE, m_pitch.value < 0); - M_Print (16, 88, " Always Run"); - M_DrawCheckbox (220, 88, cl_forwardspeed.value > 200); + // OPT_ALWAYSMLOOK: + M_Print (16, 32 + 8*OPT_ALWAYSMLOOK, " Mouse Look"); + M_DrawCheckbox (220, 32 + 8*OPT_ALWAYSMLOOK, in_mlook.state & 1); - M_Print (16, 96, " Invert Mouse"); - M_DrawCheckbox (220, 96, m_pitch.value < 0); + // OPT_LOOKSPRING: + M_Print (16, 32 + 8*OPT_LOOKSPRING, " Lookspring"); + M_DrawCheckbox (220, 32 + 8*OPT_LOOKSPRING, lookspring.value); - M_Print (16, 104, " Lookspring"); - M_DrawCheckbox (220, 104, lookspring.value); - - M_Print (16, 112, " Lookstrafe"); - M_DrawCheckbox (220, 112, lookstrafe.value); - - // jkrige - crosshair - M_Print (16, 120, " Crosshair"); - M_DrawCheckbox (220, 120, crosshair.value); - // jkrige - crosshair - - M_Print (16, 128, " Mouse Look"); - M_DrawCheckbox (220, 128, cl_mlook.value /*in_mlook.state & 1*/); // jkrige - mlook cvar - - M_Print (16, 136, " Slope Look"); - M_DrawCheckbox (220, 136, cl_slook.value); // jkrige - slook cvar + // OPT_LOOKSTRAFE: + M_Print (16, 32 + 8*OPT_LOOKSTRAFE, " Lookstrafe"); + M_DrawCheckbox (220, 32 + 8*OPT_LOOKSTRAFE, lookstrafe.value); + // OPT_VIDEO: if (vid_menudrawfn) - M_Print (16, 144, " Video Options"); - -#ifdef _WIN32 - if (modestate == MS_WINDOWED) - { - M_Print (16, 152, " Use Mouse"); - M_DrawCheckbox (220, 152, _windowed_mouse.value); - } -#endif + M_Print (16, 32 + 8*OPT_VIDEO, " Video Options"); // cursor M_DrawCharacter (200, 32 + options_cursor*8, 12+((int)(realtime*4)&1)); @@ -1360,24 +1264,32 @@ void M_Options_Key (int k) switch (k) { case K_ESCAPE: + case K_BBUTTON: M_Menu_Main_f (); break; case K_ENTER: + case K_KP_ENTER: + case K_ABUTTON: m_entersound = true; switch (options_cursor) { - case 0: + case OPT_CUSTOMIZE: M_Menu_Keys_f (); break; - /*case 1: + case OPT_CONSOLE: m_state = m_none; Con_ToggleConsole_f (); - break;*/ - case 1: - Cbuf_AddText ("exec default.cfg\n"); break; - case 14: + case OPT_DEFAULTS: + if (SCR_ModalMessage("This will reset all controls\n" + "and stored cvars. Continue? (y/n)\n", 15.0f)) + { + Cbuf_AddText ("resetcfg\n"); + Cbuf_AddText ("exec default.cfg\n"); + } + break; + case OPT_VIDEO: M_Menu_Video_f (); break; default: @@ -1390,7 +1302,7 @@ void M_Options_Key (int k) S_LocalSound ("misc/menu1.wav"); options_cursor--; if (options_cursor < 0) - options_cursor = OPTIONS_ITEMS - 1; + options_cursor = OPTIONS_ITEMS-1; break; case K_DOWNARROW: @@ -1409,98 +1321,82 @@ void M_Options_Key (int k) break; } - if (options_cursor == 14 && vid_menudrawfn == NULL) - { - if (k == K_UPARROW) - { - if (modestate == MS_WINDOWED) - options_cursor = 13; - } - else - { - if (modestate != MS_WINDOWED) - options_cursor = 0; - else - options_cursor = 15; - } - } - -#ifdef _WIN32 - if ((options_cursor == 15) && (modestate != MS_WINDOWED)) + if (options_cursor == OPTIONS_ITEMS - 1 && vid_menudrawfn == NULL) { if (k == K_UPARROW) - options_cursor = (vid_menudrawfn == NULL) ? 13 : 14; + options_cursor = OPTIONS_ITEMS - 2; else options_cursor = 0; } -#endif } //============================================================================= /* KEYS MENU */ -char *bindnames[][2] = -{ -{"+attack", "attack"}, -{"impulse 10", "change weapon"}, -{"+jump", "jump / swim up"}, -{"+forward", "walk forward"}, -{"+back", "backpedal"}, -{"+left", "turn left"}, -{"+right", "turn right"}, -{"+speed", "run"}, -{"+moveleft", "step left"}, -{"+moveright", "step right"}, -{"+strafe", "sidestep"}, -{"+lookup", "look up"}, -{"+lookdown", "look down"}, -{"centerview", "center view"}, -//{"+mlook", "mouse look"}, // jkrige - removed mlook command -//{"+klook", "keyboard look"}, // jkrige - removed klook command -{"+moveup", "swim up"}, -{"+movedown", "swim down"} +const char *bindnames[][2] = +{ + {"+attack", "attack"}, + {"impulse 10", "next weapon"}, + {"impulse 12", "prev weapon"}, + {"+jump", "jump / swim up"}, + {"+forward", "walk forward"}, + {"+back", "backpedal"}, + {"+left", "turn left"}, + {"+right", "turn right"}, + {"+speed", "run"}, + {"+moveleft", "step left"}, + {"+moveright", "step right"}, + {"+strafe", "sidestep"}, + {"+lookup", "look up"}, + {"+lookdown", "look down"}, + {"centerview", "center view"}, + {"+mlook", "mouse look"}, + {"+klook", "keyboard look"}, + {"+moveup", "swim up"}, + {"+movedown", "swim down"} }; #define NUMCOMMANDS (sizeof(bindnames)/sizeof(bindnames[0])) -int keys_cursor; -int bind_grab; +static int keys_cursor; +static qboolean bind_grab; void M_Menu_Keys_f (void) { + IN_Deactivate(modestate == MS_WINDOWED); key_dest = key_menu; m_state = m_keys; m_entersound = true; } -void M_FindKeysForCommand (char *command, int *twokeys) +void M_FindKeysForCommand (const char *command, int *threekeys) { int count; int j; int l; char *b; - twokeys[0] = twokeys[1] = -1; + threekeys[0] = threekeys[1] = threekeys[2] = -1; l = strlen(command); count = 0; - for (j=0 ; j<256 ; j++) + for (j = 0; j < MAX_KEYS; j++) { b = keybindings[j]; if (!b) continue; if (!strncmp (b, command, l) ) { - twokeys[count] = j; + threekeys[count] = j; count++; - if (count == 2) + if (count == 3) break; } } } -void M_UnbindCommand (char *command) +void M_UnbindCommand (const char *command) { int j; int l; @@ -1508,23 +1404,23 @@ void M_UnbindCommand (char *command) l = strlen(command); - for (j=0 ; j<256 ; j++) + for (j = 0; j < MAX_KEYS; j++) { b = keybindings[j]; if (!b) continue; if (!strncmp (b, command, l) ) - Key_SetBinding (j, ""); + Key_SetBinding (j, NULL); } } +extern qpic_t *pic_up, *pic_down; void M_Keys_Draw (void) { - int i, l; - int keys[2]; - char *name; - int x, y; + int i, x, y; + int keys[3]; + const char *name; qpic_t *p; p = Draw_CachePic ("gfx/ttl_cstm.lmp"); @@ -1536,14 +1432,12 @@ void M_Keys_Draw (void) M_Print (18, 32, "Enter to change, backspace to clear"); // search for known bindings - for (i=0 ; i= NUMCOMMANDS) + if (keys_cursor >= (int)NUMCOMMANDS) keys_cursor = 0; break; case K_ENTER: // go into bind mode + case K_KP_ENTER: + case K_ABUTTON: M_FindKeysForCommand (bindnames[keys_cursor][0], keys); S_LocalSound ("misc/menu2.wav"); - if (keys[1] != -1) + if (keys[2] != -1) M_UnbindCommand (bindnames[keys_cursor][0]); bind_grab = true; + IN_Activate(); // activate to allow mouse key binding break; - case K_BACKSPACE: // delete bindings - case K_DEL: // delete bindings + case K_BACKSPACE: // delete bindings + case K_DEL: S_LocalSound ("misc/menu2.wav"); M_UnbindCommand (bindnames[keys_cursor][0]); break; @@ -1635,9 +1537,7 @@ void M_Keys_Key (int k) void M_Menu_Video_f (void) { - key_dest = key_menu; - m_state = m_video; - m_entersound = true; + (*vid_menucmdfn) (); //johnfitz } @@ -1661,6 +1561,7 @@ int help_page; void M_Menu_Help_f (void) { + IN_Deactivate(modestate == MS_WINDOWED); key_dest = key_menu; m_state = m_help; m_entersound = true; @@ -1680,6 +1581,7 @@ void M_Help_Key (int key) switch (key) { case K_ESCAPE: + case K_BBUTTON: M_Menu_Main_f (); break; @@ -1704,60 +1606,15 @@ void M_Help_Key (int key) /* QUIT MENU */ int msgNumber; -int m_quit_prevstate; +enum m_state_e m_quit_prevstate; qboolean wasInMenus; -#ifndef _WIN32 -char *quitMessage [] = -{ -/* .........1.........2.... */ - " Are you gonna quit ", - " this game just like ", - " everything else? ", - " ", - - " Milord, methinks that ", - " thou art a lowly ", - " quitter. Is this true? ", - " ", - - " Do I need to bust your ", - " face open for trying ", - " to quit? ", - " ", - - " Man, I oughta smack you", - " for trying to quit! ", - " Press Y to get ", - " smacked out. ", - - " Press Y to quit like a ", - " big loser in life. ", - " Press N to stay proud ", - " and successful! ", - - " If you press Y to ", - " quit, I will summon ", - " Satan all over your ", - " hard drive! ", - - " Um, Asmodeus dislikes ", - " his children trying to ", - " quit. Press Y to return", - " to your Tinkertoys. ", - - " If you quit now, I'll ", - " throw a blanket-party ", - " for you next time! ", - " " -}; -#endif - void M_Menu_Quit_f (void) { if (m_state == m_quit) return; wasInMenus = (key_dest == key_menu); + IN_Deactivate(modestate == MS_WINDOWED); key_dest = key_menu; m_quit_prevstate = m_state; m_state = m_quit; @@ -1767,10 +1624,28 @@ void M_Menu_Quit_f (void) void M_Quit_Key (int key) +{ + if (key == K_ESCAPE) + { + if (wasInMenus) + { + m_state = m_quit_prevstate; + m_entersound = true; + } + else + { + IN_Activate(); + key_dest = key_game; + m_state = m_none; + } + } +} + + +void M_Quit_Char (int key) { switch (key) { - case K_ESCAPE: case 'n': case 'N': if (wasInMenus) @@ -1780,13 +1655,15 @@ void M_Quit_Key (int key) } else { + IN_Activate(); key_dest = key_game; m_state = m_none; } break; - case 'Y': case 'y': + case 'Y': + IN_Deactivate(modestate == MS_WINDOWED); key_dest = key_console; Host_Quit_f (); break; @@ -1798,8 +1675,19 @@ void M_Quit_Key (int key) } -void M_Quit_Draw (void) +qboolean M_Quit_TextEntry (void) +{ + return true; +} + + +void M_Quit_Draw (void) //johnfitz -- modified for new quit message { + char msg1[40]; + char msg2[] = "by Ozkan Sezer, Eric Wasylishen, others";/* msg2/msg3 are mostly [40] */ + char msg3[] = "Press y to quit"; + int boxlen; + if (wasInMenus) { m_state = m_quit_prevstate; @@ -1808,544 +1696,61 @@ void M_Quit_Draw (void) m_state = m_quit; } -#ifdef _WIN32 - M_DrawTextBox (0, 0, 38, 24); - - // jkrige - new version - //M_PrintWhite (16, 12, va(" Quake version %.2f by id Software\n\n", QUAKE_VERSION)); - M_PrintWhite (16, 12, va(" UQE Quake v%.2f by Jacques Krige ", QUAKE_VERSION)); - M_PrintWhite (16, 20, " www.jacqueskrige.com "); - // jkrige - new version - - M_PrintWhite (16, 36, "Programming Art"); - M_Print (16, 44, " John Carmack Adrian Carmack"); - M_Print (16, 52, " Michael Abrash Kevin Cloud"); - M_Print (16, 60, " John Cash Paul Steed"); - M_Print (16, 68, " Dave 'Zoid' Kirsch"); - M_PrintWhite (16, 76, "Design Biz"); - M_Print (16, 84, " John Romero Jay Wilbur"); - M_Print (16, 92, " Sandy Petersen Mike Wilson"); - M_Print (16, 100, " American McGee Donna Jackson"); - M_Print (16, 108, " Tim Willits Todd Hollenshead"); - M_PrintWhite (16, 116, "Support Projects"); - M_Print (16, 124, " Barrett Alexander Shawn Green"); - M_PrintWhite (16, 132, "Sound Effects"); - M_Print (16, 140, " Trent Reznor and Nine Inch Nails"); - M_PrintWhite (16, 148, "Quake is a trademark of Id Software,"); - M_PrintWhite (16, 156, "inc., (c)1996 Id Software, inc. All"); - M_PrintWhite (16, 164, "rights reserved. NIN logo is a"); - M_PrintWhite (16, 172, "registered trademark licensed to"); - M_PrintWhite (16, 180, "Nothing Interactive, Inc. All rights"); - M_PrintWhite (16, 188, "reserved. Press y to exit"); -#else - M_DrawTextBox (56, 76, 24, 4); - M_Print (64, 84, quitMessage[msgNumber*4+0]); - M_Print (64, 92, quitMessage[msgNumber*4+1]); - M_Print (64, 100, quitMessage[msgNumber*4+2]); - M_Print (64, 108, quitMessage[msgNumber*4+3]); -#endif -} + sprintf(msg1, "QuakeSpasm " QUAKESPASM_VER_STRING); -//============================================================================= + //okay, this is kind of fucked up. M_DrawTextBox will always act as if + //width is even. Also, the width and lines values are for the interior of the box, + //but the x and y values include the border. + boxlen = q_max(strlen(msg1), q_max((sizeof(msg2)-1),(sizeof(msg3)-1))) + 1; + if (boxlen & 1) boxlen++; + M_DrawTextBox (160-4*(boxlen+2), 76, boxlen, 4); -/* SERIAL CONFIG MENU */ + //now do the text + M_Print (160-4*strlen(msg1), 88, msg1); + M_Print (160-4*(sizeof(msg2)-1), 96, msg2); + M_PrintWhite (160-4*(sizeof(msg3)-1), 104, msg3); +} -int serialConfig_cursor; -int serialConfig_cursor_table[] = {48, 64, 80, 96, 112, 132}; -#define NUM_SERIALCONFIG_CMDS 6 +//============================================================================= +/* LAN CONFIG MENU */ -static int ISA_uarts[] = {0x3f8,0x2f8,0x3e8,0x2e8}; -static int ISA_IRQs[] = {4,3,4,3}; -int serialConfig_baudrate[] = {9600,14400,19200,28800,38400,57600}; +int lanConfig_cursor = -1; +int lanConfig_cursor_table [] = {72, 92, 124}; +#define NUM_LANCONFIG_CMDS 3 -int serialConfig_comport; -int serialConfig_irq ; -int serialConfig_baud; -char serialConfig_phone[16]; +int lanConfig_port; +char lanConfig_portname[6]; +char lanConfig_joinname[22]; -void M_Menu_SerialConfig_f (void) +void M_Menu_LanConfig_f (void) { - int n; - int port; - int baudrate; - qboolean useModem; - + IN_Deactivate(modestate == MS_WINDOWED); key_dest = key_menu; - m_state = m_serialconfig; + m_state = m_lanconfig; m_entersound = true; - if (JoiningGame && SerialConfig) - serialConfig_cursor = 4; - else - serialConfig_cursor = 5; - - (*GetComPortConfig) (0, &port, &serialConfig_irq, &baudrate, &useModem); - - // map uart's port to COMx - for (n = 0; n < 4; n++) - if (ISA_uarts[n] == port) - break; - if (n == 4) + if (lanConfig_cursor == -1) { - n = 0; - serialConfig_irq = 4; + if (JoiningGame && TCPIPConfig) + lanConfig_cursor = 2; + else + lanConfig_cursor = 1; } - serialConfig_comport = n + 1; - - // map baudrate to index - for (n = 0; n < 6; n++) - if (serialConfig_baudrate[n] == baudrate) - break; - if (n == 6) - n = 5; - serialConfig_baud = n; + if (StartingGame && lanConfig_cursor == 2) + lanConfig_cursor = 1; + lanConfig_port = DEFAULTnet_hostport; + sprintf(lanConfig_portname, "%u", lanConfig_port); m_return_onerror = false; m_return_reason[0] = 0; } -void M_SerialConfig_Draw (void) +void M_LanConfig_Draw (void) { qpic_t *p; int basex; - char *startJoin; - char *directModem; - - M_DrawTransPic (16, 4, Draw_CachePic ("gfx/qplaque.lmp") ); - p = Draw_CachePic ("gfx/p_multi.lmp"); - basex = (320-p->width)/2; - M_DrawPic (basex, 4, p); - - if (StartingGame) - startJoin = "New Game"; - else - startJoin = "Join Game"; - if (SerialConfig) - directModem = "Modem"; - else - directModem = "Direct Connect"; - M_Print (basex, 32, va ("%s - %s", startJoin, directModem)); - basex += 8; - - M_Print (basex, serialConfig_cursor_table[0], "Port"); - M_DrawTextBox (160, 40, 4, 1); - M_Print (168, serialConfig_cursor_table[0], va("COM%u", serialConfig_comport)); - - M_Print (basex, serialConfig_cursor_table[1], "IRQ"); - M_DrawTextBox (160, serialConfig_cursor_table[1]-8, 1, 1); - M_Print (168, serialConfig_cursor_table[1], va("%u", serialConfig_irq)); - - M_Print (basex, serialConfig_cursor_table[2], "Baud"); - M_DrawTextBox (160, serialConfig_cursor_table[2]-8, 5, 1); - M_Print (168, serialConfig_cursor_table[2], va("%u", serialConfig_baudrate[serialConfig_baud])); - - if (SerialConfig) - { - M_Print (basex, serialConfig_cursor_table[3], "Modem Setup..."); - if (JoiningGame) - { - M_Print (basex, serialConfig_cursor_table[4], "Phone number"); - M_DrawTextBox (160, serialConfig_cursor_table[4]-8, 16, 1); - M_Print (168, serialConfig_cursor_table[4], serialConfig_phone); - } - } - - if (JoiningGame) - { - M_DrawTextBox (basex, serialConfig_cursor_table[5]-8, 7, 1); - M_Print (basex+8, serialConfig_cursor_table[5], "Connect"); - } - else - { - M_DrawTextBox (basex, serialConfig_cursor_table[5]-8, 2, 1); - M_Print (basex+8, serialConfig_cursor_table[5], "OK"); - } - - M_DrawCharacter (basex-8, serialConfig_cursor_table [serialConfig_cursor], 12+((int)(realtime*4)&1)); - - if (serialConfig_cursor == 4) - M_DrawCharacter (168 + 8*strlen(serialConfig_phone), serialConfig_cursor_table [serialConfig_cursor], 10+((int)(realtime*4)&1)); - - if (*m_return_reason) - M_PrintWhite (basex, 148, m_return_reason); -} - - -void M_SerialConfig_Key (int key) -{ - int l; - - switch (key) - { - case K_ESCAPE: - M_Menu_Net_f (); - break; - - case K_UPARROW: - S_LocalSound ("misc/menu1.wav"); - serialConfig_cursor--; - if (serialConfig_cursor < 0) - serialConfig_cursor = NUM_SERIALCONFIG_CMDS-1; - break; - - case K_DOWNARROW: - S_LocalSound ("misc/menu1.wav"); - serialConfig_cursor++; - if (serialConfig_cursor >= NUM_SERIALCONFIG_CMDS) - serialConfig_cursor = 0; - break; - - case K_LEFTARROW: - if (serialConfig_cursor > 2) - break; - S_LocalSound ("misc/menu3.wav"); - - if (serialConfig_cursor == 0) - { - serialConfig_comport--; - if (serialConfig_comport == 0) - serialConfig_comport = 4; - serialConfig_irq = ISA_IRQs[serialConfig_comport-1]; - } - - if (serialConfig_cursor == 1) - { - serialConfig_irq--; - if (serialConfig_irq == 6) - serialConfig_irq = 5; - if (serialConfig_irq == 1) - serialConfig_irq = 7; - } - - if (serialConfig_cursor == 2) - { - serialConfig_baud--; - if (serialConfig_baud < 0) - serialConfig_baud = 5; - } - - break; - - case K_RIGHTARROW: - if (serialConfig_cursor > 2) - break; -forward: - S_LocalSound ("misc/menu3.wav"); - - if (serialConfig_cursor == 0) - { - serialConfig_comport++; - if (serialConfig_comport > 4) - serialConfig_comport = 1; - serialConfig_irq = ISA_IRQs[serialConfig_comport-1]; - } - - if (serialConfig_cursor == 1) - { - serialConfig_irq++; - if (serialConfig_irq == 6) - serialConfig_irq = 7; - if (serialConfig_irq == 8) - serialConfig_irq = 2; - } - - if (serialConfig_cursor == 2) - { - serialConfig_baud++; - if (serialConfig_baud > 5) - serialConfig_baud = 0; - } - - break; - - case K_ENTER: - if (serialConfig_cursor < 3) - goto forward; - - m_entersound = true; - - if (serialConfig_cursor == 3) - { - (*SetComPortConfig) (0, ISA_uarts[serialConfig_comport-1], serialConfig_irq, serialConfig_baudrate[serialConfig_baud], SerialConfig); - - M_Menu_ModemConfig_f (); - break; - } - - if (serialConfig_cursor == 4) - { - serialConfig_cursor = 5; - break; - } - - // serialConfig_cursor == 5 (OK/CONNECT) - (*SetComPortConfig) (0, ISA_uarts[serialConfig_comport-1], serialConfig_irq, serialConfig_baudrate[serialConfig_baud], SerialConfig); - - M_ConfigureNetSubsystem (); - - if (StartingGame) - { - M_Menu_GameOptions_f (); - break; - } - - m_return_state = m_state; - m_return_onerror = true; - key_dest = key_game; - m_state = m_none; - - if (SerialConfig) - Cbuf_AddText (va ("connect \"%s\"\n", serialConfig_phone)); - else - Cbuf_AddText ("connect\n"); - break; - - case K_BACKSPACE: - if (serialConfig_cursor == 4) - { - if (strlen(serialConfig_phone)) - serialConfig_phone[strlen(serialConfig_phone)-1] = 0; - } - break; - - default: - if (key < 32 || key > 127) - break; - if (serialConfig_cursor == 4) - { - l = strlen(serialConfig_phone); - if (l < 15) - { - serialConfig_phone[l+1] = 0; - serialConfig_phone[l] = key; - } - } - } - - if (DirectConfig && (serialConfig_cursor == 3 || serialConfig_cursor == 4)) - if (key == K_UPARROW) - serialConfig_cursor = 2; - else - serialConfig_cursor = 5; - - if (SerialConfig && StartingGame && serialConfig_cursor == 4) - if (key == K_UPARROW) - serialConfig_cursor = 3; - else - serialConfig_cursor = 5; -} - -//============================================================================= -/* MODEM CONFIG MENU */ - -int modemConfig_cursor; -int modemConfig_cursor_table [] = {40, 56, 88, 120, 156}; -#define NUM_MODEMCONFIG_CMDS 5 - -char modemConfig_dialing; -char modemConfig_clear [16]; -char modemConfig_init [32]; -char modemConfig_hangup [16]; - -void M_Menu_ModemConfig_f (void) -{ - key_dest = key_menu; - m_state = m_modemconfig; - m_entersound = true; - (*GetModemConfig) (0, &modemConfig_dialing, modemConfig_clear, modemConfig_init, modemConfig_hangup); -} - - -void M_ModemConfig_Draw (void) -{ - qpic_t *p; - int basex; - - M_DrawTransPic (16, 4, Draw_CachePic ("gfx/qplaque.lmp") ); - p = Draw_CachePic ("gfx/p_multi.lmp"); - basex = (320-p->width)/2; - M_DrawPic (basex, 4, p); - basex += 8; - - if (modemConfig_dialing == 'P') - M_Print (basex, modemConfig_cursor_table[0], "Pulse Dialing"); - else - M_Print (basex, modemConfig_cursor_table[0], "Touch Tone Dialing"); - - M_Print (basex, modemConfig_cursor_table[1], "Clear"); - M_DrawTextBox (basex, modemConfig_cursor_table[1]+4, 16, 1); - M_Print (basex+8, modemConfig_cursor_table[1]+12, modemConfig_clear); - if (modemConfig_cursor == 1) - M_DrawCharacter (basex+8 + 8*strlen(modemConfig_clear), modemConfig_cursor_table[1]+12, 10+((int)(realtime*4)&1)); - - M_Print (basex, modemConfig_cursor_table[2], "Init"); - M_DrawTextBox (basex, modemConfig_cursor_table[2]+4, 30, 1); - M_Print (basex+8, modemConfig_cursor_table[2]+12, modemConfig_init); - if (modemConfig_cursor == 2) - M_DrawCharacter (basex+8 + 8*strlen(modemConfig_init), modemConfig_cursor_table[2]+12, 10+((int)(realtime*4)&1)); - - M_Print (basex, modemConfig_cursor_table[3], "Hangup"); - M_DrawTextBox (basex, modemConfig_cursor_table[3]+4, 16, 1); - M_Print (basex+8, modemConfig_cursor_table[3]+12, modemConfig_hangup); - if (modemConfig_cursor == 3) - M_DrawCharacter (basex+8 + 8*strlen(modemConfig_hangup), modemConfig_cursor_table[3]+12, 10+((int)(realtime*4)&1)); - - M_DrawTextBox (basex, modemConfig_cursor_table[4]-8, 2, 1); - M_Print (basex+8, modemConfig_cursor_table[4], "OK"); - - M_DrawCharacter (basex-8, modemConfig_cursor_table [modemConfig_cursor], 12+((int)(realtime*4)&1)); -} - - -void M_ModemConfig_Key (int key) -{ - int l; - - switch (key) - { - case K_ESCAPE: - M_Menu_SerialConfig_f (); - break; - - case K_UPARROW: - S_LocalSound ("misc/menu1.wav"); - modemConfig_cursor--; - if (modemConfig_cursor < 0) - modemConfig_cursor = NUM_MODEMCONFIG_CMDS-1; - break; - - case K_DOWNARROW: - S_LocalSound ("misc/menu1.wav"); - modemConfig_cursor++; - if (modemConfig_cursor >= NUM_MODEMCONFIG_CMDS) - modemConfig_cursor = 0; - break; - - case K_LEFTARROW: - case K_RIGHTARROW: - if (modemConfig_cursor == 0) - { - if (modemConfig_dialing == 'P') - modemConfig_dialing = 'T'; - else - modemConfig_dialing = 'P'; - S_LocalSound ("misc/menu1.wav"); - } - break; - - case K_ENTER: - if (modemConfig_cursor == 0) - { - if (modemConfig_dialing == 'P') - modemConfig_dialing = 'T'; - else - modemConfig_dialing = 'P'; - m_entersound = true; - } - - if (modemConfig_cursor == 4) - { - (*SetModemConfig) (0, va ("%c", modemConfig_dialing), modemConfig_clear, modemConfig_init, modemConfig_hangup); - m_entersound = true; - M_Menu_SerialConfig_f (); - } - break; - - case K_BACKSPACE: - if (modemConfig_cursor == 1) - { - if (strlen(modemConfig_clear)) - modemConfig_clear[strlen(modemConfig_clear)-1] = 0; - } - - if (modemConfig_cursor == 2) - { - if (strlen(modemConfig_init)) - modemConfig_init[strlen(modemConfig_init)-1] = 0; - } - - if (modemConfig_cursor == 3) - { - if (strlen(modemConfig_hangup)) - modemConfig_hangup[strlen(modemConfig_hangup)-1] = 0; - } - break; - - default: - if (key < 32 || key > 127) - break; - - if (modemConfig_cursor == 1) - { - l = strlen(modemConfig_clear); - if (l < 15) - { - modemConfig_clear[l+1] = 0; - modemConfig_clear[l] = key; - } - } - - if (modemConfig_cursor == 2) - { - l = strlen(modemConfig_init); - if (l < 29) - { - modemConfig_init[l+1] = 0; - modemConfig_init[l] = key; - } - } - - if (modemConfig_cursor == 3) - { - l = strlen(modemConfig_hangup); - if (l < 15) - { - modemConfig_hangup[l+1] = 0; - modemConfig_hangup[l] = key; - } - } - } -} - -//============================================================================= -/* LAN CONFIG MENU */ - -int lanConfig_cursor = -1; -int lanConfig_cursor_table [] = {72, 92, 124}; -#define NUM_LANCONFIG_CMDS 3 - -int lanConfig_port; -char lanConfig_portname[6]; -char lanConfig_joinname[22]; - -void M_Menu_LanConfig_f (void) -{ - key_dest = key_menu; - m_state = m_lanconfig; - m_entersound = true; - if (lanConfig_cursor == -1) - { - if (JoiningGame && TCPIPConfig) - lanConfig_cursor = 2; - else - lanConfig_cursor = 1; - } - if (StartingGame && lanConfig_cursor == 2) - lanConfig_cursor = 1; - lanConfig_port = DEFAULTnet_hostport; - sprintf(lanConfig_portname, "%u", lanConfig_port); - - m_return_onerror = false; - m_return_reason[0] = 0; -} - - -void M_LanConfig_Draw (void) -{ - qpic_t *p; - int basex; - char *startJoin; - char *protocol; + const char *startJoin; + const char *protocol; M_DrawTransPic (16, 4, Draw_CachePic ("gfx/qplaque.lmp") ); p = Draw_CachePic ("gfx/p_multi.lmp"); @@ -2406,6 +1811,7 @@ void M_LanConfig_Key (int key) switch (key) { case K_ESCAPE: + case K_BBUTTON: M_Menu_Net_f (); break; @@ -2424,6 +1830,8 @@ void M_LanConfig_Key (int key) break; case K_ENTER: + case K_KP_ENTER: + case K_ABUTTON: if (lanConfig_cursor == 0) break; @@ -2446,6 +1854,7 @@ void M_LanConfig_Key (int key) { m_return_state = m_state; m_return_onerror = true; + IN_Activate(); key_dest = key_game; m_state = m_none; Cbuf_AddText ( va ("connect \"%s\"\n", lanConfig_joinname) ); @@ -2467,39 +1876,15 @@ void M_LanConfig_Key (int key) lanConfig_joinname[strlen(lanConfig_joinname)-1] = 0; } break; - - default: - if (key < 32 || key > 127) - break; - - if (lanConfig_cursor == 2) - { - l = strlen(lanConfig_joinname); - if (l < 21) - { - lanConfig_joinname[l+1] = 0; - lanConfig_joinname[l] = key; - } - } - - if (key < '0' || key > '9') - break; - if (lanConfig_cursor == 0) - { - l = strlen(lanConfig_portname); - if (l < 5) - { - lanConfig_portname[l+1] = 0; - lanConfig_portname[l] = key; - } - } } if (StartingGame && lanConfig_cursor == 2) + { if (key == K_UPARROW) lanConfig_cursor = 1; else lanConfig_cursor = 0; + } l = Q_atoi(lanConfig_portname); if (l > 65535) @@ -2509,13 +1894,47 @@ void M_LanConfig_Key (int key) sprintf(lanConfig_portname, "%u", lanConfig_port); } + +void M_LanConfig_Char (int key) +{ + int l; + + switch (lanConfig_cursor) + { + case 0: + if (key < '0' || key > '9') + return; + l = strlen(lanConfig_portname); + if (l < 5) + { + lanConfig_portname[l+1] = 0; + lanConfig_portname[l] = key; + } + break; + case 2: + l = strlen(lanConfig_joinname); + if (l < 21) + { + lanConfig_joinname[l+1] = 0; + lanConfig_joinname[l] = key; + } + break; + } +} + + +qboolean M_LanConfig_TextEntry (void) +{ + return (lanConfig_cursor == 0 || lanConfig_cursor == 2); +} + //============================================================================= /* GAME OPTIONS MENU */ typedef struct { - char *name; - char *description; + const char *name; + const char *description; } level_t; level_t levels[] = @@ -2569,29 +1988,29 @@ level_t levels[] = //MED 01/06/97 added hipnotic levels level_t hipnoticlevels[] = { - {"start", "Command HQ"}, // 0 + {"start", "Command HQ"}, // 0 - {"hip1m1", "The Pumping Station"}, // 1 - {"hip1m2", "Storage Facility"}, - {"hip1m3", "The Lost Mine"}, - {"hip1m4", "Research Facility"}, - {"hip1m5", "Military Complex"}, + {"hip1m1", "The Pumping Station"}, // 1 + {"hip1m2", "Storage Facility"}, + {"hip1m3", "The Lost Mine"}, + {"hip1m4", "Research Facility"}, + {"hip1m5", "Military Complex"}, - {"hip2m1", "Ancient Realms"}, // 6 - {"hip2m2", "The Black Cathedral"}, - {"hip2m3", "The Catacombs"}, - {"hip2m4", "The Crypt"}, - {"hip2m5", "Mortum's Keep"}, - {"hip2m6", "The Gremlin's Domain"}, + {"hip2m1", "Ancient Realms"}, // 6 + {"hip2m2", "The Black Cathedral"}, + {"hip2m3", "The Catacombs"}, + {"hip2m4", "The Crypt"}, + {"hip2m5", "Mortum's Keep"}, + {"hip2m6", "The Gremlin's Domain"}, - {"hip3m1", "Tur Torment"}, // 12 - {"hip3m2", "Pandemonium"}, - {"hip3m3", "Limbo"}, - {"hip3m4", "The Gauntlet"}, + {"hip3m1", "Tur Torment"}, // 12 + {"hip3m2", "Pandemonium"}, + {"hip3m3", "Limbo"}, + {"hip3m4", "The Gauntlet"}, - {"hipend", "Armagon's Lair"}, // 16 + {"hipend", "Armagon's Lair"}, // 16 - {"hipdm1", "The Edge of Oblivion"} // 17 + {"hipdm1", "The Edge of Oblivion"} // 17 }; //PGM 01/07/97 added rogue levels @@ -2619,7 +2038,7 @@ level_t roguelevels[] = typedef struct { - char *description; + const char *description; int firstLevel; int levels; } episode_t; @@ -2638,12 +2057,12 @@ episode_t episodes[] = //MED 01/06/97 added hipnotic episodes episode_t hipnoticepisodes[] = { - {"Scourge of Armagon", 0, 1}, - {"Fortress of the Dead", 1, 5}, - {"Dominion of Darkness", 6, 6}, - {"The Rift", 12, 4}, - {"Final Level", 16, 1}, - {"Deathmatch Arena", 17, 1} + {"Scourge of Armagon", 0, 1}, + {"Fortress of the Dead", 1, 5}, + {"Dominion of Darkness", 6, 6}, + {"The Rift", 12, 4}, + {"Final Level", 16, 1}, + {"Deathmatch Arena", 17, 1} }; //PGM 01/07/97 added rogue episodes @@ -2664,6 +2083,7 @@ double m_serverInfoMessageTime; void M_Menu_GameOptions_f (void) { + IN_Deactivate(modestate == MS_WINDOWED); key_dest = key_menu; m_state = m_gameoptions; m_entersound = true; @@ -2702,7 +2122,7 @@ void M_GameOptions_Draw (void) M_Print (0, 72, " Teamplay"); if (rogue) { - char *msg; + const char *msg; switch((int)teamplay.value) { @@ -2718,7 +2138,7 @@ void M_GameOptions_Draw (void) } else { - char *msg; + const char *msg; switch((int)teamplay.value) { @@ -2752,33 +2172,33 @@ void M_GameOptions_Draw (void) M_Print (160, 96, va("%i minutes", (int)timelimit.value)); M_Print (0, 112, " Episode"); - //MED 01/06/97 added hipnotic episodes - if (hipnotic) - M_Print (160, 112, hipnoticepisodes[startepisode].description); - //PGM 01/07/97 added rogue episodes - else if (rogue) - M_Print (160, 112, rogueepisodes[startepisode].description); - else - M_Print (160, 112, episodes[startepisode].description); + // MED 01/06/97 added hipnotic episodes + if (hipnotic) + M_Print (160, 112, hipnoticepisodes[startepisode].description); + // PGM 01/07/97 added rogue episodes + else if (rogue) + M_Print (160, 112, rogueepisodes[startepisode].description); + else + M_Print (160, 112, episodes[startepisode].description); M_Print (0, 120, " Level"); - //MED 01/06/97 added hipnotic episodes - if (hipnotic) - { - M_Print (160, 120, hipnoticlevels[hipnoticepisodes[startepisode].firstLevel + startlevel].description); - M_Print (160, 128, hipnoticlevels[hipnoticepisodes[startepisode].firstLevel + startlevel].name); - } - //PGM 01/07/97 added rogue episodes - else if (rogue) - { - M_Print (160, 120, roguelevels[rogueepisodes[startepisode].firstLevel + startlevel].description); - M_Print (160, 128, roguelevels[rogueepisodes[startepisode].firstLevel + startlevel].name); - } - else - { - M_Print (160, 120, levels[episodes[startepisode].firstLevel + startlevel].description); - M_Print (160, 128, levels[episodes[startepisode].firstLevel + startlevel].name); - } + // MED 01/06/97 added hipnotic episodes + if (hipnotic) + { + M_Print (160, 120, hipnoticlevels[hipnoticepisodes[startepisode].firstLevel + startlevel].description); + M_Print (160, 128, hipnoticlevels[hipnoticepisodes[startepisode].firstLevel + startlevel].name); + } + // PGM 01/07/97 added rogue episodes + else if (rogue) + { + M_Print (160, 120, roguelevels[rogueepisodes[startepisode].firstLevel + startlevel].description); + M_Print (160, 128, roguelevels[rogueepisodes[startepisode].firstLevel + startlevel].name); + } + else + { + M_Print (160, 120, levels[episodes[startepisode].firstLevel + startlevel].description); + M_Print (160, 128, levels[episodes[startepisode].firstLevel + startlevel].name); + } // line cursor M_DrawCharacter (144, gameoptions_cursor_table[gameoptions_cursor], 12+((int)(realtime*4)&1)); @@ -2806,6 +2226,7 @@ void M_GameOptions_Draw (void) void M_NetStart_Change (int dir) { int count; + float f; switch (gameoptions_cursor) { @@ -2822,44 +2243,36 @@ void M_NetStart_Change (int dir) break; case 2: - Cvar_SetValue ("coop", coop.value ? 0 : 1); + Cvar_Set ("coop", coop.value ? "0" : "1"); break; case 3: - if (rogue) - count = 6; - else - count = 2; - - Cvar_SetValue ("teamplay", teamplay.value + dir); - if (teamplay.value > count) - Cvar_SetValue ("teamplay", 0); - else if (teamplay.value < 0) - Cvar_SetValue ("teamplay", count); + count = (rogue) ? 6 : 2; + f = teamplay.value + dir; + if (f > count) f = 0; + else if (f < 0) f = count; + Cvar_SetValue ("teamplay", f); break; case 4: - Cvar_SetValue ("skill", skill.value + dir); - if (skill.value > 3) - Cvar_SetValue ("skill", 0); - if (skill.value < 0) - Cvar_SetValue ("skill", 3); + f = skill.value + dir; + if (f > 3) f = 0; + else if (f < 0) f = 3; + Cvar_SetValue ("skill", f); break; case 5: - Cvar_SetValue ("fraglimit", fraglimit.value + dir*10); - if (fraglimit.value > 100) - Cvar_SetValue ("fraglimit", 0); - if (fraglimit.value < 0) - Cvar_SetValue ("fraglimit", 100); + f = fraglimit.value + dir * 10; + if (f > 100) f = 0; + else if (f < 0) f = 100; + Cvar_SetValue ("fraglimit", f); break; case 6: - Cvar_SetValue ("timelimit", timelimit.value + dir*5); - if (timelimit.value > 60) - Cvar_SetValue ("timelimit", 0); - if (timelimit.value < 0) - Cvar_SetValue ("timelimit", 60); + f = timelimit.value + dir * 5; + if (f > 60) f = 0; + else if (f < 0) f = 60; + Cvar_SetValue ("timelimit", f); break; case 7: @@ -2887,7 +2300,7 @@ void M_NetStart_Change (int dir) case 8: startlevel += dir; - //MED 01/06/97 added hipnotic episodes + //MED 01/06/97 added hipnotic episodes if (hipnotic) count = hipnoticepisodes[startepisode].levels; //PGM 01/06/97 added hipnotic episodes @@ -2910,6 +2323,7 @@ void M_GameOptions_Key (int key) switch (key) { case K_ESCAPE: + case K_BBUTTON: M_Menu_Net_f (); break; @@ -2942,6 +2356,8 @@ void M_GameOptions_Key (int key) break; case K_ENTER: + case K_KP_ENTER: + case K_ABUTTON: S_LocalSound ("misc/menu2.wav"); if (gameoptions_cursor == 0) { @@ -2974,6 +2390,7 @@ double searchCompleteTime; void M_Menu_Search_f (void) { + IN_Deactivate(modestate == MS_WINDOWED); key_dest = key_menu; m_state = m_search; m_entersound = false; @@ -3034,6 +2451,7 @@ qboolean slist_sorted; void M_Menu_ServerList_f (void) { + IN_Deactivate(modestate == MS_WINDOWED); key_dest = key_menu; m_state = m_slist; m_entersound = true; @@ -3046,38 +2464,19 @@ void M_Menu_ServerList_f (void) void M_ServerList_Draw (void) { - int n; - char string [64]; + int n; qpic_t *p; if (!slist_sorted) { - if (hostCacheCount > 1) - { - int i,j; - hostcache_t temp; - for (i = 0; i < hostCacheCount; i++) - for (j = i+1; j < hostCacheCount; j++) - if (strcmp(hostcache[j].name, hostcache[i].name) < 0) - { - Q_memcpy(&temp, &hostcache[j], sizeof(hostcache_t)); - Q_memcpy(&hostcache[j], &hostcache[i], sizeof(hostcache_t)); - Q_memcpy(&hostcache[i], &temp, sizeof(hostcache_t)); - } - } slist_sorted = true; + NET_SlistSort (); } p = Draw_CachePic ("gfx/p_multi.lmp"); M_DrawPic ( (320-p->width)/2, 4, p); for (n = 0; n < hostCacheCount; n++) - { - if (hostcache[n].maxusers) - sprintf(string, "%-15.15s %-15.15s %2u/%2u\n", hostcache[n].name, hostcache[n].map, hostcache[n].users, hostcache[n].maxusers); - else - sprintf(string, "%-15.15s %-15.15s\n", hostcache[n].name, hostcache[n].map); - M_Print (16, 32 + 8*n, string); - } + M_Print (16, 32 + 8*n, NET_SlistPrintServer (n)); M_DrawCharacter (0, 32 + slist_cursor*8, 12+((int)(realtime*4)&1)); if (*m_return_reason) @@ -3090,6 +2489,7 @@ void M_ServerList_Key (int k) switch (k) { case K_ESCAPE: + case K_BBUTTON: M_Menu_LanConfig_f (); break; @@ -3114,13 +2514,16 @@ void M_ServerList_Key (int k) break; case K_ENTER: + case K_KP_ENTER: + case K_ABUTTON: S_LocalSound ("misc/menu2.wav"); m_return_state = m_state; m_return_onerror = true; slist_sorted = false; + IN_Activate(); key_dest = key_game; m_state = m_none; - Cbuf_AddText ( va ("connect \"%s\"\n", hostcache[slist_cursor].cname) ); + Cbuf_AddText ( va ("connect \"%s\"\n", NET_SlistPrintServerName(slist_cursor)) ); break; default: @@ -3158,25 +2561,21 @@ void M_Draw (void) if (!m_recursiveDraw) { - scr_copyeverything = 1; - if (scr_con_current) { - Draw_ConsoleBackground (vid.height); - VID_UnlockBuffer (); + Draw_ConsoleBackground (); S_ExtraUpdate (); - VID_LockBuffer (); } - else - Draw_FadeScreen (); - scr_fullupdate = 0; + Draw_FadeScreen (); //johnfitz -- fade even if console fills screen } else { m_recursiveDraw = false; } + GL_SetCanvas (CANVAS_MENU); //johnfitz + switch (m_state) { case m_none: @@ -3227,17 +2626,15 @@ void M_Draw (void) break; case m_quit: + if (!fitzmode) + { /* QuakeSpasm customization: */ + /* Quit now! S.A. */ + key_dest = key_console; + Host_Quit_f (); + } M_Quit_Draw (); break; - case m_serialconfig: - M_SerialConfig_Draw (); - break; - - case m_modemconfig: - M_ModemConfig_Draw (); - break; - case m_lanconfig: M_LanConfig_Draw (); break; @@ -3261,9 +2658,7 @@ void M_Draw (void) m_entersound = false; } - VID_UnlockBuffer (); S_ExtraUpdate (); - VID_LockBuffer (); } @@ -3322,14 +2717,6 @@ void M_Keydown (int key) M_Quit_Key (key); return; - case m_serialconfig: - M_SerialConfig_Key (key); - return; - - case m_modemconfig: - M_ModemConfig_Key (key); - return; - case m_lanconfig: M_LanConfig_Key (key); return; @@ -3349,16 +2736,47 @@ void M_Keydown (int key) } -void M_ConfigureNetSubsystem(void) +void M_Charinput (int key) { -// enable/disable net systems to match desired config + switch (m_state) + { + case m_setup: + M_Setup_Char (key); + return; + case m_quit: + M_Quit_Char (key); + return; + case m_lanconfig: + M_LanConfig_Char (key); + return; + default: + return; + } +} - Cbuf_AddText ("stopdemo\n"); - if (SerialConfig || DirectConfig) + +qboolean M_TextEntry (void) +{ + switch (m_state) { - Cbuf_AddText ("com1 enable\n"); + case m_setup: + return M_Setup_TextEntry (); + case m_quit: + return M_Quit_TextEntry (); + case m_lanconfig: + return M_LanConfig_TextEntry (); + default: + return false; } +} + + +void M_ConfigureNetSubsystem(void) +{ +// enable/disable net systems to match desired config + Cbuf_AddText ("stopdemo\n"); if (IPXConfig || TCPIPConfig) net_hostport = lanConfig_port; } + diff --git a/engine/Quake/menu.h b/engine/Quake/menu.h new file mode 100644 index 0000000..6e2c9ef --- /dev/null +++ b/engine/Quake/menu.h @@ -0,0 +1,75 @@ +/* +Copyright (C) 1996-2001 Id Software, Inc. +Copyright (C) 2002-2009 John Fitzgibbons and others +Copyright (C) 2010-2014 QuakeSpasm developers + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#ifndef _QUAKE_MENU_H +#define _QUAKE_MENU_H + +enum m_state_e { + m_none, + m_main, + m_singleplayer, + m_load, + m_save, + m_multiplayer, + m_setup, + m_net, + m_options, + m_video, + m_keys, + m_help, + m_quit, + m_lanconfig, + m_gameoptions, + m_search, + m_slist +}; + +extern enum m_state_e m_state; +extern enum m_state_e m_return_state; + +extern qboolean m_entersound; + +// +// menus +// +void M_Init (void); +void M_Keydown (int key); +void M_Charinput (int key); +qboolean M_TextEntry (void); +void M_ToggleMenu_f (void); + +void M_Menu_Main_f (void); +void M_Menu_Options_f (void); +void M_Menu_Quit_f (void); + +void M_Print (int cx, int cy, const char *str); +void M_PrintWhite (int cx, int cy, const char *str); + +void M_Draw (void); +void M_DrawCharacter (int cx, int line, int num); + +void M_DrawPic (int x, int y, qpic_t *pic); +void M_DrawTransPic (int x, int y, qpic_t *pic); +void M_DrawCheckbox (int x, int y, int on); + +#endif /* _QUAKE_MENU_H */ + diff --git a/engine/code/modelgen.h b/engine/Quake/modelgen.h similarity index 93% rename from engine/code/modelgen.h rename to engine/Quake/modelgen.h index be9ad92..92dbcf4 100644 --- a/engine/code/modelgen.h +++ b/engine/Quake/modelgen.h @@ -1,5 +1,6 @@ /* -Copyright (C) 1996-1997 Id Software, Inc. +Copyright (C) 1996-2001 Id Software, Inc. +Copyright (C) 2002-2009 John Fitzgibbons and others This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -8,7 +9,7 @@ of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. @@ -17,6 +18,10 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +#ifndef _MODELGEN_H +#define _MODELGEN_H + // // modelgen.h: header file for model generation program // @@ -132,3 +137,5 @@ typedef struct { #define IDPOLYHEADER (('O'<<24)+('P'<<16)+('D'<<8)+'I') // little-endian "IDPO" +#endif /* _MODELGEN_H */ + diff --git a/engine/Quake/net.h b/engine/Quake/net.h new file mode 100644 index 0000000..a078490 --- /dev/null +++ b/engine/Quake/net.h @@ -0,0 +1,115 @@ +/* +Copyright (C) 1996-2001 Id Software, Inc. +Copyright (C) 2002-2009 John Fitzgibbons and others +Copyright (C) 2009-2010 Ozkan Sezer +Copyright (C) 2010-2014 QuakeSpasm developers + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +/* + net.h + quake's interface to the networking layer + network functions and data, common to the + whole engine +*/ + +#ifndef _QUAKE_NET_H +#define _QUAKE_NET_H + + +#define NET_NAMELEN 64 + +#define NET_MAXMESSAGE 64000 /* ericw -- was 32000 */ + +extern int DEFAULTnet_hostport; +extern int net_hostport; + +extern cvar_t hostname; + +extern double net_time; +extern sizebuf_t net_message; +extern int net_activeconnections; + + +void NET_Init (void); +void NET_Shutdown (void); + +struct qsocket_s *NET_CheckNewConnections (void); +// returns a new connection number if there is one pending, else -1 + +struct qsocket_s *NET_Connect (const char *host); +// called by client to connect to a host. Returns -1 if not able to + +double NET_QSocketGetTime (const struct qsocket_s *sock); +const char *NET_QSocketGetAddressString (const struct qsocket_s *sock); + +qboolean NET_CanSendMessage (struct qsocket_s *sock); +// Returns true or false if the given qsocket can currently accept a +// message to be transmitted. + +int NET_GetMessage (struct qsocket_s *sock); +// returns data in net_message sizebuf +// returns 0 if no data is waiting +// returns 1 if a message was received +// returns 2 if an unreliable message was received +// returns -1 if the connection died + +int NET_SendMessage (struct qsocket_s *sock, sizebuf_t *data); +int NET_SendUnreliableMessage (struct qsocket_s *sock, sizebuf_t *data); +// returns 0 if the message connot be delivered reliably, but the connection +// is still considered valid +// returns 1 if the message was sent properly +// returns -1 if the connection died + +int NET_SendToAll(sizebuf_t *data, double blocktime); +// This is a reliable *blocking* send to all attached clients. + +void NET_Close (struct qsocket_s *sock); +// if a dead connection is returned by a get or send function, this function +// should be called when it is convenient + +// Server calls when a client is kicked off for a game related misbehavior +// like an illegal protocal conversation. Client calls when disconnecting +// from a server. +// A netcon_t number will not be reused until this function is called for it + +void NET_Poll (void); + + +// Server list related globals: +extern qboolean slistInProgress; +extern qboolean slistSilent; +extern qboolean slistLocal; + +extern int hostCacheCount; + +void NET_Slist_f (void); +void NET_SlistSort (void); +const char *NET_SlistPrintServer (int n); +const char *NET_SlistPrintServerName (int n); + + +/* FIXME: driver related, but public: + */ +extern qboolean ipxAvailable; +extern qboolean tcpipAvailable; +extern char my_ipx_address[NET_NAMELEN]; +extern char my_tcpip_address[NET_NAMELEN]; + +#endif /* _QUAKE_NET_H */ + diff --git a/engine/Quake/net_bsd.c b/engine/Quake/net_bsd.c new file mode 100644 index 0000000..59487e7 --- /dev/null +++ b/engine/Quake/net_bsd.c @@ -0,0 +1,97 @@ +/* +Copyright (C) 1996-1997 Id Software, Inc. +Copyright (C) 2010-2014 QuakeSpasm developers + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#include "q_stdinc.h" +#include "arch_def.h" +#include "net_sys.h" +#include "quakedef.h" +#include "net_defs.h" + +#include "net_dgrm.h" +#include "net_loop.h" + +net_driver_t net_drivers[] = +{ + { "Loopback", + false, + Loop_Init, + Loop_Listen, + Loop_SearchForHosts, + Loop_Connect, + Loop_CheckNewConnections, + Loop_GetMessage, + Loop_SendMessage, + Loop_SendUnreliableMessage, + Loop_CanSendMessage, + Loop_CanSendUnreliableMessage, + Loop_Close, + Loop_Shutdown + }, + + { "Datagram", + false, + Datagram_Init, + Datagram_Listen, + Datagram_SearchForHosts, + Datagram_Connect, + Datagram_CheckNewConnections, + Datagram_GetMessage, + Datagram_SendMessage, + Datagram_SendUnreliableMessage, + Datagram_CanSendMessage, + Datagram_CanSendUnreliableMessage, + Datagram_Close, + Datagram_Shutdown + } +}; + +const int net_numdrivers = (sizeof(net_drivers) / sizeof(net_drivers[0])); + +#include "net_udp.h" + +net_landriver_t net_landrivers[] = +{ + { "UDP", + false, + 0, + UDP_Init, + UDP_Shutdown, + UDP_Listen, + UDP_OpenSocket, + UDP_CloseSocket, + UDP_Connect, + UDP_CheckNewConnections, + UDP_Read, + UDP_Write, + UDP_Broadcast, + UDP_AddrToString, + UDP_StringToAddr, + UDP_GetSocketAddr, + UDP_GetNameFromAddr, + UDP_GetAddrFromName, + UDP_AddrCompare, + UDP_GetSocketPort, + UDP_SetSocketPort + } +}; + +const int net_numlandrivers = (sizeof(net_landrivers) / sizeof(net_landrivers[0])); + diff --git a/engine/Quake/net_defs.h b/engine/Quake/net_defs.h new file mode 100644 index 0000000..424b85d --- /dev/null +++ b/engine/Quake/net_defs.h @@ -0,0 +1,260 @@ +/* + * net_defs.h -- functions and data private to the network layer + * net_sys.h and its dependencies must be included before net_defs.h. + * + * Copyright (C) 1996-1997 Id Software, Inc. + * Copyright (C) 2005-2012 O.Sezer + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef __NET_DEFS_H +#define __NET_DEFS_H + +struct qsockaddr +{ +#if defined(HAVE_SA_LEN) + unsigned char qsa_len; + unsigned char qsa_family; +#else + short qsa_family; +#endif /* BSD, sockaddr */ + unsigned char qsa_data[14]; +}; + +#define NET_HEADERSIZE (2 * sizeof(unsigned int)) +#define NET_DATAGRAMSIZE (MAX_DATAGRAM + NET_HEADERSIZE) + +// NetHeader flags +#define NETFLAG_LENGTH_MASK 0x0000ffff +#define NETFLAG_DATA 0x00010000 +#define NETFLAG_ACK 0x00020000 +#define NETFLAG_NAK 0x00040000 +#define NETFLAG_EOM 0x00080000 +#define NETFLAG_UNRELIABLE 0x00100000 +#define NETFLAG_CTL 0x80000000 + +#if (NETFLAG_LENGTH_MASK & NET_MAXMESSAGE) != NET_MAXMESSAGE +#error "NET_MAXMESSAGE must fit within NETFLAG_LENGTH_MASK" +#endif + +#define NET_PROTOCOL_VERSION 3 + +/** + +This is the network info/connection protocol. It is used to find Quake +servers, get info about them, and connect to them. Once connected, the +Quake game protocol (documented elsewhere) is used. + + +General notes: + game_name is currently always "QUAKE", but is there so this same protocol + can be used for future games as well; can you say Quake2? + +CCREQ_CONNECT + string game_name "QUAKE" + byte net_protocol_version NET_PROTOCOL_VERSION + +CCREQ_SERVER_INFO + string game_name "QUAKE" + byte net_protocol_version NET_PROTOCOL_VERSION + +CCREQ_PLAYER_INFO + byte player_number + +CCREQ_RULE_INFO + string rule + +CCREP_ACCEPT + long port + +CCREP_REJECT + string reason + +CCREP_SERVER_INFO + string server_address + string host_name + string level_name + byte current_players + byte max_players + byte protocol_version NET_PROTOCOL_VERSION + +CCREP_PLAYER_INFO + byte player_number + string name + long colors + long frags + long connect_time + string address + +CCREP_RULE_INFO + string rule + string value + + note: + There are two address forms used above. The short form is just a + port number. The address that goes along with the port is defined as + "whatever address you receive this reponse from". This lets us use + the host OS to solve the problem of multiple host addresses (possibly + with no routing between them); the host will use the right address + when we reply to the inbound connection request. The long from is + a full address and port in a string. It is used for returning the + address of a server that is not running locally. + +**/ + +#define CCREQ_CONNECT 0x01 +#define CCREQ_SERVER_INFO 0x02 +#define CCREQ_PLAYER_INFO 0x03 +#define CCREQ_RULE_INFO 0x04 + +#define CCREP_ACCEPT 0x81 +#define CCREP_REJECT 0x82 +#define CCREP_SERVER_INFO 0x83 +#define CCREP_PLAYER_INFO 0x84 +#define CCREP_RULE_INFO 0x85 + +typedef struct qsocket_s +{ + struct qsocket_s *next; + double connecttime; + double lastMessageTime; + double lastSendTime; + + qboolean disconnected; + qboolean canSend; + qboolean sendNext; + + int driver; + int landriver; + sys_socket_t socket; + void *driverdata; + + unsigned int ackSequence; + unsigned int sendSequence; + unsigned int unreliableSendSequence; + int sendMessageLength; + byte sendMessage [NET_MAXMESSAGE]; + + unsigned int receiveSequence; + unsigned int unreliableReceiveSequence; + int receiveMessageLength; + byte receiveMessage [NET_MAXMESSAGE]; + + struct qsockaddr addr; + char address[NET_NAMELEN]; + +} qsocket_t; + +extern qsocket_t *net_activeSockets; +extern qsocket_t *net_freeSockets; +extern int net_numsockets; + +typedef struct +{ + const char *name; + qboolean initialized; + sys_socket_t controlSock; + sys_socket_t (*Init) (void); + void (*Shutdown) (void); + void (*Listen) (qboolean state); + sys_socket_t (*Open_Socket) (int port); + int (*Close_Socket) (sys_socket_t socketid); + int (*Connect) (sys_socket_t socketid, struct qsockaddr *addr); + sys_socket_t (*CheckNewConnections) (void); + int (*Read) (sys_socket_t socketid, byte *buf, int len, struct qsockaddr *addr); + int (*Write) (sys_socket_t socketid, byte *buf, int len, struct qsockaddr *addr); + int (*Broadcast) (sys_socket_t socketid, byte *buf, int len); + const char * (*AddrToString) (struct qsockaddr *addr); + int (*StringToAddr) (const char *string, struct qsockaddr *addr); + int (*GetSocketAddr) (sys_socket_t socketid, struct qsockaddr *addr); + int (*GetNameFromAddr) (struct qsockaddr *addr, char *name); + int (*GetAddrFromName) (const char *name, struct qsockaddr *addr); + int (*AddrCompare) (struct qsockaddr *addr1, struct qsockaddr *addr2); + int (*GetSocketPort) (struct qsockaddr *addr); + int (*SetSocketPort) (struct qsockaddr *addr, int port); +} net_landriver_t; + +#define MAX_NET_DRIVERS 8 +extern net_landriver_t net_landrivers[]; +extern const int net_numlandrivers; + +typedef struct +{ + const char *name; + qboolean initialized; + int (*Init) (void); + void (*Listen) (qboolean state); + void (*SearchForHosts) (qboolean xmit); + qsocket_t *(*Connect) (const char *host); + qsocket_t *(*CheckNewConnections) (void); + int (*QGetMessage) (qsocket_t *sock); + int (*QSendMessage) (qsocket_t *sock, sizebuf_t *data); + int (*SendUnreliableMessage) (qsocket_t *sock, sizebuf_t *data); + qboolean (*CanSendMessage) (qsocket_t *sock); + qboolean (*CanSendUnreliableMessage) (qsocket_t *sock); + void (*Close) (qsocket_t *sock); + void (*Shutdown) (void); +} net_driver_t; + +extern net_driver_t net_drivers[]; +extern const int net_numdrivers; + +/* Loop driver must always be registered the first */ +#define IS_LOOP_DRIVER(p) ((p) == 0) + +extern int net_driverlevel; + +extern int messagesSent; +extern int messagesReceived; +extern int unreliableMessagesSent; +extern int unreliableMessagesReceived; + +qsocket_t *NET_NewQSocket (void); +void NET_FreeQSocket(qsocket_t *); +double SetNetTime(void); + + +#define HOSTCACHESIZE 8 + +typedef struct +{ + char name[16]; + char map[16]; + char cname[32]; + int users; + int maxusers; + int driver; + int ldriver; + struct qsockaddr addr; +} hostcache_t; + +extern int hostCacheCount; +extern hostcache_t hostcache[HOSTCACHESIZE]; + + +typedef struct _PollProcedure +{ + struct _PollProcedure *next; + double nextTime; + void (*procedure)(void *); + void *arg; +} PollProcedure; + +void SchedulePollProcedure(PollProcedure *pp, double timeOffset); + +#endif /* __NET_DEFS_H */ + diff --git a/engine/code/net_dgrm.c b/engine/Quake/net_dgrm.c similarity index 82% rename from engine/code/net_dgrm.c rename to engine/Quake/net_dgrm.c index a293b77..4a4b4f7 100644 --- a/engine/code/net_dgrm.c +++ b/engine/Quake/net_dgrm.c @@ -1,5 +1,6 @@ /* -Copyright (C) 1996-1997 Id Software, Inc. +Copyright (C) 1996-2001 Id Software, Inc. +Copyright (C) 2010-2014 QuakeSpasm developers This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -8,7 +9,7 @@ of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. @@ -17,42 +18,15 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -// net_dgrm.c // This is enables a simple IP banning mechanism #define BAN_TEST -#ifdef BAN_TEST -#if defined(_WIN32) -#include -#elif defined (NeXT) -#include -#include -#else -#define AF_INET 2 /* internet */ -struct in_addr -{ - union - { - struct { unsigned char s_b1,s_b2,s_b3,s_b4; } S_un_b; - struct { unsigned short s_w1,s_w2; } S_un_w; - unsigned long S_addr; - } S_un; -}; -#define s_addr S_un.S_addr /* can be used for most tcp & ip code */ -struct sockaddr_in -{ - short sin_family; - unsigned short sin_port; - struct in_addr sin_addr; - char sin_zero[8]; -}; -char *inet_ntoa(struct in_addr in); -unsigned long inet_addr(const char *cp); -#endif -#endif // BAN_TEST - +#include "q_stdinc.h" +#include "arch_def.h" +#include "net_sys.h" #include "quakedef.h" +#include "net_defs.h" #include "net_dgrm.h" // these two macros are to make the code more readable @@ -62,30 +36,27 @@ unsigned long inet_addr(const char *cp); static int net_landriverlevel; /* statistic counters */ -int packetsSent = 0; -int packetsReSent = 0; -int packetsReceived = 0; -int receivedDuplicateCount = 0; -int shortPacketCount = 0; -int droppedDatagrams; - -static int myDriverLevel; - -struct +static int packetsSent = 0; +static int packetsReSent = 0; +static int packetsReceived = 0; +static int receivedDuplicateCount = 0; +static int shortPacketCount = 0; +static int droppedDatagrams; + +static struct { unsigned int length; unsigned int sequence; - byte data[MAX_DATAGRAM]; + byte data[MAX_DATAGRAM]; } packetBuffer; -extern int m_return_state; -extern int m_state; +static int myDriverLevel; + extern qboolean m_return_onerror; extern char m_return_reason[32]; -#ifdef DEBUG -char *StrAddr (struct qsockaddr *addr) +static char *StrAddr (struct qsockaddr *addr) { static char buf[34]; byte *p = (byte *)addr; @@ -95,18 +66,18 @@ char *StrAddr (struct qsockaddr *addr) sprintf (buf + n * 2, "%02x", *p++); return buf; } -#endif #ifdef BAN_TEST -unsigned long banAddr = 0x00000000; -unsigned long banMask = 0xffffffff; -void NET_Ban_f (void) +static struct in_addr banAddr; +static struct in_addr banMask; + +static void NET_Ban_f (void) { char addrStr [32]; char maskStr [32]; - void (*print) (char *fmt, ...); + void (*print_fn)(const char *fmt, ...) FUNCP_PRINTF(1,2); if (cmd_source == src_command) { @@ -115,47 +86,47 @@ void NET_Ban_f (void) Cmd_ForwardToServer (); return; } - print = Con_Printf; + print_fn = Con_Printf; } else { - if (pr_global_struct->deathmatch && !host_client->privileged) + if (pr_global_struct->deathmatch) return; - print = SV_ClientPrintf; + print_fn = SV_ClientPrintf; } switch (Cmd_Argc ()) { - case 1: - if (((struct in_addr *)&banAddr)->s_addr) - { - Q_strcpy(addrStr, inet_ntoa(*(struct in_addr *)&banAddr)); - Q_strcpy(maskStr, inet_ntoa(*(struct in_addr *)&banMask)); - print("Banning %s [%s]\n", addrStr, maskStr); - } - else - print("Banning not active\n"); - break; - - case 2: - if (Q_strcasecmp(Cmd_Argv(1), "off") == 0) - banAddr = 0x00000000; - else - banAddr = inet_addr(Cmd_Argv(1)); - banMask = 0xffffffff; - break; - - case 3: - banAddr = inet_addr(Cmd_Argv(1)); - banMask = inet_addr(Cmd_Argv(2)); - break; + case 1: + if (banAddr.s_addr != INADDR_ANY) + { + Q_strcpy(addrStr, inet_ntoa(banAddr)); + Q_strcpy(maskStr, inet_ntoa(banMask)); + print_fn("Banning %s [%s]\n", addrStr, maskStr); + } + else + print_fn("Banning not active\n"); + break; - default: - print("BAN ip_address [mask]\n"); - break; + case 2: + if (q_strcasecmp(Cmd_Argv(1), "off") == 0) + banAddr.s_addr = INADDR_ANY; + else + banAddr.s_addr = inet_addr(Cmd_Argv(1)); + banMask.s_addr = INADDR_NONE; + break; + + case 3: + banAddr.s_addr = inet_addr(Cmd_Argv(1)); + banMask.s_addr = inet_addr(Cmd_Argv(2)); + break; + + default: + print_fn("BAN ip_address [mask]\n"); + break; } } -#endif +#endif // BAN_TEST int Datagram_SendMessage (qsocket_t *sock, sizebuf_t *data) @@ -205,7 +176,7 @@ int Datagram_SendMessage (qsocket_t *sock, sizebuf_t *data) } -int SendMessageNext (qsocket_t *sock) +static int SendMessageNext (qsocket_t *sock) { unsigned int packetLen; unsigned int dataLen; @@ -238,7 +209,7 @@ int SendMessageNext (qsocket_t *sock) } -int ReSendMessage (qsocket_t *sock) +static int ReSendMessage (qsocket_t *sock) { unsigned int packetLen; unsigned int dataLen; @@ -288,7 +259,7 @@ qboolean Datagram_CanSendUnreliableMessage (qsocket_t *sock) int Datagram_SendUnreliableMessage (qsocket_t *sock, sizebuf_t *data) { - int packetLen; + int packetLen; #ifdef DEBUG if (data->cursize == 0) @@ -325,17 +296,18 @@ int Datagram_GetMessage (qsocket_t *sock) if ((net_time - sock->lastSendTime) > 1.0) ReSendMessage (sock); - while(1) - { - length = sfunc.Read (sock->socket, (byte *)&packetBuffer, NET_DATAGRAMSIZE, &readaddr); + while (1) + { + length = (unsigned int) sfunc.Read(sock->socket, (byte *)&packetBuffer, + NET_DATAGRAMSIZE, &readaddr); -// if ((rand() & 255) > 220) -// continue; + // if ((rand() & 255) > 220) + // continue; if (length == 0) break; - if (length == -1) + if (length == (unsigned int)-1) { Con_Printf("Read error\n"); return -1; @@ -343,11 +315,9 @@ int Datagram_GetMessage (qsocket_t *sock) if (sfunc.AddrCompare(&readaddr, &sock->addr) != 0) { -#ifdef DEBUG - Con_DPrintf("Forged packet received\n"); - Con_DPrintf("Expected: %s\n", StrAddr (&sock->addr)); - Con_DPrintf("Received: %s\n", StrAddr (&readaddr)); -#endif + Con_Printf("Forged packet received\n"); + Con_Printf("Expected: %s\n", StrAddr (&sock->addr)); + Con_Printf("Received: %s\n", StrAddr (&readaddr)); continue; } @@ -413,7 +383,7 @@ int Datagram_GetMessage (qsocket_t *sock) sock->sendMessageLength -= MAX_DATAGRAM; if (sock->sendMessageLength > 0) { - Q_memcpy(sock->sendMessage, sock->sendMessage+MAX_DATAGRAM, sock->sendMessageLength); + memmove (sock->sendMessage, sock->sendMessage + MAX_DATAGRAM, sock->sendMessageLength); sock->sendNext = true; } else @@ -463,7 +433,7 @@ int Datagram_GetMessage (qsocket_t *sock) } -void PrintStats(qsocket_t *s) +static void PrintStats(qsocket_t *s) { Con_Printf("canSend = %4u \n", s->canSend); Con_Printf("sendSeq = %4u ", s->sendSequence); @@ -471,7 +441,7 @@ void PrintStats(qsocket_t *s) Con_Printf("\n"); } -void NET_Stats_f (void) +static void NET_Stats_f (void) { qsocket_t *s; @@ -498,28 +468,61 @@ void NET_Stats_f (void) else { for (s = net_activeSockets; s; s = s->next) - if (Q_strcasecmp(Cmd_Argv(1), s->address) == 0) + { + if (q_strcasecmp(Cmd_Argv(1), s->address) == 0) break; + } + if (s == NULL) + { for (s = net_freeSockets; s; s = s->next) - if (Q_strcasecmp(Cmd_Argv(1), s->address) == 0) + { + if (q_strcasecmp(Cmd_Argv(1), s->address) == 0) break; + } + } + if (s == NULL) return; + PrintStats(s); } } +// recognize ip:port (based on ProQuake) +static const char *Strip_Port (const char *host) +{ + static char noport[MAX_QPATH]; + /* array size as in Host_Connect_f() */ + char *p; + int port; + + if (!host || !*host) + return host; + q_strlcpy (noport, host, sizeof(noport)); + if ((p = Q_strrchr(noport, ':')) == NULL) + return host; + *p++ = '\0'; + port = Q_atoi (p); + if (port > 0 && port < 65536 && port != net_hostport) + { + net_hostport = port; + Con_Printf("Port set to %d\n", net_hostport); + } + return noport; +} + + static qboolean testInProgress = false; static int testPollCount; static int testDriver; -static int testSocket; +static sys_socket_t testSocket; -static void Test_Poll(void); -PollProcedure testPollProcedure = {NULL, 0.0, Test_Poll}; +static void Test_Poll (void *); +static PollProcedure testPollProcedure = {NULL, 0.0, Test_Poll}; -static void Test_Poll(void) +static void Test_Poll (void *unused) { struct qsockaddr clientaddr; int control; @@ -529,14 +532,13 @@ static void Test_Poll(void) int colors; int frags; int connectTime; - byte playerNumber; net_landriverlevel = testDriver; while (1) { len = dfunc.Read (testSocket, net_message.data, net_message.maxsize, &clientaddr); - if (len < sizeof(int)) + if (len < (int) sizeof(int)) break; net_message.cursize = len; @@ -546,7 +548,7 @@ static void Test_Poll(void) MSG_ReadLong(); if (control == -1) break; - if ((control & (~NETFLAG_LENGTH_MASK)) != NETFLAG_CTL) + if ((control & (~NETFLAG_LENGTH_MASK)) != (int)NETFLAG_CTL) break; if ((control & NETFLAG_LENGTH_MASK) != len) break; @@ -554,14 +556,14 @@ static void Test_Poll(void) if (MSG_ReadByte() != CCREP_PLAYER_INFO) Sys_Error("Unexpected repsonse to Player Info request\n"); - playerNumber = MSG_ReadByte(); + MSG_ReadByte(); /* playerNumber */ Q_strcpy(name, MSG_ReadString()); colors = MSG_ReadLong(); frags = MSG_ReadLong(); connectTime = MSG_ReadLong(); Q_strcpy(address, MSG_ReadString()); - Con_Printf("%s\n frags:%3i colors:%u %u time:%u\n %s\n", name, frags, colors >> 4, colors & 0x0f, connectTime / 60, address); + Con_Printf("%s\n frags:%3i colors:%d %d time:%d\n %s\n", name, frags, colors >> 4, colors & 0x0f, connectTime / 60, address); } testPollCount--; @@ -571,35 +573,37 @@ static void Test_Poll(void) } else { - dfunc.CloseSocket(testSocket); + dfunc.Close_Socket(testSocket); testInProgress = false; } } static void Test_f (void) { - char *host; + const char *host; int n; - int max = MAX_SCOREBOARD; + int maxusers = MAX_SCOREBOARD; struct qsockaddr sendaddr; if (testInProgress) return; - host = Cmd_Argv (1); + host = Strip_Port (Cmd_Argv(1)); if (host && hostCacheCount) { for (n = 0; n < hostCacheCount; n++) - if (Q_strcasecmp (host, hostcache[n].name) == 0) + { + if (q_strcasecmp (host, hostcache[n].name) == 0) { if (hostcache[n].driver != myDriverLevel) continue; net_landriverlevel = hostcache[n].ldriver; - max = hostcache[n].maxusers; + maxusers = hostcache[n].maxusers; Q_memcpy(&sendaddr, &hostcache[n].addr, sizeof(struct qsockaddr)); break; } + } if (n < hostCacheCount) goto JustDoIt; } @@ -613,26 +617,30 @@ static void Test_f (void) if (dfunc.GetAddrFromName(host, &sendaddr) != -1) break; } + if (net_landriverlevel == net_numlandrivers) + { + Con_Printf("Could not resolve %s\n", host); return; + } JustDoIt: - testSocket = dfunc.OpenSocket(0); - if (testSocket == -1) + testSocket = dfunc.Open_Socket(0); + if (testSocket == INVALID_SOCKET) return; testInProgress = true; testPollCount = 20; testDriver = net_landriverlevel; - for (n = 0; n < max; n++) + for (n = 0; n < maxusers; n++) { SZ_Clear(&net_message); // save space for the header, filled in later MSG_WriteLong(&net_message, 0); MSG_WriteByte(&net_message, CCREQ_PLAYER_INFO); MSG_WriteByte(&net_message, n); - *((int *)net_message.data) = BigLong(NETFLAG_CTL | (net_message.cursize & NETFLAG_LENGTH_MASK)); + *((int *)net_message.data) = BigLong(NETFLAG_CTL | (net_message.cursize & NETFLAG_LENGTH_MASK)); dfunc.Write (testSocket, net_message.data, net_message.cursize, &sendaddr); } SZ_Clear(&net_message); @@ -642,12 +650,12 @@ JustDoIt: static qboolean test2InProgress = false; static int test2Driver; -static int test2Socket; +static sys_socket_t test2Socket; -static void Test2_Poll(void); -PollProcedure test2PollProcedure = {NULL, 0.0, Test2_Poll}; +static void Test2_Poll (void *); +static PollProcedure test2PollProcedure = {NULL, 0.0, Test2_Poll}; -static void Test2_Poll(void) +static void Test2_Poll (void *unused) { struct qsockaddr clientaddr; int control; @@ -659,7 +667,7 @@ static void Test2_Poll(void) name[0] = 0; len = dfunc.Read (test2Socket, net_message.data, net_message.maxsize, &clientaddr); - if (len < sizeof(int)) + if (len < (int) sizeof(int)) goto Reschedule; net_message.cursize = len; @@ -669,7 +677,7 @@ static void Test2_Poll(void) MSG_ReadLong(); if (control == -1) goto Error; - if ((control & (~NETFLAG_LENGTH_MASK)) != NETFLAG_CTL) + if ((control & (~NETFLAG_LENGTH_MASK)) != (int)NETFLAG_CTL) goto Error; if ((control & NETFLAG_LENGTH_MASK) != len) goto Error; @@ -700,26 +708,27 @@ Reschedule: Error: Con_Printf("Unexpected repsonse to Rule Info request\n"); Done: - dfunc.CloseSocket(test2Socket); + dfunc.Close_Socket(test2Socket); test2InProgress = false; return; } static void Test2_f (void) { - char *host; + const char *host; int n; struct qsockaddr sendaddr; if (test2InProgress) return; - host = Cmd_Argv (1); + host = Strip_Port (Cmd_Argv(1)); if (host && hostCacheCount) { for (n = 0; n < hostCacheCount; n++) - if (Q_strcasecmp (host, hostcache[n].name) == 0) + { + if (q_strcasecmp (host, hostcache[n].name) == 0) { if (hostcache[n].driver != myDriverLevel) continue; @@ -727,6 +736,8 @@ static void Test2_f (void) Q_memcpy(&sendaddr, &hostcache[n].addr, sizeof(struct qsockaddr)); break; } + } + if (n < hostCacheCount) goto JustDoIt; } @@ -740,12 +751,16 @@ static void Test2_f (void) if (dfunc.GetAddrFromName(host, &sendaddr) != -1) break; } + if (net_landriverlevel == net_numlandrivers) + { + Con_Printf("Could not resolve %s\n", host); return; + } JustDoIt: - test2Socket = dfunc.OpenSocket(0); - if (test2Socket == -1) + test2Socket = dfunc.Open_Socket(0); + if (test2Socket == INVALID_SOCKET) return; test2InProgress = true; @@ -765,23 +780,33 @@ JustDoIt: int Datagram_Init (void) { - int i; - int csock; + int i, num_inited; + sys_socket_t csock; +#ifdef BAN_TEST + banAddr.s_addr = INADDR_ANY; + banMask.s_addr = INADDR_NONE; +#endif myDriverLevel = net_driverlevel; + Cmd_AddCommand ("net_stats", NET_Stats_f); - if (COM_CheckParm("-nolan")) + if (safemode || COM_CheckParm("-nolan")) return -1; + num_inited = 0; for (i = 0; i < net_numlandrivers; i++) - { + { csock = net_landrivers[i].Init (); - if (csock == -1) + if (csock == INVALID_SOCKET) continue; net_landrivers[i].initialized = true; net_landrivers[i].controlSock = csock; - } + num_inited++; + } + + if (num_inited == 0) + return -1; #ifdef BAN_TEST Cmd_AddCommand ("ban", NET_Ban_f); @@ -813,7 +838,7 @@ void Datagram_Shutdown (void) void Datagram_Close (qsocket_t *sock) { - sfunc.CloseSocket(sock->socket); + sfunc.Close_Socket(sock->socket); } @@ -822,8 +847,10 @@ void Datagram_Listen (qboolean state) int i; for (i = 0; i < net_numlandrivers; i++) + { if (net_landrivers[i].initialized) net_landrivers[i].Listen (state); + } } @@ -831,8 +858,8 @@ static qsocket_t *_Datagram_CheckNewConnections (void) { struct qsockaddr clientaddr; struct qsockaddr newaddr; - int newsock; - int acceptsock; + sys_socket_t newsock; + sys_socket_t acceptsock; qsocket_t *sock; qsocket_t *s; int len; @@ -841,13 +868,13 @@ static qsocket_t *_Datagram_CheckNewConnections (void) int ret; acceptsock = dfunc.CheckNewConnections(); - if (acceptsock == -1) + if (acceptsock == INVALID_SOCKET) return NULL; SZ_Clear(&net_message); len = dfunc.Read (acceptsock, net_message.data, net_message.maxsize, &clientaddr); - if (len < sizeof(int)) + if (len < (int) sizeof(int)) return NULL; net_message.cursize = len; @@ -856,7 +883,7 @@ static qsocket_t *_Datagram_CheckNewConnections (void) MSG_ReadLong(); if (control == -1) return NULL; - if ((control & (~NETFLAG_LENGTH_MASK)) != NETFLAG_CTL) + if ((control & (~NETFLAG_LENGTH_MASK)) != (int)NETFLAG_CTL) return NULL; if ((control & NETFLAG_LENGTH_MASK) != len) return NULL; @@ -890,9 +917,10 @@ static qsocket_t *_Datagram_CheckNewConnections (void) int activeNumber; int clientNumber; client_t *client; - + playerNumber = MSG_ReadByte(); activeNumber = -1; + for (clientNumber = 0, client = svs.clients; clientNumber < svs.maxclients; clientNumber++, client++) { if (client->active) @@ -902,6 +930,7 @@ static qsocket_t *_Datagram_CheckNewConnections (void) break; } } + if (clientNumber == svs.maxclients) return NULL; @@ -924,31 +953,14 @@ static qsocket_t *_Datagram_CheckNewConnections (void) if (command == CCREQ_RULE_INFO) { - char *prevCvarName; - cvar_t *var; + const char *prevCvarName; + cvar_t *var; // find the search start location prevCvarName = MSG_ReadString(); - if (*prevCvarName) - { - var = Cvar_FindVar (prevCvarName); - if (!var) - return NULL; - var = var->next; - } - else - var = cvar_vars; - - // search for the next server cvar - while (var) - { - if (var->server) - break; - var = var->next; - } + var = Cvar_FindVarAfter (prevCvarName, CVAR_SERVERINFO); // send the response - SZ_Clear(&net_message); // save space for the header, filled in later MSG_WriteLong(&net_message, 0); @@ -986,11 +998,11 @@ static qsocket_t *_Datagram_CheckNewConnections (void) #ifdef BAN_TEST // check for a ban - if (clientaddr.sa_family == AF_INET) + if (clientaddr.qsa_family == AF_INET) { - unsigned long testAddr; + in_addr_t testAddr; testAddr = ((struct sockaddr_in *)&clientaddr)->sin_addr.s_addr; - if ((testAddr & banMask) == banAddr) + if ((testAddr & banMask.s_addr) == banAddr.s_addr) { SZ_Clear(&net_message); // save space for the header, filled in later @@ -1052,8 +1064,8 @@ static qsocket_t *_Datagram_CheckNewConnections (void) } // allocate a network socket - newsock = dfunc.OpenSocket(0); - if (newsock == -1) + newsock = dfunc.Open_Socket(0); + if (newsock == INVALID_SOCKET) { NET_FreeQSocket(sock); return NULL; @@ -1062,12 +1074,12 @@ static qsocket_t *_Datagram_CheckNewConnections (void) // connect to the client if (dfunc.Connect (newsock, &clientaddr) == -1) { - dfunc.CloseSocket(newsock); + dfunc.Close_Socket(newsock); NET_FreeQSocket(sock); return NULL; } - // everything is allocated, just fill in the details + // everything is allocated, just fill in the details sock->socket = newsock; sock->landriver = net_landriverlevel; sock->addr = clientaddr; @@ -1093,9 +1105,13 @@ qsocket_t *Datagram_CheckNewConnections (void) qsocket_t *ret = NULL; for (net_landriverlevel = 0; net_landriverlevel < net_numlandrivers; net_landriverlevel++) + { if (net_landrivers[net_landriverlevel].initialized) + { if ((ret = _Datagram_CheckNewConnections ()) != NULL) break; + } + } return ret; } @@ -1125,7 +1141,7 @@ static void _Datagram_SearchForHosts (qboolean xmit) while ((ret = dfunc.Read (dfunc.controlSock, net_message.data, net_message.maxsize, &readaddr)) > 0) { - if (ret < sizeof(int)) + if (ret < (int) sizeof(int)) continue; net_message.cursize = ret; @@ -1142,7 +1158,7 @@ static void _Datagram_SearchForHosts (qboolean xmit) MSG_ReadLong(); if (control == -1) continue; - if ((control & (~NETFLAG_LENGTH_MASK)) != NETFLAG_CTL) + if ((control & (~NETFLAG_LENGTH_MASK)) != (int)NETFLAG_CTL) continue; if ((control & NETFLAG_LENGTH_MASK) != ret) continue; @@ -1153,8 +1169,10 @@ static void _Datagram_SearchForHosts (qboolean xmit) dfunc.GetAddrFromName(MSG_ReadString(), &readaddr); // search the cache for this server for (n = 0; n < hostCacheCount; n++) + { if (dfunc.AddrCompare(&readaddr, &hostcache[n].addr) == 0) break; + } // is it already there? if (n < hostCacheCount) @@ -1183,7 +1201,7 @@ static void _Datagram_SearchForHosts (qboolean xmit) { if (i == n) continue; - if (Q_strcasecmp (hostcache[n].name, hostcache[i].name) == 0) + if (q_strcasecmp (hostcache[n].name, hostcache[i].name) == 0) { i = Q_strlen(hostcache[n].name); if (i < 15 && hostcache[n].name[i-1] > '8') @@ -1193,6 +1211,7 @@ static void _Datagram_SearchForHosts (qboolean xmit) } else hostcache[n].name[i-1]++; + i = -1; } } @@ -1211,24 +1230,27 @@ void Datagram_SearchForHosts (qboolean xmit) } -static qsocket_t *_Datagram_Connect (char *host) +static qsocket_t *_Datagram_Connect (const char *host) { struct qsockaddr sendaddr; struct qsockaddr readaddr; qsocket_t *sock; - int newsock; + sys_socket_t newsock; int ret; int reps; double start_time; int control; - char *reason; + const char *reason; // see if we can resolve the host name if (dfunc.GetAddrFromName(host, &sendaddr) == -1) + { + Con_Printf("Could not resolve %s\n", host); return NULL; + } - newsock = dfunc.OpenSocket (0); - if (newsock == -1) + newsock = dfunc.Open_Socket (0); + if (newsock == INVALID_SOCKET) return NULL; sock = NET_NewQSocket (); @@ -1242,7 +1264,8 @@ static qsocket_t *_Datagram_Connect (char *host) goto ErrorReturn; // send the connection request - Con_Printf("trying...\n"); SCR_UpdateScreen (); + Con_Printf("trying...\n"); + SCR_UpdateScreen (); start_time = net_time; for (reps = 0; reps < 3; reps++) @@ -1265,17 +1288,15 @@ static qsocket_t *_Datagram_Connect (char *host) // is it from the right place? if (sfunc.AddrCompare(&readaddr, &sendaddr) != 0) { -#ifdef DEBUG Con_Printf("wrong reply address\n"); - Con_Printf("Expected: %s\n", StrAddr (&sendaddr)); - Con_Printf("Received: %s\n", StrAddr (&readaddr)); + Con_Printf("Expected: %s | %s\n", dfunc.AddrToString (&sendaddr), StrAddr(&sendaddr)); + Con_Printf("Received: %s | %s\n", dfunc.AddrToString (&readaddr), StrAddr(&readaddr)); SCR_UpdateScreen (); -#endif ret = 0; continue; } - if (ret < sizeof(int)) + if (ret < (int) sizeof(int)) { ret = 0; continue; @@ -1291,7 +1312,7 @@ static qsocket_t *_Datagram_Connect (char *host) ret = 0; continue; } - if ((control & (~NETFLAG_LENGTH_MASK)) != NETFLAG_CTL) + if ((control & (~NETFLAG_LENGTH_MASK)) != (int)NETFLAG_CTL) { ret = 0; continue; @@ -1304,9 +1325,12 @@ static qsocket_t *_Datagram_Connect (char *host) } } while (ret == 0 && (SetNetTime() - start_time) < 2.5); + if (ret) break; - Con_Printf("still trying...\n"); SCR_UpdateScreen (); + + Con_Printf("still trying...\n"); + SCR_UpdateScreen (); start_time = SetNetTime(); } @@ -1330,8 +1354,8 @@ static qsocket_t *_Datagram_Connect (char *host) if (ret == CCREP_REJECT) { reason = MSG_ReadString(); - Con_Printf(reason); - Q_strncpy(m_return_reason, reason, 31); + Con_Printf("%s\n", reason); + q_strlcpy(m_return_reason, reason, sizeof(m_return_reason)); goto ErrorReturn; } @@ -1368,9 +1392,10 @@ static qsocket_t *_Datagram_Connect (char *host) ErrorReturn: NET_FreeQSocket(sock); ErrorReturn2: - dfunc.CloseSocket(newsock); + dfunc.Close_Socket(newsock); if (m_return_onerror) { + IN_Deactivate(modestate == MS_WINDOWED); key_dest = key_menu; m_state = m_return_state; m_return_onerror = false; @@ -1378,13 +1403,19 @@ ErrorReturn2: return NULL; } -qsocket_t *Datagram_Connect (char *host) +qsocket_t *Datagram_Connect (const char *host) { qsocket_t *ret = NULL; + host = Strip_Port (host); for (net_landriverlevel = 0; net_landriverlevel < net_numlandrivers; net_landriverlevel++) + { if (net_landrivers[net_landriverlevel].initialized) + { if ((ret = _Datagram_Connect (host)) != NULL) break; + } + } return ret; } + diff --git a/engine/code/net_dgrm.h b/engine/Quake/net_dgrm.h similarity index 77% rename from engine/code/net_dgrm.h rename to engine/Quake/net_dgrm.h index da052e7..357a829 100644 --- a/engine/code/net_dgrm.h +++ b/engine/Quake/net_dgrm.h @@ -1,5 +1,6 @@ /* -Copyright (C) 1996-1997 Id Software, Inc. +Copyright (C) 1996-2001 Id Software, Inc. +Copyright (C) 2010-2014 QuakeSpasm developers This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -8,7 +9,7 @@ of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. @@ -17,14 +18,15 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -// net_dgrm.h +#ifndef __NET_DATAGRAM_H +#define __NET_DATAGRAM_H int Datagram_Init (void); void Datagram_Listen (qboolean state); void Datagram_SearchForHosts (qboolean xmit); -qsocket_t *Datagram_Connect (char *host); -qsocket_t *Datagram_CheckNewConnections (void); +qsocket_t *Datagram_Connect (const char *host); +qsocket_t *Datagram_CheckNewConnections (void); int Datagram_GetMessage (qsocket_t *sock); int Datagram_SendMessage (qsocket_t *sock, sizebuf_t *data); int Datagram_SendUnreliableMessage (qsocket_t *sock, sizebuf_t *data); @@ -32,3 +34,6 @@ qboolean Datagram_CanSendMessage (qsocket_t *sock); qboolean Datagram_CanSendUnreliableMessage (qsocket_t *sock); void Datagram_Close (qsocket_t *sock); void Datagram_Shutdown (void); + +#endif /* __NET_DATAGRAM_H */ + diff --git a/engine/code/net_loop.c b/engine/Quake/net_loop.c similarity index 90% rename from engine/code/net_loop.c rename to engine/Quake/net_loop.c index 35aa370..8cb22db 100644 --- a/engine/code/net_loop.c +++ b/engine/Quake/net_loop.c @@ -1,5 +1,6 @@ /* -Copyright (C) 1996-1997 Id Software, Inc. +Copyright (C) 1996-2001 Id Software, Inc. +Copyright (C) 2010-2014 QuakeSpasm developers This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -8,7 +9,7 @@ of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. @@ -17,14 +18,17 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -// net_loop.c +#include "q_stdinc.h" +#include "arch_def.h" +#include "net_sys.h" #include "quakedef.h" +#include "net_defs.h" #include "net_loop.h" -qboolean localconnectpending = false; -qsocket_t *loop_client = NULL; -qsocket_t *loop_server = NULL; +static qboolean localconnectpending = false; +static qsocket_t *loop_client = NULL; +static qsocket_t *loop_server = NULL; int Loop_Init (void) { @@ -62,11 +66,11 @@ void Loop_SearchForHosts (qboolean xmit) } -qsocket_t *Loop_Connect (char *host) +qsocket_t *Loop_Connect (const char *host) { if (Q_strcmp(host,"local") != 0) return NULL; - + localconnectpending = true; if (!loop_client) @@ -97,8 +101,8 @@ qsocket_t *Loop_Connect (char *host) loop_client->driverdata = (void *)loop_server; loop_server->driverdata = (void *)loop_client; - - return loop_client; + + return loop_client; } @@ -142,7 +146,7 @@ int Loop_GetMessage (qsocket_t *sock) sock->receiveMessageLength -= length; if (sock->receiveMessageLength) - Q_memcpy(sock->receiveMessage, &sock->receiveMessage[length], sock->receiveMessageLength); + memmove (sock->receiveMessage, &sock->receiveMessage[length], sock->receiveMessageLength); if (sock->driverdata && ret == 1) ((qsocket_t *)sock->driverdata)->canSend = true; @@ -162,7 +166,7 @@ int Loop_SendMessage (qsocket_t *sock, sizebuf_t *data) bufferLength = &((qsocket_t *)sock->driverdata)->receiveMessageLength; if ((*bufferLength + data->cursize + 4) > NET_MAXMESSAGE) - Sys_Error("Loop_SendMessage: overflow\n"); + Sys_Error("Loop_SendMessage: overflow"); buffer = ((qsocket_t *)sock->driverdata)->receiveMessage + *bufferLength; @@ -243,3 +247,4 @@ void Loop_Close (qsocket_t *sock) else loop_server = NULL; } + diff --git a/engine/code/net_loop.h b/engine/Quake/net_loop.h similarity index 64% rename from engine/code/net_loop.h rename to engine/Quake/net_loop.h index 90cdb2c..267193d 100644 --- a/engine/code/net_loop.h +++ b/engine/Quake/net_loop.h @@ -1,5 +1,6 @@ /* -Copyright (C) 1996-1997 Id Software, Inc. +Copyright (C) 1996-2001 Id Software, Inc. +Copyright (C) 2010-2014 QuakeSpasm developers This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -8,7 +9,7 @@ of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. @@ -17,17 +18,23 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -// net_loop.h -int Loop_Init (void); +#ifndef __NET_LOOP_H +#define __NET_LOOP_H + +// net_loop.h +int Loop_Init (void); void Loop_Listen (qboolean state); void Loop_SearchForHosts (qboolean xmit); -qsocket_t *Loop_Connect (char *host); -qsocket_t *Loop_CheckNewConnections (void); -int Loop_GetMessage (qsocket_t *sock); -int Loop_SendMessage (qsocket_t *sock, sizebuf_t *data); -int Loop_SendUnreliableMessage (qsocket_t *sock, sizebuf_t *data); +qsocket_t *Loop_Connect (const char *host); +qsocket_t *Loop_CheckNewConnections (void); +int Loop_GetMessage (qsocket_t *sock); +int Loop_SendMessage (qsocket_t *sock, sizebuf_t *data); +int Loop_SendUnreliableMessage (qsocket_t *sock, sizebuf_t *data); qboolean Loop_CanSendMessage (qsocket_t *sock); qboolean Loop_CanSendUnreliableMessage (qsocket_t *sock); void Loop_Close (qsocket_t *sock); void Loop_Shutdown (void); + +#endif /* __NET_LOOP_H */ + diff --git a/engine/code/net_main.c b/engine/Quake/net_main.c similarity index 61% rename from engine/code/net_main.c rename to engine/Quake/net_main.c index f8eea6f..bbd599a 100644 --- a/engine/code/net_main.c +++ b/engine/Quake/net_main.c @@ -1,5 +1,6 @@ /* -Copyright (C) 1996-1997 Id Software, Inc. +Copyright (C) 1996-2001 Id Software, Inc. +Copyright (C) 2010-2014 QuakeSpasm developers This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -8,7 +9,7 @@ of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. @@ -17,30 +18,26 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -// net_main.c +#include "q_stdinc.h" +#include "arch_def.h" +#include "net_sys.h" #include "quakedef.h" -#include "net_vcr.h" +#include "net_defs.h" qsocket_t *net_activeSockets = NULL; qsocket_t *net_freeSockets = NULL; -int net_numsockets = 0; +int net_numsockets = 0; -qboolean serialAvailable = false; qboolean ipxAvailable = false; qboolean tcpipAvailable = false; -int net_hostport; -int DEFAULTnet_hostport = 26000; +int net_hostport; +int DEFAULTnet_hostport = 26000; char my_ipx_address[NET_NAMELEN]; char my_tcpip_address[NET_NAMELEN]; -void (*GetComPortConfig) (int portNumber, int *port, int *irq, int *baud, qboolean *useModem); -void (*SetComPortConfig) (int portNumber, int port, int irq, int baud, qboolean useModem); -void (*GetModemConfig) (int portNumber, char *dialType, char *clear, char *init, char *hangup); -void (*SetModemConfig) (int portNumber, char *dialType, char *clear, char *init, char *hangup); - static qboolean listening = false; qboolean slistInProgress = false; @@ -49,52 +46,34 @@ qboolean slistLocal = true; static double slistStartTime; static int slistLastShown; -static void Slist_Send(void); -static void Slist_Poll(void); -PollProcedure slistSendProcedure = {NULL, 0.0, Slist_Send}; -PollProcedure slistPollProcedure = {NULL, 0.0, Slist_Poll}; - - -sizebuf_t net_message; -int net_activeconnections = 0; - -int messagesSent = 0; -int messagesReceived = 0; -int unreliableMessagesSent = 0; -int unreliableMessagesReceived = 0; +static void Slist_Send (void *); +static void Slist_Poll (void *); +static PollProcedure slistSendProcedure = {NULL, 0.0, Slist_Send}; +static PollProcedure slistPollProcedure = {NULL, 0.0, Slist_Poll}; -cvar_t net_messagetimeout = {"net_messagetimeout","300"}; -cvar_t hostname = {"hostname", "UNNAMED"}; +sizebuf_t net_message; +int net_activeconnections = 0; -qboolean configRestored = false; -cvar_t config_com_port = {"_config_com_port", "0x3f8", true}; -cvar_t config_com_irq = {"_config_com_irq", "4", true}; -cvar_t config_com_baud = {"_config_com_baud", "57600", true}; -cvar_t config_com_modem = {"_config_com_modem", "1", true}; -cvar_t config_modem_dialtype = {"_config_modem_dialtype", "T", true}; -cvar_t config_modem_clear = {"_config_modem_clear", "ATZ", true}; -cvar_t config_modem_init = {"_config_modem_init", "", true}; -cvar_t config_modem_hangup = {"_config_modem_hangup", "AT H", true}; +int messagesSent = 0; +int messagesReceived = 0; +int unreliableMessagesSent = 0; +int unreliableMessagesReceived = 0; -#ifdef IDGODS -cvar_t idgods = {"idgods", "0"}; -#endif - -int vcrFile = -1; -qboolean recording = false; +static cvar_t net_messagetimeout = {"net_messagetimeout","300",CVAR_NONE}; +cvar_t hostname = {"hostname", "UNNAMED", CVAR_NONE}; // these two macros are to make the code more readable #define sfunc net_drivers[sock->driver] #define dfunc net_drivers[net_driverlevel] -int net_driverlevel; +int net_driverlevel; +double net_time; -double net_time; -double SetNetTime(void) +double SetNetTime (void) { - net_time = Sys_FloatTime(); + net_time = Sys_DoubleTime(); return net_time; } @@ -156,13 +135,16 @@ void NET_FreeQSocket(qsocket_t *sock) else { for (s = net_activeSockets; s; s = s->next) + { if (s->next == sock) { s->next = sock->next; break; } + } + if (!s) - Sys_Error ("NET_FreeQSocket: not active\n"); + Sys_Error ("NET_FreeQSocket: not active"); } // add it to free list @@ -172,17 +154,29 @@ void NET_FreeQSocket(qsocket_t *sock) } +double NET_QSocketGetTime (const qsocket_t *s) +{ + return s->connecttime; +} + + +const char *NET_QSocketGetAddressString (const qsocket_t *s) +{ + return s->address; +} + + static void NET_Listen_f (void) { if (Cmd_Argc () != 2) { - Con_Printf ("\"listen\" is \"%u\"\n", listening ? 1 : 0); + Con_Printf ("\"listen\" is \"%d\"\n", listening ? 1 : 0); return; } listening = Q_atoi(Cmd_Argv(1)) ? true : false; - for (net_driverlevel=0 ; net_driverlevel svs.maxclientslimit) { n = svs.maxclientslimit; - Con_Printf ("\"maxplayers\" set to \"%u\"\n", n); + Con_Printf ("\"maxplayers\" set to \"%d\"\n", n); } if ((n == 1) && listening) @@ -223,35 +217,20 @@ static void MaxPlayers_f (void) Cbuf_AddText ("listen 1\n"); svs.maxclients = n; - - // jkrige - coop and deathmatch flag fix - //if (n == 1) - // Cvar_Set ("deathmatch", "0"); - //else - // Cvar_Set ("deathmatch", "1"); if (n == 1) - { Cvar_Set ("deathmatch", "0"); - Cvar_Set ("coop", "0"); - } else - { - if (coop.value) - Cvar_Set ("deathmatch", "0"); - else - Cvar_Set ("deathmatch", "1"); - } - // jkrige - coop and deathmatch flag fix + Cvar_Set ("deathmatch", "1"); } static void NET_Port_f (void) { - int n; + int n; if (Cmd_Argc () != 2) { - Con_Printf ("\"port\" is \"%u\"\n", net_hostport); + Con_Printf ("\"port\" is \"%d\"\n", net_hostport); return; } @@ -284,7 +263,7 @@ static void PrintSlistHeader(void) static void PrintSlist(void) { - int n; + int n; for (n = slistLastShown; n < hostCacheCount; n++) { @@ -318,7 +297,7 @@ void NET_Slist_f (void) } slistInProgress = true; - slistStartTime = Sys_FloatTime(); + slistStartTime = Sys_DoubleTime(); SchedulePollProcedure(&slistSendProcedure, 0.0); SchedulePollProcedure(&slistPollProcedure, 0.1); @@ -327,27 +306,80 @@ void NET_Slist_f (void) } -static void Slist_Send(void) +void NET_SlistSort (void) +{ + if (hostCacheCount > 1) + { + int i, j; + hostcache_t temp; + for (i = 0; i < hostCacheCount; i++) + { + for (j = i + 1; j < hostCacheCount; j++) + { + if (strcmp(hostcache[j].name, hostcache[i].name) < 0) + { + memcpy(&temp, &hostcache[j], sizeof(hostcache_t)); + memcpy(&hostcache[j], &hostcache[i], sizeof(hostcache_t)); + memcpy(&hostcache[i], &temp, sizeof(hostcache_t)); + } + } + } + } +} + + +const char *NET_SlistPrintServer (int idx) +{ + static char string[64]; + + if (idx < 0 || idx >= hostCacheCount) + return ""; + + if (hostcache[idx].maxusers) + { + q_snprintf(string, sizeof(string), "%-15.15s %-15.15s %2u/%2u\n", + hostcache[idx].name, hostcache[idx].map, + hostcache[idx].users, hostcache[idx].maxusers); + } + else + { + q_snprintf(string, sizeof(string), "%-15.15s %-15.15s\n", + hostcache[idx].name, hostcache[idx].map); + } + + return string; +} + + +const char *NET_SlistPrintServerName (int idx) +{ + if (idx < 0 || idx >= hostCacheCount) + return ""; + return hostcache[idx].cname; +} + + +static void Slist_Send (void *unused) { - for (net_driverlevel=0; net_driverlevel < net_numdrivers; net_driverlevel++) + for (net_driverlevel = 0; net_driverlevel < net_numdrivers; net_driverlevel++) { - if (!slistLocal && net_driverlevel == 0) + if (!slistLocal && IS_LOOP_DRIVER(net_driverlevel)) continue; if (net_drivers[net_driverlevel].initialized == false) continue; dfunc.SearchForHosts (true); } - if ((Sys_FloatTime() - slistStartTime) < 0.5) + if ((Sys_DoubleTime() - slistStartTime) < 0.5) SchedulePollProcedure(&slistSendProcedure, 0.75); } -static void Slist_Poll(void) +static void Slist_Poll (void *unused) { - for (net_driverlevel=0; net_driverlevel < net_numdrivers; net_driverlevel++) + for (net_driverlevel = 0; net_driverlevel < net_numdrivers; net_driverlevel++) { - if (!slistLocal && net_driverlevel == 0) + if (!slistLocal && IS_LOOP_DRIVER(net_driverlevel)) continue; if (net_drivers[net_driverlevel].initialized == false) continue; @@ -357,7 +389,7 @@ static void Slist_Poll(void) if (! slistSilent) PrintSlist(); - if ((Sys_FloatTime() - slistStartTime) < 1.5) + if ((Sys_DoubleTime() - slistStartTime) < 1.5) { SchedulePollProcedure(&slistPollProcedure, 0.1); return; @@ -380,7 +412,7 @@ NET_Connect int hostCacheCount = 0; hostcache_t hostcache[HOSTCACHESIZE]; -qsocket_t *NET_Connect (char *host) +qsocket_t *NET_Connect (const char *host) { qsocket_t *ret; int n; @@ -393,7 +425,7 @@ qsocket_t *NET_Connect (char *host) if (host) { - if (Q_strcasecmp (host, "local") == 0) + if (q_strcasecmp (host, "local") == 0) { numdrivers = 1; goto JustDoIt; @@ -402,7 +434,7 @@ qsocket_t *NET_Connect (char *host) if (hostCacheCount) { for (n = 0; n < hostCacheCount; n++) - if (Q_strcasecmp (host, hostcache[n].name) == 0) + if (q_strcasecmp (host, hostcache[n].name) == 0) { host = hostcache[n].cname; break; @@ -415,7 +447,7 @@ qsocket_t *NET_Connect (char *host) slistSilent = host ? true : false; NET_Slist_f (); - while(slistInProgress) + while (slistInProgress) NET_Poll(); if (host == NULL) @@ -427,15 +459,19 @@ qsocket_t *NET_Connect (char *host) } if (hostCacheCount) + { for (n = 0; n < hostCacheCount; n++) - if (Q_strcasecmp (host, hostcache[n].name) == 0) + { + if (q_strcasecmp (host, hostcache[n].name) == 0) { host = hostcache[n].cname; break; } + } + } JustDoIt: - for (net_driverlevel=0 ; net_driverleveladdress, NET_NAMELEN); - } return ret; } } - - if (recording) - { - vcrConnect.time = host_time; - vcrConnect.op = VCR_OP_CONNECT; - vcrConnect.session = 0; - Sys_FileWrite (vcrFile, &vcrConnect, sizeof(vcrConnect)); - } return NULL; } @@ -540,18 +552,6 @@ returns 1 if a message was received returns -1 if connection is invalid ================= */ - -struct -{ - double time; - int op; - long session; - int ret; - int len; -} vcrGetMessage; - -extern void PrintStats(qsocket_t *s); - int NET_GetMessage (qsocket_t *sock) { int ret; @@ -570,7 +570,7 @@ int NET_GetMessage (qsocket_t *sock) ret = sfunc.QGetMessage(sock); // see if this connection has timed out - if (ret == 0 && sock->driver) + if (ret == 0 && !IS_LOOP_DRIVER(sock->driver)) { if (net_time - sock->lastMessageTime > net_messagetimeout.value) { @@ -579,10 +579,9 @@ int NET_GetMessage (qsocket_t *sock) } } - if (ret > 0) { - if (sock->driver) + if (!IS_LOOP_DRIVER(sock->driver)) { sock->lastMessageTime = net_time; if (ret == 1) @@ -590,28 +589,6 @@ int NET_GetMessage (qsocket_t *sock) else if (ret == 2) unreliableMessagesReceived++; } - - if (recording) - { - vcrGetMessage.time = host_time; - vcrGetMessage.op = VCR_OP_GETMESSAGE; - vcrGetMessage.session = (intptr_t)sock; - vcrGetMessage.ret = ret; - vcrGetMessage.len = net_message.cursize; - Sys_FileWrite (vcrFile, &vcrGetMessage, 24); - Sys_FileWrite (vcrFile, net_message.data, net_message.cursize); - } - } - else - { - if (recording) - { - vcrGetMessage.time = host_time; - vcrGetMessage.op = VCR_OP_GETMESSAGE; - vcrGetMessage.session = (intptr_t)sock; - vcrGetMessage.ret = ret; - Sys_FileWrite (vcrFile, &vcrGetMessage, 20); - } } return ret; @@ -629,18 +606,10 @@ returns 1 if the message was sent properly returns -1 if the connection died ================== */ -struct -{ - double time; - int op; - long session; - int r; -} vcrSendMessage; - int NET_SendMessage (qsocket_t *sock, sizebuf_t *data) { int r; - + if (!sock) return -1; @@ -652,18 +621,9 @@ int NET_SendMessage (qsocket_t *sock, sizebuf_t *data) SetNetTime(); r = sfunc.QSendMessage(sock, data); - if (r == 1 && sock->driver) + if (r == 1 && !IS_LOOP_DRIVER(sock->driver)) messagesSent++; - if (recording) - { - vcrSendMessage.time = host_time; - vcrSendMessage.op = VCR_OP_SENDMESSAGE; - vcrSendMessage.session = (intptr_t)sock; - vcrSendMessage.r = r; - Sys_FileWrite (vcrFile, &vcrSendMessage, 20); - } - return r; } @@ -671,7 +631,7 @@ int NET_SendMessage (qsocket_t *sock, sizebuf_t *data) int NET_SendUnreliableMessage (qsocket_t *sock, sizebuf_t *data) { int r; - + if (!sock) return -1; @@ -683,18 +643,9 @@ int NET_SendUnreliableMessage (qsocket_t *sock, sizebuf_t *data) SetNetTime(); r = sfunc.SendUnreliableMessage(sock, data); - if (r == 1 && sock->driver) + if (r == 1 && !IS_LOOP_DRIVER(sock->driver)) unreliableMessagesSent++; - if (recording) - { - vcrSendMessage.time = host_time; - vcrSendMessage.op = VCR_OP_SENDMESSAGE; - vcrSendMessage.session = (intptr_t)sock; - vcrSendMessage.r = r; - Sys_FileWrite (vcrFile, &vcrSendMessage, 20); - } - return r; } @@ -709,8 +660,6 @@ message to be transmitted. */ qboolean NET_CanSendMessage (qsocket_t *sock) { - int r; - if (!sock) return false; @@ -719,64 +668,56 @@ qboolean NET_CanSendMessage (qsocket_t *sock) SetNetTime(); - r = sfunc.CanSendMessage(sock); - - if (recording) - { - vcrSendMessage.time = host_time; - vcrSendMessage.op = VCR_OP_CANSENDMESSAGE; - vcrSendMessage.session = (intptr_t)sock; - vcrSendMessage.r = r; - Sys_FileWrite (vcrFile, &vcrSendMessage, 20); - } - - return r; + return sfunc.CanSendMessage(sock); } -int NET_SendToAll(sizebuf_t *data, int blocktime) +int NET_SendToAll (sizebuf_t *data, double blocktime) { double start; int i; int count = 0; - qboolean state1 [MAX_SCOREBOARD]; - qboolean state2 [MAX_SCOREBOARD]; + qboolean msg_init[MAX_SCOREBOARD]; /* did we write the message to the client's connection */ + qboolean msg_sent[MAX_SCOREBOARD]; /* did the msg arrive its destination (canSend state). */ - for (i=0, host_client = svs.clients ; inetconnection) continue; if (host_client->active) + */ + if (host_client->netconnection && host_client->active) { - if (host_client->netconnection->driver == 0) + if (IS_LOOP_DRIVER(host_client->netconnection->driver)) { NET_SendMessage(host_client->netconnection, data); - state1[i] = true; - state2[i] = true; + msg_init[i] = true; + msg_sent[i] = true; continue; } count++; - state1[i] = false; - state2[i] = false; + msg_init[i] = false; + msg_sent[i] = false; } else { - state1[i] = true; - state2[i] = true; + msg_init[i] = true; + msg_sent[i] = true; } } - start = Sys_FloatTime(); + start = Sys_DoubleTime(); while (count) { count = 0; - for (i=0, host_client = svs.clients ; inetconnection)) { - state1[i] = true; + msg_init[i] = true; NET_SendMessage(host_client->netconnection, data); } else @@ -787,11 +728,11 @@ int NET_SendToAll(sizebuf_t *data, int blocktime) continue; } - if (! state2[i]) + if (! msg_sent[i]) { if (NET_CanSendMessage (host_client->netconnection)) { - state2[i] = true; + msg_sent[i] = true; } else { @@ -801,7 +742,7 @@ int NET_SendToAll(sizebuf_t *data, int blocktime) continue; } } - if ((Sys_FloatTime() - start) > blocktime) + if ((Sys_DoubleTime() - start) > blocktime) break; } return count; @@ -819,18 +760,8 @@ NET_Init void NET_Init (void) { int i; - int controlSocket; qsocket_t *s; - if (COM_CheckParm("-playback")) - { - net_numdrivers = 1; - net_drivers[0].Init = VCR_Init; - } - - if (COM_CheckParm("-record")) - recording = true; - i = COM_CheckParm ("-port"); if (!i) i = COM_CheckParm ("-udpport"); @@ -846,11 +777,11 @@ void NET_Init (void) } net_hostport = DEFAULTnet_hostport; - if (COM_CheckParm("-listen") || cls.state == ca_dedicated) - listening = true; net_numsockets = svs.maxclientslimit; if (cls.state != ca_dedicated) net_numsockets++; + if (COM_CheckParm("-listen") || cls.state == ca_dedicated) + listening = true; SetNetTime(); @@ -867,17 +798,6 @@ void NET_Init (void) Cvar_RegisterVariable (&net_messagetimeout); Cvar_RegisterVariable (&hostname); - Cvar_RegisterVariable (&config_com_port); - Cvar_RegisterVariable (&config_com_irq); - Cvar_RegisterVariable (&config_com_baud); - Cvar_RegisterVariable (&config_com_modem); - Cvar_RegisterVariable (&config_modem_dialtype); - Cvar_RegisterVariable (&config_modem_clear); - Cvar_RegisterVariable (&config_modem_init); - Cvar_RegisterVariable (&config_modem_hangup); -#ifdef IDGODS - Cvar_RegisterVariable (&idgods); -#endif Cmd_AddCommand ("slist", NET_Slist_f); Cmd_AddCommand ("listen", NET_Listen_f); @@ -885,21 +805,33 @@ void NET_Init (void) Cmd_AddCommand ("port", NET_Port_f); // initialize all the drivers - for (net_driverlevel=0 ; net_driverlevelnextTime = Sys_FloatTime() + timeOffset; + proc->nextTime = Sys_DoubleTime() + timeOffset; for (pp = pollProcedureList, prev = NULL; pp; pp = pp->next) { if (pp->nextTime >= proc->nextTime) @@ -993,20 +904,3 @@ void SchedulePollProcedure(PollProcedure *proc, double timeOffset) prev->next = proc; } - -#ifdef IDGODS -#define IDNET 0xc0f62800 - -qboolean IsID(struct qsockaddr *addr) -{ - if (idgods.value == 0.0) - return false; - - if (addr->sa_family != 2) - return false; - - if ((BigLong(*(int *)&addr->sa_data[2]) & 0xffffff00) == IDNET) - return true; - return false; -} -#endif diff --git a/engine/Quake/net_sys.h b/engine/Quake/net_sys.h new file mode 100644 index 0000000..77727e3 --- /dev/null +++ b/engine/Quake/net_sys.h @@ -0,0 +1,199 @@ +/* + * net_sys.h -- common network system header. + * - depends on arch_def.h + * - may depend on q_stdinc.h + * + * Copyright (C) 2007-2012 O.Sezer + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef __NET_SYS_H__ +#define __NET_SYS_H__ + +#include +#include +#include +#include + +#if defined(PLATFORM_BSD) || defined(PLATFORM_OSX) || \ + defined(PLATFORM_AMIGA) /* bsdsocket.library */ || \ + defined(__GNU__) /* GNU/Hurd */ || defined(__riscos__) +/* struct sockaddr has unsigned char sa_len as the first member in BSD + * variants and the family member is also an unsigned char instead of an + * unsigned short. This should matter only when PLATFORM_UNIX is defined, + * however, checking for the offset of sa_family in every platform that + * provide a struct sockaddr doesn't hurt either (see down below for the + * compile time asserts.) */ +/* FIXME : GET RID OF THIS ABOMINATION !!! */ +#define HAVE_SA_LEN 1 +#define SA_FAM_OFFSET 1 +#else +#undef HAVE_SA_LEN +#define SA_FAM_OFFSET 0 +#endif /* BSD, sockaddr */ + +/* unix includes and compatibility macros */ +#if defined(PLATFORM_UNIX) || defined(PLATFORM_RISCOS) + +#include +#include +#if defined(__sun) || defined(sun) +#include +#include +#endif /* __sunos__ */ +#include +#include +#include +#include +#include + +typedef int sys_socket_t; +#define INVALID_SOCKET (-1) +#define SOCKET_ERROR (-1) + +#if defined(__APPLE__) && defined(SO_NKE) && !defined(SO_NOADDRERR) + /* ancient Mac OS X SDKs 10.2 and older are missing socklen_t */ +typedef int socklen_t; /* defining as signed int to match the old api */ +#endif /* ancient OSX SDKs */ + +#define SOCKETERRNO errno +#define ioctlsocket ioctl +#define closesocket close +#define selectsocket select +#define IOCTLARG_P(x) /* (char *) */ x + +#define NET_EWOULDBLOCK EWOULDBLOCK +#define NET_ECONNREFUSED ECONNREFUSED + +#define socketerror(x) strerror((x)) + +/* Verify that we defined HAVE_SA_LEN correctly: */ +COMPILE_TIME_ASSERT(sockaddr, offsetof(struct sockaddr, sa_family) == SA_FAM_OFFSET); + +#endif /* end of unix stuff */ + + +/* amiga includes and compatibility macros */ +#if defined(PLATFORM_AMIGA) /* Amiga bsdsocket.library */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +typedef int sys_socket_t; +#define INVALID_SOCKET (-1) +#define SOCKET_ERROR (-1) + +#if !(defined(__AROS__) || defined(__amigaos4__)) +typedef LONG socklen_t; /* int32_t */ +#endif +#if !defined(__amigaos4__) +#if (LONG_MAX <= 2147483647L) +typedef unsigned long in_addr_t; /* u_int32_t */ +#else +typedef unsigned int in_addr_t; /* u_int32_t */ +#endif +#endif + +#define SOCKETERRNO Errno() +#define ioctlsocket IoctlSocket +#define closesocket CloseSocket +#define selectsocket(_N,_R,_W,_E,_T) \ + WaitSelect((_N),(_R),(_W),(_E),(_T),NULL) +#define IOCTLARG_P(x) (char *) x +#if defined(__amigaos4__) || defined(PLATFORM_AMIGAOS3) +#define inet_ntoa(x) Inet_NtoA(x.s_addr) /* Inet_NtoA(*(ULONG*)&x) */ +#define h_errno Errno() +#endif + +#define NET_EWOULDBLOCK EWOULDBLOCK +#define NET_ECONNREFUSED ECONNREFUSED + +#define socketerror(x) strerror((x)) +/* there is h_errno but no hstrerror() */ +#define hstrerror(x) strerror((x)) + +/* Verify that we defined HAVE_SA_LEN correctly: */ +COMPILE_TIME_ASSERT(sockaddr, offsetof(struct sockaddr, sa_family) == SA_FAM_OFFSET); + +#endif /* end of amiga bsdsocket.library stuff */ + + +/* windows includes and compatibility macros */ +#if defined(PLATFORM_WINDOWS) + +/* NOTE: winsock[2].h already includes windows.h */ +#if !defined(_USE_WINSOCK2) +#include +#else +#include +#include +#endif + +/* there is no in_addr_t on windows: define it as + the type of the S_addr of in_addr structure */ +typedef u_long in_addr_t; /* uint32_t */ + +/* on windows, socklen_t is to be a winsock2 thing */ +#if !defined(IP_MSFILTER_SIZE) +typedef int socklen_t; +#endif /* socklen_t type */ + +typedef SOCKET sys_socket_t; + +#define selectsocket select +#define IOCTLARG_P(x) /* (u_long *) */ x + +#define SOCKETERRNO WSAGetLastError() +#define NET_EWOULDBLOCK WSAEWOULDBLOCK +#define NET_ECONNREFUSED WSAECONNREFUSED +/* must #include "wsaerror.h" for this : */ +#define socketerror(x) __WSAE_StrError((x)) + +/* Verify that we defined HAVE_SA_LEN correctly: */ +COMPILE_TIME_ASSERT(sockaddr, offsetof(struct sockaddr, sa_family) == SA_FAM_OFFSET); + +#endif /* end of windows stuff */ + + +/* macros which may still be missing */ + +#if !defined(INADDR_NONE) +#define INADDR_NONE ((in_addr_t) 0xffffffff) +#endif /* INADDR_NONE */ + +#if !defined(INADDR_LOOPBACK) +#define INADDR_LOOPBACK ((in_addr_t) 0x7f000001) /* 127.0.0.1 */ +#endif /* INADDR_LOOPBACK */ + + +#if !defined(MAXHOSTNAMELEN) +/* SUSv2 guarantees that `Host names are limited to 255 bytes'. + POSIX 1003.1-2001 guarantees that `Host names (not including + the terminating NUL) are limited to HOST_NAME_MAX bytes'. */ +#define MAXHOSTNAMELEN 256 +#endif /* MAXHOSTNAMELEN */ + + +#endif /* __NET_SYS_H__ */ + diff --git a/engine/Quake/net_udp.c b/engine/Quake/net_udp.c new file mode 100644 index 0000000..b545851 --- /dev/null +++ b/engine/Quake/net_udp.c @@ -0,0 +1,462 @@ +/* +Copyright (C) 1996-2001 Id Software, Inc. +Copyright (C) 2007-2008 Kristian Duske +Copyright (C) 2010-2014 QuakeSpasm developers + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#include "q_stdinc.h" +#include "arch_def.h" +#include "net_sys.h" +#include "quakedef.h" +#include "net_defs.h" + +static sys_socket_t net_acceptsocket = INVALID_SOCKET; // socket for fielding new connections +static sys_socket_t net_controlsocket; +static sys_socket_t net_broadcastsocket = 0; +static struct sockaddr_in broadcastaddr; + +static in_addr_t myAddr; + +#include "net_udp.h" + +//============================================================================= + +sys_socket_t UDP_Init (void) +{ + int err; + char *tst; + char buff[MAXHOSTNAMELEN]; + struct hostent *local; + struct qsockaddr addr; + + if (COM_CheckParm ("-noudp")) + return INVALID_SOCKET; + + // determine my name & address + myAddr = htonl(INADDR_LOOPBACK); + if (gethostname(buff, MAXHOSTNAMELEN) != 0) + { + err = SOCKETERRNO; + Con_SafePrintf("UDP_Init: gethostname failed (%s)\n", + socketerror(err)); + } + else + { + buff[MAXHOSTNAMELEN - 1] = 0; +#ifdef PLATFORM_OSX + // ericw -- if our hostname ends in ".local" (a macOS thing), + // don't bother calling gethostbyname(), because it blocks for a few seconds + // and then fails (on my system anyway.) + tst = strstr(buff, ".local"); + if (tst && tst[6] == '\0') + { + Con_SafePrintf("UDP_Init: skipping gethostbyname for %s\n", buff); + } + else +#endif + if (!(local = gethostbyname(buff))) + { + Con_SafePrintf("UDP_Init: gethostbyname failed (%s)\n", + hstrerror(h_errno)); + } + else if (local->h_addrtype != AF_INET) + { + Con_SafePrintf("UDP_Init: address from gethostbyname not IPv4\n"); + } + else + { + myAddr = *(in_addr_t *)local->h_addr_list[0]; + } + } + + if ((net_controlsocket = UDP_OpenSocket(0)) == INVALID_SOCKET) + { + Con_SafePrintf("UDP_Init: Unable to open control socket, UDP disabled\n"); + return INVALID_SOCKET; + } + + broadcastaddr.sin_family = AF_INET; + broadcastaddr.sin_addr.s_addr = INADDR_BROADCAST; + broadcastaddr.sin_port = htons((unsigned short)net_hostport); + + UDP_GetSocketAddr (net_controlsocket, &addr); + strcpy(my_tcpip_address, UDP_AddrToString (&addr)); + tst = strrchr(my_tcpip_address, ':'); + if (tst) *tst = 0; + + Con_SafePrintf("UDP Initialized\n"); + tcpipAvailable = true; + + return net_controlsocket; +} + +//============================================================================= + +void UDP_Shutdown (void) +{ + UDP_Listen (false); + UDP_CloseSocket (net_controlsocket); +} + +//============================================================================= + +void UDP_Listen (qboolean state) +{ + // enable listening + if (state) + { + if (net_acceptsocket != INVALID_SOCKET) + return; + if ((net_acceptsocket = UDP_OpenSocket (net_hostport)) == INVALID_SOCKET) + Sys_Error ("UDP_Listen: Unable to open accept socket"); + return; + } + + // disable listening + if (net_acceptsocket == INVALID_SOCKET) + return; + UDP_CloseSocket (net_acceptsocket); + net_acceptsocket = INVALID_SOCKET; +} + +//============================================================================= + +sys_socket_t UDP_OpenSocket (int port) +{ + sys_socket_t newsocket; + struct sockaddr_in address; + int _true = 1; + int err; + + if ((newsocket = socket (PF_INET, SOCK_DGRAM, IPPROTO_UDP)) == INVALID_SOCKET) + { + err = SOCKETERRNO; + Con_SafePrintf("UDP_OpenSocket: %s\n", socketerror(err)); + return INVALID_SOCKET; + } + + if (ioctlsocket (newsocket, FIONBIO, &_true) == SOCKET_ERROR) + goto ErrorReturn; + + memset(&address, 0, sizeof(struct sockaddr_in)); + address.sin_family = AF_INET; + address.sin_addr.s_addr = INADDR_ANY; + address.sin_port = htons((unsigned short)port); + if (bind (newsocket, (struct sockaddr *)&address, sizeof(address)) == 0) + return newsocket; + +ErrorReturn: + err = SOCKETERRNO; + Con_SafePrintf("UDP_OpenSocket: %s\n", socketerror(err)); + UDP_CloseSocket (newsocket); + return INVALID_SOCKET; +} + +//============================================================================= + +int UDP_CloseSocket (sys_socket_t socketid) +{ + if (socketid == net_broadcastsocket) + net_broadcastsocket = 0; + return closesocket (socketid); +} + +//============================================================================= + +/* +============ +PartialIPAddress + +this lets you type only as much of the net address as required, using +the local network components to fill in the rest +============ +*/ +static int PartialIPAddress (const char *in, struct qsockaddr *hostaddr) +{ + char buff[256]; + char *b; + int addr, mask, num, port, run; + + buff[0] = '.'; + b = buff; + strcpy(buff+1, in); + if (buff[1] == '.') + b++; + + addr = 0; + mask = -1; + while (*b == '.') + { + b++; + num = 0; + run = 0; + while (!( *b < '0' || *b > '9')) + { + num = num*10 + *b++ - '0'; + if (++run > 3) + return -1; + } + if ((*b < '0' || *b > '9') && *b != '.' && *b != ':' && *b != 0) + return -1; + if (num < 0 || num > 255) + return -1; + mask <<= 8; + addr = (addr<<8) + num; + } + + if (*b++ == ':') + port = atoi(b); + else + port = net_hostport; + + hostaddr->qsa_family = AF_INET; + ((struct sockaddr_in *)hostaddr)->sin_port = htons((unsigned short)port); + ((struct sockaddr_in *)hostaddr)->sin_addr.s_addr = + (myAddr & htonl(mask)) | htonl(addr); + + return 0; +} + +//============================================================================= + +int UDP_Connect (sys_socket_t socketid, struct qsockaddr *addr) +{ + return 0; +} + +//============================================================================= + +sys_socket_t UDP_CheckNewConnections (void) +{ + int available; + struct sockaddr_in from; + socklen_t fromlen; + char buff[1]; + + if (net_acceptsocket == INVALID_SOCKET) + return INVALID_SOCKET; + + if (ioctl (net_acceptsocket, FIONREAD, &available) == -1) + { + int err = SOCKETERRNO; + Sys_Error ("UDP: ioctlsocket (FIONREAD) failed (%s)", socketerror(err)); + } + if (available) + return net_acceptsocket; + // quietly absorb empty packets + recvfrom (net_acceptsocket, buff, 0, 0, (struct sockaddr *) &from, &fromlen); + return INVALID_SOCKET; +} + +//============================================================================= + +int UDP_Read (sys_socket_t socketid, byte *buf, int len, struct qsockaddr *addr) +{ + socklen_t addrlen = sizeof(struct qsockaddr); + int ret; + + ret = recvfrom (socketid, buf, len, 0, (struct sockaddr *)addr, &addrlen); + if (ret == SOCKET_ERROR) + { + int err = SOCKETERRNO; + if (err == NET_EWOULDBLOCK || err == NET_ECONNREFUSED) + return 0; + Con_SafePrintf ("UDP_Read, recvfrom: %s\n", socketerror(err)); + } + return ret; +} + +//============================================================================= + +static int UDP_MakeSocketBroadcastCapable (sys_socket_t socketid) +{ + int i = 1; + + // make this socket broadcast capable + if (setsockopt(socketid, SOL_SOCKET, SO_BROADCAST, (char *)&i, sizeof(i)) + == SOCKET_ERROR) + { + int err = SOCKETERRNO; + Con_SafePrintf ("UDP, setsockopt: %s\n", socketerror(err)); + return -1; + } + net_broadcastsocket = socketid; + + return 0; +} + +//============================================================================= + +int UDP_Broadcast (sys_socket_t socketid, byte *buf, int len) +{ + int ret; + + if (socketid != net_broadcastsocket) + { + if (net_broadcastsocket != 0) + Sys_Error("Attempted to use multiple broadcasts sockets"); + ret = UDP_MakeSocketBroadcastCapable (socketid); + if (ret == -1) + { + Con_Printf("Unable to make socket broadcast capable\n"); + return ret; + } + } + + return UDP_Write (socketid, buf, len, (struct qsockaddr *)&broadcastaddr); +} + +//============================================================================= + +int UDP_Write (sys_socket_t socketid, byte *buf, int len, struct qsockaddr *addr) +{ + int ret; + + ret = sendto (socketid, buf, len, 0, (struct sockaddr *)addr, + sizeof(struct qsockaddr)); + if (ret == SOCKET_ERROR) + { + int err = SOCKETERRNO; + if (err == NET_EWOULDBLOCK) + return 0; + Con_SafePrintf ("UDP_Write, sendto: %s\n", socketerror(err)); + } + return ret; +} + +//============================================================================= + +const char *UDP_AddrToString (struct qsockaddr *addr) +{ + static char buffer[22]; + int haddr; + + haddr = ntohl(((struct sockaddr_in *)addr)->sin_addr.s_addr); + q_snprintf (buffer, sizeof(buffer), "%d.%d.%d.%d:%d", (haddr >> 24) & 0xff, + (haddr >> 16) & 0xff, (haddr >> 8) & 0xff, haddr & 0xff, + ntohs(((struct sockaddr_in *)addr)->sin_port)); + return buffer; +} + +//============================================================================= + +int UDP_StringToAddr (const char *string, struct qsockaddr *addr) +{ + int ha1, ha2, ha3, ha4, hp, ipaddr; + + sscanf(string, "%d.%d.%d.%d:%d", &ha1, &ha2, &ha3, &ha4, &hp); + ipaddr = (ha1 << 24) | (ha2 << 16) | (ha3 << 8) | ha4; + + addr->qsa_family = AF_INET; + ((struct sockaddr_in *)addr)->sin_addr.s_addr = htonl(ipaddr); + ((struct sockaddr_in *)addr)->sin_port = htons((unsigned short)hp); + return 0; +} + +//============================================================================= + +int UDP_GetSocketAddr (sys_socket_t socketid, struct qsockaddr *addr) +{ + socklen_t addrlen = sizeof(struct qsockaddr); + in_addr_t a; + + memset(addr, 0, sizeof(struct qsockaddr)); + if (getsockname(socketid, (struct sockaddr *)addr, &addrlen) != 0) + return -1; + + a = ((struct sockaddr_in *)addr)->sin_addr.s_addr; + if (a == 0 || a == htonl(INADDR_LOOPBACK)) + ((struct sockaddr_in *)addr)->sin_addr.s_addr = myAddr; + + return 0; +} + +//============================================================================= + +int UDP_GetNameFromAddr (struct qsockaddr *addr, char *name) +{ + struct hostent *hostentry; + + hostentry = gethostbyaddr ((char *)&((struct sockaddr_in *)addr)->sin_addr, + sizeof(struct in_addr), AF_INET); + if (hostentry) + { + strncpy (name, (char *)hostentry->h_name, NET_NAMELEN - 1); + return 0; + } + + strcpy (name, UDP_AddrToString (addr)); + return 0; +} + +//============================================================================= + +int UDP_GetAddrFromName (const char *name, struct qsockaddr *addr) +{ + struct hostent *hostentry; + + if (name[0] >= '0' && name[0] <= '9') + return PartialIPAddress (name, addr); + + hostentry = gethostbyname (name); + if (!hostentry) + return -1; + + addr->qsa_family = AF_INET; + ((struct sockaddr_in *)addr)->sin_port = htons((unsigned short)net_hostport); + ((struct sockaddr_in *)addr)->sin_addr.s_addr = + *(in_addr_t *)hostentry->h_addr_list[0]; + + return 0; +} + +//============================================================================= + +int UDP_AddrCompare (struct qsockaddr *addr1, struct qsockaddr *addr2) +{ + if (addr1->qsa_family != addr2->qsa_family) + return -1; + + if (((struct sockaddr_in *)addr1)->sin_addr.s_addr != + ((struct sockaddr_in *)addr2)->sin_addr.s_addr) + return -1; + + if (((struct sockaddr_in *)addr1)->sin_port != + ((struct sockaddr_in *)addr2)->sin_port) + return 1; + + return 0; +} + +//============================================================================= + +int UDP_GetSocketPort (struct qsockaddr *addr) +{ + return ntohs(((struct sockaddr_in *)addr)->sin_port); +} + + +int UDP_SetSocketPort (struct qsockaddr *addr, int port) +{ + ((struct sockaddr_in *)addr)->sin_port = htons((unsigned short)port); + return 0; +} + +//============================================================================= + diff --git a/engine/Quake/net_udp.h b/engine/Quake/net_udp.h new file mode 100644 index 0000000..5df71df --- /dev/null +++ b/engine/Quake/net_udp.h @@ -0,0 +1,45 @@ +/* +Copyright (C) 1996-1997 Id Software, Inc. +Copyright (C) 2010-2014 QuakeSpasm developers + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#ifndef __net_udp_h +#define __net_udp_h + +sys_socket_t UDP_Init (void); +void UDP_Shutdown (void); +void UDP_Listen (qboolean state); +sys_socket_t UDP_OpenSocket (int port); +int UDP_CloseSocket (sys_socket_t socketid); +int UDP_Connect (sys_socket_t socketid, struct qsockaddr *addr); +sys_socket_t UDP_CheckNewConnections (void); +int UDP_Read (sys_socket_t socketid, byte *buf, int len, struct qsockaddr *addr); +int UDP_Write (sys_socket_t socketid, byte *buf, int len, struct qsockaddr *addr); +int UDP_Broadcast (sys_socket_t socketid, byte *buf, int len); +const char *UDP_AddrToString (struct qsockaddr *addr); +int UDP_StringToAddr (const char *string, struct qsockaddr *addr); +int UDP_GetSocketAddr (sys_socket_t socketid, struct qsockaddr *addr); +int UDP_GetNameFromAddr (struct qsockaddr *addr, char *name); +int UDP_GetAddrFromName (const char *name, struct qsockaddr *addr); +int UDP_AddrCompare (struct qsockaddr *addr1, struct qsockaddr *addr2); +int UDP_GetSocketPort (struct qsockaddr *addr); +int UDP_SetSocketPort (struct qsockaddr *addr, int port); + +#endif /* __net_udp_h */ + diff --git a/engine/Quake/net_win.c b/engine/Quake/net_win.c new file mode 100644 index 0000000..2d4ec9e --- /dev/null +++ b/engine/Quake/net_win.c @@ -0,0 +1,122 @@ +/* +Copyright (C) 1996-2001 Id Software, Inc. +Copyright (C) 2010-2014 QuakeSpasm developers + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#include "q_stdinc.h" +#include "arch_def.h" +#include "net_sys.h" +#include "quakedef.h" +#include "net_defs.h" + +#include "net_dgrm.h" +#include "net_loop.h" + +net_driver_t net_drivers[] = +{ + { "Loopback", + false, + Loop_Init, + Loop_Listen, + Loop_SearchForHosts, + Loop_Connect, + Loop_CheckNewConnections, + Loop_GetMessage, + Loop_SendMessage, + Loop_SendUnreliableMessage, + Loop_CanSendMessage, + Loop_CanSendUnreliableMessage, + Loop_Close, + Loop_Shutdown + }, + + { "Datagram", + false, + Datagram_Init, + Datagram_Listen, + Datagram_SearchForHosts, + Datagram_Connect, + Datagram_CheckNewConnections, + Datagram_GetMessage, + Datagram_SendMessage, + Datagram_SendUnreliableMessage, + Datagram_CanSendMessage, + Datagram_CanSendUnreliableMessage, + Datagram_Close, + Datagram_Shutdown + } +}; + +const int net_numdrivers = (sizeof(net_drivers) / sizeof(net_drivers[0])); + + +#include "net_wins.h" +#include "net_wipx.h" + +net_landriver_t net_landrivers[] = +{ + { "Winsock TCPIP", + false, + 0, + WINS_Init, + WINS_Shutdown, + WINS_Listen, + WINS_OpenSocket, + WINS_CloseSocket, + WINS_Connect, + WINS_CheckNewConnections, + WINS_Read, + WINS_Write, + WINS_Broadcast, + WINS_AddrToString, + WINS_StringToAddr, + WINS_GetSocketAddr, + WINS_GetNameFromAddr, + WINS_GetAddrFromName, + WINS_AddrCompare, + WINS_GetSocketPort, + WINS_SetSocketPort + }, + + { "Winsock IPX", + false, + 0, + WIPX_Init, + WIPX_Shutdown, + WIPX_Listen, + WIPX_OpenSocket, + WIPX_CloseSocket, + WIPX_Connect, + WIPX_CheckNewConnections, + WIPX_Read, + WIPX_Write, + WIPX_Broadcast, + WIPX_AddrToString, + WIPX_StringToAddr, + WIPX_GetSocketAddr, + WIPX_GetNameFromAddr, + WIPX_GetAddrFromName, + WIPX_AddrCompare, + WIPX_GetSocketPort, + WIPX_SetSocketPort + } +}; + +const int net_numlandrivers = (sizeof(net_landrivers) / sizeof(net_landrivers[0])); + diff --git a/engine/Quake/net_wins.c b/engine/Quake/net_wins.c new file mode 100644 index 0000000..f45a522 --- /dev/null +++ b/engine/Quake/net_wins.c @@ -0,0 +1,544 @@ +/* +Copyright (C) 1996-2001 Id Software, Inc. +Copyright (C) 2010-2014 QuakeSpasm developers + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#include "q_stdinc.h" +#include "arch_def.h" +#include "net_sys.h" +#include "quakedef.h" +#include "net_defs.h" + +static sys_socket_t net_acceptsocket = INVALID_SOCKET; // socket for fielding new connections +static sys_socket_t net_controlsocket; +static sys_socket_t net_broadcastsocket = 0; +static struct sockaddr_in broadcastaddr; + +static in_addr_t myAddr; + +#include "net_wins.h" + +int winsock_initialized = 0; +WSADATA winsockdata; +#define __wsaerr_static /* not static: used by net_wipx.c too */ +#include "wsaerror.h" + +//============================================================================= + +#if !defined(_USE_WINSOCK2) +static double blocktime; + +static INT_PTR PASCAL FAR BlockingHook (void) +{ + MSG msg; + BOOL ret; + + if ((Sys_DoubleTime() - blocktime) > 2.0) + { + WSACancelBlockingCall(); + return FALSE; + } + + /* get the next message, if any */ + ret = (BOOL) PeekMessage(&msg, NULL, 0, 0, PM_REMOVE); + + /* if we got one, process it */ + if (ret) + { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + + /* TRUE if we got a message */ + return ret; +} +#endif /* ! _USE_WINSOCK2 */ + + +static void WINS_GetLocalAddress (void) +{ + struct hostent *local = NULL; + char buff[MAXHOSTNAMELEN]; + in_addr_t addr; + int err; + + if (myAddr != INADDR_ANY) + return; + + if (gethostname(buff, MAXHOSTNAMELEN) == SOCKET_ERROR) + { + err = SOCKETERRNO; + Con_SafePrintf("WINS_GetLocalAddress: gethostname failed (%s)\n", + socketerror(err)); + return; + } + + buff[MAXHOSTNAMELEN - 1] = 0; +#ifndef _USE_WINSOCK2 + blocktime = Sys_DoubleTime(); + WSASetBlockingHook(BlockingHook); +#endif + local = gethostbyname(buff); + err = WSAGetLastError(); +#ifndef _USE_WINSOCK2 + WSAUnhookBlockingHook(); +#endif + if (local == NULL) + { + Con_SafePrintf("WINS_GetLocalAddress: gethostbyname failed (%s)\n", + __WSAE_StrError(err)); + return; + } + + myAddr = *(in_addr_t *)local->h_addr_list[0]; + + addr = ntohl(myAddr); + sprintf(my_tcpip_address, "%ld.%ld.%ld.%ld", (addr >> 24) & 0xff, (addr >> 16) & 0xff, (addr >> 8) & 0xff, addr & 0xff); +} + + +sys_socket_t WINS_Init (void) +{ + int i, err; + char buff[MAXHOSTNAMELEN]; + + if (COM_CheckParm ("-noudp")) + return -1; + + if (winsock_initialized == 0) + { + err = WSAStartup(MAKEWORD(1,1), &winsockdata); + if (err != 0) + { + Con_SafePrintf("Winsock initialization failed (%s)\n", + socketerror(err)); + return INVALID_SOCKET; + } + } + winsock_initialized++; + + // determine my name & address + if (gethostname(buff, MAXHOSTNAMELEN) != 0) + { + err = SOCKETERRNO; + Con_SafePrintf("WINS_Init: gethostname failed (%s)\n", + socketerror(err)); + } + else + { + buff[MAXHOSTNAMELEN - 1] = 0; + } + i = COM_CheckParm ("-ip"); + if (i) + { + if (i < com_argc-1) + { + myAddr = inet_addr(com_argv[i+1]); + if (myAddr == INADDR_NONE) + Sys_Error ("%s is not a valid IP address", com_argv[i+1]); + strcpy(my_tcpip_address, com_argv[i+1]); + } + else + { + Sys_Error ("NET_Init: you must specify an IP address after -ip"); + } + } + else + { + myAddr = INADDR_ANY; + strcpy(my_tcpip_address, "INADDR_ANY"); + } + + if ((net_controlsocket = WINS_OpenSocket(0)) == INVALID_SOCKET) + { + Con_SafePrintf("WINS_Init: Unable to open control socket, UDP disabled\n"); + if (--winsock_initialized == 0) + WSACleanup (); + return INVALID_SOCKET; + } + + broadcastaddr.sin_family = AF_INET; + broadcastaddr.sin_addr.s_addr = INADDR_BROADCAST; + broadcastaddr.sin_port = htons((unsigned short)net_hostport); + + Con_SafePrintf("UDP Initialized\n"); + tcpipAvailable = true; + + return net_controlsocket; +} + +//============================================================================= + +void WINS_Shutdown (void) +{ + WINS_Listen (false); + WINS_CloseSocket (net_controlsocket); + if (--winsock_initialized == 0) + WSACleanup (); +} + +//============================================================================= + +void WINS_Listen (qboolean state) +{ + // enable listening + if (state) + { + if (net_acceptsocket != INVALID_SOCKET) + return; + WINS_GetLocalAddress(); + if ((net_acceptsocket = WINS_OpenSocket (net_hostport)) == INVALID_SOCKET) + Sys_Error ("WINS_Listen: Unable to open accept socket"); + return; + } + + // disable listening + if (net_acceptsocket == INVALID_SOCKET) + return; + WINS_CloseSocket (net_acceptsocket); + net_acceptsocket = INVALID_SOCKET; +} + +//============================================================================= + +sys_socket_t WINS_OpenSocket (int port) +{ + sys_socket_t newsocket; + struct sockaddr_in address; + u_long _true = 1; + int err; + + if ((newsocket = socket (PF_INET, SOCK_DGRAM, IPPROTO_UDP)) == INVALID_SOCKET) + { + err = SOCKETERRNO; + Con_SafePrintf("WINS_OpenSocket: %s\n", socketerror(err)); + return INVALID_SOCKET; + } + + if (ioctlsocket (newsocket, FIONBIO, &_true) == SOCKET_ERROR) + goto ErrorReturn; + + memset(&address, 0, sizeof(struct sockaddr_in)); + address.sin_family = AF_INET; + address.sin_addr.s_addr = myAddr; + address.sin_port = htons((unsigned short)port); + if (bind (newsocket, (struct sockaddr *)&address, sizeof(address)) == 0) + return newsocket; + + if (tcpipAvailable) + { + err = SOCKETERRNO; + Sys_Error ("Unable to bind to %s (%s)", + WINS_AddrToString ((struct qsockaddr *) &address), + socketerror(err)); + return INVALID_SOCKET; /* not reached */ + } + /* else: we are still in init phase, no need to error */ + +ErrorReturn: + err = SOCKETERRNO; + Con_SafePrintf("WINS_OpenSocket: %s\n", socketerror(err)); + closesocket (newsocket); + return INVALID_SOCKET; +} + +//============================================================================= + +int WINS_CloseSocket (sys_socket_t socketid) +{ + if (socketid == net_broadcastsocket) + net_broadcastsocket = 0; + return closesocket (socketid); +} + +//============================================================================= + +/* +============ +PartialIPAddress + +this lets you type only as much of the net address as required, using +the local network components to fill in the rest +============ +*/ +static int PartialIPAddress (const char *in, struct qsockaddr *hostaddr) +{ + char buff[256]; + char *b; + int addr, mask, num, port, run; + + buff[0] = '.'; + b = buff; + strcpy(buff+1, in); + if (buff[1] == '.') + b++; + + addr = 0; + mask = -1; + while (*b == '.') + { + b++; + num = 0; + run = 0; + while (!( *b < '0' || *b > '9')) + { + num = num*10 + *b++ - '0'; + if (++run > 3) + return -1; + } + if ((*b < '0' || *b > '9') && *b != '.' && *b != ':' && *b != 0) + return -1; + if (num < 0 || num > 255) + return -1; + mask <<= 8; + addr = (addr<<8) + num; + } + + if (*b++ == ':') + port = Q_atoi(b); + else + port = net_hostport; + + hostaddr->qsa_family = AF_INET; + ((struct sockaddr_in *)hostaddr)->sin_port = htons((unsigned short)port); + ((struct sockaddr_in *)hostaddr)->sin_addr.s_addr = + (myAddr & htonl(mask)) | htonl(addr); + + return 0; +} + +//============================================================================= + +int WINS_Connect (sys_socket_t socketid, struct qsockaddr *addr) +{ + return 0; +} + +//============================================================================= + +sys_socket_t WINS_CheckNewConnections (void) +{ + char buf[4096]; + + if (net_acceptsocket == INVALID_SOCKET) + return INVALID_SOCKET; + + if (recvfrom (net_acceptsocket, buf, sizeof(buf), MSG_PEEK, NULL, NULL) + != SOCKET_ERROR) + { + return net_acceptsocket; + } + return INVALID_SOCKET; +} + +//============================================================================= + +int WINS_Read (sys_socket_t socketid, byte *buf, int len, struct qsockaddr *addr) +{ + socklen_t addrlen = sizeof(struct qsockaddr); + int ret; + + ret = recvfrom (socketid, (char *)buf, len, 0, (struct sockaddr *)addr, &addrlen); + if (ret == SOCKET_ERROR) + { + int err = SOCKETERRNO; + if (err == NET_EWOULDBLOCK || err == NET_ECONNREFUSED) + return 0; + Con_SafePrintf ("WINS_Read, recvfrom: %s\n", socketerror(err)); + } + return ret; +} + +//============================================================================= + +static int WINS_MakeSocketBroadcastCapable (sys_socket_t socketid) +{ + int i = 1; + + // make this socket broadcast capable + if (setsockopt(socketid, SOL_SOCKET, SO_BROADCAST, (char *)&i, sizeof(i)) + == SOCKET_ERROR) + { + int err = SOCKETERRNO; + Con_SafePrintf ("UDP, setsockopt: %s\n", socketerror(err)); + return -1; + } + net_broadcastsocket = socketid; + + return 0; +} + +//============================================================================= + +int WINS_Broadcast (sys_socket_t socketid, byte *buf, int len) +{ + int ret; + + if (socketid != net_broadcastsocket) + { + if (net_broadcastsocket != 0) + Sys_Error("Attempted to use multiple broadcasts sockets"); + WINS_GetLocalAddress(); + ret = WINS_MakeSocketBroadcastCapable (socketid); + if (ret == -1) + { + Con_Printf("Unable to make socket broadcast capable\n"); + return ret; + } + } + + return WINS_Write (socketid, buf, len, (struct qsockaddr *)&broadcastaddr); +} + +//============================================================================= + +int WINS_Write (sys_socket_t socketid, byte *buf, int len, struct qsockaddr *addr) +{ + int ret; + + ret = sendto (socketid, (char *)buf, len, 0, (struct sockaddr *)addr, + sizeof(struct qsockaddr)); + if (ret == SOCKET_ERROR) + { + int err = SOCKETERRNO; + if (err == NET_EWOULDBLOCK) + return 0; + Con_SafePrintf ("WINS_Write, sendto: %s\n", socketerror(err)); + } + return ret; +} + +//============================================================================= + +const char *WINS_AddrToString (struct qsockaddr *addr) +{ + static char buffer[22]; + int haddr; + + haddr = ntohl(((struct sockaddr_in *)addr)->sin_addr.s_addr); + sprintf(buffer, "%d.%d.%d.%d:%d", (haddr >> 24) & 0xff, + (haddr >> 16) & 0xff, (haddr >> 8) & 0xff, haddr & 0xff, + ntohs(((struct sockaddr_in *)addr)->sin_port)); + return buffer; +} + +//============================================================================= + +int WINS_StringToAddr (const char *string, struct qsockaddr *addr) +{ + int ha1, ha2, ha3, ha4, hp, ipaddr; + + sscanf(string, "%d.%d.%d.%d:%d", &ha1, &ha2, &ha3, &ha4, &hp); + ipaddr = (ha1 << 24) | (ha2 << 16) | (ha3 << 8) | ha4; + + addr->qsa_family = AF_INET; + ((struct sockaddr_in *)addr)->sin_addr.s_addr = htonl(ipaddr); + ((struct sockaddr_in *)addr)->sin_port = htons((unsigned short)hp); + return 0; +} + +//============================================================================= + +int WINS_GetSocketAddr (sys_socket_t socketid, struct qsockaddr *addr) +{ + socklen_t addrlen = sizeof(struct qsockaddr); + in_addr_t a; + + memset(addr, 0, sizeof(struct qsockaddr)); + getsockname(socketid, (struct sockaddr *)addr, &addrlen); + + a = ((struct sockaddr_in *)addr)->sin_addr.s_addr; + if (a == 0 || a == htonl(INADDR_LOOPBACK)) + ((struct sockaddr_in *)addr)->sin_addr.s_addr = myAddr; + + return 0; +} + +//============================================================================= + +int WINS_GetNameFromAddr (struct qsockaddr *addr, char *name) +{ + struct hostent *hostentry; + + hostentry = gethostbyaddr ((char *)&((struct sockaddr_in *)addr)->sin_addr, + sizeof(struct in_addr), AF_INET); + if (hostentry) + { + Q_strncpy (name, (char *)hostentry->h_name, NET_NAMELEN - 1); + return 0; + } + + Q_strcpy (name, WINS_AddrToString (addr)); + return 0; +} + +//============================================================================= + +int WINS_GetAddrFromName (const char *name, struct qsockaddr *addr) +{ + struct hostent *hostentry; + + if (name[0] >= '0' && name[0] <= '9') + return PartialIPAddress (name, addr); + + hostentry = gethostbyname (name); + if (!hostentry) + return -1; + + addr->qsa_family = AF_INET; + ((struct sockaddr_in *)addr)->sin_port = htons((unsigned short)net_hostport); + ((struct sockaddr_in *)addr)->sin_addr.s_addr = + *(in_addr_t *)hostentry->h_addr_list[0]; + + return 0; +} + +//============================================================================= + +int WINS_AddrCompare (struct qsockaddr *addr1, struct qsockaddr *addr2) +{ + if (addr1->qsa_family != addr2->qsa_family) + return -1; + + if (((struct sockaddr_in *)addr1)->sin_addr.s_addr != + ((struct sockaddr_in *)addr2)->sin_addr.s_addr) + return -1; + + if (((struct sockaddr_in *)addr1)->sin_port != + ((struct sockaddr_in *)addr2)->sin_port) + return 1; + + return 0; +} + +//============================================================================= + +int WINS_GetSocketPort (struct qsockaddr *addr) +{ + return ntohs(((struct sockaddr_in *)addr)->sin_port); +} + + +int WINS_SetSocketPort (struct qsockaddr *addr, int port) +{ + ((struct sockaddr_in *)addr)->sin_port = htons((unsigned short)port); + return 0; +} + +//============================================================================= + diff --git a/engine/code/net_wins.h b/engine/Quake/net_wins.h similarity index 50% rename from engine/code/net_wins.h rename to engine/Quake/net_wins.h index 756ce64..59abda4 100644 --- a/engine/code/net_wins.h +++ b/engine/Quake/net_wins.h @@ -1,5 +1,6 @@ /* -Copyright (C) 1996-1997 Id Software, Inc. +Copyright (C) 1996-2001 Id Software, Inc. +Copyright (C) 2010-2014 QuakeSpasm developers This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -8,7 +9,7 @@ of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. @@ -17,23 +18,28 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -// net_wins.h -int WINS_Init (void); +#ifndef __NET_WINSOCK_H +#define __NET_WINSOCK_H + +sys_socket_t WINS_Init (void); void WINS_Shutdown (void); void WINS_Listen (qboolean state); -int WINS_OpenSocket (int port); -int WINS_CloseSocket (int socket); -int WINS_Connect (int socket, struct qsockaddr *addr); -int WINS_CheckNewConnections (void); -int WINS_Read (int socket, byte *buf, int len, struct qsockaddr *addr); -int WINS_Write (int socket, byte *buf, int len, struct qsockaddr *addr); -int WINS_Broadcast (int socket, byte *buf, int len); -char *WINS_AddrToString (struct qsockaddr *addr); -int WINS_StringToAddr (char *string, struct qsockaddr *addr); -int WINS_GetSocketAddr (int socket, struct qsockaddr *addr); +sys_socket_t WINS_OpenSocket (int port); +int WINS_CloseSocket (sys_socket_t socketid); +int WINS_Connect (sys_socket_t socketid, struct qsockaddr *addr); +sys_socket_t WINS_CheckNewConnections (void); +int WINS_Read (sys_socket_t socketid, byte *buf, int len, struct qsockaddr *addr); +int WINS_Write (sys_socket_t socketid, byte *buf, int len, struct qsockaddr *addr); +int WINS_Broadcast (sys_socket_t socketid, byte *buf, int len); +const char *WINS_AddrToString (struct qsockaddr *addr); +int WINS_StringToAddr (const char *string, struct qsockaddr *addr); +int WINS_GetSocketAddr (sys_socket_t socketid, struct qsockaddr *addr); int WINS_GetNameFromAddr (struct qsockaddr *addr, char *name); -int WINS_GetAddrFromName (char *name, struct qsockaddr *addr); +int WINS_GetAddrFromName (const char *name, struct qsockaddr *addr); int WINS_AddrCompare (struct qsockaddr *addr1, struct qsockaddr *addr2); int WINS_GetSocketPort (struct qsockaddr *addr); int WINS_SetSocketPort (struct qsockaddr *addr, int port); + +#endif /* __NET_WINSOCK_H */ + diff --git a/engine/code/net_wipx.c b/engine/Quake/net_wipx.c similarity index 54% rename from engine/code/net_wipx.c rename to engine/Quake/net_wipx.c index c6f9f10..155686b 100644 --- a/engine/code/net_wipx.c +++ b/engine/Quake/net_wipx.c @@ -1,5 +1,6 @@ /* -Copyright (C) 1996-1997 Id Software, Inc. +Copyright (C) 1996-2001 Id Software, Inc. +Copyright (C) 2010-2014 QuakeSpasm developers This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -8,7 +9,7 @@ of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. @@ -17,56 +18,52 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + // net_wipx.c -#include "quakedef.h" -#include "winquake.h" +#include "q_stdinc.h" +#include "arch_def.h" +#include "net_sys.h" #include +#include "quakedef.h" +#include "net_defs.h" #include "net_wipx.h" extern cvar_t hostname; -#define MAXHOSTNAMELEN 256 - -static int net_acceptsocket = -1; // socket for fielding new connections -static int net_controlsocket; -static struct qsockaddr broadcastaddr; +static sys_socket_t net_acceptsocket = INVALID_SOCKET; // socket for fielding new connections +static sys_socket_t net_controlsocket; +static struct sockaddr_ipx broadcastaddr; +/* externs from net_wins.c: */ extern qboolean winsock_initialized; extern WSADATA winsockdata; +extern const char *__WSAE_StrError (int); #define IPXSOCKETS 18 -static int ipxsocket[IPXSOCKETS]; +static sys_socket_t ipxsocket[IPXSOCKETS]; static int sequence[IPXSOCKETS]; //============================================================================= -int WIPX_Init (void) +sys_socket_t WIPX_Init (void) { - int i; + int i, err; + char *colon; char buff[MAXHOSTNAMELEN]; - struct qsockaddr addr; - char *p; - int r; - WORD wVersionRequested; + struct qsockaddr addr; if (COM_CheckParm ("-noipx")) - return -1; - -// make sure LoadLibrary has happened successfully - if (!winsock_lib_initialized) - return -1; + return INVALID_SOCKET; if (winsock_initialized == 0) { - wVersionRequested = MAKEWORD(1, 1); - - r = pWSAStartup (MAKEWORD(1, 1), &winsockdata); - - if (r) + err = WSAStartup(MAKEWORD(1,1), &winsockdata); + if (err != 0) { - Con_Printf ("Winsock initialization failed.\n"); - return -1; + Con_SafePrintf("Winsock initialization failed (%s)\n", + socketerror(err)); + return INVALID_SOCKET; } } winsock_initialized++; @@ -75,48 +72,37 @@ int WIPX_Init (void) ipxsocket[i] = 0; // determine my name & address - if (pgethostname(buff, MAXHOSTNAMELEN) == 0) + if (gethostname(buff, MAXHOSTNAMELEN) != 0) { - // if the quake hostname isn't set, set it to the machine name - if (Q_strcmp(hostname.string, "UNNAMED") == 0) - { - // see if it's a text IP address (well, close enough) - for (p = buff; *p; p++) - if ((*p < '0' || *p > '9') && *p != '.') - break; - - // if it is a real name, strip off the domain; we only want the host - if (*p) - { - for (i = 0; i < 15; i++) - if (buff[i] == '.') - break; - buff[i] = 0; - } - Cvar_Set ("hostname", buff); - } + err = SOCKETERRNO; + Con_SafePrintf("WIPX_Init: gethostname failed (%s)\n", + socketerror(err)); + } + else + { + buff[MAXHOSTNAMELEN - 1] = 0; } - if ((net_controlsocket = WIPX_OpenSocket (0)) == -1) + if ((net_controlsocket = WIPX_OpenSocket(0)) == INVALID_SOCKET) { - Con_Printf("WIPX_Init: Unable to open control socket\n"); + Con_SafePrintf("WIPX_Init: Unable to open control socket, IPX disabled\n"); if (--winsock_initialized == 0) - pWSACleanup (); - return -1; + WSACleanup (); + return INVALID_SOCKET; } - ((struct sockaddr_ipx *)&broadcastaddr)->sa_family = AF_IPX; - memset(((struct sockaddr_ipx *)&broadcastaddr)->sa_netnum, 0, 4); - memset(((struct sockaddr_ipx *)&broadcastaddr)->sa_nodenum, 0xff, 6); - ((struct sockaddr_ipx *)&broadcastaddr)->sa_socket = htons((unsigned short)net_hostport); + broadcastaddr.sa_family = AF_IPX; + memset(broadcastaddr.sa_netnum, 0, 4); + memset(broadcastaddr.sa_nodenum, 0xff, 6); + broadcastaddr.sa_socket = htons((unsigned short)net_hostport); WIPX_GetSocketAddr (net_controlsocket, &addr); - Q_strcpy(my_ipx_address, WIPX_AddrToString (&addr)); - p = Q_strrchr (my_ipx_address, ':'); - if (p) - *p = 0; + Q_strcpy(my_ipx_address, WIPX_AddrToString (&addr)); + colon = Q_strrchr (my_ipx_address, ':'); + if (colon) + *colon = 0; - Con_Printf("Winsock IPX Initialized\n"); + Con_SafePrintf("IPX Initialized\n"); ipxAvailable = true; return net_controlsocket; @@ -129,7 +115,7 @@ void WIPX_Shutdown (void) WIPX_Listen (false); WIPX_CloseSocket (net_controlsocket); if (--winsock_initialized == 0) - pWSACleanup (); + WSACleanup (); } //============================================================================= @@ -139,163 +125,182 @@ void WIPX_Listen (qboolean state) // enable listening if (state) { - if (net_acceptsocket != -1) + if (net_acceptsocket != INVALID_SOCKET) return; - if ((net_acceptsocket = WIPX_OpenSocket (net_hostport)) == -1) - Sys_Error ("WIPX_Listen: Unable to open accept socket\n"); + if ((net_acceptsocket = WIPX_OpenSocket (net_hostport)) == INVALID_SOCKET) + Sys_Error ("WIPX_Listen: Unable to open accept socket"); return; } // disable listening - if (net_acceptsocket == -1) + if (net_acceptsocket == INVALID_SOCKET) return; WIPX_CloseSocket (net_acceptsocket); - net_acceptsocket = -1; + net_acceptsocket = INVALID_SOCKET; } //============================================================================= -int WIPX_OpenSocket (int port) +sys_socket_t WIPX_OpenSocket (int port) { - int handle; - int newsocket; + int err; + sys_socket_t handle, newsocket; struct sockaddr_ipx address; u_long _true = 1; for (handle = 0; handle < IPXSOCKETS; handle++) + { if (ipxsocket[handle] == 0) break; + } if (handle == IPXSOCKETS) - return -1; + { + Con_SafePrintf("WIPX_OpenSocket: Out of free IPX handles.\n"); + return INVALID_SOCKET; + } - if ((newsocket = psocket (AF_IPX, SOCK_DGRAM, NSPROTO_IPX)) == INVALID_SOCKET) - return -1; + if ((newsocket = socket (AF_IPX, SOCK_DGRAM, NSPROTO_IPX)) == INVALID_SOCKET) + { + err = SOCKETERRNO; + Con_SafePrintf("WIPX_OpenSocket: %s\n", socketerror(err)); + return INVALID_SOCKET; + } - if (pioctlsocket (newsocket, FIONBIO, &_true) == -1) + if (ioctlsocket (newsocket, FIONBIO, &_true) == SOCKET_ERROR) goto ErrorReturn; - if (psetsockopt(newsocket, SOL_SOCKET, SO_BROADCAST, (char *)&_true, sizeof(_true)) < 0) + if (setsockopt(newsocket, SOL_SOCKET, SO_BROADCAST, (char *)&_true, sizeof(_true)) + == SOCKET_ERROR) goto ErrorReturn; address.sa_family = AF_IPX; memset(address.sa_netnum, 0, 4); memset(address.sa_nodenum, 0, 6);; address.sa_socket = htons((unsigned short)port); - if( bind (newsocket, (void *)&address, sizeof(address)) == 0) + if (bind (newsocket, (struct sockaddr *)&address, sizeof(address)) == 0) { ipxsocket[handle] = newsocket; sequence[handle] = 0; return handle; } - Sys_Error ("Winsock IPX bind failed\n"); + if (ipxAvailable) + { + err = SOCKETERRNO; + Sys_Error ("IPX bind failed (%s)", socketerror(err)); + return INVALID_SOCKET; /* not reached */ + } + /* else: we are still in init phase, no need to error */ + ErrorReturn: - pclosesocket (newsocket); - return -1; + err = SOCKETERRNO; + Con_SafePrintf("WIPX_OpenSocket: %s\n", socketerror(err)); + closesocket (newsocket); + return INVALID_SOCKET; } //============================================================================= -int WIPX_CloseSocket (int handle) +int WIPX_CloseSocket (sys_socket_t handle) { - int socket = ipxsocket[handle]; + sys_socket_t socketid = ipxsocket[handle]; int ret; - ret = pclosesocket (socket); + ret = closesocket (socketid); ipxsocket[handle] = 0; return ret; } - //============================================================================= -int WIPX_Connect (int handle, struct qsockaddr *addr) +int WIPX_Connect (sys_socket_t handle, struct qsockaddr *addr) { return 0; } //============================================================================= -int WIPX_CheckNewConnections (void) +sys_socket_t WIPX_CheckNewConnections (void) { - unsigned long available; + u_long available; - if (net_acceptsocket == -1) - return -1; + if (net_acceptsocket == INVALID_SOCKET) + return INVALID_SOCKET; - if (pioctlsocket (ipxsocket[net_acceptsocket], FIONREAD, &available) == -1) - Sys_Error ("WIPX: ioctlsocket (FIONREAD) failed\n"); + if (ioctlsocket (ipxsocket[net_acceptsocket], FIONREAD, &available) == SOCKET_ERROR) + { + int err = SOCKETERRNO; + Sys_Error ("WIPX: ioctlsocket (FIONREAD) failed (%s)", socketerror(err)); + } if (available) return net_acceptsocket; - return -1; + return INVALID_SOCKET; } //============================================================================= -static byte packetBuffer[NET_DATAGRAMSIZE + 4]; +static byte netpacketBuffer[NET_DATAGRAMSIZE + 4]; -int WIPX_Read (int handle, byte *buf, int len, struct qsockaddr *addr) +int WIPX_Read (sys_socket_t handle, byte *buf, int len, struct qsockaddr *addr) { - int addrlen = sizeof (struct qsockaddr); - int socket = ipxsocket[handle]; + socklen_t addrlen = sizeof(struct qsockaddr); + sys_socket_t socketid = ipxsocket[handle]; int ret; - ret = precvfrom (socket, packetBuffer, len+4, 0, (struct sockaddr *)addr, &addrlen); - if (ret == -1) + ret = recvfrom (socketid, (char *)netpacketBuffer, len+4, 0, (struct sockaddr *)addr, &addrlen); + if (ret == SOCKET_ERROR) { - // jkrige - vs2005 - //int errno = pWSAGetLastError(); - - //if (errno == WSAEWOULDBLOCK || errno == WSAECONNREFUSED) - // return 0; - int err = pWSAGetLastError(); - - if (err == WSAEWOULDBLOCK || err == WSAECONNREFUSED) + int err = SOCKETERRNO; + if (err == NET_EWOULDBLOCK || err == NET_ECONNREFUSED) return 0; - // jkrige - vs2005 + Con_SafePrintf ("WIPX_Read, recvfrom: %s\n", socketerror(err)); } if (ret < 4) return 0; - + // remove sequence number, it's only needed for DOS IPX ret -= 4; - memcpy(buf, packetBuffer+4, ret); + memcpy(buf, netpacketBuffer+4, ret); return ret; } //============================================================================= -int WIPX_Broadcast (int handle, byte *buf, int len) +int WIPX_Broadcast (sys_socket_t handle, byte *buf, int len) { - return WIPX_Write (handle, buf, len, &broadcastaddr); + return WIPX_Write (handle, buf, len, (struct qsockaddr *)&broadcastaddr); } //============================================================================= -int WIPX_Write (int handle, byte *buf, int len, struct qsockaddr *addr) +int WIPX_Write (sys_socket_t handle, byte *buf, int len, struct qsockaddr *addr) { - int socket = ipxsocket[handle]; + sys_socket_t socketid = ipxsocket[handle]; int ret; // build packet with sequence number - *(int *)(&packetBuffer[0]) = sequence[handle]; + memcpy(&netpacketBuffer[0], &sequence[handle], 4); sequence[handle]++; - memcpy(&packetBuffer[4], buf, len); + memcpy(&netpacketBuffer[4], buf, len); len += 4; - ret = psendto (socket, packetBuffer, len, 0, (struct sockaddr *)addr, sizeof(struct qsockaddr)); - if (ret == -1) - if (pWSAGetLastError() == WSAEWOULDBLOCK) + ret = sendto (socketid, (char *)netpacketBuffer, len, 0, (struct sockaddr *)addr, sizeof(struct qsockaddr)); + if (ret == SOCKET_ERROR) + { + int err = SOCKETERRNO; + if (err == NET_EWOULDBLOCK) return 0; + Con_SafePrintf ("WIPX_Write, sendto: %s\n", socketerror(err)); + } return ret; } //============================================================================= -char *WIPX_AddrToString (struct qsockaddr *addr) +const char *WIPX_AddrToString (struct qsockaddr *addr) { static char buf[28]; @@ -317,21 +322,22 @@ char *WIPX_AddrToString (struct qsockaddr *addr) //============================================================================= -int WIPX_StringToAddr (char *string, struct qsockaddr *addr) +int WIPX_StringToAddr (const char *string, struct qsockaddr *addr) { - int val; - char buf[3]; + int val; + char buf[3]; buf[2] = 0; Q_memset(addr, 0, sizeof(struct qsockaddr)); - addr->sa_family = AF_IPX; + addr->qsa_family = AF_IPX; -#define DO(src,dest) \ - buf[0] = string[src]; \ - buf[1] = string[src + 1]; \ - if (sscanf (buf, "%x", &val) != 1) \ - return -1; \ - ((struct sockaddr_ipx *)addr)->dest = val +#define DO(src,dest) do { \ + buf[0] = string[src]; \ + buf[1] = string[src + 1]; \ + if (sscanf (buf, "%x", &val) != 1) \ + return -1; \ + ((struct sockaddr_ipx *)addr)->dest = val; \ + } while (0) DO(0, sa_netnum[0]); DO(2, sa_netnum[1]); @@ -353,19 +359,17 @@ int WIPX_StringToAddr (char *string, struct qsockaddr *addr) //============================================================================= -int WIPX_GetSocketAddr (int handle, struct qsockaddr *addr) +int WIPX_GetSocketAddr (sys_socket_t handle, struct qsockaddr *addr) { - int socket = ipxsocket[handle]; - int addrlen = sizeof(struct qsockaddr); - unsigned int a; + sys_socket_t socketid = ipxsocket[handle]; + socklen_t addrlen = sizeof(struct qsockaddr); Q_memset(addr, 0, sizeof(struct qsockaddr)); - if(pgetsockname(socket, (struct sockaddr *)addr, &addrlen) != 0) + if (getsockname(socketid, (struct sockaddr *)addr, &addrlen) != 0) { - // jkrige - vs2005 - //int errno = pWSAGetLastError(); - int err = pWSAGetLastError(); - // jkrige - vs2005 + int err = SOCKETERRNO; + /* FIXME: what action should be taken?... */ + Con_SafePrintf ("WIPX, getsockname: %s\n", socketerror(err)); } return 0; @@ -381,10 +385,10 @@ int WIPX_GetNameFromAddr (struct qsockaddr *addr, char *name) //============================================================================= -int WIPX_GetAddrFromName(char *name, struct qsockaddr *addr) +int WIPX_GetAddrFromName (const char *name, struct qsockaddr *addr) { - int n; - char buf[32]; + int n; + char buf[32]; n = Q_strlen(name); @@ -408,17 +412,20 @@ int WIPX_GetAddrFromName(char *name, struct qsockaddr *addr) int WIPX_AddrCompare (struct qsockaddr *addr1, struct qsockaddr *addr2) { - if (addr1->sa_family != addr2->sa_family) + if (addr1->qsa_family != addr2->qsa_family) return -1; if (*((struct sockaddr_ipx *)addr1)->sa_netnum && *((struct sockaddr_ipx *)addr2)->sa_netnum) + { if (memcmp(((struct sockaddr_ipx *)addr1)->sa_netnum, ((struct sockaddr_ipx *)addr2)->sa_netnum, 4) != 0) return -1; + } + if (memcmp(((struct sockaddr_ipx *)addr1)->sa_nodenum, ((struct sockaddr_ipx *)addr2)->sa_nodenum, 6) != 0) return -1; if (((struct sockaddr_ipx *)addr1)->sa_socket != ((struct sockaddr_ipx *)addr2)->sa_socket) - return 1; + return 1; return 0; } @@ -438,3 +445,4 @@ int WIPX_SetSocketPort (struct qsockaddr *addr, int port) } //============================================================================= + diff --git a/engine/code/net_wipx.h b/engine/Quake/net_wipx.h similarity index 50% rename from engine/code/net_wipx.h rename to engine/Quake/net_wipx.h index ed82dc1..e8a24d3 100644 --- a/engine/code/net_wipx.h +++ b/engine/Quake/net_wipx.h @@ -1,5 +1,6 @@ /* -Copyright (C) 1996-1997 Id Software, Inc. +Copyright (C) 1996-2001 Id Software, Inc. +Copyright (C) 2010-2014 QuakeSpasm developers This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -8,7 +9,7 @@ of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. @@ -17,23 +18,28 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -// net_wipx.h -int WIPX_Init (void); +#ifndef __NET_WINIPX_H +#define __NET_WINIPX_H + +sys_socket_t WIPX_Init (void); void WIPX_Shutdown (void); void WIPX_Listen (qboolean state); -int WIPX_OpenSocket (int port); -int WIPX_CloseSocket (int socket); -int WIPX_Connect (int socket, struct qsockaddr *addr); -int WIPX_CheckNewConnections (void); -int WIPX_Read (int socket, byte *buf, int len, struct qsockaddr *addr); -int WIPX_Write (int socket, byte *buf, int len, struct qsockaddr *addr); -int WIPX_Broadcast (int socket, byte *buf, int len); -char *WIPX_AddrToString (struct qsockaddr *addr); -int WIPX_StringToAddr (char *string, struct qsockaddr *addr); -int WIPX_GetSocketAddr (int socket, struct qsockaddr *addr); +sys_socket_t WIPX_OpenSocket (int port); +int WIPX_CloseSocket (sys_socket_t socketid); +int WIPX_Connect (sys_socket_t socketid, struct qsockaddr *addr); +sys_socket_t WIPX_CheckNewConnections (void); +int WIPX_Read (sys_socket_t socketid, byte *buf, int len, struct qsockaddr *addr); +int WIPX_Write (sys_socket_t socketid, byte *buf, int len, struct qsockaddr *addr); +int WIPX_Broadcast (sys_socket_t socketid, byte *buf, int len); +const char *WIPX_AddrToString (struct qsockaddr *addr); +int WIPX_StringToAddr (const char *string, struct qsockaddr *addr); +int WIPX_GetSocketAddr (sys_socket_t socketid, struct qsockaddr *addr); int WIPX_GetNameFromAddr (struct qsockaddr *addr, char *name); -int WIPX_GetAddrFromName (char *name, struct qsockaddr *addr); +int WIPX_GetAddrFromName (const char *name, struct qsockaddr *addr); int WIPX_AddrCompare (struct qsockaddr *addr1, struct qsockaddr *addr2); int WIPX_GetSocketPort (struct qsockaddr *addr); int WIPX_SetSocketPort (struct qsockaddr *addr, int port); + +#endif /* __NET_WINIPX_H */ + diff --git a/engine/Quake/pl_linux.c b/engine/Quake/pl_linux.c new file mode 100644 index 0000000..9e62ceb --- /dev/null +++ b/engine/Quake/pl_linux.c @@ -0,0 +1,95 @@ +/* +Copyright (C) 1996-2001 Id Software, Inc. +Copyright (C) 2002-2005 John Fitzgibbons and others +Copyright (C) 2007-2008 Kristian Duske +Copyright (C) 2010-2014 QuakeSpasm developers + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#include "quakedef.h" +#if defined(SDL_FRAMEWORK) || defined(NO_SDL_CONFIG) +#if defined(USE_SDL2) +#include +#else +#include +#endif +#else +#include "SDL.h" +#endif + +static const Uint8 bmp_bytes[] = +{ +#include "qs_bmp.h" +}; + +void PL_SetWindowIcon (void) +{ + SDL_RWops *rwop; + SDL_Surface *icon; + Uint32 colorkey; + + /* SDL_RWFromConstMem() requires SDL >= 1.2.7 */ + rwop = SDL_RWFromConstMem(bmp_bytes, sizeof(bmp_bytes)); + if (rwop == NULL) + return; + icon = SDL_LoadBMP_RW(rwop, 1); + if (icon == NULL) + return; + /* make pure magenta (#ff00ff) tranparent */ + colorkey = SDL_MapRGB(icon->format, 255, 0, 255); +#if defined(USE_SDL2) + SDL_SetColorKey(icon, SDL_TRUE, colorkey); + SDL_SetWindowIcon((SDL_Window*) VID_GetWindow(), icon); +#else + SDL_SetColorKey(icon, SDL_SRCCOLORKEY, colorkey); + SDL_WM_SetIcon(icon, NULL); +#endif + SDL_FreeSurface(icon); +} + +void PL_VID_Shutdown (void) +{ +} + +#define MAX_CLIPBOARDTXT MAXCMDLINE /* 256 */ +char *PL_GetClipboardData (void) +{ + char *data = NULL; +#if defined(USE_SDL2) + char *cliptext = SDL_GetClipboardText(); + + if (cliptext != NULL) + { + size_t size = strlen(cliptext) + 1; + /* this is intended for simple small text copies + * such as an ip address, etc: do chop the size + * here, otherwise we may experience Z_Malloc() + * failures and all other not-oh-so-fun stuff. */ + size = q_min(MAX_CLIPBOARDTXT, size); + data = (char *) Z_Malloc(size); + q_strlcpy (data, cliptext, size); + } +#endif + + return data; +} + +void PL_ErrorDialog (const char *errorMsg) +{ +} + diff --git a/engine/Quake/pl_osx.m b/engine/Quake/pl_osx.m new file mode 100644 index 0000000..e1022dd --- /dev/null +++ b/engine/Quake/pl_osx.m @@ -0,0 +1,77 @@ +/* +Copyright (C) 1996-2001 Id Software, Inc. +Copyright (C) 2002-2005 John Fitzgibbons and others +Copyright (C) 2007-2008 Kristian Duske +Copyright (C) 2010-2014 QuakeSpasm developers + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#include "quakedef.h" +#if defined(SDL_FRAMEWORK) || defined(NO_SDL_CONFIG) +#if defined(USE_SDL2) +#include +#else +#include +#endif +#else +#include "SDL.h" +#endif +#import + +void PL_SetWindowIcon (void) +{ +/* nothing to do on OS X */ +} + +void PL_VID_Shutdown (void) +{ +} + +#define MAX_CLIPBOARDTXT MAXCMDLINE /* 256 */ +char *PL_GetClipboardData (void) +{ + char *data = NULL; + NSPasteboard* pasteboard = [NSPasteboard generalPasteboard]; + NSArray* types = [pasteboard types]; + + if ([types containsObject: NSStringPboardType]) { + NSString* clipboardString = [pasteboard stringForType: NSStringPboardType]; + if (clipboardString != NULL && [clipboardString length] > 0) { + size_t sz = [clipboardString length] + 1; + sz = q_min(MAX_CLIPBOARDTXT, sz); + data = (char *) Z_Malloc(sz); +#if (MAC_OS_X_VERSION_MIN_REQUIRED < 1040) /* for ppc builds targeting 10.3 and older */ + q_strlcpy (data, [clipboardString cString], sz); +#else + q_strlcpy (data, [clipboardString cStringUsingEncoding: NSASCIIStringEncoding], sz); +#endif + } + } + return data; +} + +void PL_ErrorDialog(const char *errorMsg) +{ +#if (MAC_OS_X_VERSION_MIN_REQUIRED < 1040) /* ppc builds targeting 10.3 and older */ + NSString* msg = [NSString stringWithCString:errorMsg]; +#else + NSString* msg = [NSString stringWithCString:errorMsg encoding:NSASCIIStringEncoding]; +#endif + NSRunCriticalAlertPanel (@"Quake Error", @"%@", @"OK", nil, nil, msg); +} + diff --git a/engine/Quake/pl_win.c b/engine/Quake/pl_win.c new file mode 100644 index 0000000..d6a5045 --- /dev/null +++ b/engine/Quake/pl_win.c @@ -0,0 +1,114 @@ +/* +Copyright (C) 1996-2001 Id Software, Inc. +Copyright (C) 2002-2005 John Fitzgibbons and others +Copyright (C) 2007-2008 Kristian Duske +Copyright (C) 2010-2014 QuakeSpasm developers + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#include "quakedef.h" +#include +#if defined(SDL_FRAMEWORK) || defined(NO_SDL_CONFIG) +#if defined(USE_SDL2) +#include +#include +#else +#include +#include +#endif +#else +#include "SDL.h" +#include "SDL_syswm.h" +#endif + +static HICON icon; + +void PL_SetWindowIcon (void) +{ + HINSTANCE handle; + SDL_SysWMinfo wminfo; + HWND hwnd; + + handle = GetModuleHandle(NULL); + icon = LoadIcon(handle, "icon"); + + if (!icon) + return; /* no icon in the exe */ + + SDL_VERSION(&wminfo.version); + +#if defined(USE_SDL2) + if (SDL_GetWindowWMInfo((SDL_Window*) VID_GetWindow(), &wminfo) != SDL_TRUE) + return; /* wrong SDL version */ + + hwnd = wminfo.info.win.window; +#else + if (SDL_GetWMInfo(&wminfo) != 1) + return; /* wrong SDL version */ + + hwnd = wminfo.window; +#endif +#ifdef _WIN64 + SetClassLongPtr(hwnd, GCLP_HICON, (LONG_PTR) icon); +#else + SetClassLong(hwnd, GCL_HICON, (LONG) icon); +#endif +} + +void PL_VID_Shutdown (void) +{ + DestroyIcon(icon); +} + +#define MAX_CLIPBOARDTXT MAXCMDLINE /* 256 */ +char *PL_GetClipboardData (void) +{ + char *data = NULL; + char *cliptext; + + if (OpenClipboard(NULL) != 0) + { + HANDLE hClipboardData; + + if ((hClipboardData = GetClipboardData(CF_TEXT)) != NULL) + { + cliptext = (char *) GlobalLock(hClipboardData); + if (cliptext != NULL) + { + size_t size = GlobalSize(hClipboardData) + 1; + /* this is intended for simple small text copies + * such as an ip address, etc: do chop the size + * here, otherwise we may experience Z_Malloc() + * failures and all other not-oh-so-fun stuff. */ + size = q_min(MAX_CLIPBOARDTXT, size); + data = (char *) Z_Malloc(size); + q_strlcpy (data, cliptext, size); + GlobalUnlock (hClipboardData); + } + } + CloseClipboard (); + } + return data; +} + +void PL_ErrorDialog(const char *errorMsg) +{ + MessageBox (NULL, errorMsg, "Quake Error", + MB_OK | MB_SETFOREGROUND | MB_ICONSTOP); +} + diff --git a/engine/code/snd_fmod.h b/engine/Quake/platform.h similarity index 51% rename from engine/code/snd_fmod.h rename to engine/Quake/platform.h index e80d82e..679ecff 100644 --- a/engine/code/snd_fmod.h +++ b/engine/Quake/platform.h @@ -1,5 +1,8 @@ /* -Copyright (C) 1996-1997 Id Software, Inc. +Copyright (C) 1996-2001 Id Software, Inc. +Copyright (C) 2002-2005 John Fitzgibbons and others +Copyright (C) 2007-2008 Kristian Duske +Copyright (C) 2010-2014 QuakeSpasm developers This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -17,28 +20,21 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -// snd_fmod.c: FMOD sound system implementation for music playback - -// Developed by Jacques Krige -// Ultimate Quake Engine -// http://www.jacqueskrige.com - -#ifndef _SND_FMOD_H_ -#define _SND_FMOD_H_ - -#ifdef UQE_FMOD -typedef struct FMOD_SYSTEM FMOD_SYSTEM; -extern FMOD_SYSTEM *fmod_system; - -void FMOD_Init (); -void FMOD_Shutdown (void); -void FMOD_MusicStart (char *name, qboolean loop, qboolean notify); -void FMOD_MusicStop (void); -void FMOD_MusicPause (void); -void FMOD_MusicResume (void); -void FMOD_MusicUpdate (void); -void FMOD_MusicActivate (qboolean active); -qboolean FMOD_MusicActive (void); -#endif - -#endif + +#ifndef _QUAKE_PLATFORM_H +#define _QUAKE_PLATFORM_H + +/* platform dependent way to set the window icon */ +void PL_SetWindowIcon(void); + +/* platform dependent cleanup */ +void PL_VID_Shutdown (void); + +/* retrieve text from the clipboard (returns Z_Malloc()'ed data) */ +char *PL_GetClipboardData (void); + +/* show an error dialog */ +void PL_ErrorDialog(const char *text); + +#endif /* _QUAKE_PLATFORM_H */ + diff --git a/engine/code/pr_cmds.c b/engine/Quake/pr_cmds.c similarity index 58% rename from engine/code/pr_cmds.c rename to engine/Quake/pr_cmds.c index 71d9ce0..ad3a203 100644 --- a/engine/code/pr_cmds.c +++ b/engine/Quake/pr_cmds.c @@ -1,5 +1,7 @@ /* -Copyright (C) 1996-1997 Id Software, Inc. +Copyright (C) 1996-2001 Id Software, Inc. +Copyright (C) 2002-2009 John Fitzgibbons and others +Copyright (C) 2010-2014 QuakeSpasm developers This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -8,7 +10,7 @@ of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. @@ -20,25 +22,55 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "quakedef.h" +#define STRINGTEMP_BUFFERS 16 +#define STRINGTEMP_LENGTH 1024 +static char pr_string_temp[STRINGTEMP_BUFFERS][STRINGTEMP_LENGTH]; +static byte pr_string_tempindex = 0; + +static char *PR_GetTempString (void) +{ + return pr_string_temp[(STRINGTEMP_BUFFERS-1) & ++pr_string_tempindex]; +} + #define RETURN_EDICT(e) (((int *)pr_globals)[OFS_RETURN] = EDICT_TO_PROG(e)) +#define MSG_BROADCAST 0 // unreliable to all +#define MSG_ONE 1 // reliable to one (msg_entity) +#define MSG_ALL 2 // reliable to all +#define MSG_INIT 3 // write to the init string + /* =============================================================================== - BUILT-IN FUNCTIONS + BUILT-IN FUNCTIONS =============================================================================== */ -char *PF_VarString (int first) +static char *PF_VarString (int first) { int i; - static char out[256]; - + static char out[1024]; + size_t s; + out[0] = 0; - for (i=first ; i= sizeof(out)) + { + Con_Warning("PF_VarString: overflow (string truncated)\n"); + return out; + } + } + if (s > 255) + { + if (!dev_overflows.varstring || dev_overflows.varstring + CONSOLE_RESPAM_TIME < realtime) + { + Con_DWarning("PF_VarString: %i characters exceeds standard limit of 255 (max = %d).\n", (int) s, (int)(sizeof(out) - 1)); + dev_overflows.varstring = realtime; + } } return out; } @@ -46,7 +78,7 @@ char *PF_VarString (int first) /* ================= -PF_errror +PF_error This is a TERMINAL error, which will kill off the entire server. Dumps self. @@ -54,14 +86,14 @@ Dumps self. error(value) ================= */ -void PF_error (void) +static void PF_error (void) { char *s; edict_t *ed; - + s = PF_VarString(0); Con_Printf ("======SERVER ERROR in %s:\n%s\n", - PR_GetString(pr_xfunction->s_name), s); + PR_GetString(pr_xfunction->s_name), s); ed = PROG_TO_EDICT(pr_global_struct->self); ED_Print (ed); @@ -78,19 +110,19 @@ removed, but the level can continue. objerror(value) ================= */ -void PF_objerror (void) +static void PF_objerror (void) { char *s; edict_t *ed; - + s = PF_VarString(0); Con_Printf ("======OBJECT ERROR in %s:\n%s\n", - PR_GetString(pr_xfunction->s_name), s); + PR_GetString(pr_xfunction->s_name), s); ed = PROG_TO_EDICT(pr_global_struct->self); ED_Print (ed); ED_Free (ed); - - Host_Error ("Program error"); + + //Host_Error ("Program error"); //johnfitz -- by design, this should not be fatal } @@ -103,7 +135,7 @@ Writes new values for v_forward, v_up, and v_right based on angles makevectors(vector) ============== */ -void PF_makevectors (void) +static void PF_makevectors (void) { AngleVectors (G_VECTOR(OFS_PARM0), pr_global_struct->v_forward, pr_global_struct->v_right, pr_global_struct->v_up); } @@ -112,16 +144,21 @@ void PF_makevectors (void) ================= PF_setorigin -This is the only valid way to move an object without using the physics of the world (setting velocity and waiting). Directly changing origin will not set internal links correctly, so clipping would be messed up. This should be called when an object is spawned, and then only if it is teleported. +This is the only valid way to move an object without using the physics +of the world (setting velocity and waiting). Directly changing origin +will not set internal links correctly, so clipping would be messed up. + +This should be called when an object is spawned, and then only if it is +teleported. setorigin (entity, origin) ================= */ -void PF_setorigin (void) +static void PF_setorigin (void) { edict_t *e; float *org; - + e = G_EDICT(OFS_PARM0); org = G_VECTOR(OFS_PARM1); VectorCopy (org, e->v.origin); @@ -129,7 +166,7 @@ void PF_setorigin (void) } -void SetMinMaxSize (edict_t *e, float *min, float *max, qboolean rotate) +static void SetMinMaxSize (edict_t *e, float *minvec, float *maxvec, qboolean rotate) { float *angles; vec3_t rmin, rmax; @@ -138,52 +175,52 @@ void SetMinMaxSize (edict_t *e, float *min, float *max, qboolean rotate) float a; vec3_t base, transformed; int i, j, k, l; - - for (i=0 ; i<3 ; i++) - if (min[i] > max[i]) + + for (i = 0; i < 3; i++) + if (minvec[i] > maxvec[i]) PR_RunError ("backwards mins/maxs"); rotate = false; // FIXME: implement rotation properly again if (!rotate) { - VectorCopy (min, rmin); - VectorCopy (max, rmax); + VectorCopy (minvec, rmin); + VectorCopy (maxvec, rmax); } else { // find min / max for rotations angles = e->v.angles; - + a = angles[1]/180 * M_PI; - + xvector[0] = cos(a); xvector[1] = sin(a); yvector[0] = -sin(a); yvector[1] = cos(a); - - VectorCopy (min, bounds[0]); - VectorCopy (max, bounds[1]); - + + VectorCopy (minvec, bounds[0]); + VectorCopy (maxvec, bounds[1]); + rmin[0] = rmin[1] = rmin[2] = 9999; rmax[0] = rmax[1] = rmax[2] = -9999; - - for (i=0 ; i<= 1 ; i++) + + for (i = 0; i <= 1; i++) { base[0] = bounds[i][0]; - for (j=0 ; j<= 1 ; j++) + for (j = 0; j <= 1; j++) { base[1] = bounds[j][1]; - for (k=0 ; k<= 1 ; k++) + for (k = 0; k <= 1; k++) { base[2] = bounds[k][2]; - + // transform the point transformed[0] = xvector[0]*base[0] + yvector[0]*base[1]; transformed[1] = xvector[1]*base[0] + yvector[1]*base[1]; transformed[2] = base[2]; - - for (l=0 ; l<3 ; l++) + + for (l = 0; l < 3; l++) { if (transformed[l] < rmin[l]) rmin[l] = transformed[l]; @@ -194,12 +231,12 @@ void SetMinMaxSize (edict_t *e, float *min, float *max, qboolean rotate) } } } - + // set derived values VectorCopy (rmin, e->v.mins); VectorCopy (rmax, e->v.maxs); - VectorSubtract (max, min, e->v.size); - + VectorSubtract (maxvec, minvec, e->v.size); + SV_LinkEdict (e, false); } @@ -212,15 +249,15 @@ the size box is rotated by the current angle setsize (entity, minvector, maxvector) ================= */ -void PF_setsize (void) +static void PF_setsize (void) { edict_t *e; - float *min, *max; - + float *minvec, *maxvec; + e = G_EDICT(OFS_PARM0); - min = G_VECTOR(OFS_PARM1); - max = G_VECTOR(OFS_PARM2); - SetMinMaxSize (e, min, max, false); + minvec = G_VECTOR(OFS_PARM1); + maxvec = G_VECTOR(OFS_PARM2); + SetMinMaxSize (e, minvec, maxvec, false); } @@ -231,32 +268,41 @@ PF_setmodel setmodel(entity, model) ================= */ -void PF_setmodel (void) +static void PF_setmodel (void) { - edict_t *e; - char *m, **check; - model_t *mod; int i; + const char *m, **check; + qmodel_t *mod; + edict_t *e; e = G_EDICT(OFS_PARM0); m = G_STRING(OFS_PARM1); // check to see if model was properly precached - for (i=0, check = sv.model_precache ; *check ; i++, check++) + for (i = 0, check = sv.model_precache; *check; i++, check++) + { if (!strcmp(*check, m)) break; - - if (!*check) - PR_RunError ("no precache: %s\n", m); - + } + if (!*check) + { + PR_RunError ("no precache: %s", m); + } e->v.model = PR_SetEngineString(*check); e->v.modelindex = i; //SV_ModelIndex (m); mod = sv.models[ (int)e->v.modelindex]; // Mod_ForName (m, true); - + if (mod) - SetMinMaxSize (e, mod->mins, mod->maxs, true); + //johnfitz -- correct physics cullboxes for bmodels + { + if (mod->type == mod_brush) + SetMinMaxSize (e, mod->clipmins, mod->clipmaxs, true); + else + SetMinMaxSize (e, mod->mins, mod->maxs, true); + } + //johnfitz else SetMinMaxSize (e, vec3_origin, vec3_origin, true); } @@ -270,7 +316,7 @@ broadcast print to everyone on server bprint(value) ================= */ -void PF_bprint (void) +static void PF_bprint (void) { char *s; @@ -287,23 +333,23 @@ single print to a specific client sprint(clientent, value) ================= */ -void PF_sprint (void) +static void PF_sprint (void) { char *s; client_t *client; - int entnum; - + int entnum; + entnum = G_EDICTNUM(OFS_PARM0); s = PF_VarString(1); - + if (entnum < 1 || entnum > svs.maxclients) { Con_Printf ("tried to sprint to a non-client\n"); return; } - + client = &svs.clients[entnum-1]; - + MSG_WriteChar (&client->message,svc_print); MSG_WriteString (&client->message, s ); } @@ -318,25 +364,25 @@ single print to a specific client centerprint(clientent, value) ================= */ -void PF_centerprint (void) +static void PF_centerprint (void) { char *s; client_t *client; - int entnum; - + int entnum; + entnum = G_EDICTNUM(OFS_PARM0); s = PF_VarString(1); - + if (entnum < 1 || entnum > svs.maxclients) { Con_Printf ("tried to sprint to a non-client\n"); return; } - + client = &svs.clients[entnum-1]; - + MSG_WriteChar (&client->message,svc_centerprint); - MSG_WriteString (&client->message, s ); + MSG_WriteString (&client->message, s); } @@ -347,28 +393,28 @@ PF_normalize vector normalize(vector) ================= */ -void PF_normalize (void) +static void PF_normalize (void) { float *value1; vec3_t newvalue; - float new; - + double new_temp; + value1 = G_VECTOR(OFS_PARM0); - new = value1[0] * value1[0] + value1[1] * value1[1] + value1[2]*value1[2]; - new = sqrt(new); - - if (new == 0) + new_temp = (double)value1[0] * value1[0] + (double)value1[1] * value1[1] + (double)value1[2]*value1[2]; + new_temp = sqrt (new_temp); + + if (new_temp == 0) newvalue[0] = newvalue[1] = newvalue[2] = 0; else { - new = 1/new; - newvalue[0] = value1[0] * new; - newvalue[1] = value1[1] * new; - newvalue[2] = value1[2] * new; + new_temp = 1 / new_temp; + newvalue[0] = value1[0] * new_temp; + newvalue[1] = value1[1] * new_temp; + newvalue[2] = value1[2] * new_temp; } - - VectorCopy (newvalue, G_VECTOR(OFS_RETURN)); + + VectorCopy (newvalue, G_VECTOR(OFS_RETURN)); } /* @@ -378,17 +424,17 @@ PF_vlen scalar vlen(vector) ================= */ -void PF_vlen (void) +static void PF_vlen (void) { float *value1; - float new; - + double new_temp; + value1 = G_VECTOR(OFS_PARM0); - new = value1[0] * value1[0] + value1[1] * value1[1] + value1[2]*value1[2]; - new = sqrt(new); - - G_FLOAT(OFS_RETURN) = new; + new_temp = (double)value1[0] * value1[0] + (double)value1[1] * value1[1] + (double)value1[2]*value1[2]; + new_temp = sqrt(new_temp); + + G_FLOAT(OFS_RETURN) = new_temp; } /* @@ -398,11 +444,11 @@ PF_vectoyaw float vectoyaw(vector) ================= */ -void PF_vectoyaw (void) +static void PF_vectoyaw (void) { float *value1; float yaw; - + value1 = G_VECTOR(OFS_PARM0); if (value1[1] == 0 && value1[0] == 0) @@ -425,12 +471,12 @@ PF_vectoangles vector vectoangles(vector) ================= */ -void PF_vectoangles (void) +static void PF_vectoangles (void) { float *value1; float forward; float yaw, pitch; - + value1 = G_VECTOR(OFS_PARM0); if (value1[1] == 0 && value1[0] == 0) @@ -462,17 +508,17 @@ void PF_vectoangles (void) ================= PF_Random -Returns a number from 0<= num < 1 +Returns a number from 0 <= num < 1 random() ================= */ -void PF_random (void) +static void PF_random (void) { float num; - - num = (rand ()&0x7fff) / ((float)0x7fff); - + + num = (rand() & 0x7fff) / ((float)0x7fff); + G_FLOAT(OFS_RETURN) = num; } @@ -483,12 +529,12 @@ PF_particle particle(origin, color, count) ================= */ -void PF_particle (void) +static void PF_particle (void) { float *org, *dir; float color; float count; - + org = G_VECTOR(OFS_PARM0); dir = G_VECTOR(OFS_PARM1); color = G_FLOAT(OFS_PARM2); @@ -503,37 +549,60 @@ PF_ambientsound ================= */ -void PF_ambientsound (void) +static void PF_ambientsound (void) { - char **check; - char *samp; + const char *samp, **check; float *pos; - float vol, attenuation; - int i, soundnum; + float vol, attenuation; + int i, soundnum; + int large = false; //johnfitz -- PROTOCOL_FITZQUAKE - pos = G_VECTOR (OFS_PARM0); + pos = G_VECTOR (OFS_PARM0); samp = G_STRING(OFS_PARM1); vol = G_FLOAT(OFS_PARM2); attenuation = G_FLOAT(OFS_PARM3); - + // check to see if samp was properly precached - for (soundnum=0, check = sv.sound_precache ; *check ; check++, soundnum++) - if (!strcmp(*check,samp)) + for (soundnum = 0, check = sv.sound_precache; *check; check++, soundnum++) + { + if (!strcmp(*check, samp)) break; - + } + if (!*check) { Con_Printf ("no precache: %s\n", samp); return; } + //johnfitz -- PROTOCOL_FITZQUAKE + if (soundnum > 255) + { + if (sv.protocol == PROTOCOL_NETQUAKE) + return; //don't send any info protocol can't support + else + large = true; + } + //johnfitz + // add an svc_spawnambient command to the level signon packet - MSG_WriteByte (&sv.signon,svc_spawnstaticsound); - for (i=0 ; i<3 ; i++) - MSG_WriteCoord(&sv.signon, pos[i]); + //johnfitz -- PROTOCOL_FITZQUAKE + if (large) + MSG_WriteByte (&sv.signon,svc_spawnstaticsound2); + else + MSG_WriteByte (&sv.signon,svc_spawnstaticsound); + //johnfitz + + for (i = 0; i < 3; i++) + MSG_WriteCoord(&sv.signon, pos[i], sv.protocolflags); - MSG_WriteByte (&sv.signon, soundnum); + //johnfitz -- PROTOCOL_FITZQUAKE + if (large) + MSG_WriteShort(&sv.signon, soundnum); + else + MSG_WriteByte (&sv.signon, soundnum); + //johnfitz MSG_WriteByte (&sv.signon, vol*255); MSG_WriteByte (&sv.signon, attenuation*64); @@ -548,35 +617,35 @@ Each entity can have eight independant sound sources, like voice, weapon, feet, etc. Channel 0 is an auto-allocate channel, the others override anything -allready running on that entity/channel pair. +already running on that entity/channel pair. An attenuation of 0 will play full volume everywhere in the level. Larger attenuations will drop off. ================= */ -void PF_sound (void) +static void PF_sound (void) { - char *sample; - int channel; + const char *sample; + int channel; edict_t *entity; - int volume; - float attenuation; - + int volume; + float attenuation; + entity = G_EDICT(OFS_PARM0); channel = G_FLOAT(OFS_PARM1); sample = G_STRING(OFS_PARM2); volume = G_FLOAT(OFS_PARM3) * 255; attenuation = G_FLOAT(OFS_PARM4); - + if (volume < 0 || volume > 255) - Sys_Error ("SV_StartSound: volume = %i", volume); + Host_Error ("SV_StartSound: volume = %i", volume); if (attenuation < 0 || attenuation > 4) - Sys_Error ("SV_StartSound: attenuation = %f", attenuation); + Host_Error ("SV_StartSound: attenuation = %f", attenuation); if (channel < 0 || channel > 7) - Sys_Error ("SV_StartSound: channel = %i", channel); + Host_Error ("SV_StartSound: channel = %i", channel); SV_StartSound (entity, channel, sample, volume, attenuation); } @@ -588,10 +657,10 @@ PF_break break() ================= */ -void PF_break (void) +static void PF_break (void) { -Con_Printf ("break statement\n"); -*(int *)-4 = 0; // dump to debugger + Con_Printf ("break statement\n"); + *(int *)-4 = 0; // dump to debugger // PR_RunError ("break statement"); } @@ -606,11 +675,11 @@ if the tryents flag is set. traceline (vector1, vector2, tryents) ================= */ -void PF_traceline (void) +static void PF_traceline (void) { float *v1, *v2; trace_t trace; - int nomonsters; + int nomonsters; edict_t *ent; v1 = G_VECTOR(OFS_PARM0); @@ -618,36 +687,21 @@ void PF_traceline (void) nomonsters = G_FLOAT(OFS_PARM2); ent = G_EDICT(OFS_PARM3); - trace = SV_Move (v1, vec3_origin, vec3_origin, v2, nomonsters, ent); - - pr_global_struct->trace_allsolid = trace.allsolid; - pr_global_struct->trace_startsolid = trace.startsolid; - pr_global_struct->trace_fraction = trace.fraction; - pr_global_struct->trace_inwater = trace.inwater; - pr_global_struct->trace_inopen = trace.inopen; - VectorCopy (trace.endpos, pr_global_struct->trace_endpos); - VectorCopy (trace.plane.normal, pr_global_struct->trace_plane_normal); - pr_global_struct->trace_plane_dist = trace.plane.dist; - if (trace.ent) - pr_global_struct->trace_ent = EDICT_TO_PROG(trace.ent); - else - pr_global_struct->trace_ent = EDICT_TO_PROG(sv.edicts); -} - - -#ifdef QUAKE2 -extern trace_t SV_Trace_Toss (edict_t *ent, edict_t *ignore); - -void PF_TraceToss (void) -{ - trace_t trace; - edict_t *ent; - edict_t *ignore; + /* FIXME FIXME FIXME: Why do we hit this with certain progs.dat ?? */ + if (developer.value) { + if (IS_NAN(v1[0]) || IS_NAN(v1[1]) || IS_NAN(v1[2]) || + IS_NAN(v2[0]) || IS_NAN(v2[1]) || IS_NAN(v2[2])) { + Con_Warning ("NAN in traceline:\nv1(%f %f %f) v2(%f %f %f)\nentity %d\n", + v1[0], v1[1], v1[2], v2[0], v2[1], v2[2], NUM_FOR_EDICT(ent)); + } + } - ent = G_EDICT(OFS_PARM0); - ignore = G_EDICT(OFS_PARM1); + if (IS_NAN(v1[0]) || IS_NAN(v1[1]) || IS_NAN(v1[2])) + v1[0] = v1[1] = v1[2] = 0; + if (IS_NAN(v2[0]) || IS_NAN(v2[1]) || IS_NAN(v2[2])) + v2[0] = v2[1] = v2[2] = 0; - trace = SV_Trace_Toss (ent, ignore); + trace = SV_Move (v1, vec3_origin, vec3_origin, v2, nomonsters, ent); pr_global_struct->trace_allsolid = trace.allsolid; pr_global_struct->trace_startsolid = trace.startsolid; @@ -656,14 +710,12 @@ void PF_TraceToss (void) pr_global_struct->trace_inopen = trace.inopen; VectorCopy (trace.endpos, pr_global_struct->trace_endpos); VectorCopy (trace.plane.normal, pr_global_struct->trace_plane_normal); - pr_global_struct->trace_plane_dist = trace.plane.dist; + pr_global_struct->trace_plane_dist = trace.plane.dist; if (trace.ent) pr_global_struct->trace_ent = EDICT_TO_PROG(trace.ent); else pr_global_struct->trace_ent = EDICT_TO_PROG(sv.edicts); } -#endif - /* ================= @@ -675,21 +727,25 @@ FIXME: make work... scalar checkpos (entity, vector) ================= */ -void PF_checkpos (void) +#if 0 +static void PF_checkpos (void) { } +#endif //============================================================================ -byte checkpvs[MAX_MAP_LEAFS/8]; +static byte *checkpvs; //ericw -- changed to malloc +static int checkpvs_capacity; -int PF_newcheckclient (int check) +static int PF_newcheckclient (int check) { int i; byte *pvs; edict_t *ent; mleaf_t *leaf; vec3_t org; + int pvsbytes; // cycle to the next one @@ -728,7 +784,16 @@ int PF_newcheckclient (int check) VectorAdd (ent->v.origin, ent->v.view_ofs, org); leaf = Mod_PointInLeaf (org, sv.worldmodel); pvs = Mod_LeafPVS (leaf, sv.worldmodel); - memcpy (checkpvs, pvs, (sv.worldmodel->numleafs+7)>>3 ); + + pvsbytes = (sv.worldmodel->numleafs+7)>>3; + if (checkpvs == NULL || pvsbytes > checkpvs_capacity) + { + checkpvs_capacity = pvsbytes; + checkpvs = (byte *) realloc (checkpvs, checkpvs_capacity); + if (!checkpvs) + Sys_Error ("PF_newcheckclient: realloc() failed on %d bytes", checkpvs_capacity); + } + memcpy (checkpvs, pvs, pvsbytes); return i; } @@ -749,14 +814,14 @@ name checkclient () ================= */ #define MAX_CHECK 16 -int c_invis, c_notvis; -void PF_checkclient (void) +static int c_invis, c_notvis; +static void PF_checkclient (void) { edict_t *ent, *self; mleaf_t *leaf; int l; vec3_t view; - + // find a new check if on a new frame if (sv.time - sv.lastchecktime >= 0.1) { @@ -764,7 +829,7 @@ void PF_checkclient (void) sv.lastchecktime = sv.time; } -// return check if it might be visible +// return check if it might be visible ent = EDICT_NUM(sv.lastcheck); if (ent->free || ent->v.health <= 0) { @@ -777,15 +842,15 @@ void PF_checkclient (void) VectorAdd (self->v.origin, self->v.view_ofs, view); leaf = Mod_PointInLeaf (view, sv.worldmodel); l = (leaf - sv.worldmodel->leafs) - 1; - if ( (l<0) || !(checkpvs[l>>3] & (1<<(l&7)) ) ) + if ( (l < 0) || !(checkpvs[l>>3] & (1 << (l & 7))) ) { -c_notvis++; + c_notvis++; RETURN_EDICT(sv.edicts); return; } // might be able to see it -c_invis++; + c_invis++; RETURN_EDICT(ent); } @@ -801,17 +866,17 @@ Sends text over to the client's execution buffer stuffcmd (clientent, value) ================= */ -void PF_stuffcmd (void) +static void PF_stuffcmd (void) { int entnum; - char *str; + const char *str; client_t *old; - + entnum = G_EDICTNUM(OFS_PARM0); if (entnum < 1 || entnum > svs.maxclients) PR_RunError ("Parm 0 not a client"); - str = G_STRING(OFS_PARM1); - + str = G_STRING(OFS_PARM1); + old = host_client; host_client = &svs.clients[entnum-1]; Host_ClientCommands ("%s", str); @@ -827,11 +892,11 @@ Sends text over to the client's execution buffer localcmd (string) ================= */ -void PF_localcmd (void) +static void PF_localcmd (void) { - char *str; - - str = G_STRING(OFS_PARM0); + const char *str; + + str = G_STRING(OFS_PARM0); Cbuf_AddText (str); } @@ -842,12 +907,12 @@ PF_cvar float cvar (string) ================= */ -void PF_cvar (void) +static void PF_cvar (void) { - char *str; - + const char *str; + str = G_STRING(OFS_PARM0); - + G_FLOAT(OFS_RETURN) = Cvar_VariableValue (str); } @@ -858,13 +923,13 @@ PF_cvar_set float cvar (string) ================= */ -void PF_cvar_set (void) +static void PF_cvar_set (void) { - char *var, *val; - + const char *var, *val; + var = G_STRING(OFS_PARM0); val = G_STRING(OFS_PARM1); - + Cvar_Set (var, val); } @@ -877,31 +942,31 @@ Returns a chain of entities that have origins within a spherical area findradius (origin, radius) ================= */ -void PF_findradius (void) +static void PF_findradius (void) { edict_t *ent, *chain; float rad; float *org; vec3_t eorg; - int i, j; + int i, j; chain = (edict_t *)sv.edicts; - + org = G_VECTOR(OFS_PARM0); rad = G_FLOAT(OFS_PARM1); ent = NEXT_EDICT(sv.edicts); - for (i=1 ; ifree) continue; if (ent->v.solid == SOLID_NOT) continue; - for (j=0 ; j<3 ; j++) - eorg[j] = org[j] - (ent->v.origin[j] + (ent->v.mins[j] + ent->v.maxs[j])*0.5); - if (Length(eorg) > rad) + for (j = 0; j < 3; j++) + eorg[j] = org[j] - (ent->v.origin[j] + (ent->v.mins[j] + ent->v.maxs[j]) * 0.5); + if (VectorLength(eorg) > rad) continue; - + ent->v.chain = EDICT_TO_PROG(chain); chain = ent; } @@ -909,137 +974,78 @@ void PF_findradius (void) RETURN_EDICT(chain); } - /* ========= PF_dprint ========= */ -void PF_dprint (void) +static void PF_dprint (void) { Con_DPrintf ("%s",PF_VarString(0)); } -char pr_string_temp[128]; - -void PF_ftos (void) +static void PF_ftos (void) { float v; + char *s; + v = G_FLOAT(OFS_PARM0); - + s = PR_GetTempString(); if (v == (int)v) - sprintf (pr_string_temp, "%d",(int)v); + sprintf (s, "%d",(int)v); else - { - // jkrige - FTOS fix - //sprintf (pr_string_temp, "%5.1f",v); - sprintf (pr_string_temp, "%1f",v); - // jkrige - FTOS fix - } - - G_INT(OFS_RETURN) = PR_SetEngineString(pr_string_temp); + sprintf (s, "%5.1f",v); + G_INT(OFS_RETURN) = PR_SetEngineString(s); } -void PF_fabs (void) +static void PF_fabs (void) { float v; v = G_FLOAT(OFS_PARM0); G_FLOAT(OFS_RETURN) = fabs(v); } -void PF_vtos (void) +static void PF_vtos (void) { - sprintf (pr_string_temp, "'%5.1f %5.1f %5.1f'", G_VECTOR(OFS_PARM0)[0], G_VECTOR(OFS_PARM0)[1], G_VECTOR(OFS_PARM0)[2]); - G_INT(OFS_RETURN) = PR_SetEngineString(pr_string_temp); -} + char *s; -#ifdef QUAKE2 -void PF_etos (void) -{ - sprintf (pr_string_temp, "entity %i", G_EDICTNUM(OFS_PARM0)); - G_INT(OFS_RETURN) = pr_string_temp - pr_strings; + s = PR_GetTempString(); + sprintf (s, "'%5.1f %5.1f %5.1f'", G_VECTOR(OFS_PARM0)[0], G_VECTOR(OFS_PARM0)[1], G_VECTOR(OFS_PARM0)[2]); + G_INT(OFS_RETURN) = PR_SetEngineString(s); } -#endif -void PF_Spawn (void) +static void PF_Spawn (void) { edict_t *ed; + ed = ED_Alloc(); + RETURN_EDICT(ed); } -void PF_Remove (void) +static void PF_Remove (void) { edict_t *ed; - + ed = G_EDICT(OFS_PARM0); ED_Free (ed); } // entity (entity start, .string field, string match) find = #5; -void PF_Find (void) -#ifdef QUAKE2 +static void PF_Find (void) { - int e; + int e; int f; - char *s, *t; + const char *s, *t; edict_t *ed; - edict_t *first; - edict_t *second; - edict_t *last; - first = second = last = (edict_t *)sv.edicts; e = G_EDICTNUM(OFS_PARM0); f = G_INT(OFS_PARM1); s = G_STRING(OFS_PARM2); if (!s) PR_RunError ("PF_Find: bad search string"); - - for (e++ ; e < sv.num_edicts ; e++) - { - ed = EDICT_NUM(e); - if (ed->free) - continue; - t = E_STRING(ed,f); - if (!t) - continue; - if (!strcmp(t,s)) - { - if (first == (edict_t *)sv.edicts) - first = ed; - else if (second == (edict_t *)sv.edicts) - second = ed; - ed->v.chain = EDICT_TO_PROG(last); - last = ed; - } - } - - if (first != last) - { - if (last != second) - first->v.chain = last->v.chain; - else - first->v.chain = EDICT_TO_PROG(last); - last->v.chain = EDICT_TO_PROG((edict_t *)sv.edicts); - if (second && second != last) - second->v.chain = EDICT_TO_PROG(last); - } - RETURN_EDICT(first); -} -#else -{ - int e; - int f; - char *s, *t; - edict_t *ed; - e = G_EDICTNUM(OFS_PARM0); - f = G_INT(OFS_PARM1); - s = G_STRING(OFS_PARM2); - if (!s) - PR_RunError ("PF_Find: bad search string"); - for (e++ ; e < sv.num_edicts ; e++) { ed = EDICT_NUM(e); @@ -1057,32 +1063,31 @@ void PF_Find (void) RETURN_EDICT(sv.edicts); } -#endif -void PR_CheckEmptyString (char *s) +static void PR_CheckEmptyString (const char *s) { if (s[0] <= ' ') PR_RunError ("Bad string"); } -void PF_precache_file (void) +static void PF_precache_file (void) { // precache_file is only used to copy files with qcc, it does nothing G_INT(OFS_RETURN) = G_INT(OFS_PARM0); } -void PF_precache_sound (void) +static void PF_precache_sound (void) { - char *s; + const char *s; int i; - + if (sv.state != ss_loading) PR_RunError ("PF_Precache_*: Precache can only be done in spawn functions"); - + s = G_STRING(OFS_PARM0); G_INT(OFS_RETURN) = G_INT(OFS_PARM0); PR_CheckEmptyString (s); - - for (i=0 ; iself); yaw = G_FLOAT(OFS_PARM0); dist = G_FLOAT(OFS_PARM1); - + if ( !( (int)ent->v.flags & (FL_ONGROUND|FL_FLY|FL_SWIM) ) ) { G_FLOAT(OFS_RETURN) = 0; return; } - yaw = yaw*M_PI*2 / 360; - - move[0] = cos(yaw)*dist; - move[1] = sin(yaw)*dist; + yaw = yaw * M_PI * 2 / 360; + + move[0] = cos(yaw) * dist; + move[1] = sin(yaw) * dist; move[2] = 0; // save program state, because SV_movestep may call other progs oldf = pr_xfunction; oldself = pr_global_struct->self; - + G_FLOAT(OFS_RETURN) = SV_movestep(ent, move, true); - - + + // restore program state pr_xfunction = oldf; pr_global_struct->self = oldself; @@ -1192,17 +1197,17 @@ PF_droptofloor void() droptofloor =============== */ -void PF_droptofloor (void) +static void PF_droptofloor (void) { edict_t *ent; vec3_t end; trace_t trace; - + ent = PROG_TO_EDICT(pr_global_struct->self); VectorCopy (ent->v.origin, end); end[2] -= 256; - + trace = SV_Move (ent->v.origin, ent->v.mins, ent->v.maxs, end, false, ent); if (trace.fraction == 1 || trace.allsolid) @@ -1224,33 +1229,42 @@ PF_lightstyle void(float style, string value) lightstyle =============== */ -void PF_lightstyle (void) +static void PF_lightstyle (void) { int style; - char *val; + const char *val; client_t *client; - int j; - + int j; + style = G_FLOAT(OFS_PARM0); val = G_STRING(OFS_PARM1); +// bounds check to avoid clobbering sv struct + if (style < 0 || style >= MAX_LIGHTSTYLES) + { + Con_DWarning("PF_lightstyle: invalid style %d\n", style); + return; + } + // change the string in sv sv.lightstyles[style] = val; - + // send message to all clients on this server if (sv.state != ss_active) return; - - for (j=0, client = svs.clients ; jactive || client->spawned) { MSG_WriteChar (&client->message, svc_lightstyle); - MSG_WriteChar (&client->message,style); + MSG_WriteChar (&client->message, style); MSG_WriteString (&client->message, val); } + } } -void PF_rint (void) +static void PF_rint (void) { float f; f = G_FLOAT(OFS_PARM0); @@ -1259,11 +1273,13 @@ void PF_rint (void) else G_FLOAT(OFS_RETURN) = (int)(f - 0.5); } -void PF_floor (void) + +static void PF_floor (void) { G_FLOAT(OFS_RETURN) = floor(G_FLOAT(OFS_PARM0)); } -void PF_ceil (void) + +static void PF_ceil (void) { G_FLOAT(OFS_RETURN) = ceil(G_FLOAT(OFS_PARM0)); } @@ -1274,10 +1290,10 @@ void PF_ceil (void) PF_checkbottom ============= */ -void PF_checkbottom (void) +static void PF_checkbottom (void) { edict_t *ent; - + ent = G_EDICT(OFS_PARM0); G_FLOAT(OFS_RETURN) = SV_CheckBottom (ent); @@ -1288,13 +1304,13 @@ void PF_checkbottom (void) PF_pointcontents ============= */ -void PF_pointcontents (void) +static void PF_pointcontents (void) { float *v; - + v = G_VECTOR(OFS_PARM0); - G_FLOAT(OFS_RETURN) = SV_PointContents (v); + G_FLOAT(OFS_RETURN) = SV_PointContents (v); } /* @@ -1304,11 +1320,11 @@ PF_nextent entity nextent(entity) ============= */ -void PF_nextent (void) +static void PF_nextent (void) { int i; edict_t *ent; - + i = G_EDICTNUM(OFS_PARM0); while (1) { @@ -1335,8 +1351,8 @@ Pick a vector for the player to shoot along vector aim(entity, missilespeed) ============= */ -cvar_t sv_aim = {"sv_aim", "0.93"}; -void PF_aim (void) +cvar_t sv_aim = {"sv_aim", "1", CVAR_NONE}; // ericw -- turn autoaim off by default. was 0.93 +static void PF_aim (void) { edict_t *ent, *check, *bestent; vec3_t start, dir, end, bestdir; @@ -1344,9 +1360,10 @@ void PF_aim (void) trace_t tr; float dist, bestdist; float speed; - + ent = G_EDICT(OFS_PARM0); speed = G_FLOAT(OFS_PARM1); + (void) speed; /* variable set but not used */ VectorCopy (ent->v.origin, start); start[2] += 20; @@ -1356,20 +1373,19 @@ void PF_aim (void) VectorMA (start, 2048, dir, end); tr = SV_Move (start, vec3_origin, vec3_origin, end, false, ent); if (tr.ent && tr.ent->v.takedamage == DAMAGE_AIM - && (!teamplay.value || ent->v.team <=0 || ent->v.team != tr.ent->v.team) ) + && (!teamplay.value || ent->v.team <= 0 || ent->v.team != tr.ent->v.team) ) { VectorCopy (pr_global_struct->v_forward, G_VECTOR(OFS_RETURN)); return; } - // try all possible entities VectorCopy (dir, bestdir); bestdist = sv_aim.value; bestent = NULL; - + check = NEXT_EDICT(sv.edicts); - for (i=1 ; iv.takedamage != DAMAGE_AIM) continue; @@ -1377,9 +1393,8 @@ void PF_aim (void) continue; if (teamplay.value && ent->v.team > 0 && ent->v.team == check->v.team) continue; // don't aim at teammate - for (j=0 ; j<3 ; j++) - end[j] = check->v.origin[j] - + 0.5*(check->v.mins[j] + check->v.maxs[j]); + for (j = 0; j < 3; j++) + end[j] = check->v.origin[j] + 0.5 * (check->v.mins[j] + check->v.maxs[j]); VectorSubtract (end, start, dir); VectorNormalize (dir); dist = DotProduct (dir, pr_global_struct->v_forward); @@ -1392,7 +1407,7 @@ void PF_aim (void) bestent = check; } } - + if (bestent) { VectorSubtract (bestent->v.origin, ent->v.origin, dir); @@ -1400,7 +1415,7 @@ void PF_aim (void) VectorScale (pr_global_struct->v_forward, dist, end); end[2] = dir[2]; VectorNormalize (end); - VectorCopy (end, G_VECTOR(OFS_RETURN)); + VectorCopy (end, G_VECTOR(OFS_RETURN)); } else { @@ -1419,55 +1434,12 @@ void PF_changeyaw (void) { edict_t *ent; float ideal, current, move, speed; - + ent = PROG_TO_EDICT(pr_global_struct->self); current = anglemod( ent->v.angles[1] ); ideal = ent->v.ideal_yaw; speed = ent->v.yaw_speed; - - if (current == ideal) - return; - move = ideal - current; - if (ideal > current) - { - if (move >= 180) - move = move - 360; - } - else - { - if (move <= -180) - move = move + 360; - } - if (move > 0) - { - if (move > speed) - move = speed; - } - else - { - if (move < -speed) - move = -speed; - } - - ent->v.angles[1] = anglemod (current + move); -} -#ifdef QUAKE2 -/* -============== -PF_changepitch -============== -*/ -void PF_changepitch (void) -{ - edict_t *ent; - float ideal, current, move, speed; - - ent = G_EDICT(OFS_PARM0); - current = anglemod( ent->v.angles[0] ); - ideal = ent->v.idealpitch; - speed = ent->v.pitch_speed; - if (current == ideal) return; move = ideal - current; @@ -1491,10 +1463,9 @@ void PF_changepitch (void) if (move < -speed) move = -speed; } - - ent->v.angles[0] = anglemod (current + move); + + ent->v.angles[1] = anglemod (current + move); } -#endif /* =============================================================================== @@ -1504,12 +1475,7 @@ MESSAGE WRITING =============================================================================== */ -#define MSG_BROADCAST 0 // unreliable to all -#define MSG_ONE 1 // reliable to one (msg_entity) -#define MSG_ALL 2 // reliable to all -#define MSG_INIT 3 // write to the init string - -sizebuf_t *WriteDest (void) +static sizebuf_t *WriteDest (void) { int entnum; int dest; @@ -1520,17 +1486,17 @@ sizebuf_t *WriteDest (void) { case MSG_BROADCAST: return &sv.datagram; - + case MSG_ONE: ent = PROG_TO_EDICT(pr_global_struct->msg_entity); entnum = NUM_FOR_EDICT(ent); if (entnum < 1 || entnum > svs.maxclients) PR_RunError ("WriteDest: not a client"); return &svs.clients[entnum-1].message; - + case MSG_ALL: return &sv.reliable_datagram; - + case MSG_INIT: return &sv.signon; @@ -1538,75 +1504,118 @@ sizebuf_t *WriteDest (void) PR_RunError ("WriteDest: bad destination"); break; } - + return NULL; } -void PF_WriteByte (void) +static void PF_WriteByte (void) { MSG_WriteByte (WriteDest(), G_FLOAT(OFS_PARM1)); } -void PF_WriteChar (void) +static void PF_WriteChar (void) { MSG_WriteChar (WriteDest(), G_FLOAT(OFS_PARM1)); } -void PF_WriteShort (void) +static void PF_WriteShort (void) { MSG_WriteShort (WriteDest(), G_FLOAT(OFS_PARM1)); } -void PF_WriteLong (void) +static void PF_WriteLong (void) { MSG_WriteLong (WriteDest(), G_FLOAT(OFS_PARM1)); } -void PF_WriteAngle (void) +static void PF_WriteAngle (void) { - MSG_WriteAngle (WriteDest(), G_FLOAT(OFS_PARM1)); + MSG_WriteAngle (WriteDest(), G_FLOAT(OFS_PARM1), sv.protocolflags); } -void PF_WriteCoord (void) +static void PF_WriteCoord (void) { - MSG_WriteCoord (WriteDest(), G_FLOAT(OFS_PARM1)); + MSG_WriteCoord (WriteDest(), G_FLOAT(OFS_PARM1), sv.protocolflags); } -void PF_WriteString (void) +static void PF_WriteString (void) { MSG_WriteString (WriteDest(), G_STRING(OFS_PARM1)); } - -void PF_WriteEntity (void) +static void PF_WriteEntity (void) { MSG_WriteShort (WriteDest(), G_EDICTNUM(OFS_PARM1)); } //============================================================================= -int SV_ModelIndex (char *name); - -void PF_makestatic (void) +static void PF_makestatic (void) { edict_t *ent; int i; - + int bits = 0; //johnfitz -- PROTOCOL_FITZQUAKE + ent = G_EDICT(OFS_PARM0); - MSG_WriteByte (&sv.signon,svc_spawnstatic); + //johnfitz -- don't send invisible static entities + if (ent->alpha == ENTALPHA_ZERO) { + ED_Free (ent); + return; + } + //johnfitz - MSG_WriteByte (&sv.signon, SV_ModelIndex(PR_GetString(ent->v.model))); + //johnfitz -- PROTOCOL_FITZQUAKE + if (sv.protocol == PROTOCOL_NETQUAKE) + { + if (SV_ModelIndex(PR_GetString(ent->v.model)) & 0xFF00 || (int)(ent->v.frame) & 0xFF00) + { + ED_Free (ent); + return; //can't display the correct model & frame, so don't show it at all + } + } + else + { + if (SV_ModelIndex(PR_GetString(ent->v.model)) & 0xFF00) + bits |= B_LARGEMODEL; + if ((int)(ent->v.frame) & 0xFF00) + bits |= B_LARGEFRAME; + if (ent->alpha != ENTALPHA_DEFAULT) + bits |= B_ALPHA; + } + + if (bits) + { + MSG_WriteByte (&sv.signon, svc_spawnstatic2); + MSG_WriteByte (&sv.signon, bits); + } + else + MSG_WriteByte (&sv.signon, svc_spawnstatic); + + if (bits & B_LARGEMODEL) + MSG_WriteShort (&sv.signon, SV_ModelIndex(PR_GetString(ent->v.model))); + else + MSG_WriteByte (&sv.signon, SV_ModelIndex(PR_GetString(ent->v.model))); + + if (bits & B_LARGEFRAME) + MSG_WriteShort (&sv.signon, ent->v.frame); + else + MSG_WriteByte (&sv.signon, ent->v.frame); + //johnfitz - MSG_WriteByte (&sv.signon, ent->v.frame); MSG_WriteByte (&sv.signon, ent->v.colormap); MSG_WriteByte (&sv.signon, ent->v.skin); - for (i=0 ; i<3 ; i++) + for (i = 0; i < 3; i++) { - MSG_WriteCoord(&sv.signon, ent->v.origin[i]); - MSG_WriteAngle(&sv.signon, ent->v.angles[i]); + MSG_WriteCoord(&sv.signon, ent->v.origin[i], sv.protocolflags); + MSG_WriteAngle(&sv.signon, ent->v.angles[i], sv.protocolflags); } + //johnfitz -- PROTOCOL_FITZQUAKE + if (bits & B_ALPHA) + MSG_WriteByte (&sv.signon, ent->alpha); + //johnfitz + // throw the entity away now ED_Free (ent); } @@ -1618,7 +1627,7 @@ void PF_makestatic (void) PF_setspawnparms ============== */ -void PF_setspawnparms (void) +static void PF_setspawnparms (void) { edict_t *ent; int i; @@ -1632,7 +1641,7 @@ void PF_setspawnparms (void) // copy spawn parms out of the client_t client = svs.clients + (i-1); - for (i=0 ; i< NUM_SPAWN_PARMS ; i++) + for (i = 0; i < NUM_SPAWN_PARMS; i++) (&pr_global_struct->parm1)[i] = client->spawn_parms[i]; } @@ -1641,298 +1650,114 @@ void PF_setspawnparms (void) PF_changelevel ============== */ -void PF_changelevel (void) +static void PF_changelevel (void) { -#ifdef QUAKE2 - char *s1, *s2; - - if (svs.changelevel_issued) - return; - svs.changelevel_issued = true; - - s1 = G_STRING(OFS_PARM0); - s2 = G_STRING(OFS_PARM1); - - if ((int)pr_global_struct->serverflags & (SFL_NEW_UNIT | SFL_NEW_EPISODE)) - Cbuf_AddText (va("changelevel %s %s\n",s1, s2)); - else - Cbuf_AddText (va("changelevel2 %s %s\n",s1, s2)); -#else - char *s; + const char *s; // make sure we don't issue two changelevels if (svs.changelevel_issued) return; svs.changelevel_issued = true; - + s = G_STRING(OFS_PARM0); Cbuf_AddText (va("changelevel %s\n",s)); -#endif -} - - -#ifdef QUAKE2 - -#define CONTENT_WATER -3 -#define CONTENT_SLIME -4 -#define CONTENT_LAVA -5 - -#define FL_IMMUNE_WATER 131072 -#define FL_IMMUNE_SLIME 262144 -#define FL_IMMUNE_LAVA 524288 - -#define CHAN_VOICE 2 -#define CHAN_BODY 4 - -#define ATTN_NORM 1 - -void PF_WaterMove (void) -{ - edict_t *self; - int flags; - int waterlevel; - int watertype; - float drownlevel; - float damage = 0.0; - - self = PROG_TO_EDICT(pr_global_struct->self); - - if (self->v.movetype == MOVETYPE_NOCLIP) - { - self->v.air_finished = sv.time + 12; - G_FLOAT(OFS_RETURN) = damage; - return; - } - - if (self->v.health < 0) - { - G_FLOAT(OFS_RETURN) = damage; - return; - } - - if (self->v.deadflag == DEAD_NO) - drownlevel = 3; - else - drownlevel = 1; - - flags = (int)self->v.flags; - waterlevel = (int)self->v.waterlevel; - watertype = (int)self->v.watertype; - - if (!(flags & (FL_IMMUNE_WATER + FL_GODMODE))) - if (((flags & FL_SWIM) && (waterlevel < drownlevel)) || (waterlevel >= drownlevel)) - { - if (self->v.air_finished < sv.time) - if (self->v.pain_finished < sv.time) - { - self->v.dmg = self->v.dmg + 2; - if (self->v.dmg > 15) - self->v.dmg = 10; -// T_Damage (self, world, world, self.dmg, 0, FALSE); - damage = self->v.dmg; - self->v.pain_finished = sv.time + 1.0; - } - } - else - { - if (self->v.air_finished < sv.time) -// sound (self, CHAN_VOICE, "player/gasp2.wav", 1, ATTN_NORM); - SV_StartSound (self, CHAN_VOICE, "player/gasp2.wav", 255, ATTN_NORM); - else if (self->v.air_finished < sv.time + 9) -// sound (self, CHAN_VOICE, "player/gasp1.wav", 1, ATTN_NORM); - SV_StartSound (self, CHAN_VOICE, "player/gasp1.wav", 255, ATTN_NORM); - self->v.air_finished = sv.time + 12.0; - self->v.dmg = 2; - } - - if (!waterlevel) - { - if (flags & FL_INWATER) - { - // play leave water sound -// sound (self, CHAN_BODY, "misc/outwater.wav", 1, ATTN_NORM); - SV_StartSound (self, CHAN_BODY, "misc/outwater.wav", 255, ATTN_NORM); - self->v.flags = (float)(flags &~FL_INWATER); - } - self->v.air_finished = sv.time + 12.0; - G_FLOAT(OFS_RETURN) = damage; - return; - } - - if (watertype == CONTENT_LAVA) - { // do damage - if (!(flags & (FL_IMMUNE_LAVA + FL_GODMODE))) - if (self->v.dmgtime < sv.time) - { - if (self->v.radsuit_finished < sv.time) - self->v.dmgtime = sv.time + 0.2; - else - self->v.dmgtime = sv.time + 1.0; -// T_Damage (self, world, world, 10*self.waterlevel, 0, TRUE); - damage = (float)(10*waterlevel); - } - } - else if (watertype == CONTENT_SLIME) - { // do damage - if (!(flags & (FL_IMMUNE_SLIME + FL_GODMODE))) - if (self->v.dmgtime < sv.time && self->v.radsuit_finished < sv.time) - { - self->v.dmgtime = sv.time + 1.0; -// T_Damage (self, world, world, 4*self.waterlevel, 0, TRUE); - damage = (float)(4*waterlevel); - } - } - - if ( !(flags & FL_INWATER) ) - { - -// player enter water sound - if (watertype == CONTENT_LAVA) -// sound (self, CHAN_BODY, "player/inlava.wav", 1, ATTN_NORM); - SV_StartSound (self, CHAN_BODY, "player/inlava.wav", 255, ATTN_NORM); - if (watertype == CONTENT_WATER) -// sound (self, CHAN_BODY, "player/inh2o.wav", 1, ATTN_NORM); - SV_StartSound (self, CHAN_BODY, "player/inh2o.wav", 255, ATTN_NORM); - if (watertype == CONTENT_SLIME) -// sound (self, CHAN_BODY, "player/slimbrn2.wav", 1, ATTN_NORM); - SV_StartSound (self, CHAN_BODY, "player/slimbrn2.wav", 255, ATTN_NORM); - - self->v.flags = (float)(flags | FL_INWATER); - self->v.dmgtime = 0; - } - - if (! (flags & FL_WATERJUMP) ) - { -// self.velocity = self.velocity - 0.8*self.waterlevel*frametime*self.velocity; - VectorMA (self->v.velocity, -0.8 * self->v.waterlevel * host_frametime, self->v.velocity, self->v.velocity); - } - - G_FLOAT(OFS_RETURN) = damage; -} - - -void PF_sin (void) -{ - G_FLOAT(OFS_RETURN) = sin(G_FLOAT(OFS_PARM0)); -} - -void PF_cos (void) -{ - G_FLOAT(OFS_RETURN) = cos(G_FLOAT(OFS_PARM0)); } -void PF_sqrt (void) -{ - G_FLOAT(OFS_RETURN) = sqrt(G_FLOAT(OFS_PARM0)); -} -#endif - -void PF_Fixme (void) -{ - PR_RunError ("unimplemented bulitin"); -} - - - -builtin_t pr_builtin[] = -{ -PF_Fixme, -PF_makevectors, // void(entity e) makevectors = #1; -PF_setorigin, // void(entity e, vector o) setorigin = #2; -PF_setmodel, // void(entity e, string m) setmodel = #3; -PF_setsize, // void(entity e, vector min, vector max) setsize = #4; -PF_Fixme, // void(entity e, vector min, vector max) setabssize = #5; -PF_break, // void() break = #6; -PF_random, // float() random = #7; -PF_sound, // void(entity e, float chan, string samp) sound = #8; -PF_normalize, // vector(vector v) normalize = #9; -PF_error, // void(string e) error = #10; -PF_objerror, // void(string e) objerror = #11; -PF_vlen, // float(vector v) vlen = #12; -PF_vectoyaw, // float(vector v) vectoyaw = #13; -PF_Spawn, // entity() spawn = #14; -PF_Remove, // void(entity e) remove = #15; -PF_traceline, // float(vector v1, vector v2, float tryents) traceline = #16; -PF_checkclient, // entity() clientlist = #17; -PF_Find, // entity(entity start, .string fld, string match) find = #18; -PF_precache_sound, // void(string s) precache_sound = #19; -PF_precache_model, // void(string s) precache_model = #20; -PF_stuffcmd, // void(entity client, string s)stuffcmd = #21; -PF_findradius, // entity(vector org, float rad) findradius = #22; -PF_bprint, // void(string s) bprint = #23; -PF_sprint, // void(entity client, string s) sprint = #24; -PF_dprint, // void(string s) dprint = #25; -PF_ftos, // void(string s) ftos = #26; -PF_vtos, // void(string s) vtos = #27; -PF_coredump, -PF_traceon, -PF_traceoff, -PF_eprint, // void(entity e) debug print an entire entity -PF_walkmove, // float(float yaw, float dist) walkmove -PF_Fixme, // float(float yaw, float dist) walkmove -PF_droptofloor, -PF_lightstyle, -PF_rint, -PF_floor, -PF_ceil, -PF_Fixme, -PF_checkbottom, -PF_pointcontents, -PF_Fixme, -PF_fabs, -PF_aim, -PF_cvar, -PF_localcmd, -PF_nextent, -PF_particle, -PF_changeyaw, -PF_Fixme, -PF_vectoangles, - -PF_WriteByte, -PF_WriteChar, -PF_WriteShort, -PF_WriteLong, -PF_WriteCoord, -PF_WriteAngle, -PF_WriteString, -PF_WriteEntity, - -#ifdef QUAKE2 -PF_sin, -PF_cos, -PF_sqrt, -PF_changepitch, -PF_TraceToss, -PF_etos, -PF_WaterMove, -#else -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -#endif - -SV_MoveToGoal, -PF_precache_file, -PF_makestatic, - -PF_changelevel, -PF_Fixme, - -PF_cvar_set, -PF_centerprint, - -PF_ambientsound, - -PF_precache_model, -PF_precache_sound, // precache_sound2 is different only for qcc -PF_precache_file, - -PF_setspawnparms +static void PF_Fixme (void) +{ + PR_RunError ("unimplemented builtin"); +} + + +static builtin_t pr_builtin[] = +{ + PF_Fixme, + PF_makevectors, // void(entity e) makevectors = #1 + PF_setorigin, // void(entity e, vector o) setorigin = #2 + PF_setmodel, // void(entity e, string m) setmodel = #3 + PF_setsize, // void(entity e, vector min, vector max) setsize = #4 + PF_Fixme, // void(entity e, vector min, vector max) setabssize = #5 + PF_break, // void() break = #6 + PF_random, // float() random = #7 + PF_sound, // void(entity e, float chan, string samp) sound = #8 + PF_normalize, // vector(vector v) normalize = #9 + PF_error, // void(string e) error = #10 + PF_objerror, // void(string e) objerror = #11 + PF_vlen, // float(vector v) vlen = #12 + PF_vectoyaw, // float(vector v) vectoyaw = #13 + PF_Spawn, // entity() spawn = #14 + PF_Remove, // void(entity e) remove = #15 + PF_traceline, // float(vector v1, vector v2, float tryents) traceline = #16 + PF_checkclient, // entity() clientlist = #17 + PF_Find, // entity(entity start, .string fld, string match) find = #18 + PF_precache_sound, // void(string s) precache_sound = #19 + PF_precache_model, // void(string s) precache_model = #20 + PF_stuffcmd, // void(entity client, string s)stuffcmd = #21 + PF_findradius, // entity(vector org, float rad) findradius = #22 + PF_bprint, // void(string s) bprint = #23 + PF_sprint, // void(entity client, string s) sprint = #24 + PF_dprint, // void(string s) dprint = #25 + PF_ftos, // void(string s) ftos = #26 + PF_vtos, // void(string s) vtos = #27 + PF_coredump, + PF_traceon, + PF_traceoff, + PF_eprint, // void(entity e) debug print an entire entity + PF_walkmove, // float(float yaw, float dist) walkmove + PF_Fixme, // float(float yaw, float dist) walkmove + PF_droptofloor, + PF_lightstyle, + PF_rint, + PF_floor, + PF_ceil, + PF_Fixme, + PF_checkbottom, + PF_pointcontents, + PF_Fixme, + PF_fabs, + PF_aim, + PF_cvar, + PF_localcmd, + PF_nextent, + PF_particle, + PF_changeyaw, + PF_Fixme, + PF_vectoangles, + + PF_WriteByte, + PF_WriteChar, + PF_WriteShort, + PF_WriteLong, + PF_WriteCoord, + PF_WriteAngle, + PF_WriteString, + PF_WriteEntity, + + PF_Fixme, + PF_Fixme, + PF_Fixme, + PF_Fixme, + PF_Fixme, + PF_Fixme, + PF_Fixme, + + SV_MoveToGoal, + PF_precache_file, + PF_makestatic, + + PF_changelevel, + PF_Fixme, + + PF_cvar_set, + PF_centerprint, + + PF_ambientsound, + + PF_precache_model, + PF_precache_sound, // precache_sound2 is different only for qcc + PF_precache_file, + + PF_setspawnparms }; builtin_t *pr_builtins = pr_builtin; diff --git a/engine/code/pr_comp.h b/engine/Quake/pr_comp.h similarity index 78% rename from engine/code/pr_comp.h rename to engine/Quake/pr_comp.h index b237ed5..bc6c62e 100644 --- a/engine/code/pr_comp.h +++ b/engine/Quake/pr_comp.h @@ -1,5 +1,6 @@ /* -Copyright (C) 1996-1997 Id Software, Inc. +Copyright (C) 1996-2001 Id Software, Inc. +Copyright (C) 2010-2014 QuakeSpasm developers This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -8,7 +9,7 @@ of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. @@ -18,17 +19,30 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#ifndef __PR_COMP_H +#define __PR_COMP_H + // this file is shared by quake and qcc typedef int func_t; typedef int string_t; -typedef enum {ev_void, ev_string, ev_float, ev_vector, ev_entity, ev_field, ev_function, ev_pointer} etype_t; - +typedef enum +{ + ev_bad = -1, + ev_void = 0, + ev_string, + ev_float, + ev_vector, + ev_entity, + ev_field, + ev_function, + ev_pointer +} etype_t; #define OFS_NULL 0 #define OFS_RETURN 1 -#define OFS_PARM0 4 // leave 3 ofs for each parm to hold vectors +#define OFS_PARM0 4 // leave 3 ofs for each parm to hold vectors #define OFS_PARM1 7 #define OFS_PARM2 10 #define OFS_PARM3 13 @@ -39,7 +53,8 @@ typedef enum {ev_void, ev_string, ev_float, ev_vector, ev_entity, ev_field, ev_f #define RESERVED_OFS 28 -enum { +enum +{ OP_DONE, OP_MUL_F, OP_MUL_V, @@ -50,19 +65,19 @@ enum { OP_ADD_V, OP_SUB_F, OP_SUB_V, - + OP_EQ_F, OP_EQ_V, OP_EQ_S, OP_EQ_E, OP_EQ_FNC, - + OP_NE_F, OP_NE_V, OP_NE_S, OP_NE_E, OP_NE_FNC, - + OP_LE, OP_GE, OP_LT, @@ -112,25 +127,25 @@ enum { OP_GOTO, OP_AND, OP_OR, - + OP_BITAND, OP_BITOR }; - typedef struct statement_s { unsigned short op; - short a,b,c; + short a, b, c; } dstatement_t; typedef struct { - unsigned short type; // if DEF_SAVEGLOBGAL bit is set - // the variable needs to be saved in savegames + unsigned short type; // if DEF_SAVEGLOBAL bit is set + // the variable needs to be saved in savegames unsigned short ofs; - int s_name; + int s_name; } ddef_t; + #define DEF_SAVEGLOBAL (1<<15) #define MAX_PARMS 8 @@ -139,13 +154,13 @@ typedef struct { int first_statement; // negative numbers are builtins int parm_start; - int locals; // total ints of parms + locals - + int locals; // total ints of parms + locals + int profile; // runtime - + int s_name; int s_file; // source file defined in - + int numparms; byte parm_size[MAX_PARMS]; } dfunction_t; @@ -155,26 +170,28 @@ typedef struct typedef struct { int version; - int crc; // check of header file - + int crc; // check of header file + int ofs_statements; int numstatements; // statement 0 is an error int ofs_globaldefs; int numglobaldefs; - + int ofs_fielddefs; int numfielddefs; - + int ofs_functions; int numfunctions; // function 0 is an empty - + int ofs_strings; - int numstrings; // first string is a null string + int numstrings; // first string is a null string int ofs_globals; int numglobals; - + int entityfields; } dprograms_t; +#endif /* __PR_COMP_H */ + diff --git a/engine/code/pr_edict.c b/engine/Quake/pr_edict.c similarity index 56% rename from engine/code/pr_edict.c rename to engine/Quake/pr_edict.c index c27d403..c52f7c0 100644 --- a/engine/code/pr_edict.c +++ b/engine/Quake/pr_edict.c @@ -1,5 +1,7 @@ /* -Copyright (C) 1996-1997 Id Software, Inc. +Copyright (C) 1996-2001 Id Software, Inc. +Copyright (C) 2002-2009 John Fitzgibbons and others +Copyright (C) 2010-2014 QuakeSpasm developers This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -8,7 +10,7 @@ of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. @@ -24,47 +26,62 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. dprograms_t *progs; dfunction_t *pr_functions; -static char *pr_strings; -static int pr_stringssize; -static char **pr_knownstrings; -static int pr_maxknownstrings; -static int pr_numknownstrings; +static char *pr_strings; +static int pr_stringssize; +static const char **pr_knownstrings; +static int pr_maxknownstrings; +static int pr_numknownstrings; +static ddef_t *pr_fielddefs; +static ddef_t *pr_globaldefs; + +qboolean pr_alpha_supported; //johnfitz -ddef_t *pr_fielddefs; -ddef_t *pr_globaldefs; dstatement_t *pr_statements; globalvars_t *pr_global_struct; -float *pr_globals; // same as pr_global_struct -int pr_edict_size; // in bytes - -unsigned short pr_crc; +float *pr_globals; // same as pr_global_struct +int pr_edict_size; // in bytes -int type_size[8] = {1,sizeof(string_t)/4,1,3,1,1,sizeof(func_t)/4,sizeof(void *)/4}; +unsigned short pr_crc; -ddef_t *ED_FieldAtOfs (int ofs); -qboolean ED_ParseEpair (void *base, ddef_t *key, char *s); +int type_size[8] = { + 1, // ev_void + 1, // sizeof(string_t) / 4 // ev_string + 1, // ev_float + 3, // ev_vector + 1, // ev_entity + 1, // ev_field + 1, // sizeof(func_t) / 4 // ev_function + 1 // sizeof(void *) / 4 // ev_pointer +}; -cvar_t nomonsters = {"nomonsters", "0"}; -cvar_t gamecfg = {"gamecfg", "0"}; -cvar_t scratch1 = {"scratch1", "0"}; -cvar_t scratch2 = {"scratch2", "0"}; -cvar_t scratch3 = {"scratch3", "0"}; -cvar_t scratch4 = {"scratch4", "0"}; -cvar_t savedgamecfg = {"savedgamecfg", "0", true}; -cvar_t saved1 = {"saved1", "0", true}; -cvar_t saved2 = {"saved2", "0", true}; -cvar_t saved3 = {"saved3", "0", true}; -cvar_t saved4 = {"saved4", "0", true}; +static ddef_t *ED_FieldAtOfs (int ofs); +static qboolean ED_ParseEpair (void *base, ddef_t *key, const char *s); #define MAX_FIELD_LEN 64 -#define GEFV_CACHESIZE 2 +#define GEFV_CACHESIZE 2 typedef struct { ddef_t *pcache; char field[MAX_FIELD_LEN]; } gefv_cache; -static gefv_cache gefvCache[GEFV_CACHESIZE] = {{NULL, ""}, {NULL, ""}}; +static gefv_cache gefvCache[GEFV_CACHESIZE] = +{ + { NULL, "" }, + { NULL, "" } +}; + +cvar_t nomonsters = {"nomonsters", "0", CVAR_NONE}; +cvar_t gamecfg = {"gamecfg", "0", CVAR_NONE}; +cvar_t scratch1 = {"scratch1", "0", CVAR_NONE}; +cvar_t scratch2 = {"scratch2", "0", CVAR_NONE}; +cvar_t scratch3 = {"scratch3", "0", CVAR_NONE}; +cvar_t scratch4 = {"scratch4", "0", CVAR_NONE}; +cvar_t savedgamecfg = {"savedgamecfg", "0", CVAR_ARCHIVE}; +cvar_t saved1 = {"saved1", "0", CVAR_ARCHIVE}; +cvar_t saved2 = {"saved2", "0", CVAR_ARCHIVE}; +cvar_t saved3 = {"saved3", "0", CVAR_ARCHIVE}; +cvar_t saved4 = {"saved4", "0", CVAR_ARCHIVE}; /* ================= @@ -95,7 +112,7 @@ edict_t *ED_Alloc (void) int i; edict_t *e; - for ( i=svs.maxclients+1 ; iv.angles); ed->v.nextthink = -1; ed->v.solid = 0; - + ed->alpha = ENTALPHA_DEFAULT; //johnfitz -- reset alpha for next entity + ed->freetime = sv.time; } @@ -151,12 +169,12 @@ void ED_Free (edict_t *ed) ED_GlobalAtOfs ============ */ -ddef_t *ED_GlobalAtOfs (int ofs) +static ddef_t *ED_GlobalAtOfs (int ofs) { ddef_t *def; int i; - - for (i=0 ; inumglobaldefs ; i++) + + for (i = 0; i < progs->numglobaldefs; i++) { def = &pr_globaldefs[i]; if (def->ofs == ofs) @@ -170,12 +188,12 @@ ddef_t *ED_GlobalAtOfs (int ofs) ED_FieldAtOfs ============ */ -ddef_t *ED_FieldAtOfs (int ofs) +static ddef_t *ED_FieldAtOfs (int ofs) { ddef_t *def; int i; - - for (i=0 ; inumfielddefs ; i++) + + for (i = 0; i < progs->numfielddefs; i++) { def = &pr_fielddefs[i]; if (def->ofs == ofs) @@ -189,15 +207,15 @@ ddef_t *ED_FieldAtOfs (int ofs) ED_FindField ============ */ -ddef_t *ED_FindField (char *name) +static ddef_t *ED_FindField (const char *name) { ddef_t *def; int i; - - for (i=0 ; inumfielddefs ; i++) + + for (i = 0; i < progs->numfielddefs; i++) { def = &pr_fielddefs[i]; - if (!strcmp(PR_GetString(def->s_name), name) ) + if ( !strcmp(PR_GetString(def->s_name), name) ) return def; } return NULL; @@ -209,15 +227,15 @@ ddef_t *ED_FindField (char *name) ED_FindGlobal ============ */ -ddef_t *ED_FindGlobal (char *name) +static ddef_t *ED_FindGlobal (const char *name) { ddef_t *def; int i; - - for (i=0 ; inumglobaldefs ; i++) + + for (i = 0; i < progs->numglobaldefs; i++) { def = &pr_globaldefs[i]; - if (!strcmp(PR_GetString(def->s_name), name) ) + if ( !strcmp(PR_GetString(def->s_name), name) ) return def; } return NULL; @@ -229,28 +247,32 @@ ddef_t *ED_FindGlobal (char *name) ED_FindFunction ============ */ -dfunction_t *ED_FindFunction (char *name) +static dfunction_t *ED_FindFunction (const char *fn_name) { dfunction_t *func; int i; - - for (i=0 ; inumfunctions ; i++) + + for (i = 0; i < progs->numfunctions; i++) { func = &pr_functions[i]; - if (!strcmp(PR_GetString(func->s_name), name) ) + if ( !strcmp(PR_GetString(func->s_name), fn_name) ) return func; } return NULL; } - -eval_t *GetEdictFieldValue(edict_t *ed, char *field) +/* +============ +GetEdictFieldValue +============ +*/ +eval_t *GetEdictFieldValue(edict_t *ed, const char *field) { ddef_t *def = NULL; int i; static int rep = 0; - for (i=0 ; istring)); break; - case ev_entity: + case ev_entity: sprintf (line, "entity %i", NUM_FOR_EDICT(PROG_TO_EDICT(val->edict)) ); break; case ev_function: @@ -323,56 +346,57 @@ char *PR_ValueString (etype_t type, eval_t *val) sprintf (line, "bad type %i", type); break; } - + return line; } /* ============ PR_UglyValueString +(etype_t type, eval_t *val) Returns a string describing *data in a type specific manner Easier to parse than PR_ValueString ============= */ -char *PR_UglyValueString (etype_t type, eval_t *val) +static const char *PR_UglyValueString (int type, eval_t *val) { - static char line[256]; + static char line[1024]; ddef_t *def; dfunction_t *f; - + type &= ~DEF_SAVEGLOBAL; switch (type) { case ev_string: - sprintf (line, "%s", PR_GetString(val->string)); + q_snprintf (line, sizeof(line), "%s", PR_GetString(val->string)); break; - case ev_entity: - sprintf (line, "%i", NUM_FOR_EDICT(PROG_TO_EDICT(val->edict))); + case ev_entity: + q_snprintf (line, sizeof(line), "%i", NUM_FOR_EDICT(PROG_TO_EDICT(val->edict))); break; case ev_function: f = pr_functions + val->function; - sprintf (line, "%s", PR_GetString(f->s_name)); + q_snprintf (line, sizeof(line), "%s", PR_GetString(f->s_name)); break; case ev_field: def = ED_FieldAtOfs ( val->_int ); - sprintf (line, "%s", PR_GetString(def->s_name)); + q_snprintf (line, sizeof(line), "%s", PR_GetString(def->s_name)); break; case ev_void: - sprintf (line, "void"); + q_snprintf (line, sizeof(line), "void"); break; case ev_float: - sprintf (line, "%f", val->_float); + q_snprintf (line, sizeof(line), "%f", val->_float); break; case ev_vector: - sprintf (line, "%f %f %f", val->vector[0], val->vector[1], val->vector[2]); + q_snprintf (line, sizeof(line), "%f %f %f", val->vector[0], val->vector[1], val->vector[2]); break; default: - sprintf (line, "bad type %i", type); + q_snprintf (line, sizeof(line), "bad type %i", type); break; } - + return line; } @@ -384,49 +408,49 @@ Returns a string with a description and the contents of a global, padded to 20 field width ============ */ -char *PR_GlobalString (int ofs) +const char *PR_GlobalString (int ofs) { - char *s; + static char line[512]; + const char *s; int i; - ddef_t *def; - void *val; - static char line[128]; - + ddef_t *def; + void *val; + val = (void *)&pr_globals[ofs]; def = ED_GlobalAtOfs(ofs); if (!def) - sprintf (line,"%i(???)", ofs); + sprintf (line,"%i(?)", ofs); else { - s = PR_ValueString (def->type, val); + s = PR_ValueString (def->type, (eval_t *)val); sprintf (line,"%i(%s)%s", ofs, PR_GetString(def->s_name), s); } - + i = strlen(line); - for ( ; i<20 ; i++) - strcat (line," "); - strcat (line," "); - + for ( ; i < 20; i++) + strcat (line, " "); + strcat (line, " "); + return line; } -char *PR_GlobalStringNoContents (int ofs) +const char *PR_GlobalStringNoContents (int ofs) { + static char line[512]; int i; - ddef_t *def; - static char line[128]; - + ddef_t *def; + def = ED_GlobalAtOfs(ofs); if (!def) - sprintf (line,"%i(???)", ofs); + sprintf (line,"%i(?)", ofs); else sprintf (line,"%i(%s)", ofs, PR_GetString(def->s_name)); - + i = strlen(line); - for ( ; i<20 ; i++) - strcat (line," "); - strcat (line," "); - + for ( ; i < 20; i++) + strcat (line, " "); + strcat (line, " "); + return line; } @@ -440,11 +464,10 @@ For debugging */ void ED_Print (edict_t *ed) { - int l; ddef_t *d; int *v; - int i, j; - char *name; + int i, j, l; + const char *name; int type; if (ed->free) @@ -453,31 +476,33 @@ void ED_Print (edict_t *ed) return; } - Con_Printf("\nEDICT %i:\n", NUM_FOR_EDICT(ed)); - for (i=1 ; inumfielddefs ; i++) + Con_SafePrintf("\nEDICT %i:\n", NUM_FOR_EDICT(ed)); //johnfitz -- was Con_Printf + for (i = 1; i < progs->numfielddefs; i++) { d = &pr_fielddefs[i]; name = PR_GetString(d->s_name); - if (name[strlen(name)-2] == '_') + l = strlen (name); + if (l > 1 && name[l - 2] == '_') continue; // skip _x, _y, _z vars - + v = (int *)((char *)&ed->v + d->ofs*4); // if the value is still all 0, skip the field type = d->type & ~DEF_SAVEGLOBAL; - - for (j=0 ; jtype, (eval_t *)v)); + Con_SafePrintf ("%s\n", PR_ValueString(d->type, (eval_t *)v)); //johnfitz -- was Con_Printf } } @@ -493,7 +518,7 @@ void ED_Write (FILE *f, edict_t *ed) ddef_t *d; int *v; int i, j; - char *name; + const char *name; int type; fprintf (f, "{\n"); @@ -503,28 +528,36 @@ void ED_Write (FILE *f, edict_t *ed) fprintf (f, "}\n"); return; } - - for (i=1 ; inumfielddefs ; i++) + + for (i = 1; i < progs->numfielddefs; i++) { d = &pr_fielddefs[i]; name = PR_GetString(d->s_name); - if (name[strlen(name)-2] == '_') + j = strlen (name); + if (j > 1 && name[j - 2] == '_') continue; // skip _x, _y, _z vars - + v = (int *)((char *)&ed->v + d->ofs*4); // if the value is still all 0, skip the field type = d->type & ~DEF_SAVEGLOBAL; - for (j=0 ; jtype, (eval_t *)v)); + + fprintf (f, "\"%s\" ", name); + fprintf (f, "\"%s\"\n", PR_UglyValueString(d->type, (eval_t *)v)); } + //johnfitz -- save entity alpha manually when progs.dat doesn't know about alpha + if (!pr_alpha_supported && ed->alpha != ENTALPHA_DEFAULT) + fprintf (f, "\"alpha\" \"%f\"\n", ENTALPHA_TOSAVE(ed->alpha)); + //johnfitz + fprintf (f, "}\n"); } @@ -543,9 +576,12 @@ For debugging, prints all the entities in the current server void ED_PrintEdicts (void) { int i; - + + if (!sv.active) + return; + Con_Printf ("%i entities\n", sv.num_edicts); - for (i=0 ; i= sv.num_edicts) + if (i < 0 || i >= sv.num_edicts) { Con_Printf("Bad edict number\n"); return; @@ -576,14 +615,16 @@ ED_Count For debugging ============= */ -void ED_Count (void) +static void ED_Count (void) { - int i; edict_t *ent; - int active, models, solid, step; + int i, active, models, solid, step; + + if (!sv.active) + return; active = models = solid = step = 0; - for (i=0 ; ifree) @@ -602,13 +643,13 @@ void ED_Count (void) Con_Printf ("view :%3i\n", models); Con_Printf ("touch :%3i\n", solid); Con_Printf ("step :%3i\n", step); - } + /* ============================================================================== - ARCHIVING GLOBALS +ARCHIVING GLOBALS FIXME: need to tag constants, doesn't really work ============================================================================== @@ -623,11 +664,11 @@ void ED_WriteGlobals (FILE *f) { ddef_t *def; int i; - char *name; + const char *name; int type; - fprintf (f,"{\n"); - for (i=0 ; inumglobaldefs ; i++) + fprintf (f, "{\n"); + for (i = 0; i < progs->numglobaldefs; i++) { def = &pr_globaldefs[i]; type = def->type; @@ -635,16 +676,14 @@ void ED_WriteGlobals (FILE *f) continue; type &= ~DEF_SAVEGLOBAL; - if (type != ev_string - && type != ev_float - && type != ev_entity) + if (type != ev_string && type != ev_float && type != ev_entity) continue; name = PR_GetString(def->s_name); - fprintf (f,"\"%s\" ", name); - fprintf (f,"\"%s\"\n", PR_UglyValueString(type, (eval_t *)&pr_globals[def->ofs])); + fprintf (f, "\"%s\" ", name); + fprintf (f, "\"%s\"\n", PR_UglyValueString(type, (eval_t *)&pr_globals[def->ofs])); } - fprintf (f,"}\n"); + fprintf (f, "}\n"); } /* @@ -652,29 +691,29 @@ void ED_WriteGlobals (FILE *f) ED_ParseGlobals ============= */ -void ED_ParseGlobals (char *data) +const char *ED_ParseGlobals (const char *data) { char keyname[64]; ddef_t *key; while (1) - { + { // parse key data = COM_Parse (data); if (com_token[0] == '}') break; if (!data) - Sys_Error ("ED_ParseEntity: EOF without closing brace"); + Host_Error ("ED_ParseEntity: EOF without closing brace"); - strcpy (keyname, com_token); + q_strlcpy (keyname, com_token, sizeof(keyname)); - // parse value + // parse value data = COM_Parse (data); if (!data) - Sys_Error ("ED_ParseEntity: EOF without closing brace"); + Host_Error ("ED_ParseEntity: EOF without closing brace"); if (com_token[0] == '}') - Sys_Error ("ED_ParseEntity: closing brace without data"); + Host_Error ("ED_ParseEntity: closing brace without data"); key = ED_FindGlobal (keyname); if (!key) @@ -686,6 +725,7 @@ void ED_ParseGlobals (char *data) if (!ED_ParseEpair ((void *)pr_globals, key, com_token)) Host_Error ("ED_ParseGlobals: parse error"); } + return data; } //============================================================================ @@ -696,16 +736,16 @@ void ED_ParseGlobals (char *data) ED_NewString ============= */ -string_t ED_NewString (char *string) +static string_t ED_NewString (const char *string) { char *new_p; - int i,l; - string_t num; - + int i, l; + string_t num; + l = strlen(string) + 1; - num = PR_AllocString(l, &new_p); + num = PR_AllocString (l, &new_p); - for (i=0 ; i< l ; i++) + for (i = 0; i < l; i++) { if (string[i] == '\\' && i < l-1) { @@ -718,7 +758,7 @@ string_t ED_NewString (char *string) else *new_p++ = string[i]; } - + return num; } @@ -731,55 +771,69 @@ Can parse either fields or globals returns false if error ============= */ -qboolean ED_ParseEpair (void *base, ddef_t *key, char *s) +static qboolean ED_ParseEpair (void *base, ddef_t *key, const char *s) { int i; char string[128]; ddef_t *def; char *v, *w; + char *end; void *d; dfunction_t *func; - + d = (void *)((int *)base + key->ofs); - + switch (key->type & ~DEF_SAVEGLOBAL) { case ev_string: - *(string_t *)d = ED_NewString (s); + *(string_t *)d = ED_NewString(s); break; - + case ev_float: *(float *)d = atof (s); break; - + case ev_vector: - strcpy (string, s); + q_strlcpy (string, s, sizeof(string)); + end = (char *)string + strlen(string); v = string; w = string; - for (i=0 ; i<3 ; i++) + + for (i = 0; i < 3 && (w <= end); i++) // ericw -- added (w <= end) check { + // set v to the next space (or 0 byte), and change that char to a 0 byte while (*v && *v != ' ') v++; *v = 0; ((float *)d)[i] = atof (w); w = v = v+1; } + // ericw -- fill remaining elements to 0 in case we hit the end of string + // before reading 3 floats. + if (i < 3) + { + Con_DWarning ("Avoided reading garbage for \"%s\" \"%s\"\n", PR_GetString(key->s_name), s); + for (; i < 3; i++) + ((float *)d)[i] = 0.0f; + } break; - + case ev_entity: *(int *)d = EDICT_TO_PROG(EDICT_NUM(atoi (s))); break; - + case ev_field: def = ED_FindField (s); if (!def) { - Con_Printf ("Can't find field %s\n", s); + //johnfitz -- HACK -- suppress error becuase fog/sky fields might not be mentioned in defs.qc + if (strncmp(s, "sky", 3) && strcmp(s, "fog")) + Con_DPrintf ("Can't find field %s\n", s); return false; } *(int *)d = G_INT(def->ofs); break; - + case ev_function: func = ED_FindFunction (s); if (!func) @@ -789,7 +843,7 @@ qboolean ED_ParseEpair (void *base, ddef_t *key, char *s) } *(func_t *)d = func - pr_functions; break; - + default: break; } @@ -805,47 +859,46 @@ ed should be a properly initialized empty edict. Used for initial level load and for savegames. ==================== */ -char *ED_ParseEdict (char *data, edict_t *ent) +const char *ED_ParseEdict (const char *data, edict_t *ent) { ddef_t *key; - qboolean anglehack; - qboolean init; char keyname[256]; - int n; + qboolean anglehack, init; + int n; init = false; -// clear it + // clear it if (ent != sv.edicts) // hack memset (&ent->v, 0, progs->entityfields * 4); -// go through all the dictionary pairs + // go through all the dictionary pairs while (1) - { - // parse key + { + // parse key data = COM_Parse (data); if (com_token[0] == '}') break; if (!data) - Sys_Error ("ED_ParseEntity: EOF without closing brace"); - -// anglehack is to allow QuakeEd to write single scalar angles -// and allow them to be turned into vectors. (FIXME...) -if (!strcmp(com_token, "angle")) -{ - strcpy (com_token, "angles"); - anglehack = true; -} -else - anglehack = false; + Host_Error ("ED_ParseEntity: EOF without closing brace"); + + // anglehack is to allow QuakeEd to write single scalar angles + // and allow them to be turned into vectors. (FIXME...) + if (!strcmp(com_token, "angle")) + { + strcpy (com_token, "angles"); + anglehack = true; + } + else + anglehack = false; -// FIXME: change light to _light to get rid of this hack -if (!strcmp(com_token, "light")) - strcpy (com_token, "light_lev"); // hack for single light def + // FIXME: change light to _light to get rid of this hack + if (!strcmp(com_token, "light")) + strcpy (com_token, "light_lev"); // hack for single light def - strcpy (keyname, com_token); + q_strlcpy (keyname, com_token, sizeof(keyname)); - // another hack to fix heynames with trailing spaces + // another hack to fix keynames with trailing spaces n = strlen(keyname); while (n && keyname[n-1] == ' ') { @@ -853,40 +906,41 @@ if (!strcmp(com_token, "light")) n--; } - // parse value + // parse value data = COM_Parse (data); if (!data) - Sys_Error ("ED_ParseEntity: EOF without closing brace"); + Host_Error ("ED_ParseEntity: EOF without closing brace"); if (com_token[0] == '}') - Sys_Error ("ED_ParseEntity: closing brace without data"); + Host_Error ("ED_ParseEntity: closing brace without data"); - init = true; + init = true; -// keynames with a leading underscore are used for utility comments, -// and are immediately discarded by quake + // keynames with a leading underscore are used for utility comments, + // and are immediately discarded by quake if (keyname[0] == '_') continue; - if (strcmpi(keyname,"SKY") == 0) // jkrige - skybox - { - strcpy(sv.skybox, com_token); - continue; - } - + //johnfitz -- hack to support .alpha even when progs.dat doesn't know about it + if (!strcmp(keyname, "alpha")) + ent->alpha = ENTALPHA_ENCODE(atof(com_token)); + //johnfitz + key = ED_FindField (keyname); if (!key) { - Con_Printf ("'%s' is not a field\n", keyname); + //johnfitz -- HACK -- suppress error becuase fog/sky/alpha fields might not be mentioned in defs.qc + if (strncmp(keyname, "sky", 3) && strcmp(keyname, "fog") && strcmp(keyname, "alpha")) + Con_DPrintf ("\"%s\" is not a field\n", keyname); //johnfitz -- was Con_Printf continue; } -if (anglehack) -{ -char temp[32]; -strcpy (temp, com_token); -sprintf (com_token, "0 %s 0", temp); -} + if (anglehack) + { + char temp[32]; + strcpy (temp, com_token); + sprintf (com_token, "0 %s 0", temp); + } if (!ED_ParseEpair ((void *)&ent->v, key, com_token)) Host_Error ("ED_ParseEdict: parse error"); @@ -914,25 +968,23 @@ Used for both fresh maps and savegame loads. A fresh map would also need to call ED_CallSpawnFunctions () to let the objects initialize themselves. ================ */ -void ED_LoadFromFile (char *data) -{ - edict_t *ent; - int inhibit; +void ED_LoadFromFile (const char *data) +{ dfunction_t *func; - - ent = NULL; - inhibit = 0; + edict_t *ent = NULL; + int inhibit = 0; + pr_global_struct->time = sv.time; - -// parse ents + + // parse ents while (1) { -// parse the opening brace + // parse the opening brace data = COM_Parse (data); if (!data) break; if (com_token[0] != '{') - Sys_Error ("ED_LoadFromFile: found %s when expecting {",com_token); + Host_Error ("ED_LoadFromFile: found %s when expecting {",com_token); if (!ent) ent = EDICT_NUM(0); @@ -940,12 +992,12 @@ void ED_LoadFromFile (char *data) ent = ED_Alloc (); data = ED_ParseEdict (data, ent); -// remove things from different skill levels or deathmatch + // remove things from different skill levels or deathmatch if (deathmatch.value) { if (((int)ent->v.spawnflags & SPAWNFLAG_NOT_DEATHMATCH)) { - ED_Free (ent); + ED_Free (ent); inhibit++; continue; } @@ -954,7 +1006,7 @@ void ED_LoadFromFile (char *data) || (current_skill == 1 && ((int)ent->v.spawnflags & SPAWNFLAG_NOT_MEDIUM)) || (current_skill >= 2 && ((int)ent->v.spawnflags & SPAWNFLAG_NOT_HARD)) ) { - ED_Free (ent); + ED_Free (ent); inhibit++; continue; } @@ -964,7 +1016,7 @@ void ED_LoadFromFile (char *data) // if (!ent->v.classname) { - Con_Printf ("No classname for:\n"); + Con_SafePrintf ("No classname for:\n"); //johnfitz -- was Con_Printf ED_Print (ent); ED_Free (ent); continue; @@ -975,7 +1027,7 @@ void ED_LoadFromFile (char *data) if (!func) { - Con_Printf ("No spawn function for:\n"); + Con_SafePrintf ("No spawn function for:\n"); //johnfitz -- was Con_Printf ED_Print (ent); ED_Free (ent); continue; @@ -983,7 +1035,7 @@ void ED_LoadFromFile (char *data) pr_global_struct->self = EDICT_TO_PROG(ent); PR_ExecuteProgram (func - pr_functions); - } + } Con_DPrintf ("%i entities inhibited\n", inhibit); } @@ -996,39 +1048,42 @@ PR_LoadProgs */ void PR_LoadProgs (void) { - int i; + int i; -// flush the non-C variable lookup cache - for (i=0 ; iversion != PROG_VERSION) - Sys_Error ("progs.dat has wrong version number (%i should be %i)", progs->version, PROG_VERSION); + Host_Error ("progs.dat has wrong version number (%i should be %i)", progs->version, PROG_VERSION); if (progs->crc != PROGHEADER_CRC) - Sys_Error ("progs.dat system vars have been modified, progdefs.h is out of date"); + Host_Error ("progs.dat system vars have been modified, progdefs.h is out of date"); pr_functions = (dfunction_t *)((byte *)progs + progs->ofs_functions); pr_strings = (char *)progs + progs->ofs_strings; + if (progs->ofs_strings + progs->numstrings >= com_filesize) + Host_Error ("progs.dat strings go past end of file\n"); // initialize the strings pr_numknownstrings = 0; pr_maxknownstrings = 0; pr_stringssize = progs->numstrings; - if (pr_knownstrings) Z_Free((void *)pr_knownstrings); + if (pr_knownstrings) + Z_Free ((void *)pr_knownstrings); pr_knownstrings = NULL; PR_SetEngineString(""); @@ -1038,16 +1093,9 @@ void PR_LoadProgs (void) pr_global_struct = (globalvars_t *)((byte *)progs + progs->ofs_globals); pr_globals = (float *)pr_global_struct; - - pr_edict_size = progs->entityfields * 4 + sizeof (edict_t) - sizeof(entvars_t); - // Round off to next highest whole word address - // this ensures that pointers in the engine data area are always properly aligned - pr_edict_size += sizeof(void *) - 1; - pr_edict_size &= ~(sizeof(void *) - 1); - -// byte swap the lumps - for (i=0 ; inumstatements ; i++) + // byte swap the lumps + for (i = 0; i < progs->numstatements; i++) { pr_statements[i].op = LittleShort(pr_statements[i].op); pr_statements[i].a = LittleShort(pr_statements[i].a); @@ -1055,34 +1103,48 @@ void PR_LoadProgs (void) pr_statements[i].c = LittleShort(pr_statements[i].c); } - for (i=0 ; inumfunctions; i++) + for (i = 0; i < progs->numfunctions; i++) { - pr_functions[i].first_statement = LittleLong (pr_functions[i].first_statement); - pr_functions[i].parm_start = LittleLong (pr_functions[i].parm_start); - pr_functions[i].s_name = LittleLong (pr_functions[i].s_name); - pr_functions[i].s_file = LittleLong (pr_functions[i].s_file); - pr_functions[i].numparms = LittleLong (pr_functions[i].numparms); - pr_functions[i].locals = LittleLong (pr_functions[i].locals); - } - - for (i=0 ; inumglobaldefs ; i++) + pr_functions[i].first_statement = LittleLong (pr_functions[i].first_statement); + pr_functions[i].parm_start = LittleLong (pr_functions[i].parm_start); + pr_functions[i].s_name = LittleLong (pr_functions[i].s_name); + pr_functions[i].s_file = LittleLong (pr_functions[i].s_file); + pr_functions[i].numparms = LittleLong (pr_functions[i].numparms); + pr_functions[i].locals = LittleLong (pr_functions[i].locals); + } + + for (i = 0; i < progs->numglobaldefs; i++) { pr_globaldefs[i].type = LittleShort (pr_globaldefs[i].type); pr_globaldefs[i].ofs = LittleShort (pr_globaldefs[i].ofs); pr_globaldefs[i].s_name = LittleLong (pr_globaldefs[i].s_name); } - for (i=0 ; inumfielddefs ; i++) + pr_alpha_supported = false; //johnfitz + + for (i = 0; i < progs->numfielddefs; i++) { pr_fielddefs[i].type = LittleShort (pr_fielddefs[i].type); if (pr_fielddefs[i].type & DEF_SAVEGLOBAL) - Sys_Error ("PR_LoadProgs: pr_fielddefs[i].type & DEF_SAVEGLOBAL"); + Host_Error ("PR_LoadProgs: pr_fielddefs[i].type & DEF_SAVEGLOBAL"); pr_fielddefs[i].ofs = LittleShort (pr_fielddefs[i].ofs); pr_fielddefs[i].s_name = LittleLong (pr_fielddefs[i].s_name); + + //johnfitz -- detect alpha support in progs.dat + if (!strcmp(pr_strings + pr_fielddefs[i].s_name,"alpha")) + pr_alpha_supported = true; + //johnfitz } - for (i=0 ; inumglobals ; i++) + for (i = 0; i < progs->numglobals; i++) ((int *)pr_globals)[i] = LittleLong (((int *)pr_globals)[i]); + + pr_edict_size = progs->entityfields * 4 + sizeof(edict_t) - sizeof(entvars_t); + // round off to next highest whole word address (esp for Alpha) + // this ensures that pointers in the engine data area are always + // properly aligned + pr_edict_size += sizeof(void *) - 1; + pr_edict_size &= ~(sizeof(void *) - 1); } @@ -1111,52 +1173,48 @@ void PR_Init (void) } - edict_t *EDICT_NUM(int n) { if (n < 0 || n >= sv.max_edicts) - Sys_Error ("EDICT_NUM: bad number %i", n); - return (edict_t *)((byte *)sv.edicts+ (n)*pr_edict_size); + Host_Error ("EDICT_NUM: bad number %i", n); + return (edict_t *)((byte *)sv.edicts + (n)*pr_edict_size); } int NUM_FOR_EDICT(edict_t *e) { int b; - + b = (byte *)e - (byte *)sv.edicts; b = b / pr_edict_size; - + if (b < 0 || b >= sv.num_edicts) - Sys_Error ("NUM_FOR_EDICT: bad pointer"); + Host_Error ("NUM_FOR_EDICT: bad pointer"); return b; } -// =============== -// String handling -// =============== +//=========================================================================== + #define PR_STRING_ALLOCSLOTS 256 -static void PR_AllocStringSlots(void) +static void PR_AllocStringSlots (void) { pr_maxknownstrings += PR_STRING_ALLOCSLOTS; - Con_DPrintf("PR_AllocStringSlots: realloc'ing for %d slots\n", pr_maxknownstrings); - pr_knownstrings = (char **)Z_Realloc((void *)pr_knownstrings, pr_maxknownstrings * sizeof(char *)); + Con_DPrintf2("PR_AllocStringSlots: realloc'ing for %d slots\n", pr_maxknownstrings); + pr_knownstrings = (const char **) Z_Realloc ((void *)pr_knownstrings, pr_maxknownstrings * sizeof(char *)); } -char *PR_GetString(int num) +const char *PR_GetString (int num) { if (num >= 0 && num < pr_stringssize) return pr_strings + num; - else if (num < 0 && num >= -pr_numknownstrings) { if (!pr_knownstrings[-1 - num]) { - Host_Error("PR_GetString: attempt to get a non-existent string %d\n", num); + Host_Error ("PR_GetString: attempt to get a non-existant string %d\n", num); return ""; } - return pr_knownstrings[-1 - num]; } else @@ -1166,52 +1224,63 @@ char *PR_GetString(int num) } } -int PR_SetEngineString(char *s) +int PR_SetEngineString (const char *s) { - int i; + int i; if (!s) return 0; - +#if 0 /* can't: sv.model_precache & sv.sound_precache points to pr_strings */ + if (s >= pr_strings && s <= pr_strings + pr_stringssize) + Host_Error("PR_SetEngineString: \"%s\" in pr_strings area\n", s); +#else if (s >= pr_strings && s <= pr_strings + pr_stringssize - 2) return (int)(s - pr_strings); - +#endif for (i = 0; i < pr_numknownstrings; i++) { if (pr_knownstrings[i] == s) return -1 - i; } - - if (i >= pr_maxknownstrings) - PR_AllocStringSlots(); - - pr_numknownstrings++; - + // new unknown engine string + //Con_DPrintf ("PR_SetEngineString: new engine string %p\n", s); +#if 0 + for (i = 0; i < pr_numknownstrings; i++) + { + if (!pr_knownstrings[i]) + break; + } +#endif +// if (i >= pr_numknownstrings) +// { + if (i >= pr_maxknownstrings) + PR_AllocStringSlots(); + pr_numknownstrings++; +// } pr_knownstrings[i] = s; return -1 - i; } -int PR_AllocString(int size, char **ptr) +int PR_AllocString (int size, char **ptr) { int i; if (!size) return 0; - for (i = 0; i < pr_numknownstrings; i++) { if (!pr_knownstrings[i]) break; } - - if (i >= pr_maxknownstrings) - PR_AllocStringSlots(); - - pr_numknownstrings++; - +// if (i >= pr_numknownstrings) +// { + if (i >= pr_maxknownstrings) + PR_AllocStringSlots(); + pr_numknownstrings++; +// } pr_knownstrings[i] = (char *)Hunk_AllocName(size, "string"); if (ptr) - *ptr = (char *)pr_knownstrings[i]; - + *ptr = (char *) pr_knownstrings[i]; return -1 - i; -} \ No newline at end of file +} + diff --git a/engine/Quake/pr_exec.c b/engine/Quake/pr_exec.c new file mode 100644 index 0000000..ad9503e --- /dev/null +++ b/engine/Quake/pr_exec.c @@ -0,0 +1,654 @@ +/* +Copyright (C) 1996-2001 Id Software, Inc. +Copyright (C) 2010-2014 QuakeSpasm developers + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#include "quakedef.h" + +typedef struct +{ + int s; + dfunction_t *f; +} prstack_t; + +#define MAX_STACK_DEPTH 64 /* was 32 */ +static prstack_t pr_stack[MAX_STACK_DEPTH]; +static int pr_depth; + +#define LOCALSTACK_SIZE 2048 +static int localstack[LOCALSTACK_SIZE]; +static int localstack_used; + +qboolean pr_trace; +dfunction_t *pr_xfunction; +int pr_xstatement; +int pr_argc; + +static const char *pr_opnames[] = +{ + "DONE", + + "MUL_F", + "MUL_V", + "MUL_FV", + "MUL_VF", + + "DIV", + + "ADD_F", + "ADD_V", + + "SUB_F", + "SUB_V", + + "EQ_F", + "EQ_V", + "EQ_S", + "EQ_E", + "EQ_FNC", + + "NE_F", + "NE_V", + "NE_S", + "NE_E", + "NE_FNC", + + "LE", + "GE", + "LT", + "GT", + + "INDIRECT", + "INDIRECT", + "INDIRECT", + "INDIRECT", + "INDIRECT", + "INDIRECT", + + "ADDRESS", + + "STORE_F", + "STORE_V", + "STORE_S", + "STORE_ENT", + "STORE_FLD", + "STORE_FNC", + + "STOREP_F", + "STOREP_V", + "STOREP_S", + "STOREP_ENT", + "STOREP_FLD", + "STOREP_FNC", + + "RETURN", + + "NOT_F", + "NOT_V", + "NOT_S", + "NOT_ENT", + "NOT_FNC", + + "IF", + "IFNOT", + + "CALL0", + "CALL1", + "CALL2", + "CALL3", + "CALL4", + "CALL5", + "CALL6", + "CALL7", + "CALL8", + + "STATE", + + "GOTO", + + "AND", + "OR", + + "BITAND", + "BITOR" +}; + +const char *PR_GlobalString (int ofs); +const char *PR_GlobalStringNoContents (int ofs); + + +//============================================================================= + +/* +================= +PR_PrintStatement +================= +*/ +static void PR_PrintStatement (dstatement_t *s) +{ + int i; + + if ((unsigned int)s->op < sizeof(pr_opnames)/sizeof(pr_opnames[0])) + { + Con_Printf("%s ", pr_opnames[s->op]); + i = strlen(pr_opnames[s->op]); + for ( ; i < 10; i++) + Con_Printf(" "); + } + + if (s->op == OP_IF || s->op == OP_IFNOT) + Con_Printf("%sbranch %i", PR_GlobalString(s->a), s->b); + else if (s->op == OP_GOTO) + { + Con_Printf("branch %i", s->a); + } + else if ((unsigned int)(s->op-OP_STORE_F) < 6) + { + Con_Printf("%s", PR_GlobalString(s->a)); + Con_Printf("%s", PR_GlobalStringNoContents(s->b)); + } + else + { + if (s->a) + Con_Printf("%s", PR_GlobalString(s->a)); + if (s->b) + Con_Printf("%s", PR_GlobalString(s->b)); + if (s->c) + Con_Printf("%s", PR_GlobalStringNoContents(s->c)); + } + Con_Printf("\n"); +} + +/* +============ +PR_StackTrace +============ +*/ +static void PR_StackTrace (void) +{ + int i; + dfunction_t *f; + + if (pr_depth == 0) + { + Con_Printf("\n"); + return; + } + + pr_stack[pr_depth].f = pr_xfunction; + for (i = pr_depth; i >= 0; i--) + { + f = pr_stack[i].f; + if (!f) + { + Con_Printf("\n"); + } + else + { + Con_Printf("%12s : %s\n", PR_GetString(f->s_file), PR_GetString(f->s_name)); + } + } +} + + +/* +============ +PR_Profile_f + +============ +*/ +void PR_Profile_f (void) +{ + int i, num; + int pmax; + dfunction_t *f, *best; + + if (!sv.active) + return; + + num = 0; + do + { + pmax = 0; + best = NULL; + for (i = 0; i < progs->numfunctions; i++) + { + f = &pr_functions[i]; + if (f->profile > pmax) + { + pmax = f->profile; + best = f; + } + } + if (best) + { + if (num < 10) + Con_Printf("%7i %s\n", best->profile, PR_GetString(best->s_name)); + num++; + best->profile = 0; + } + } while (best); +} + + +/* +============ +PR_RunError + +Aborts the currently executing function +============ +*/ +void PR_RunError (const char *error, ...) +{ + va_list argptr; + char string[1024]; + + va_start (argptr, error); + q_vsnprintf (string, sizeof(string), error, argptr); + va_end (argptr); + + PR_PrintStatement(pr_statements + pr_xstatement); + PR_StackTrace(); + + Con_Printf("%s\n", string); + + pr_depth = 0; // dump the stack so host_error can shutdown functions + + Host_Error("Program error"); +} + +/* +==================== +PR_EnterFunction + +Returns the new program statement counter +==================== +*/ +static int PR_EnterFunction (dfunction_t *f) +{ + int i, j, c, o; + + pr_stack[pr_depth].s = pr_xstatement; + pr_stack[pr_depth].f = pr_xfunction; + pr_depth++; + if (pr_depth >= MAX_STACK_DEPTH) + PR_RunError("stack overflow"); + + // save off any locals that the new function steps on + c = f->locals; + if (localstack_used + c > LOCALSTACK_SIZE) + PR_RunError("PR_ExecuteProgram: locals stack overflow\n"); + + for (i = 0; i < c ; i++) + localstack[localstack_used + i] = ((int *)pr_globals)[f->parm_start + i]; + localstack_used += c; + + // copy parameters + o = f->parm_start; + for (i = 0; i < f->numparms; i++) + { + for (j = 0; j < f->parm_size[i]; j++) + { + ((int *)pr_globals)[o] = ((int *)pr_globals)[OFS_PARM0 + i*3 + j]; + o++; + } + } + + pr_xfunction = f; + return f->first_statement - 1; // offset the s++ +} + +/* +==================== +PR_LeaveFunction +==================== +*/ +static int PR_LeaveFunction (void) +{ + int i, c; + + if (pr_depth <= 0) + Host_Error("prog stack underflow"); + + // Restore locals from the stack + c = pr_xfunction->locals; + localstack_used -= c; + if (localstack_used < 0) + PR_RunError("PR_ExecuteProgram: locals stack underflow"); + + for (i = 0; i < c; i++) + ((int *)pr_globals)[pr_xfunction->parm_start + i] = localstack[localstack_used + i]; + + // up stack + pr_depth--; + pr_xfunction = pr_stack[pr_depth].f; + return pr_stack[pr_depth].s; +} + + +/* +==================== +PR_ExecuteProgram + +The interpretation main loop +==================== +*/ +#define OPA ((eval_t *)&pr_globals[(unsigned short)st->a]) +#define OPB ((eval_t *)&pr_globals[(unsigned short)st->b]) +#define OPC ((eval_t *)&pr_globals[(unsigned short)st->c]) + +void PR_ExecuteProgram (func_t fnum) +{ + eval_t *ptr; + dstatement_t *st; + dfunction_t *f, *newf; + int profile, startprofile; + edict_t *ed; + int exitdepth; + + if (!fnum || fnum >= progs->numfunctions) + { + if (pr_global_struct->self) + ED_Print (PROG_TO_EDICT(pr_global_struct->self)); + Host_Error ("PR_ExecuteProgram: NULL function"); + } + + f = &pr_functions[fnum]; + + pr_trace = false; + +// make a stack frame + exitdepth = pr_depth; + + st = &pr_statements[PR_EnterFunction(f)]; + startprofile = profile = 0; + + while (1) + { + st++; /* next statement */ + + if (++profile > 100000) + { + pr_xstatement = st - pr_statements; + PR_RunError("runaway loop error"); + } + + if (pr_trace) + PR_PrintStatement(st); + + switch (st->op) + { + case OP_ADD_F: + OPC->_float = OPA->_float + OPB->_float; + break; + case OP_ADD_V: + OPC->vector[0] = OPA->vector[0] + OPB->vector[0]; + OPC->vector[1] = OPA->vector[1] + OPB->vector[1]; + OPC->vector[2] = OPA->vector[2] + OPB->vector[2]; + break; + + case OP_SUB_F: + OPC->_float = OPA->_float - OPB->_float; + break; + case OP_SUB_V: + OPC->vector[0] = OPA->vector[0] - OPB->vector[0]; + OPC->vector[1] = OPA->vector[1] - OPB->vector[1]; + OPC->vector[2] = OPA->vector[2] - OPB->vector[2]; + break; + + case OP_MUL_F: + OPC->_float = OPA->_float * OPB->_float; + break; + case OP_MUL_V: + OPC->_float = OPA->vector[0] * OPB->vector[0] + + OPA->vector[1] * OPB->vector[1] + + OPA->vector[2] * OPB->vector[2]; + break; + case OP_MUL_FV: + OPC->vector[0] = OPA->_float * OPB->vector[0]; + OPC->vector[1] = OPA->_float * OPB->vector[1]; + OPC->vector[2] = OPA->_float * OPB->vector[2]; + break; + case OP_MUL_VF: + OPC->vector[0] = OPB->_float * OPA->vector[0]; + OPC->vector[1] = OPB->_float * OPA->vector[1]; + OPC->vector[2] = OPB->_float * OPA->vector[2]; + break; + + case OP_DIV_F: + OPC->_float = OPA->_float / OPB->_float; + break; + + case OP_BITAND: + OPC->_float = (int)OPA->_float & (int)OPB->_float; + break; + + case OP_BITOR: + OPC->_float = (int)OPA->_float | (int)OPB->_float; + break; + + case OP_GE: + OPC->_float = OPA->_float >= OPB->_float; + break; + case OP_LE: + OPC->_float = OPA->_float <= OPB->_float; + break; + case OP_GT: + OPC->_float = OPA->_float > OPB->_float; + break; + case OP_LT: + OPC->_float = OPA->_float < OPB->_float; + break; + case OP_AND: + OPC->_float = OPA->_float && OPB->_float; + break; + case OP_OR: + OPC->_float = OPA->_float || OPB->_float; + break; + + case OP_NOT_F: + OPC->_float = !OPA->_float; + break; + case OP_NOT_V: + OPC->_float = !OPA->vector[0] && !OPA->vector[1] && !OPA->vector[2]; + break; + case OP_NOT_S: + OPC->_float = !OPA->string || !*PR_GetString(OPA->string); + break; + case OP_NOT_FNC: + OPC->_float = !OPA->function; + break; + case OP_NOT_ENT: + OPC->_float = (PROG_TO_EDICT(OPA->edict) == sv.edicts); + break; + + case OP_EQ_F: + OPC->_float = OPA->_float == OPB->_float; + break; + case OP_EQ_V: + OPC->_float = (OPA->vector[0] == OPB->vector[0]) && + (OPA->vector[1] == OPB->vector[1]) && + (OPA->vector[2] == OPB->vector[2]); + break; + case OP_EQ_S: + OPC->_float = !strcmp(PR_GetString(OPA->string), PR_GetString(OPB->string)); + break; + case OP_EQ_E: + OPC->_float = OPA->_int == OPB->_int; + break; + case OP_EQ_FNC: + OPC->_float = OPA->function == OPB->function; + break; + + case OP_NE_F: + OPC->_float = OPA->_float != OPB->_float; + break; + case OP_NE_V: + OPC->_float = (OPA->vector[0] != OPB->vector[0]) || + (OPA->vector[1] != OPB->vector[1]) || + (OPA->vector[2] != OPB->vector[2]); + break; + case OP_NE_S: + OPC->_float = strcmp(PR_GetString(OPA->string), PR_GetString(OPB->string)); + break; + case OP_NE_E: + OPC->_float = OPA->_int != OPB->_int; + break; + case OP_NE_FNC: + OPC->_float = OPA->function != OPB->function; + break; + + case OP_STORE_F: + case OP_STORE_ENT: + case OP_STORE_FLD: // integers + case OP_STORE_S: + case OP_STORE_FNC: // pointers + OPB->_int = OPA->_int; + break; + case OP_STORE_V: + OPB->vector[0] = OPA->vector[0]; + OPB->vector[1] = OPA->vector[1]; + OPB->vector[2] = OPA->vector[2]; + break; + + case OP_STOREP_F: + case OP_STOREP_ENT: + case OP_STOREP_FLD: // integers + case OP_STOREP_S: + case OP_STOREP_FNC: // pointers + ptr = (eval_t *)((byte *)sv.edicts + OPB->_int); + ptr->_int = OPA->_int; + break; + case OP_STOREP_V: + ptr = (eval_t *)((byte *)sv.edicts + OPB->_int); + ptr->vector[0] = OPA->vector[0]; + ptr->vector[1] = OPA->vector[1]; + ptr->vector[2] = OPA->vector[2]; + break; + + case OP_ADDRESS: + ed = PROG_TO_EDICT(OPA->edict); +#ifdef PARANOID + NUM_FOR_EDICT(ed); // Make sure it's in range +#endif + if (ed == (edict_t *)sv.edicts && sv.state == ss_active) + { + pr_xstatement = st - pr_statements; + PR_RunError("assignment to world entity"); + } + OPC->_int = (byte *)((int *)&ed->v + OPB->_int) - (byte *)sv.edicts; + break; + + case OP_LOAD_F: + case OP_LOAD_FLD: + case OP_LOAD_ENT: + case OP_LOAD_S: + case OP_LOAD_FNC: + ed = PROG_TO_EDICT(OPA->edict); +#ifdef PARANOID + NUM_FOR_EDICT(ed); // Make sure it's in range +#endif + OPC->_int = ((eval_t *)((int *)&ed->v + OPB->_int))->_int; + break; + + case OP_LOAD_V: + ed = PROG_TO_EDICT(OPA->edict); +#ifdef PARANOID + NUM_FOR_EDICT(ed); // Make sure it's in range +#endif + ptr = (eval_t *)((int *)&ed->v + OPB->_int); + OPC->vector[0] = ptr->vector[0]; + OPC->vector[1] = ptr->vector[1]; + OPC->vector[2] = ptr->vector[2]; + break; + + case OP_IFNOT: + if (!OPA->_int) + st += st->b - 1; /* -1 to offset the st++ */ + break; + + case OP_IF: + if (OPA->_int) + st += st->b - 1; /* -1 to offset the st++ */ + break; + + case OP_GOTO: + st += st->a - 1; /* -1 to offset the st++ */ + break; + + case OP_CALL0: + case OP_CALL1: + case OP_CALL2: + case OP_CALL3: + case OP_CALL4: + case OP_CALL5: + case OP_CALL6: + case OP_CALL7: + case OP_CALL8: + pr_xfunction->profile += profile - startprofile; + startprofile = profile; + pr_xstatement = st - pr_statements; + pr_argc = st->op - OP_CALL0; + if (!OPA->function) + PR_RunError("NULL function"); + newf = &pr_functions[OPA->function]; + if (newf->first_statement < 0) + { // Built-in function + int i = -newf->first_statement; + if (i >= pr_numbuiltins) + PR_RunError("Bad builtin call number %d", i); + pr_builtins[i](); + break; + } + // Normal function + st = &pr_statements[PR_EnterFunction(newf)]; + break; + + case OP_DONE: + case OP_RETURN: + pr_xfunction->profile += profile - startprofile; + startprofile = profile; + pr_xstatement = st - pr_statements; + pr_globals[OFS_RETURN] = pr_globals[(unsigned short)st->a]; + pr_globals[OFS_RETURN + 1] = pr_globals[(unsigned short)st->a + 1]; + pr_globals[OFS_RETURN + 2] = pr_globals[(unsigned short)st->a + 2]; + st = &pr_statements[PR_LeaveFunction()]; + if (pr_depth == exitdepth) + { // Done + return; + } + break; + + case OP_STATE: + ed = PROG_TO_EDICT(pr_global_struct->self); + ed->v.nextthink = pr_global_struct->time + 0.1; + ed->v.frame = OPA->_float; + ed->v.think = OPB->function; + break; + + default: + pr_xstatement = st - pr_statements; + PR_RunError("Bad opcode %i", st->op); + } + } /* end of while(1) loop */ +} +#undef OPA +#undef OPB +#undef OPC + diff --git a/engine/code/progdefs.h b/engine/Quake/progdefs.h similarity index 74% rename from engine/code/progdefs.h rename to engine/Quake/progdefs.h index db86de1..5a806f5 100644 --- a/engine/code/progdefs.h +++ b/engine/Quake/progdefs.h @@ -1,5 +1,6 @@ /* -Copyright (C) 1996-1997 Id Software, Inc. +Copyright (C) 1996-2001 Id Software, Inc. +Copyright (C) 2002-2009 John Fitzgibbons and others This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -8,7 +9,7 @@ of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. @@ -17,8 +18,11 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#ifdef QUAKE2 -#include "progdefs.q2" -#else + +#ifndef __PROGDEFS_H +#define __PROGDEFS_H + #include "progdefs.q1" -#endif + +#endif /* __PROGDEFS_H */ + diff --git a/engine/code/progdefs.q1 b/engine/Quake/progdefs.q1 similarity index 100% rename from engine/code/progdefs.q1 rename to engine/Quake/progdefs.q1 diff --git a/engine/Quake/progs.h b/engine/Quake/progs.h new file mode 100644 index 0000000..c0e8066 --- /dev/null +++ b/engine/Quake/progs.h @@ -0,0 +1,144 @@ +/* +Copyright (C) 1996-2001 Id Software, Inc. +Copyright (C) 2002-2009 John Fitzgibbons and others +Copyright (C) 2010-2014 QuakeSpasm developers + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#ifndef _QUAKE_PROGS_H +#define _QUAKE_PROGS_H + +#include "pr_comp.h" /* defs shared with qcc */ +#include "progdefs.h" /* generated by program cdefs */ + +typedef union eval_s +{ + string_t string; + float _float; + float vector[3]; + func_t function; + int _int; + int edict; +} eval_t; + +#define MAX_ENT_LEAFS 32 +typedef struct edict_s +{ + qboolean free; + link_t area; /* linked to a division node or leaf */ + + int num_leafs; + int leafnums[MAX_ENT_LEAFS]; + + entity_state_t baseline; + unsigned char alpha; /* johnfitz -- hack to support alpha since it's not part of entvars_t */ + qboolean sendinterval; /* johnfitz -- send time until nextthink to client for better lerp timing */ + + float freetime; /* sv.time when the object was freed */ + entvars_t v; /* C exported fields from progs */ + + /* other fields from progs come immediately after */ +} edict_t; + +#define EDICT_FROM_AREA(l) STRUCT_FROM_LINK(l,edict_t,area) + +//============================================================================ + +extern dprograms_t *progs; +extern dfunction_t *pr_functions; +extern dstatement_t *pr_statements; +extern globalvars_t *pr_global_struct; +extern float *pr_globals; /* same as pr_global_struct */ + +extern int pr_edict_size; /* in bytes */ + + +void PR_Init (void); + +void PR_ExecuteProgram (func_t fnum); +void PR_LoadProgs (void); + +const char *PR_GetString (int num); +int PR_SetEngineString (const char *s); +int PR_AllocString (int bufferlength, char **ptr); + +void PR_Profile_f (void); + +edict_t *ED_Alloc (void); +void ED_Free (edict_t *ed); + +void ED_Print (edict_t *ed); +void ED_Write (FILE *f, edict_t *ed); +const char *ED_ParseEdict (const char *data, edict_t *ent); + +void ED_WriteGlobals (FILE *f); +const char *ED_ParseGlobals (const char *data); + +void ED_LoadFromFile (const char *data); + +/* +#define EDICT_NUM(n) ((edict_t *)(sv.edicts+ (n)*pr_edict_size)) +#define NUM_FOR_EDICT(e) (((byte *)(e) - sv.edicts) / pr_edict_size) +*/ +edict_t *EDICT_NUM(int n); +int NUM_FOR_EDICT(edict_t *e); + +#define NEXT_EDICT(e) ((edict_t *)( (byte *)e + pr_edict_size)) + +#define EDICT_TO_PROG(e) ((byte *)e - (byte *)sv.edicts) +#define PROG_TO_EDICT(e) ((edict_t *)((byte *)sv.edicts + e)) + +#define G_FLOAT(o) (pr_globals[o]) +#define G_INT(o) (*(int *)&pr_globals[o]) +#define G_EDICT(o) ((edict_t *)((byte *)sv.edicts+ *(int *)&pr_globals[o])) +#define G_EDICTNUM(o) NUM_FOR_EDICT(G_EDICT(o)) +#define G_VECTOR(o) (&pr_globals[o]) +#define G_STRING(o) (PR_GetString(*(string_t *)&pr_globals[o])) +#define G_FUNCTION(o) (*(func_t *)&pr_globals[o]) + +#define E_FLOAT(e,o) (((float*)&e->v)[o]) +#define E_INT(e,o) (*(int *)&((float*)&e->v)[o]) +#define E_VECTOR(e,o) (&((float*)&e->v)[o]) +#define E_STRING(e,o) (PR_GetString(*(string_t *)&((float*)&e->v)[o])) + +extern int type_size[8]; + +typedef void (*builtin_t) (void); +extern builtin_t *pr_builtins; +extern int pr_numbuiltins; + +extern int pr_argc; + +extern qboolean pr_trace; +extern dfunction_t *pr_xfunction; +extern int pr_xstatement; + +extern unsigned short pr_crc; + +FUNC_NORETURN void PR_RunError (const char *error, ...) FUNC_PRINTF(1,2); +#ifdef __WATCOMC__ +#pragma aux PR_RunError aborts; +#endif + +void ED_PrintEdicts (void); +void ED_PrintNum (int ent); + +eval_t *GetEdictFieldValue(edict_t *ed, const char *field); + +#endif /* _QUAKE_PROGS_H */ + diff --git a/engine/Quake/protocol.h b/engine/Quake/protocol.h new file mode 100644 index 0000000..81c7e96 --- /dev/null +++ b/engine/Quake/protocol.h @@ -0,0 +1,257 @@ +/* +Copyright (C) 1996-2001 Id Software, Inc. +Copyright (C) 2002-2009 John Fitzgibbons and others +Copyright (C) 2010-2014 QuakeSpasm developers + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#ifndef _QUAKE_PROTOCOL_H +#define _QUAKE_PROTOCOL_H + +// protocol.h -- communications protocols + +#define PROTOCOL_NETQUAKE 15 //johnfitz -- standard quake protocol +#define PROTOCOL_FITZQUAKE 666 //johnfitz -- added new protocol for fitzquake 0.85 +#define PROTOCOL_RMQ 999 + +// PROTOCOL_RMQ protocol flags +#define PRFL_SHORTANGLE (1 << 1) +#define PRFL_FLOATANGLE (1 << 2) +#define PRFL_24BITCOORD (1 << 3) +#define PRFL_FLOATCOORD (1 << 4) +#define PRFL_EDICTSCALE (1 << 5) +#define PRFL_ALPHASANITY (1 << 6) // cleanup insanity with alpha +#define PRFL_INT32COORD (1 << 7) +#define PRFL_MOREFLAGS (1 << 31) // not supported + +// if the high bit of the servercmd is set, the low bits are fast update flags: +#define U_MOREBITS (1<<0) +#define U_ORIGIN1 (1<<1) +#define U_ORIGIN2 (1<<2) +#define U_ORIGIN3 (1<<3) +#define U_ANGLE2 (1<<4) +#define U_STEP (1<<5) //johnfitz -- was U_NOLERP, renamed since it's only used for MOVETYPE_STEP +#define U_FRAME (1<<6) +#define U_SIGNAL (1<<7) // just differentiates from other updates + +// svc_update can pass all of the fast update bits, plus more +#define U_ANGLE1 (1<<8) +#define U_ANGLE3 (1<<9) +#define U_MODEL (1<<10) +#define U_COLORMAP (1<<11) +#define U_SKIN (1<<12) +#define U_EFFECTS (1<<13) +#define U_LONGENTITY (1<<14) +//johnfitz -- PROTOCOL_FITZQUAKE -- new bits +#define U_EXTEND1 (1<<15) +#define U_ALPHA (1<<16) // 1 byte, uses ENTALPHA_ENCODE, not sent if equal to baseline +#define U_FRAME2 (1<<17) // 1 byte, this is .frame & 0xFF00 (second byte) +#define U_MODEL2 (1<<18) // 1 byte, this is .modelindex & 0xFF00 (second byte) +#define U_LERPFINISH (1<<19) // 1 byte, 0.0-1.0 maps to 0-255, not sent if exactly 0.1, this is ent->v.nextthink - sv.time, used for lerping +#define U_SCALE (1<<20) // 1 byte, for PROTOCOL_RMQ PRFL_EDICTSCALE, currently read but ignored +#define U_UNUSED21 (1<<21) +#define U_UNUSED22 (1<<22) +#define U_EXTEND2 (1<<23) // another byte to follow, future expansion +//johnfitz + +//johnfitz -- PROTOCOL_NEHAHRA transparency +#define U_TRANS (1<<15) +//johnfitz + +#define SU_VIEWHEIGHT (1<<0) +#define SU_IDEALPITCH (1<<1) +#define SU_PUNCH1 (1<<2) +#define SU_PUNCH2 (1<<3) +#define SU_PUNCH3 (1<<4) +#define SU_VELOCITY1 (1<<5) +#define SU_VELOCITY2 (1<<6) +#define SU_VELOCITY3 (1<<7) +#define SU_UNUSED8 (1<<8) //AVAILABLE BIT +#define SU_ITEMS (1<<9) +#define SU_ONGROUND (1<<10) // no data follows, the bit is it +#define SU_INWATER (1<<11) // no data follows, the bit is it +#define SU_WEAPONFRAME (1<<12) +#define SU_ARMOR (1<<13) +#define SU_WEAPON (1<<14) +//johnfitz -- PROTOCOL_FITZQUAKE -- new bits +#define SU_EXTEND1 (1<<15) // another byte to follow +#define SU_WEAPON2 (1<<16) // 1 byte, this is .weaponmodel & 0xFF00 (second byte) +#define SU_ARMOR2 (1<<17) // 1 byte, this is .armorvalue & 0xFF00 (second byte) +#define SU_AMMO2 (1<<18) // 1 byte, this is .currentammo & 0xFF00 (second byte) +#define SU_SHELLS2 (1<<19) // 1 byte, this is .ammo_shells & 0xFF00 (second byte) +#define SU_NAILS2 (1<<20) // 1 byte, this is .ammo_nails & 0xFF00 (second byte) +#define SU_ROCKETS2 (1<<21) // 1 byte, this is .ammo_rockets & 0xFF00 (second byte) +#define SU_CELLS2 (1<<22) // 1 byte, this is .ammo_cells & 0xFF00 (second byte) +#define SU_EXTEND2 (1<<23) // another byte to follow +#define SU_WEAPONFRAME2 (1<<24) // 1 byte, this is .weaponframe & 0xFF00 (second byte) +#define SU_WEAPONALPHA (1<<25) // 1 byte, this is alpha for weaponmodel, uses ENTALPHA_ENCODE, not sent if ENTALPHA_DEFAULT +#define SU_UNUSED26 (1<<26) +#define SU_UNUSED27 (1<<27) +#define SU_UNUSED28 (1<<28) +#define SU_UNUSED29 (1<<29) +#define SU_UNUSED30 (1<<30) +#define SU_EXTEND3 (1<<31) // another byte to follow, future expansion +//johnfitz + +// a sound with no channel is a local only sound +#define SND_VOLUME (1<<0) // a byte +#define SND_ATTENUATION (1<<1) // a byte +#define SND_LOOPING (1<<2) // a long + +#define DEFAULT_SOUND_PACKET_VOLUME 255 +#define DEFAULT_SOUND_PACKET_ATTENUATION 1.0 + +//johnfitz -- PROTOCOL_FITZQUAKE -- new bits +#define SND_LARGEENTITY (1<<3) // a short + byte (instead of just a short) +#define SND_LARGESOUND (1<<4) // a short soundindex (instead of a byte) +//johnfitz + +//johnfitz -- PROTOCOL_FITZQUAKE -- flags for entity baseline messages +#define B_LARGEMODEL (1<<0) // modelindex is short instead of byte +#define B_LARGEFRAME (1<<1) // frame is short instead of byte +#define B_ALPHA (1<<2) // 1 byte, uses ENTALPHA_ENCODE, not sent if ENTALPHA_DEFAULT +//johnfitz + +//johnfitz -- PROTOCOL_FITZQUAKE -- alpha encoding +#define ENTALPHA_DEFAULT 0 //entity's alpha is "default" (i.e. water obeys r_wateralpha) -- must be zero so zeroed out memory works +#define ENTALPHA_ZERO 1 //entity is invisible (lowest possible alpha) +#define ENTALPHA_ONE 255 //entity is fully opaque (highest possible alpha) +#define ENTALPHA_ENCODE(a) (((a)==0)?ENTALPHA_DEFAULT:Q_rint(CLAMP(1,(a)*254.0f+1,255))) //server convert to byte to send to client +#define ENTALPHA_DECODE(a) (((a)==ENTALPHA_DEFAULT)?1.0f:((float)(a)-1)/(254)) //client convert to float for rendering +#define ENTALPHA_TOSAVE(a) (((a)==ENTALPHA_DEFAULT)?0.0f:(((a)==ENTALPHA_ZERO)?-1.0f:((float)(a)-1)/(254))) //server convert to float for savegame +//johnfitz + +// defaults for clientinfo messages +#define DEFAULT_VIEWHEIGHT 22 + +// game types sent by serverinfo +// these determine which intermission screen plays +#define GAME_COOP 0 +#define GAME_DEATHMATCH 1 + +//================== +// note that there are some defs.qc that mirror to these numbers +// also related to svc_strings[] in cl_parse +//================== + +// +// server to client +// +#define svc_bad 0 +#define svc_nop 1 +#define svc_disconnect 2 +#define svc_updatestat 3 // [byte] [long] +#define svc_version 4 // [long] server version +#define svc_setview 5 // [short] entity number +#define svc_sound 6 // +#define svc_time 7 // [float] server time +#define svc_print 8 // [string] null terminated string +#define svc_stufftext 9 // [string] stuffed into client's console buffer + // the string should be \n terminated +#define svc_setangle 10 // [angle3] set the view angle to this absolute value +#define svc_serverinfo 11 // [long] version + // [string] signon string + // [string]..[0]model cache + // [string]...[0]sounds cache +#define svc_lightstyle 12 // [byte] [string] +#define svc_updatename 13 // [byte] [string] +#define svc_updatefrags 14 // [byte] [short] +#define svc_clientdata 15 // +#define svc_stopsound 16 // +#define svc_updatecolors 17 // [byte] [byte] +#define svc_particle 18 // [vec3] +#define svc_damage 19 +#define svc_spawnstatic 20 +//#define svc_spawnbinary 21 +#define svc_spawnbaseline 22 +#define svc_temp_entity 23 +#define svc_setpause 24 // [byte] on / off +#define svc_signonnum 25 // [byte] used for the signon sequence +#define svc_centerprint 26 // [string] to put in center of the screen +#define svc_killedmonster 27 +#define svc_foundsecret 28 +#define svc_spawnstaticsound 29 // [coord3] [byte] samp [byte] vol [byte] aten +#define svc_intermission 30 // [string] music +#define svc_finale 31 // [string] music [string] text +#define svc_cdtrack 32 // [byte] track [byte] looptrack +#define svc_sellscreen 33 +#define svc_cutscene 34 + +//johnfitz -- PROTOCOL_FITZQUAKE -- new server messages +#define svc_skybox 37 // [string] name +#define svc_bf 40 +#define svc_fog 41 // [byte] density [byte] red [byte] green [byte] blue [float] time +#define svc_spawnbaseline2 42 // support for large modelindex, large framenum, alpha, using flags +#define svc_spawnstatic2 43 // support for large modelindex, large framenum, alpha, using flags +#define svc_spawnstaticsound2 44 // [coord3] [short] samp [byte] vol [byte] aten +//johnfitz + +// +// client to server +// +#define clc_bad 0 +#define clc_nop 1 +#define clc_disconnect 2 +#define clc_move 3 // [usercmd_t] +#define clc_stringcmd 4 // [string] message + +// +// temp entity events +// +#define TE_SPIKE 0 +#define TE_SUPERSPIKE 1 +#define TE_GUNSHOT 2 +#define TE_EXPLOSION 3 +#define TE_TAREXPLOSION 4 +#define TE_LIGHTNING1 5 +#define TE_LIGHTNING2 6 +#define TE_WIZSPIKE 7 +#define TE_KNIGHTSPIKE 8 +#define TE_LIGHTNING3 9 +#define TE_LAVASPLASH 10 +#define TE_TELEPORT 11 +#define TE_EXPLOSION2 12 + +// PGM 01/21/97 +#define TE_BEAM 13 +// PGM 01/21/97 + +typedef struct +{ + vec3_t origin; + vec3_t angles; + unsigned short modelindex; //johnfitz -- was int + unsigned short frame; //johnfitz -- was int + unsigned char colormap; //johnfitz -- was int + unsigned char skin; //johnfitz -- was int + unsigned char alpha; //johnfitz -- added + int effects; +} entity_state_t; + +typedef struct +{ + vec3_t viewangles; + +// intended velocities + float forwardmove; + float sidemove; + float upmove; +} usercmd_t; + +#endif /* _QUAKE_PROTOCOL_H */ + diff --git a/engine/Quake/q_ctype.h b/engine/Quake/q_ctype.h new file mode 100644 index 0000000..729f796 --- /dev/null +++ b/engine/Quake/q_ctype.h @@ -0,0 +1,99 @@ +/* Locale insensitive ctype.h functions taken from the RPM library - + * RPM is Copyright (c) 1998 by Red Hat Software, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef Q_CTYPE_H +#define Q_CTYPE_H + +static inline int q_isascii(int c) +{ + return ((c & ~0x7f) == 0); +} + +static inline int q_islower(int c) +{ + return (c >= 'a' && c <= 'z'); +} + +static inline int q_isupper(int c) +{ + return (c >= 'A' && c <= 'Z'); +} + +static inline int q_isalpha(int c) +{ + return (q_islower(c) || q_isupper(c)); +} + +static inline int q_isdigit(int c) +{ + return (c >= '0' && c <= '9'); +} + +static inline int q_isxdigit(int c) +{ + return (q_isdigit(c) || (c >= 'a' && c <= 'f') || + (c >= 'A' && c <= 'F')); +} + +static inline int q_isalnum(int c) +{ + return (q_isalpha(c) || q_isdigit(c)); +} + +static inline int q_isblank(int c) +{ + return (c == ' ' || c == '\t'); +} + +static inline int q_isspace(int c) +{ + switch(c) { + case ' ': case '\t': + case '\n': case '\r': + case '\f': case '\v': return 1; + } + return 0; +} + +static inline int q_isgraph(int c) +{ + return (c > 0x20 && c <= 0x7e); +} + +static inline int q_isprint(int c) +{ + return (c >= 0x20 && c <= 0x7e); +} + +static inline int q_toascii(int c) +{ + return (c & 0x7f); +} + +static inline int q_tolower(int c) +{ + return ((q_isupper(c)) ? (c | ('a' - 'A')) : c); +} + +static inline int q_toupper(int c) +{ + return ((q_islower(c)) ? (c & ~('a' - 'A')) : c); +} + +#endif /* Q_CTYPE_H */ diff --git a/engine/Quake/q_sound.h b/engine/Quake/q_sound.h new file mode 100644 index 0000000..ded7b5d --- /dev/null +++ b/engine/Quake/q_sound.h @@ -0,0 +1,190 @@ +/* +Copyright (C) 1996-2001 Id Software, Inc. +Copyright (C) 2002-2009 John Fitzgibbons and others +Copyright (C) 2007-2008 Kristian Duske +Copyright (C) 2010-2014 QuakeSpasm developers + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ +// sound.h -- client sound i/o functions + +#ifndef __QUAKE_SOUND__ +#define __QUAKE_SOUND__ + +/* !!! if this is changed, it must be changed in asm_i386.h too !!! */ +typedef struct +{ + int left; + int right; +} portable_samplepair_t; + +typedef struct sfx_s +{ + char name[MAX_QPATH]; + cache_user_t cache; +} sfx_t; + +/* !!! if this is changed, it must be changed in asm_i386.h too !!! */ +typedef struct +{ + int length; + int loopstart; + int speed; + int width; + int stereo; + byte data[1]; /* variable sized */ +} sfxcache_t; + +typedef struct +{ + int channels; + int samples; /* mono samples in buffer */ + int submission_chunk; /* don't mix less than this # */ + int samplepos; /* in mono samples */ + int samplebits; + int signed8; /* device opened for S8 format? (e.g. Amiga AHI) */ + int speed; + unsigned char *buffer; +} dma_t; + +/* !!! if this is changed, it must be changed in asm_i386.h too !!! */ +typedef struct +{ + sfx_t *sfx; /* sfx number */ + int leftvol; /* 0-255 volume */ + int rightvol; /* 0-255 volume */ + int end; /* end time in global paintsamples */ + int pos; /* sample position in sfx */ + int looping; /* where to loop, -1 = no looping */ + int entnum; /* to allow overriding a specific sound */ + int entchannel; + vec3_t origin; /* origin of sound effect */ + vec_t dist_mult; /* distance multiplier (attenuation/clipK) */ + int master_vol; /* 0-255 master volume */ +} channel_t; + +#define WAV_FORMAT_PCM 1 + +typedef struct +{ + int rate; + int width; + int channels; + int loopstart; + int samples; + int dataofs; /* chunk starts this many bytes from file start */ +} wavinfo_t; + +void S_Init (void); +void S_Startup (void); +void S_Shutdown (void); +void S_StartSound (int entnum, int entchannel, sfx_t *sfx, vec3_t origin, float fvol, float attenuation); +void S_StaticSound (sfx_t *sfx, vec3_t origin, float vol, float attenuation); +void S_StopSound (int entnum, int entchannel); +void S_StopAllSounds(qboolean clear); +void S_ClearBuffer (void); +void S_Update (vec3_t origin, vec3_t forward, vec3_t right, vec3_t up); +void S_ExtraUpdate (void); + +void S_BlockSound (void); +void S_UnblockSound (void); + +sfx_t *S_PrecacheSound (const char *sample); +void S_TouchSound (const char *sample); +void S_ClearPrecache (void); +void S_BeginPrecaching (void); +void S_EndPrecaching (void); +void S_PaintChannels (int endtime); +void S_InitPaintChannels (void); + +/* picks a channel based on priorities, empty slots, number of channels */ +channel_t *SND_PickChannel (int entnum, int entchannel); + +/* spatializes a channel */ +void SND_Spatialize (channel_t *ch); + +/* music stream support */ +void S_RawSamples(int samples, int rate, int width, int channels, byte * data, float volume); + /* Expects data in signed 16 bit, or unsigned 8 bit format. */ + +/* initializes cycling through a DMA buffer and returns information on it */ +qboolean SNDDMA_Init(dma_t *dma); + +/* gets the current DMA position */ +int SNDDMA_GetDMAPos(void); + +/* shutdown the DMA xfer. */ +void SNDDMA_Shutdown(void); + +/* validates & locks the dma buffer */ +void SNDDMA_LockBuffer(void); + +/* unlocks the dma buffer / sends sound to the device */ +void SNDDMA_Submit(void); + +/* blocks sound output upon window focus loss */ +void SNDDMA_BlockSound(void); + +/* unblocks the output upon window focus gain */ +void SNDDMA_UnblockSound(void); + +/* ==================================================================== + * User-setable variables + * ==================================================================== + */ + +#define MAX_CHANNELS 1024 // ericw -- was 512 /* johnfitz -- was 128 */ +#define MAX_DYNAMIC_CHANNELS 128 /* johnfitz -- was 8 */ + +extern channel_t snd_channels[MAX_CHANNELS]; +/* 0 to MAX_DYNAMIC_CHANNELS-1 = normal entity sounds + * MAX_DYNAMIC_CHANNELS to MAX_DYNAMIC_CHANNELS + NUM_AMBIENTS -1 = water, etc + * MAX_DYNAMIC_CHANNELS + NUM_AMBIENTS to total_channels = static sounds + */ + +extern volatile dma_t *shm; + +extern int total_channels; +extern int soundtime; +extern int paintedtime; +extern int s_rawend; + +extern vec3_t listener_origin; +extern vec3_t listener_forward; +extern vec3_t listener_right; +extern vec3_t listener_up; + +extern cvar_t sndspeed; +extern cvar_t snd_mixspeed; +extern cvar_t snd_filterquality; +extern cvar_t sfxvolume; +extern cvar_t loadas8bit; + +#define MAX_RAW_SAMPLES 8192 +extern portable_samplepair_t s_rawsamples[MAX_RAW_SAMPLES]; + +extern cvar_t bgmvolume; + +void S_LocalSound (const char *name); +sfxcache_t *S_LoadSound (sfx_t *s); + +wavinfo_t GetWavinfo (const char *name, byte *wav, int wavlength); + +void SND_InitScaletable (void); + +#endif /* __QUAKE_SOUND__ */ + diff --git a/engine/Quake/q_stdinc.h b/engine/Quake/q_stdinc.h new file mode 100644 index 0000000..269b160 --- /dev/null +++ b/engine/Quake/q_stdinc.h @@ -0,0 +1,241 @@ +/* + * q_stdinc.h - includes the minimum necessary stdc headers, + * defines common and / or missing types. + * + * NOTE: for net stuff use net_sys.h, + * for byte order use q_endian.h, + * for math stuff use mathlib.h, + * for locale-insensitive ctype.h functions use q_ctype.h. + * + * Copyright (C) 1996-1997 Id Software, Inc. + * Copyright (C) 2007-2011 O.Sezer + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef __QSTDINC_H +#define __QSTDINC_H + +#include +#include +#include +#ifndef _WIN32 /* others we support without sys/param.h? */ +#include +#endif + +#include + +/* NOTES on TYPE SIZES: + Quake/Hexen II engine relied on 32 bit int type size + with ILP32 (not LP32) model in mind. We now support + LP64 and LLP64, too. We expect: + sizeof (char) == 1 + sizeof (short) == 2 + sizeof (int) == 4 + sizeof (float) == 4 + sizeof (long) == 4 / 8 + sizeof (pointer *) == 4 / 8 + For this, we need stdint.h (or inttypes.h) + FIXME: On some platforms, only inttypes.h is available. + FIXME: Properly replace certain short and int usage + with int16_t and int32_t. + */ +#if defined(_MSC_VER) && (_MSC_VER < 1600) +/* MS Visual Studio provides stdint.h only starting with + * version 2010. Even in VS2010, there is no inttypes.h.. */ +#include "msinttypes/stdint.h" +#else +#include +#endif + +#include +#include +#include + +/*==========================================================================*/ + +#ifndef NULL +#if defined(__cplusplus) +#define NULL 0 +#else +#define NULL ((void *)0) +#endif +#endif + +#define Q_MAXCHAR ((char)0x7f) +#define Q_MAXSHORT ((short)0x7fff) +#define Q_MAXINT ((int)0x7fffffff) +#define Q_MAXLONG ((int)0x7fffffff) +#define Q_MAXFLOAT ((int)0x7fffffff) + +#define Q_MINCHAR ((char)0x80) +#define Q_MINSHORT ((short)0x8000) +#define Q_MININT ((int)0x80000000) +#define Q_MINLONG ((int)0x80000000) +#define Q_MINFLOAT ((int)0x7fffffff) + +/* Make sure the types really have the right + * sizes: These macros are from SDL headers. + */ +#define COMPILE_TIME_ASSERT(name, x) \ + typedef int dummy_ ## name[(x) * 2 - 1] + +COMPILE_TIME_ASSERT(char, sizeof(char) == 1); +COMPILE_TIME_ASSERT(float, sizeof(float) == 4); +COMPILE_TIME_ASSERT(long, sizeof(long) >= 4); +COMPILE_TIME_ASSERT(int, sizeof(int) == 4); +COMPILE_TIME_ASSERT(short, sizeof(short) == 2); + +/* make sure enums are the size of ints for structure packing */ +typedef enum { + THE_DUMMY_VALUE +} THE_DUMMY_ENUM; +COMPILE_TIME_ASSERT(enum, sizeof(THE_DUMMY_ENUM) == sizeof(int)); + + +/* Provide a substitute for offsetof() if we don't have one. + * This variant works on most (but not *all*) systems... + */ +#ifndef offsetof +#define offsetof(t,m) ((size_t)&(((t *)0)->m)) +#endif + + +/*==========================================================================*/ + +typedef unsigned char byte; + +#undef true +#undef false +#if defined(__cplusplus) +/* some structures have qboolean members and the x86 asm code expect + * those members to be 4 bytes long. therefore, qboolean must be 32 + * bits and it can NOT be binary compatible with the 8 bit C++ bool. */ +typedef int qboolean; +COMPILE_TIME_ASSERT(falsehood, (0 == false)); +COMPILE_TIME_ASSERT(truth, (1 == true)); +#else +typedef enum { + false = 0, + true = 1 +} qboolean; +COMPILE_TIME_ASSERT(falsehood, ((1 != 1) == false)); +COMPILE_TIME_ASSERT(truth, ((1 == 1) == true)); +#endif +COMPILE_TIME_ASSERT(qboolean, sizeof(qboolean) == 4); + +/*==========================================================================*/ + +/* math */ +typedef float vec_t; +typedef vec_t vec3_t[3]; +typedef vec_t vec4_t[4]; +typedef vec_t vec5_t[5]; +typedef int fixed4_t; +typedef int fixed8_t; +typedef int fixed16_t; + + +/*==========================================================================*/ + +/* MAX_OSPATH (max length of a filesystem pathname, i.e. PATH_MAX) + * Note: See GNU Hurd and others' notes about brokenness of this: + * http://www.gnu.org/software/hurd/community/gsoc/project_ideas/maxpath.html + * http://insanecoding.blogspot.com/2007/11/pathmax-simply-isnt.html */ + +#if !defined(PATH_MAX) +/* equivalent values? */ +#if defined(MAXPATHLEN) +#define PATH_MAX MAXPATHLEN +#elif defined(_WIN32) && defined(_MAX_PATH) +#define PATH_MAX _MAX_PATH +#elif defined(_WIN32) && defined(MAX_PATH) +#define PATH_MAX MAX_PATH +#else /* fallback */ +#define PATH_MAX 1024 +#endif +#endif /* PATH_MAX */ + +#define MAX_OSPATH PATH_MAX + +/*==========================================================================*/ + +/* missing types: */ +#if defined(_MSC_VER) +typedef ptrdiff_t ssize_t; +#endif + +/*==========================================================================*/ + +/* function attributes, etc */ + +#if defined(__GNUC__) +#define FUNC_PRINTF(x,y) __attribute__((__format__(__printf__,x,y))) +#else +#define FUNC_PRINTF(x,y) +#endif + +/* argument format attributes for function pointers are supported for gcc >= 3.1 */ +#if defined(__GNUC__) && (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 0)) +#define FUNCP_PRINTF FUNC_PRINTF +#else +#define FUNCP_PRINTF(x,y) +#endif + +/* llvm's optnone function attribute started with clang-3.5.0 */ +#if defined(__clang__) && \ + (__clang_major__ > 3 || (__clang_major__ == 3 && __clang_minor__ >= 5)) +#define FUNC_NO_OPTIMIZE __attribute__((__optnone__)) +/* function optimize attribute is added starting with gcc 4.4.0 */ +#elif defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 3)) +#define FUNC_NO_OPTIMIZE __attribute__((__optimize__("0"))) +#else +#define FUNC_NO_OPTIMIZE +#endif + +#if defined(__GNUC__) +#define FUNC_NORETURN __attribute__((__noreturn__)) +#elif defined(_MSC_VER) && (_MSC_VER >= 1200) +#define FUNC_NORETURN __declspec(noreturn) +#elif defined(__WATCOMC__) +#define FUNC_NORETURN /* use the 'aborts' aux pragma */ +#else +#define FUNC_NORETURN +#endif + +#if defined(__GNUC__) && ((__GNUC__ > 3) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1)) +#define FUNC_NOINLINE __attribute__((__noinline__)) +#elif defined(_MSC_VER) && (_MSC_VER >= 1300) +#define FUNC_NOINLINE __declspec(noinline) +#else +#define FUNC_NOINLINE +#endif + +#if defined(__GNUC__) && ((__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5)) +#define FUNC_NOCLONE __attribute__((__noclone__)) +#else +#define FUNC_NOCLONE +#endif + +#if defined(_MSC_VER) && !defined(__cplusplus) +#define inline __inline +#endif /* _MSC_VER */ + +/*==========================================================================*/ + + +#endif /* __QSTDINC_H */ + diff --git a/engine/Quake/qs_bmp.h b/engine/Quake/qs_bmp.h new file mode 100644 index 0000000..fd2b2b5 --- /dev/null +++ b/engine/Quake/qs_bmp.h @@ -0,0 +1,189 @@ +0x42, 0x4d, 0xc6, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x02, 0x00, 0x00, 0x28, 0x00, +0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x13, 0x0b, 0x00, 0x00, 0x13, 0x0b, 0x00, 0x00, 0xa4, 0x00, +0x00, 0x00, 0xa4, 0x00, 0x00, 0x00, 0x06, 0x06, 0x06, 0x00, 0x05, 0x06, 0x07, 0x00, 0x06, 0x06, +0x07, 0x00, 0x07, 0x06, 0x07, 0x00, 0x06, 0x07, 0x06, 0x00, 0x06, 0x07, 0x07, 0x00, 0x07, 0x07, +0x07, 0x00, 0x07, 0x08, 0x07, 0x00, 0x08, 0x08, 0x08, 0x00, 0x07, 0x08, 0x09, 0x00, 0x08, 0x08, +0x09, 0x00, 0x07, 0x09, 0x08, 0x00, 0x08, 0x09, 0x08, 0x00, 0x09, 0x09, 0x08, 0x00, 0x08, 0x09, +0x09, 0x00, 0x09, 0x09, 0x09, 0x00, 0x08, 0x09, 0x0a, 0x00, 0x09, 0x09, 0x0a, 0x00, 0x09, 0x09, +0x0b, 0x00, 0x09, 0x0a, 0x09, 0x00, 0x08, 0x0a, 0x0a, 0x00, 0x09, 0x0a, 0x0a, 0x00, 0x0a, 0x0a, +0x0a, 0x00, 0x09, 0x0a, 0x0b, 0x00, 0x0a, 0x0a, 0x0b, 0x00, 0x09, 0x0a, 0x0c, 0x00, 0x09, 0x0b, +0x0b, 0x00, 0x0a, 0x0b, 0x0b, 0x00, 0x0a, 0x0b, 0x0c, 0x00, 0x0b, 0x0b, 0x0c, 0x00, 0x0a, 0x0b, +0x0d, 0x00, 0x0b, 0x0c, 0x0c, 0x00, 0x0b, 0x0c, 0x0d, 0x00, 0x0a, 0x0c, 0x0e, 0x00, 0x0b, 0x0c, +0x0e, 0x00, 0x0c, 0x0c, 0x0f, 0x00, 0x0b, 0x0d, 0x0d, 0x00, 0x0b, 0x0d, 0x0e, 0x00, 0x0c, 0x0d, +0x0e, 0x00, 0x0c, 0x0d, 0x0f, 0x00, 0x0d, 0x0d, 0x0f, 0x00, 0x0b, 0x0d, 0x10, 0x00, 0x0c, 0x0d, +0x10, 0x00, 0x0c, 0x0e, 0x0f, 0x00, 0x0d, 0x0e, 0x0f, 0x00, 0x0c, 0x0e, 0x10, 0x00, 0x0d, 0x0e, +0x10, 0x00, 0x0b, 0x0e, 0x11, 0x00, 0x0c, 0x0e, 0x11, 0x00, 0x0d, 0x0e, 0x11, 0x00, 0x0d, 0x0f, +0x10, 0x00, 0x0d, 0x0f, 0x11, 0x00, 0x0e, 0x0f, 0x11, 0x00, 0x0d, 0x0f, 0x12, 0x00, 0x0e, 0x0f, +0x12, 0x00, 0x0d, 0x0f, 0x13, 0x00, 0x0e, 0x10, 0x11, 0x00, 0x0d, 0x10, 0x12, 0x00, 0x0b, 0x10, +0x13, 0x00, 0x0e, 0x10, 0x12, 0x00, 0x0e, 0x10, 0x13, 0x00, 0x0d, 0x10, 0x14, 0x00, 0x0e, 0x10, +0x14, 0x00, 0x0d, 0x11, 0x13, 0x00, 0x0e, 0x11, 0x13, 0x00, 0x0f, 0x11, 0x13, 0x00, 0x0e, 0x11, +0x14, 0x00, 0x0f, 0x11, 0x14, 0x00, 0x0f, 0x11, 0x15, 0x00, 0x0f, 0x12, 0x14, 0x00, 0x0f, 0x12, +0x15, 0x00, 0x10, 0x12, 0x15, 0x00, 0x0f, 0x12, 0x16, 0x00, 0x10, 0x12, 0x16, 0x00, 0x0f, 0x12, +0x17, 0x00, 0x0f, 0x13, 0x16, 0x00, 0x10, 0x13, 0x16, 0x00, 0x10, 0x13, 0x17, 0x00, 0x11, 0x13, +0x17, 0x00, 0x11, 0x13, 0x18, 0x00, 0x10, 0x14, 0x17, 0x00, 0x11, 0x14, 0x17, 0x00, 0x10, 0x14, +0x18, 0x00, 0x12, 0x15, 0x18, 0x00, 0x10, 0x15, 0x19, 0x00, 0x12, 0x15, 0x19, 0x00, 0x10, 0x15, +0x1a, 0x00, 0x11, 0x15, 0x1a, 0x00, 0x12, 0x15, 0x1a, 0x00, 0x12, 0x15, 0x1b, 0x00, 0x11, 0x16, +0x1a, 0x00, 0x12, 0x16, 0x1a, 0x00, 0x13, 0x16, 0x1a, 0x00, 0x12, 0x16, 0x1b, 0x00, 0x13, 0x16, +0x1b, 0x00, 0x12, 0x17, 0x1b, 0x00, 0x13, 0x17, 0x1b, 0x00, 0x13, 0x17, 0x1c, 0x00, 0x14, 0x17, +0x1c, 0x00, 0x14, 0x17, 0x1d, 0x00, 0x13, 0x18, 0x1d, 0x00, 0x14, 0x18, 0x1d, 0x00, 0x15, 0x18, +0x1f, 0x00, 0x14, 0x19, 0x1d, 0x00, 0x15, 0x19, 0x1d, 0x00, 0x15, 0x19, 0x1e, 0x00, 0x15, 0x19, +0x1f, 0x00, 0x16, 0x19, 0x1f, 0x00, 0x15, 0x19, 0x20, 0x00, 0x16, 0x1a, 0x1e, 0x00, 0x14, 0x1a, +0x1f, 0x00, 0x15, 0x1a, 0x1f, 0x00, 0x16, 0x1a, 0x1f, 0x00, 0x15, 0x1a, 0x20, 0x00, 0x16, 0x1a, +0x21, 0x00, 0x15, 0x1b, 0x21, 0x00, 0x17, 0x1b, 0x22, 0x00, 0x17, 0x1b, 0x23, 0x00, 0x16, 0x1c, +0x22, 0x00, 0x17, 0x1d, 0x22, 0x00, 0x17, 0x1d, 0x23, 0x00, 0x18, 0x1d, 0x23, 0x00, 0x19, 0x1d, +0x23, 0x00, 0x17, 0x1d, 0x24, 0x00, 0x18, 0x1e, 0x23, 0x00, 0x18, 0x1e, 0x24, 0x00, 0x18, 0x1e, +0x25, 0x00, 0x19, 0x1e, 0x25, 0x00, 0x18, 0x1e, 0x26, 0x00, 0x19, 0x1f, 0x26, 0x00, 0x1a, 0x1f, +0x26, 0x00, 0x1a, 0x1f, 0x27, 0x00, 0x1a, 0x1f, 0x28, 0x00, 0x1a, 0x20, 0x26, 0x00, 0x19, 0x20, +0x27, 0x00, 0x1a, 0x20, 0x27, 0x00, 0x1a, 0x20, 0x28, 0x00, 0x1b, 0x20, 0x29, 0x00, 0x1b, 0x21, +0x28, 0x00, 0x1b, 0x21, 0x29, 0x00, 0x1c, 0x21, 0x2a, 0x00, 0x1d, 0x22, 0x29, 0x00, 0x1c, 0x22, +0x2a, 0x00, 0x1d, 0x22, 0x2a, 0x00, 0x1e, 0x23, 0x2c, 0x00, 0x1d, 0x24, 0x2b, 0x00, 0x1d, 0x24, +0x2c, 0x00, 0x1c, 0x24, 0x2d, 0x00, 0x1e, 0x25, 0x2d, 0x00, 0x1f, 0x25, 0x2e, 0x00, 0x1e, 0x26, +0x2e, 0x00, 0x1f, 0x26, 0x2e, 0x00, 0x1f, 0x26, 0x30, 0x00, 0x21, 0x27, 0x2e, 0x00, 0x20, 0x27, +0x2f, 0x00, 0x20, 0x27, 0x31, 0x00, 0x20, 0x29, 0x32, 0x00, 0x20, 0x29, 0x33, 0x00, 0x21, 0x2a, +0x33, 0x00, 0x24, 0x2c, 0x35, 0x00, 0x24, 0x2c, 0x38, 0x00, 0x26, 0x31, 0x3b, 0x00, 0x27, 0x31, +0x3b, 0x00, 0xff, 0x00, 0xff, 0x00, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, +0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, +0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, +0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, +0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, +0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, +0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, +0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0x05, 0x1a, 0xa3, +0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, +0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, +0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0x25, 0x48, 0xa3, +0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, +0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, +0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0x4a, 0x54, 0xa3, +0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, +0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, +0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0x8a, 0x8c, 0xa3, +0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, +0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, +0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0x41, 0x5e, 0xa3, +0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, +0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, +0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0x0d, 0x27, 0xa3, +0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, +0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, +0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0x1b, 0x1f, 0xa3, +0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, +0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, +0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0x00, 0x32, 0x69, 0x29, +0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, +0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, +0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0x21, 0x38, 0x63, 0x2b, +0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, +0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, +0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0x3d, 0x2b, 0x1c, 0x0e, +0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, +0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, +0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0x5d, 0x7e, 0x2b, 0x08, +0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, +0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, +0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0x5d, 0x80, 0x4d, 0x4c, +0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, +0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, +0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0x24, 0x4a, 0x9c, 0xa1, +0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, +0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, +0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0x10, 0x39, 0x76, 0x46, 0x6d, 0x9a, +0x60, 0x3f, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, +0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, +0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0x01, 0x78, 0x8e, 0x32, 0x37, 0x81, 0x6c, 0x2a, 0x3c, +0x55, 0x2c, 0x1d, 0x2d, 0x17, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, +0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, +0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0x06, 0x27, 0x55, 0x82, 0x9b, 0x45, 0x0e, 0x47, 0x61, 0x0f, 0x1a, +0x0f, 0x20, 0x62, 0x28, 0x0f, 0x18, 0x08, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, +0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, +0xa3, 0xa3, 0xa3, 0xa3, 0x35, 0x1b, 0x40, 0x98, 0x4d, 0x18, 0x15, 0x1c, 0x26, 0x1b, 0x3b, 0x49, +0x20, 0x46, 0x67, 0x1b, 0x13, 0x0c, 0x15, 0x20, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, +0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, +0xa3, 0xa3, 0xa3, 0x25, 0x4d, 0x3c, 0x34, 0x2b, 0x1c, 0x08, 0x0b, 0x0f, 0x1b, 0x32, 0x9e, 0x8a, +0x08, 0x27, 0x22, 0x0f, 0x36, 0x6f, 0x75, 0x3b, 0x39, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, +0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, +0xa3, 0xa3, 0x7d, 0x7a, 0x56, 0x48, 0x68, 0x32, 0x06, 0xa3, 0xa3, 0xa3, 0x14, 0x40, 0x86, 0x6e, +0xa3, 0xa3, 0xa3, 0x06, 0x2d, 0x85, 0x92, 0x5b, 0x32, 0x6a, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, +0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, +0xa3, 0x1c, 0x58, 0x8a, 0x65, 0x18, 0x21, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0x07, 0x43, 0x83, 0x43, +0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0x73, 0x91, 0x7f, 0x62, 0x20, 0x15, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, +0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, +0x1e, 0x31, 0x0f, 0x2e, 0x1c, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0x1b, 0x1b, 0x32, 0x16, +0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0x43, 0x3b, 0x22, 0x55, 0x47, 0xa3, 0xa3, 0xa3, 0xa3, +0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, +0x72, 0x9d, 0x60, 0x33, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0x2d, 0x0f, 0x1b, 0x0f, +0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0x11, 0x2d, 0x93, 0x55, 0xa3, 0xa3, 0xa3, 0xa3, +0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0x50, +0x44, 0x90, 0x8a, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0x3a, 0x77, 0x88, 0x47, +0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0x25, 0x45, 0x25, 0x25, 0xa3, 0xa3, 0xa3, +0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0x8a, +0x51, 0x23, 0x43, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0x57, 0x5a, 0xa0, 0x84, 0x87, +0x74, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0x02, 0x08, 0x8f, 0x8b, 0xa3, 0xa3, 0xa3, +0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa2, 0x96, +0x6a, 0x41, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0x4e, 0x95, 0x68, 0x5a, 0x4b, 0x7b, +0x70, 0x4c, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0x04, 0x53, 0x8d, 0x79, 0xa3, 0xa3, +0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0x79, 0x80, +0x5b, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, +0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0x0e, 0x7c, 0x94, 0xa3, 0xa3, +0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0x4f, 0x6a, +0x47, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, +0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0x5f, 0x40, 0x1b, 0xa3, 0xa3, +0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0x46, 0x2d, +0x08, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, +0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0x97, 0x82, 0x18, 0xa3, 0xa3, +0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0x58, 0x43, +0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, +0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0x69, 0x5c, 0xa3, 0xa3, +0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0x71, 0x40, +0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, +0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0x65, 0x60, 0xa3, 0xa3, +0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0x52, 0x2d, +0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, +0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0x66, 0x5e, 0xa3, 0xa3, +0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0x2d, 0x20, +0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, +0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0x6f, 0x6b, 0xa3, 0xa3, +0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0x2b, 0x5b, +0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, +0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0x2e, 0x44, 0xa3, 0xa3, +0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0x25, 0x41, +0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, +0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0x40, 0x1e, 0xa3, 0xa3, +0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0x10, 0x38, +0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, +0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0x69, 0x42, 0xa3, 0xa3, +0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0x3b, +0x19, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, +0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0x03, 0x20, 0xa3, 0xa3, 0xa3, +0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0x53, +0x1d, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, +0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0x4f, 0x15, 0xa3, 0xa3, 0xa3, +0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, +0x1d, 0x09, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, +0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0x48, 0x89, 0xa3, 0xa3, 0xa3, 0xa3, +0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, +0x1e, 0x33, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, +0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0x5b, 0x39, 0xa3, 0xa3, 0xa3, 0xa3, +0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, +0xa3, 0x3b, 0x2a, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, +0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0x59, 0x9f, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, +0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, +0xa3, 0xa3, 0x33, 0x0a, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, +0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0x2f, 0x64, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, +0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, +0xa3, 0xa3, 0xa3, 0x1d, 0x2b, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, +0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0x12, 0x99, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, +0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, +0xa3, 0xa3, 0xa3, 0xa3, 0x49, 0x3e, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, +0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0x1c, 0x36, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, +0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, +0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0x30, 0x5e, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, +0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0x8a, 0x48, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, +0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, +0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, +0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, +0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, +0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, +0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, +0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3 diff --git a/engine/Quake/quakedef.h b/engine/Quake/quakedef.h new file mode 100644 index 0000000..85a7e7b --- /dev/null +++ b/engine/Quake/quakedef.h @@ -0,0 +1,334 @@ +/* +Copyright (C) 1996-2001 Id Software, Inc. +Copyright (C) 2002-2009 John Fitzgibbons and others +Copyright (C) 2007-2008 Kristian Duske +Copyright (C) 2010-2019 QuakeSpasm developers + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#ifndef QUAKEDEFS_H +#define QUAKEDEFS_H + +// quakedef.h -- primary header for client + +#define QUAKE_GAME // as opposed to utilities + +#define VERSION 1.09 +#define GLQUAKE_VERSION 1.00 +#define D3DQUAKE_VERSION 0.01 +#define WINQUAKE_VERSION 0.996 +#define LINUX_VERSION 1.30 +#define X11_VERSION 1.10 + +#define FITZQUAKE_VERSION 0.85 //johnfitz +#define QUAKESPASM_VERSION 0.93 +#define QUAKESPASM_VER_PATCH 2 // helper to print a string like 0.93.2 +#ifndef QUAKESPASM_VER_SUFFIX +#define QUAKESPASM_VER_SUFFIX // optional version suffix string literal like "-beta1" +#endif + +#define QS_STRINGIFY_(x) #x +#define QS_STRINGIFY(x) QS_STRINGIFY_(x) + +// combined version string like "0.92.1-beta1" +#define QUAKESPASM_VER_STRING QS_STRINGIFY(QUAKESPASM_VERSION) "." QS_STRINGIFY(QUAKESPASM_VER_PATCH) QUAKESPASM_VER_SUFFIX + +//define PARANOID // speed sapping error checking + +#define GAMENAME "id1" // directory to look in by default + +#include "q_stdinc.h" + +// !!! if this is changed, it must be changed in d_ifacea.h too !!! +#define CACHE_SIZE 32 // used to align key data structures + +#define Q_UNUSED(x) (x = x) // for pesky compiler / lint warnings + +#define MINIMUM_MEMORY 0x550000 +#define MINIMUM_MEMORY_LEVELPAK (MINIMUM_MEMORY + 0x100000) + +#define MAX_NUM_ARGVS 50 + +// up / down +#define PITCH 0 + +// left / right +#define YAW 1 + +// fall over +#define ROLL 2 + + +#define MAX_QPATH 64 // max length of a quake game pathname + +#define ON_EPSILON 0.1 // point on plane side epsilon + +#define DIST_EPSILON (0.03125) // 1/32 epsilon to keep floating point happy (moved from world.c) + +#define MAX_MSGLEN 64000 // max length of a reliable message //ericw -- was 32000 +#define MAX_DATAGRAM 32000 // max length of unreliable message //johnfitz -- was 1024 + +#define DATAGRAM_MTU 1400 // johnfitz -- actual limit for unreliable messages to nonlocal clients + +// +// per-level limits +// +#define MIN_EDICTS 256 // johnfitz -- lowest allowed value for max_edicts cvar +#define MAX_EDICTS 32000 // johnfitz -- highest allowed value for max_edicts cvar + // ents past 8192 can't play sounds in the standard protocol +#define MAX_LIGHTSTYLES 64 +#define MAX_MODELS 2048 // johnfitz -- was 256 +#define MAX_SOUNDS 2048 // johnfitz -- was 256 + +#define SAVEGAME_COMMENT_LENGTH 39 + +#define MAX_STYLESTRING 64 + +// +// stats are integers communicated to the client by the server +// +#define MAX_CL_STATS 32 +#define STAT_HEALTH 0 +#define STAT_FRAGS 1 +#define STAT_WEAPON 2 +#define STAT_AMMO 3 +#define STAT_ARMOR 4 +#define STAT_WEAPONFRAME 5 +#define STAT_SHELLS 6 +#define STAT_NAILS 7 +#define STAT_ROCKETS 8 +#define STAT_CELLS 9 +#define STAT_ACTIVEWEAPON 10 +#define STAT_TOTALSECRETS 11 +#define STAT_TOTALMONSTERS 12 +#define STAT_SECRETS 13 // bumped on client side by svc_foundsecret +#define STAT_MONSTERS 14 // bumped by svc_killedmonster + +// stock defines +// +#define IT_SHOTGUN 1 +#define IT_SUPER_SHOTGUN 2 +#define IT_NAILGUN 4 +#define IT_SUPER_NAILGUN 8 +#define IT_GRENADE_LAUNCHER 16 +#define IT_ROCKET_LAUNCHER 32 +#define IT_LIGHTNING 64 +#define IT_SUPER_LIGHTNING 128 +#define IT_SHELLS 256 +#define IT_NAILS 512 +#define IT_ROCKETS 1024 +#define IT_CELLS 2048 +#define IT_AXE 4096 +#define IT_ARMOR1 8192 +#define IT_ARMOR2 16384 +#define IT_ARMOR3 32768 +#define IT_SUPERHEALTH 65536 +#define IT_KEY1 131072 +#define IT_KEY2 262144 +#define IT_INVISIBILITY 524288 +#define IT_INVULNERABILITY 1048576 +#define IT_SUIT 2097152 +#define IT_QUAD 4194304 +#define IT_SIGIL1 (1<<28) +#define IT_SIGIL2 (1<<29) +#define IT_SIGIL3 (1<<30) +#define IT_SIGIL4 (1<<31) + +//=========================================== +//rogue changed and added defines + +#define RIT_SHELLS 128 +#define RIT_NAILS 256 +#define RIT_ROCKETS 512 +#define RIT_CELLS 1024 +#define RIT_AXE 2048 +#define RIT_LAVA_NAILGUN 4096 +#define RIT_LAVA_SUPER_NAILGUN 8192 +#define RIT_MULTI_GRENADE 16384 +#define RIT_MULTI_ROCKET 32768 +#define RIT_PLASMA_GUN 65536 +#define RIT_ARMOR1 8388608 +#define RIT_ARMOR2 16777216 +#define RIT_ARMOR3 33554432 +#define RIT_LAVA_NAILS 67108864 +#define RIT_PLASMA_AMMO 134217728 +#define RIT_MULTI_ROCKETS 268435456 +#define RIT_SHIELD 536870912 +#define RIT_ANTIGRAV 1073741824 +#define RIT_SUPERHEALTH 2147483648 + +//MED 01/04/97 added hipnotic defines +//=========================================== +//hipnotic added defines +#define HIT_PROXIMITY_GUN_BIT 16 +#define HIT_MJOLNIR_BIT 7 +#define HIT_LASER_CANNON_BIT 23 +#define HIT_PROXIMITY_GUN (1< +#include +#else +#include +#include +#endif +#else +#include "SDL.h" +#include "SDL_opengl.h" +#endif +#ifndef APIENTRY +#define APIENTRY +#endif + +#include "console.h" +#include "wad.h" +#include "vid.h" +#include "screen.h" +#include "draw.h" +#include "render.h" +#include "view.h" +#include "sbar.h" +#include "q_sound.h" +#include "client.h" + +#include "gl_model.h" +#include "world.h" + +#include "image.h" //johnfitz +#include "gl_texmgr.h" //johnfitz +#include "input.h" +#include "keys.h" +#include "menu.h" +#include "cdaudio.h" +#include "glquake.h" + + +//============================================================================= + +// the host system specifies the base of the directory tree, the +// command line parms passed to the program, and the amount of memory +// available for the program to use + +extern qboolean noclip_anglehack; + +// +// host +// +extern quakeparms_t *host_parms; + +extern cvar_t sys_ticrate; +extern cvar_t sys_throttle; +extern cvar_t sys_nostdout; +extern cvar_t developer; +extern cvar_t max_edicts; //johnfitz + +extern qboolean host_initialized; // true if into command execution +extern double host_frametime; +extern byte *host_colormap; +extern int host_framecount; // incremented every frame, never reset +extern double realtime; // not bounded in any way, changed at + // start of every frame, never reset + +typedef struct filelist_item_s +{ + char name[32]; + struct filelist_item_s *next; +} filelist_item_t; + +extern filelist_item_t *modlist; +extern filelist_item_t *extralevels; +extern filelist_item_t *demolist; + +void Host_ClearMemory (void); +void Host_ServerFrame (void); +void Host_InitCommands (void); +void Host_Init (void); +void Host_Shutdown(void); +void Host_Callback_Notify (cvar_t *var); /* callback function for CVAR_NOTIFY */ +FUNC_NORETURN void Host_Error (const char *error, ...) FUNC_PRINTF(1,2); +FUNC_NORETURN void Host_EndGame (const char *message, ...) FUNC_PRINTF(1,2); +#ifdef __WATCOMC__ +#pragma aux Host_Error aborts; +#pragma aux Host_EndGame aborts; +#endif +void Host_Frame (float time); +void Host_Quit_f (void); +void Host_ClientCommands (const char *fmt, ...) FUNC_PRINTF(1,2); +void Host_ShutdownServer (qboolean crash); +void Host_WriteConfiguration (void); + +void ExtraMaps_Init (void); +void Modlist_Init (void); +void DemoList_Init (void); + +void DemoList_Rebuild (void); + +extern int current_skill; // skill level for currently loaded level (in case + // the user changes the cvar while the level is + // running, this reflects the level actually in use) + +extern qboolean isDedicated; + +extern int minimum_memory; + +#endif /* QUAKEDEFS_H */ + diff --git a/engine/Quake/r_alias.c b/engine/Quake/r_alias.c new file mode 100644 index 0000000..1f1f1e1 --- /dev/null +++ b/engine/Quake/r_alias.c @@ -0,0 +1,992 @@ +/* +Copyright (C) 1996-2001 Id Software, Inc. +Copyright (C) 2002-2009 John Fitzgibbons and others +Copyright (C) 2010-2014 QuakeSpasm developers + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +//r_alias.c -- alias model rendering + +#include "quakedef.h" + +extern cvar_t r_drawflat, gl_overbright_models, gl_fullbrights, r_lerpmodels, r_lerpmove; //johnfitz + +//up to 16 color translated skins +gltexture_t *playertextures[MAX_SCOREBOARD]; //johnfitz -- changed to an array of pointers + +#define NUMVERTEXNORMALS 162 + +float r_avertexnormals[NUMVERTEXNORMALS][3] = +{ +#include "anorms.h" +}; + +extern vec3_t lightcolor; //johnfitz -- replaces "float shadelight" for lit support + +// precalculated dot products for quantized angles +#define SHADEDOT_QUANT 16 +float r_avertexnormal_dots[SHADEDOT_QUANT][256] = +{ +#include "anorm_dots.h" +}; + +extern vec3_t lightspot; + +float *shadedots = r_avertexnormal_dots[0]; +vec3_t shadevector; + +float entalpha; //johnfitz + +qboolean overbright; //johnfitz + +qboolean shading = true; //johnfitz -- if false, disable vertex shading for various reasons (fullbright, r_lightmap, showtris, etc) + +//johnfitz -- struct for passing lerp information to drawing functions +typedef struct { + short pose1; + short pose2; + float blend; + vec3_t origin; + vec3_t angles; +} lerpdata_t; +//johnfitz + +static GLuint r_alias_program; + +// uniforms used in vert shader +static GLuint blendLoc; +static GLuint shadevectorLoc; +static GLuint lightColorLoc; + +// uniforms used in frag shader +static GLuint texLoc; +static GLuint fullbrightTexLoc; +static GLuint useFullbrightTexLoc; +static GLuint useOverbrightLoc; +static GLuint useAlphaTestLoc; + +#define pose1VertexAttrIndex 0 +#define pose1NormalAttrIndex 1 +#define pose2VertexAttrIndex 2 +#define pose2NormalAttrIndex 3 +#define texCoordsAttrIndex 4 + +/* +============= +GLARB_GetXYZOffset + +Returns the offset of the first vertex's meshxyz_t.xyz in the vbo for the given +model and pose. +============= +*/ +static void *GLARB_GetXYZOffset (aliashdr_t *hdr, int pose) +{ + const int xyzoffs = offsetof (meshxyz_t, xyz); + return (void *) (currententity->model->vboxyzofs + (hdr->numverts_vbo * pose * sizeof (meshxyz_t)) + xyzoffs); +} + +/* +============= +GLARB_GetNormalOffset + +Returns the offset of the first vertex's meshxyz_t.normal in the vbo for the +given model and pose. +============= +*/ +static void *GLARB_GetNormalOffset (aliashdr_t *hdr, int pose) +{ + const int normaloffs = offsetof (meshxyz_t, normal); + return (void *)(currententity->model->vboxyzofs + (hdr->numverts_vbo * pose * sizeof (meshxyz_t)) + normaloffs); +} + +/* +============= +GLAlias_CreateShaders +============= +*/ +void GLAlias_CreateShaders (void) +{ + const glsl_attrib_binding_t bindings[] = { + { "TexCoords", texCoordsAttrIndex }, + { "Pose1Vert", pose1VertexAttrIndex }, + { "Pose1Normal", pose1NormalAttrIndex }, + { "Pose2Vert", pose2VertexAttrIndex }, + { "Pose2Normal", pose2NormalAttrIndex } + }; + + const GLchar *vertSource = \ + "#version 110\n" + "\n" + "uniform float Blend;\n" + "uniform vec3 ShadeVector;\n" + "uniform vec4 LightColor;\n" + "attribute vec4 TexCoords; // only xy are used \n" + "attribute vec4 Pose1Vert;\n" + "attribute vec3 Pose1Normal;\n" + "attribute vec4 Pose2Vert;\n" + "attribute vec3 Pose2Normal;\n" + "\n" + "varying float FogFragCoord;\n" + "\n" + "float r_avertexnormal_dot(vec3 vertexnormal) // from MH \n" + "{\n" + " float dot = dot(vertexnormal, ShadeVector);\n" + " // wtf - this reproduces anorm_dots within as reasonable a degree of tolerance as the >= 0 case\n" + " if (dot < 0.0)\n" + " return 1.0 + dot * (13.0 / 44.0);\n" + " else\n" + " return 1.0 + dot;\n" + "}\n" + "void main()\n" + "{\n" + " gl_TexCoord[0] = TexCoords;\n" + " vec4 lerpedVert = mix(vec4(Pose1Vert.xyz, 1.0), vec4(Pose2Vert.xyz, 1.0), Blend);\n" + " gl_Position = gl_ModelViewProjectionMatrix * lerpedVert;\n" + " FogFragCoord = gl_Position.w;\n" + " float dot1 = r_avertexnormal_dot(Pose1Normal);\n" + " float dot2 = r_avertexnormal_dot(Pose2Normal);\n" + " gl_FrontColor = LightColor * vec4(vec3(mix(dot1, dot2, Blend)), 1.0);\n" + "}\n"; + + const GLchar *fragSource = \ + "#version 110\n" + "\n" + "uniform sampler2D Tex;\n" + "uniform sampler2D FullbrightTex;\n" + "uniform bool UseFullbrightTex;\n" + "uniform bool UseOverbright;\n" + "uniform bool UseAlphaTest;\n" + "\n" + "varying float FogFragCoord;\n" + "\n" + "void main()\n" + "{\n" + " vec4 result = texture2D(Tex, gl_TexCoord[0].xy);\n" + " if (UseAlphaTest && (result.a < 0.666))\n" + " discard;\n" + " result *= gl_Color;\n" + " if (UseOverbright)\n" + " result.rgb *= 2.0;\n" + " if (UseFullbrightTex)\n" + " result += texture2D(FullbrightTex, gl_TexCoord[0].xy);\n" + " result = clamp(result, 0.0, 1.0);\n" + " float fog = exp(-gl_Fog.density * gl_Fog.density * FogFragCoord * FogFragCoord);\n" + " fog = clamp(fog, 0.0, 1.0);\n" + " result = mix(gl_Fog.color, result, fog);\n" + " result.a = gl_Color.a;\n" // FIXME: This will make almost transparent things cut holes though heavy fog + " gl_FragColor = result;\n" + "}\n"; + + if (!gl_glsl_alias_able) + return; + + r_alias_program = GL_CreateProgram (vertSource, fragSource, sizeof(bindings)/sizeof(bindings[0]), bindings); + + if (r_alias_program != 0) + { + // get uniform locations + blendLoc = GL_GetUniformLocation (&r_alias_program, "Blend"); + shadevectorLoc = GL_GetUniformLocation (&r_alias_program, "ShadeVector"); + lightColorLoc = GL_GetUniformLocation (&r_alias_program, "LightColor"); + texLoc = GL_GetUniformLocation (&r_alias_program, "Tex"); + fullbrightTexLoc = GL_GetUniformLocation (&r_alias_program, "FullbrightTex"); + useFullbrightTexLoc = GL_GetUniformLocation (&r_alias_program, "UseFullbrightTex"); + useOverbrightLoc = GL_GetUniformLocation (&r_alias_program, "UseOverbright"); + useAlphaTestLoc = GL_GetUniformLocation (&r_alias_program, "UseAlphaTest"); + } +} + +/* +============= +GL_DrawAliasFrame_GLSL -- ericw + +Optimized alias model drawing codepath. +Compared to the original GL_DrawAliasFrame, this makes 1 draw call, +no vertex data is uploaded (it's already in the r_meshvbo and r_meshindexesvbo +static VBOs), and lerping and lighting is done in the vertex shader. + +Supports optional overbright, optional fullbright pixels. + +Based on code by MH from RMQEngine +============= +*/ +void GL_DrawAliasFrame_GLSL (aliashdr_t *paliashdr, lerpdata_t lerpdata, gltexture_t *tx, gltexture_t *fb) +{ + float blend; + + if (lerpdata.pose1 != lerpdata.pose2) + { + blend = lerpdata.blend; + } + else // poses the same means either 1. the entity has paused its animation, or 2. r_lerpmodels is disabled + { + blend = 0; + } + + GL_UseProgramFunc (r_alias_program); + + GL_BindBuffer (GL_ARRAY_BUFFER, currententity->model->meshvbo); + GL_BindBuffer (GL_ELEMENT_ARRAY_BUFFER, currententity->model->meshindexesvbo); + + GL_EnableVertexAttribArrayFunc (texCoordsAttrIndex); + GL_EnableVertexAttribArrayFunc (pose1VertexAttrIndex); + GL_EnableVertexAttribArrayFunc (pose2VertexAttrIndex); + GL_EnableVertexAttribArrayFunc (pose1NormalAttrIndex); + GL_EnableVertexAttribArrayFunc (pose2NormalAttrIndex); + + GL_VertexAttribPointerFunc (texCoordsAttrIndex, 2, GL_FLOAT, GL_FALSE, 0, (void *)(intptr_t)currententity->model->vbostofs); + GL_VertexAttribPointerFunc (pose1VertexAttrIndex, 4, GL_UNSIGNED_BYTE, GL_FALSE, sizeof (meshxyz_t), GLARB_GetXYZOffset (paliashdr, lerpdata.pose1)); + GL_VertexAttribPointerFunc (pose2VertexAttrIndex, 4, GL_UNSIGNED_BYTE, GL_FALSE, sizeof (meshxyz_t), GLARB_GetXYZOffset (paliashdr, lerpdata.pose2)); +// GL_TRUE to normalize the signed bytes to [-1 .. 1] + GL_VertexAttribPointerFunc (pose1NormalAttrIndex, 4, GL_BYTE, GL_TRUE, sizeof (meshxyz_t), GLARB_GetNormalOffset (paliashdr, lerpdata.pose1)); + GL_VertexAttribPointerFunc (pose2NormalAttrIndex, 4, GL_BYTE, GL_TRUE, sizeof (meshxyz_t), GLARB_GetNormalOffset (paliashdr, lerpdata.pose2)); + +// set uniforms + GL_Uniform1fFunc (blendLoc, blend); + GL_Uniform3fFunc (shadevectorLoc, shadevector[0], shadevector[1], shadevector[2]); + GL_Uniform4fFunc (lightColorLoc, lightcolor[0], lightcolor[1], lightcolor[2], entalpha); + GL_Uniform1iFunc (texLoc, 0); + GL_Uniform1iFunc (fullbrightTexLoc, 1); + GL_Uniform1iFunc (useFullbrightTexLoc, (fb != NULL) ? 1 : 0); + GL_Uniform1fFunc (useOverbrightLoc, overbright ? 1 : 0); + GL_Uniform1iFunc (useAlphaTestLoc, (currententity->model->flags & MF_HOLEY) ? 1 : 0); + +// set textures + GL_SelectTexture (GL_TEXTURE0); + GL_Bind (tx); + + if (fb) + { + GL_SelectTexture (GL_TEXTURE1); + GL_Bind (fb); + } + +// draw + glDrawElements (GL_TRIANGLES, paliashdr->numindexes, GL_UNSIGNED_SHORT, (void *)(intptr_t)currententity->model->vboindexofs); + +// clean up + GL_DisableVertexAttribArrayFunc (texCoordsAttrIndex); + GL_DisableVertexAttribArrayFunc (pose1VertexAttrIndex); + GL_DisableVertexAttribArrayFunc (pose2VertexAttrIndex); + GL_DisableVertexAttribArrayFunc (pose1NormalAttrIndex); + GL_DisableVertexAttribArrayFunc (pose2NormalAttrIndex); + + GL_UseProgramFunc (0); + GL_SelectTexture (GL_TEXTURE0); + + rs_aliaspasses += paliashdr->numtris; +} + +/* +============= +GL_DrawAliasFrame -- johnfitz -- rewritten to support colored light, lerping, entalpha, multitexture, and r_drawflat +============= +*/ +void GL_DrawAliasFrame (aliashdr_t *paliashdr, lerpdata_t lerpdata) +{ + float vertcolor[4]; + trivertx_t *verts1, *verts2; + int *commands; + int count; + float u,v; + float blend, iblend; + qboolean lerping; + + if (lerpdata.pose1 != lerpdata.pose2) + { + lerping = true; + verts1 = (trivertx_t *)((byte *)paliashdr + paliashdr->posedata); + verts2 = verts1; + verts1 += lerpdata.pose1 * paliashdr->poseverts; + verts2 += lerpdata.pose2 * paliashdr->poseverts; + blend = lerpdata.blend; + iblend = 1.0f - blend; + } + else // poses the same means either 1. the entity has paused its animation, or 2. r_lerpmodels is disabled + { + lerping = false; + verts1 = (trivertx_t *)((byte *)paliashdr + paliashdr->posedata); + verts2 = verts1; // avoid bogus compiler warning + verts1 += lerpdata.pose1 * paliashdr->poseverts; + blend = iblend = 0; // avoid bogus compiler warning + } + + commands = (int *)((byte *)paliashdr + paliashdr->commands); + + vertcolor[3] = entalpha; //never changes, so there's no need to put this inside the loop + + while (1) + { + // get the vertex count and primitive type + count = *commands++; + if (!count) + break; // done + + if (count < 0) + { + count = -count; + glBegin (GL_TRIANGLE_FAN); + } + else + glBegin (GL_TRIANGLE_STRIP); + + do + { + u = ((float *)commands)[0]; + v = ((float *)commands)[1]; + if (mtexenabled) + { + GL_MTexCoord2fFunc (GL_TEXTURE0_ARB, u, v); + GL_MTexCoord2fFunc (GL_TEXTURE1_ARB, u, v); + } + else + glTexCoord2f (u, v); + + commands += 2; + + if (shading) + { + if (r_drawflat_cheatsafe) + { + srand(count * (unsigned int)(src_offset_t)commands); + glColor3f (rand()%256/255.0, rand()%256/255.0, rand()%256/255.0); + } + else if (lerping) + { + vertcolor[0] = (shadedots[verts1->lightnormalindex]*iblend + shadedots[verts2->lightnormalindex]*blend) * lightcolor[0]; + vertcolor[1] = (shadedots[verts1->lightnormalindex]*iblend + shadedots[verts2->lightnormalindex]*blend) * lightcolor[1]; + vertcolor[2] = (shadedots[verts1->lightnormalindex]*iblend + shadedots[verts2->lightnormalindex]*blend) * lightcolor[2]; + glColor4fv (vertcolor); + } + else + { + vertcolor[0] = shadedots[verts1->lightnormalindex] * lightcolor[0]; + vertcolor[1] = shadedots[verts1->lightnormalindex] * lightcolor[1]; + vertcolor[2] = shadedots[verts1->lightnormalindex] * lightcolor[2]; + glColor4fv (vertcolor); + } + } + + if (lerping) + { + glVertex3f (verts1->v[0]*iblend + verts2->v[0]*blend, + verts1->v[1]*iblend + verts2->v[1]*blend, + verts1->v[2]*iblend + verts2->v[2]*blend); + verts1++; + verts2++; + } + else + { + glVertex3f (verts1->v[0], verts1->v[1], verts1->v[2]); + verts1++; + } + } while (--count); + + glEnd (); + } + + rs_aliaspasses += paliashdr->numtris; +} + +/* +================= +R_SetupAliasFrame -- johnfitz -- rewritten to support lerping +================= +*/ +void R_SetupAliasFrame (aliashdr_t *paliashdr, int frame, lerpdata_t *lerpdata) +{ + entity_t *e = currententity; + int posenum, numposes; + + if ((frame >= paliashdr->numframes) || (frame < 0)) + { + Con_DPrintf ("R_AliasSetupFrame: no such frame %d for '%s'\n", frame, e->model->name); + frame = 0; + } + + posenum = paliashdr->frames[frame].firstpose; + numposes = paliashdr->frames[frame].numposes; + + if (numposes > 1) + { + e->lerptime = paliashdr->frames[frame].interval; + posenum += (int)(cl.time / e->lerptime) % numposes; + } + else + e->lerptime = 0.1; + + if (e->lerpflags & LERP_RESETANIM) //kill any lerp in progress + { + e->lerpstart = 0; + e->previouspose = posenum; + e->currentpose = posenum; + e->lerpflags -= LERP_RESETANIM; + } + else if (e->currentpose != posenum) // pose changed, start new lerp + { + if (e->lerpflags & LERP_RESETANIM2) //defer lerping one more time + { + e->lerpstart = 0; + e->previouspose = posenum; + e->currentpose = posenum; + e->lerpflags -= LERP_RESETANIM2; + } + else + { + e->lerpstart = cl.time; + e->previouspose = e->currentpose; + e->currentpose = posenum; + } + } + + //set up values + if (r_lerpmodels.value && !(e->model->flags & MOD_NOLERP && r_lerpmodels.value != 2)) + { + if (e->lerpflags & LERP_FINISH && numposes == 1) + lerpdata->blend = CLAMP (0, (cl.time - e->lerpstart) / (e->lerpfinish - e->lerpstart), 1); + else + lerpdata->blend = CLAMP (0, (cl.time - e->lerpstart) / e->lerptime, 1); + lerpdata->pose1 = e->previouspose; + lerpdata->pose2 = e->currentpose; + } + else //don't lerp + { + lerpdata->blend = 1; + lerpdata->pose1 = posenum; + lerpdata->pose2 = posenum; + } +} + +/* +================= +R_SetupEntityTransform -- johnfitz -- set up transform part of lerpdata +================= +*/ +void R_SetupEntityTransform (entity_t *e, lerpdata_t *lerpdata) +{ + float blend; + vec3_t d; + int i; + + // if LERP_RESETMOVE, kill any lerps in progress + if (e->lerpflags & LERP_RESETMOVE) + { + e->movelerpstart = 0; + VectorCopy (e->origin, e->previousorigin); + VectorCopy (e->origin, e->currentorigin); + VectorCopy (e->angles, e->previousangles); + VectorCopy (e->angles, e->currentangles); + e->lerpflags -= LERP_RESETMOVE; + } + else if (!VectorCompare (e->origin, e->currentorigin) || !VectorCompare (e->angles, e->currentangles)) // origin/angles changed, start new lerp + { + e->movelerpstart = cl.time; + VectorCopy (e->currentorigin, e->previousorigin); + VectorCopy (e->origin, e->currentorigin); + VectorCopy (e->currentangles, e->previousangles); + VectorCopy (e->angles, e->currentangles); + } + + //set up values + if (r_lerpmove.value && e != &cl.viewent && e->lerpflags & LERP_MOVESTEP) + { + if (e->lerpflags & LERP_FINISH) + blend = CLAMP (0, (cl.time - e->movelerpstart) / (e->lerpfinish - e->movelerpstart), 1); + else + blend = CLAMP (0, (cl.time - e->movelerpstart) / 0.1, 1); + + //translation + VectorSubtract (e->currentorigin, e->previousorigin, d); + lerpdata->origin[0] = e->previousorigin[0] + d[0] * blend; + lerpdata->origin[1] = e->previousorigin[1] + d[1] * blend; + lerpdata->origin[2] = e->previousorigin[2] + d[2] * blend; + + //rotation + VectorSubtract (e->currentangles, e->previousangles, d); + for (i = 0; i < 3; i++) + { + if (d[i] > 180) d[i] -= 360; + if (d[i] < -180) d[i] += 360; + } + lerpdata->angles[0] = e->previousangles[0] + d[0] * blend; + lerpdata->angles[1] = e->previousangles[1] + d[1] * blend; + lerpdata->angles[2] = e->previousangles[2] + d[2] * blend; + } + else //don't lerp + { + VectorCopy (e->origin, lerpdata->origin); + VectorCopy (e->angles, lerpdata->angles); + } +} + +/* +================= +R_SetupAliasLighting -- johnfitz -- broken out from R_DrawAliasModel and rewritten +================= +*/ +void R_SetupAliasLighting (entity_t *e) +{ + vec3_t dist; + float add; + int i; + int quantizedangle; + float radiansangle; + + R_LightPoint (e->origin); + + //add dlights + for (i=0 ; i= cl.time) + { + VectorSubtract (currententity->origin, cl_dlights[i].origin, dist); + add = cl_dlights[i].radius - VectorLength(dist); + if (add > 0) + VectorMA (lightcolor, add, cl_dlights[i].color, lightcolor); + } + } + + // minimum light value on gun (24) + if (e == &cl.viewent) + { + add = 72.0f - (lightcolor[0] + lightcolor[1] + lightcolor[2]); + if (add > 0.0f) + { + lightcolor[0] += add / 3.0f; + lightcolor[1] += add / 3.0f; + lightcolor[2] += add / 3.0f; + } + } + + // minimum light value on players (8) + if (currententity > cl_entities && currententity <= cl_entities + cl.maxclients) + { + add = 24.0f - (lightcolor[0] + lightcolor[1] + lightcolor[2]); + if (add > 0.0f) + { + lightcolor[0] += add / 3.0f; + lightcolor[1] += add / 3.0f; + lightcolor[2] += add / 3.0f; + } + } + + // clamp lighting so it doesn't overbright as much (96) + if (overbright) + { + add = 288.0f / (lightcolor[0] + lightcolor[1] + lightcolor[2]); + if (add < 1.0f) + VectorScale(lightcolor, add, lightcolor); + } + + //hack up the brightness when fullbrights but no overbrights (256) + if (gl_fullbrights.value && !gl_overbright_models.value) + if (e->model->flags & MOD_FBRIGHTHACK) + { + lightcolor[0] = 256.0f; + lightcolor[1] = 256.0f; + lightcolor[2] = 256.0f; + } + + quantizedangle = ((int)(e->angles[1] * (SHADEDOT_QUANT / 360.0))) & (SHADEDOT_QUANT - 1); + +//ericw -- shadevector is passed to the shader to compute shadedots inside the +//shader, see GLAlias_CreateShaders() + radiansangle = (quantizedangle / 16.0) * 2.0 * 3.14159; + shadevector[0] = cos(-radiansangle); + shadevector[1] = sin(-radiansangle); + shadevector[2] = 1; + VectorNormalize(shadevector); +//ericw -- + + shadedots = r_avertexnormal_dots[quantizedangle]; + VectorScale (lightcolor, 1.0f / 200.0f, lightcolor); +} + +/* +================= +R_DrawAliasModel -- johnfitz -- almost completely rewritten +================= +*/ +void R_DrawAliasModel (entity_t *e) +{ + aliashdr_t *paliashdr; + int i, anim, skinnum; + gltexture_t *tx, *fb; + lerpdata_t lerpdata; + qboolean alphatest = !!(e->model->flags & MF_HOLEY); + + // + // setup pose/lerp data -- do it first so we don't miss updates due to culling + // + paliashdr = (aliashdr_t *)Mod_Extradata (e->model); + R_SetupAliasFrame (paliashdr, e->frame, &lerpdata); + R_SetupEntityTransform (e, &lerpdata); + + // + // cull it + // + if (R_CullModelForEntity(e)) + return; + + // + // transform it + // + glPushMatrix (); + R_RotateForEntity (lerpdata.origin, lerpdata.angles); + glTranslatef (paliashdr->scale_origin[0], paliashdr->scale_origin[1], paliashdr->scale_origin[2]); + glScalef (paliashdr->scale[0], paliashdr->scale[1], paliashdr->scale[2]); + + // + // random stuff + // + if (gl_smoothmodels.value && !r_drawflat_cheatsafe) + glShadeModel (GL_SMOOTH); + if (gl_affinemodels.value) + glHint (GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST); + overbright = gl_overbright_models.value; + shading = true; + + // + // set up for alpha blending + // + if (r_drawflat_cheatsafe || r_lightmap_cheatsafe) //no alpha in drawflat or lightmap mode + entalpha = 1; + else + entalpha = ENTALPHA_DECODE(e->alpha); + if (entalpha == 0) + goto cleanup; + if (entalpha < 1) + { + if (!gl_texture_env_combine) overbright = false; //overbright can't be done in a single pass without combiners + glDepthMask(GL_FALSE); + glEnable(GL_BLEND); + } + else if (alphatest) + glEnable (GL_ALPHA_TEST); + + // + // set up lighting + // + rs_aliaspolys += paliashdr->numtris; + R_SetupAliasLighting (e); + + // + // set up textures + // + GL_DisableMultitexture(); + anim = (int)(cl.time*10) & 3; + skinnum = e->skinnum; + if ((skinnum >= paliashdr->numskins) || (skinnum < 0)) + { + Con_DPrintf ("R_DrawAliasModel: no such skin # %d for '%s'\n", skinnum, e->model->name); + // ericw -- display skin 0 for winquake compatibility + skinnum = 0; + } + tx = paliashdr->gltextures[skinnum][anim]; + fb = paliashdr->fbtextures[skinnum][anim]; + if (e->colormap != vid.colormap && !gl_nocolors.value) + { + i = e - cl_entities; + if (i >= 1 && i<=cl.maxclients /* && !strcmp (currententity->model->name, "progs/player.mdl") */) + tx = playertextures[i - 1]; + } + if (!gl_fullbrights.value) + fb = NULL; + + // + // draw it + // + if (r_drawflat_cheatsafe) + { + glDisable (GL_TEXTURE_2D); + GL_DrawAliasFrame (paliashdr, lerpdata); + glEnable (GL_TEXTURE_2D); + srand((int) (cl.time * 1000)); //restore randomness + } + else if (r_fullbright_cheatsafe) + { + GL_Bind (tx); + shading = false; + glColor4f(1,1,1,entalpha); + GL_DrawAliasFrame (paliashdr, lerpdata); + if (fb) + { + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + GL_Bind(fb); + glEnable(GL_BLEND); + glBlendFunc (GL_ONE, GL_ONE); + glDepthMask(GL_FALSE); + glColor3f(entalpha,entalpha,entalpha); + Fog_StartAdditive (); + GL_DrawAliasFrame (paliashdr, lerpdata); + Fog_StopAdditive (); + glDepthMask(GL_TRUE); + glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glDisable(GL_BLEND); + } + } + else if (r_lightmap_cheatsafe) + { + glDisable (GL_TEXTURE_2D); + shading = false; + glColor3f(1,1,1); + GL_DrawAliasFrame (paliashdr, lerpdata); + glEnable (GL_TEXTURE_2D); + } +// call fast path if possible. if the shader compliation failed for some reason, +// r_alias_program will be 0. + else if (r_alias_program != 0) + { + GL_DrawAliasFrame_GLSL (paliashdr, lerpdata, tx, fb); + } + else if (overbright) + { + if (gl_texture_env_combine && gl_mtexable && gl_texture_env_add && fb) //case 1: everything in one pass + { + GL_Bind (tx); + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT); + glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_MODULATE); + glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_TEXTURE); + glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, GL_PRIMARY_COLOR_EXT); + glTexEnvf(GL_TEXTURE_ENV, GL_RGB_SCALE_EXT, 2.0f); + GL_EnableMultitexture(); // selects TEXTURE1 + GL_Bind (fb); + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_ADD); + glEnable(GL_BLEND); + GL_DrawAliasFrame (paliashdr, lerpdata); + glDisable(GL_BLEND); + GL_DisableMultitexture(); + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); + } + else if (gl_texture_env_combine) //case 2: overbright in one pass, then fullbright pass + { + // first pass + GL_Bind(tx); + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT); + glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_MODULATE); + glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_TEXTURE); + glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, GL_PRIMARY_COLOR_EXT); + glTexEnvf(GL_TEXTURE_ENV, GL_RGB_SCALE_EXT, 2.0f); + GL_DrawAliasFrame (paliashdr, lerpdata); + glTexEnvf(GL_TEXTURE_ENV, GL_RGB_SCALE_EXT, 1.0f); + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); + // second pass + if (fb) + { + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + GL_Bind(fb); + glEnable(GL_BLEND); + glBlendFunc (GL_ONE, GL_ONE); + glDepthMask(GL_FALSE); + shading = false; + glColor3f(entalpha,entalpha,entalpha); + Fog_StartAdditive (); + GL_DrawAliasFrame (paliashdr, lerpdata); + Fog_StopAdditive (); + glDepthMask(GL_TRUE); + glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glDisable(GL_BLEND); + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); + } + } + else //case 3: overbright in two passes, then fullbright pass + { + // first pass + GL_Bind(tx); + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + GL_DrawAliasFrame (paliashdr, lerpdata); + // second pass -- additive with black fog, to double the object colors but not the fog color + glEnable(GL_BLEND); + glBlendFunc (GL_ONE, GL_ONE); + glDepthMask(GL_FALSE); + Fog_StartAdditive (); + GL_DrawAliasFrame (paliashdr, lerpdata); + Fog_StopAdditive (); + glDepthMask(GL_TRUE); + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glDisable(GL_BLEND); + // third pass + if (fb) + { + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + GL_Bind(fb); + glEnable(GL_BLEND); + glBlendFunc (GL_ONE, GL_ONE); + glDepthMask(GL_FALSE); + shading = false; + glColor3f(entalpha,entalpha,entalpha); + Fog_StartAdditive (); + GL_DrawAliasFrame (paliashdr, lerpdata); + Fog_StopAdditive (); + glDepthMask(GL_TRUE); + glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glDisable(GL_BLEND); + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); + } + } + } + else + { + if (gl_mtexable && gl_texture_env_add && fb) //case 4: fullbright mask using multitexture + { + GL_DisableMultitexture(); // selects TEXTURE0 + GL_Bind (tx); + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + GL_EnableMultitexture(); // selects TEXTURE1 + GL_Bind (fb); + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_ADD); + glEnable(GL_BLEND); + GL_DrawAliasFrame (paliashdr, lerpdata); + glDisable(GL_BLEND); + GL_DisableMultitexture(); + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); + } + else //case 5: fullbright mask without multitexture + { + // first pass + GL_Bind(tx); + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + GL_DrawAliasFrame (paliashdr, lerpdata); + // second pass + if (fb) + { + GL_Bind(fb); + glEnable(GL_BLEND); + glBlendFunc (GL_ONE, GL_ONE); + glDepthMask(GL_FALSE); + shading = false; + glColor3f(entalpha,entalpha,entalpha); + Fog_StartAdditive (); + GL_DrawAliasFrame (paliashdr, lerpdata); + Fog_StopAdditive (); + glDepthMask(GL_TRUE); + glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glDisable(GL_BLEND); + } + } + } + +cleanup: + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); + glHint (GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); + glShadeModel (GL_FLAT); + glDepthMask(GL_TRUE); + glDisable(GL_BLEND); + if (alphatest) + glDisable (GL_ALPHA_TEST); + glColor3f(1,1,1); + glPopMatrix (); +} + +//johnfitz -- values for shadow matrix +#define SHADOW_SKEW_X -0.7 //skew along x axis. -0.7 to mimic glquake shadows +#define SHADOW_SKEW_Y 0 //skew along y axis. 0 to mimic glquake shadows +#define SHADOW_VSCALE 0 //0=completely flat +#define SHADOW_HEIGHT 0.1 //how far above the floor to render the shadow +//johnfitz + +/* +============= +GL_DrawAliasShadow -- johnfitz -- rewritten + +TODO: orient shadow onto "lightplane" (a global mplane_t*) +============= +*/ +void GL_DrawAliasShadow (entity_t *e) +{ + float shadowmatrix[16] = {1, 0, 0, 0, + 0, 1, 0, 0, + SHADOW_SKEW_X, SHADOW_SKEW_Y, SHADOW_VSCALE, 0, + 0, 0, SHADOW_HEIGHT, 1}; + float lheight; + aliashdr_t *paliashdr; + lerpdata_t lerpdata; + + if (R_CullModelForEntity(e)) + return; + + if (e == &cl.viewent || e->model->flags & MOD_NOSHADOW) + return; + + entalpha = ENTALPHA_DECODE(e->alpha); + if (entalpha == 0) return; + + paliashdr = (aliashdr_t *)Mod_Extradata (e->model); + R_SetupAliasFrame (paliashdr, e->frame, &lerpdata); + R_SetupEntityTransform (e, &lerpdata); + R_LightPoint (e->origin); + lheight = currententity->origin[2] - lightspot[2]; + +// set up matrix + glPushMatrix (); + glTranslatef (lerpdata.origin[0], lerpdata.origin[1], lerpdata.origin[2]); + glTranslatef (0,0,-lheight); + glMultMatrixf (shadowmatrix); + glTranslatef (0,0,lheight); + glRotatef (lerpdata.angles[1], 0, 0, 1); + glRotatef (-lerpdata.angles[0], 0, 1, 0); + glRotatef (lerpdata.angles[2], 1, 0, 0); + glTranslatef (paliashdr->scale_origin[0], paliashdr->scale_origin[1], paliashdr->scale_origin[2]); + glScalef (paliashdr->scale[0], paliashdr->scale[1], paliashdr->scale[2]); + +// draw it + glDepthMask(GL_FALSE); + glEnable (GL_BLEND); + GL_DisableMultitexture (); + glDisable (GL_TEXTURE_2D); + shading = false; + glColor4f(0,0,0,entalpha * 0.5); + GL_DrawAliasFrame (paliashdr, lerpdata); + glEnable (GL_TEXTURE_2D); + glDisable (GL_BLEND); + glDepthMask(GL_TRUE); + +//clean up + glPopMatrix (); +} + +/* +================= +R_DrawAliasModel_ShowTris -- johnfitz +================= +*/ +void R_DrawAliasModel_ShowTris (entity_t *e) +{ + aliashdr_t *paliashdr; + lerpdata_t lerpdata; + + if (R_CullModelForEntity(e)) + return; + + paliashdr = (aliashdr_t *)Mod_Extradata (e->model); + R_SetupAliasFrame (paliashdr, e->frame, &lerpdata); + R_SetupEntityTransform (e, &lerpdata); + + glPushMatrix (); + R_RotateForEntity (lerpdata.origin,lerpdata.angles); + glTranslatef (paliashdr->scale_origin[0], paliashdr->scale_origin[1], paliashdr->scale_origin[2]); + glScalef (paliashdr->scale[0], paliashdr->scale[1], paliashdr->scale[2]); + + shading = false; + glColor3f(1,1,1); + GL_DrawAliasFrame (paliashdr, lerpdata); + + glPopMatrix (); +} + diff --git a/engine/Quake/r_brush.c b/engine/Quake/r_brush.c new file mode 100644 index 0000000..1499908 --- /dev/null +++ b/engine/Quake/r_brush.c @@ -0,0 +1,1324 @@ +/* +Copyright (C) 1996-2001 Id Software, Inc. +Copyright (C) 2002-2009 John Fitzgibbons and others +Copyright (C) 2007-2008 Kristian Duske +Copyright (C) 2010-2014 QuakeSpasm developers + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ +// r_brush.c: brush model rendering. renamed from r_surf.c + +#include "quakedef.h" + +extern cvar_t gl_fullbrights, r_drawflat, gl_overbright, r_oldwater; //johnfitz +extern cvar_t gl_zfix; // QuakeSpasm z-fighting fix + +int gl_lightmap_format; +int lightmap_bytes; + +#define MAX_SANITY_LIGHTMAPS (1u<<20) +struct lightmap_s *lightmap; +int lightmap_count; +int last_lightmap_allocated; +int allocated[LMBLOCK_WIDTH]; + +unsigned blocklights[LMBLOCK_WIDTH*LMBLOCK_HEIGHT*3]; //johnfitz -- was 18*18, added lit support (*3) and loosened surface extents maximum (LMBLOCK_WIDTH*LMBLOCK_HEIGHT) + + +/* +=============== +R_TextureAnimation -- johnfitz -- added "frame" param to eliminate use of "currententity" global + +Returns the proper texture for a given time and base texture +=============== +*/ +texture_t *R_TextureAnimation (texture_t *base, int frame) +{ + int relative; + int count; + + if (frame) + if (base->alternate_anims) + base = base->alternate_anims; + + if (!base->anim_total) + return base; + + relative = (int)(cl.time*10) % base->anim_total; + + count = 0; + while (base->anim_min > relative || base->anim_max <= relative) + { + base = base->anim_next; + if (!base) + Sys_Error ("R_TextureAnimation: broken cycle"); + if (++count > 100) + Sys_Error ("R_TextureAnimation: infinite cycle"); + } + + return base; +} + +/* +================ +DrawGLPoly +================ +*/ +void DrawGLPoly (glpoly_t *p) +{ + float *v; + int i; + + glBegin (GL_POLYGON); + v = p->verts[0]; + for (i=0 ; inumverts ; i++, v+= VERTEXSIZE) + { + glTexCoord2f (v[3], v[4]); + glVertex3fv (v); + } + glEnd (); +} + +/* +================ +DrawGLTriangleFan -- johnfitz -- like DrawGLPoly but for r_showtris +================ +*/ +void DrawGLTriangleFan (glpoly_t *p) +{ + float *v; + int i; + + glBegin (GL_TRIANGLE_FAN); + v = p->verts[0]; + for (i=0 ; inumverts ; i++, v+= VERTEXSIZE) + { + glVertex3fv (v); + } + glEnd (); +} + +/* +============================================================= + + BRUSH MODELS + +============================================================= +*/ + +#if 0 +/* +================ +R_DrawSequentialPoly -- johnfitz -- rewritten +================ +*/ +void R_DrawSequentialPoly (msurface_t *s) +{ + glpoly_t *p; + texture_t *t; + float *v; + float entalpha; + int i; + + t = R_TextureAnimation (s->texinfo->texture, currententity->frame); + entalpha = ENTALPHA_DECODE(currententity->alpha); + +// drawflat + if (r_drawflat_cheatsafe) + { + if ((s->flags & SURF_DRAWTURB) && r_oldwater.value) + { + for (p = s->polys->next; p; p = p->next) + { + srand((unsigned int) (uintptr_t) p); + glColor3f (rand()%256/255.0, rand()%256/255.0, rand()%256/255.0); + DrawGLPoly (p); + rs_brushpasses++; + } + return; + } + + srand((unsigned int) (uintptr_t) s->polys); + glColor3f (rand()%256/255.0, rand()%256/255.0, rand()%256/255.0); + DrawGLPoly (s->polys); + rs_brushpasses++; + return; + } + +// fullbright + if ((r_fullbright_cheatsafe) && !(s->flags & SURF_DRAWTILED)) + { + if (entalpha < 1) + { + glDepthMask(GL_FALSE); + glEnable(GL_BLEND); + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + glColor4f(1, 1, 1, entalpha); + } + + if (s->flags & SURF_DRAWFENCE) + glEnable (GL_ALPHA_TEST); // Flip on alpha test + + GL_Bind (t->gltexture); + DrawGLPoly (s->polys); + rs_brushpasses++; + + if (s->flags & SURF_DRAWFENCE) + glDisable (GL_ALPHA_TEST); // Flip alpha test back off + + if (entalpha < 1) + { + glDepthMask(GL_TRUE); + glDisable(GL_BLEND); + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); + glColor3f(1, 1, 1); + } + goto fullbrights; + } + +// r_lightmap + if (r_lightmap_cheatsafe) + { + if (s->flags & SURF_DRAWTILED) + { + glDisable (GL_TEXTURE_2D); + DrawGLPoly (s->polys); + glEnable (GL_TEXTURE_2D); + rs_brushpasses++; + return; + } + + R_RenderDynamicLightmaps (s); + GL_Bind (lightmap_textures[s->lightmaptexturenum]); + if (!gl_overbright.value) + { + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + glColor3f(0.5, 0.5, 0.5); + } + glBegin (GL_POLYGON); + v = s->polys->verts[0]; + for (i=0 ; ipolys->numverts ; i++, v+= VERTEXSIZE) + { + glTexCoord2f (v[5], v[6]); + glVertex3fv (v); + } + glEnd (); + if (!gl_overbright.value) + { + glColor3f(1,1,1); + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); + } + rs_brushpasses++; + return; + } + +// sky poly -- skip it, already handled in gl_sky.c + if (s->flags & SURF_DRAWSKY) + return; + +// water poly + if (s->flags & SURF_DRAWTURB) + { + if (currententity->alpha == ENTALPHA_DEFAULT) + entalpha = CLAMP(0.0, GL_WaterAlphaForSurface(s), 1.0); + + if (entalpha < 1) + { + glDepthMask(GL_FALSE); + glEnable(GL_BLEND); + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + glColor4f(1, 1, 1, entalpha); + } + if (r_oldwater.value) + { + GL_Bind (s->texinfo->texture->gltexture); + for (p = s->polys->next; p; p = p->next) + { + DrawWaterPoly (p); + rs_brushpasses++; + } + rs_brushpasses++; + } + else + { + GL_Bind (s->texinfo->texture->warpimage); + s->texinfo->texture->update_warp = true; // FIXME: one frame too late! + DrawGLPoly (s->polys); + rs_brushpasses++; + } + if (entalpha < 1) + { + glDepthMask(GL_TRUE); + glDisable(GL_BLEND); + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); + glColor3f(1, 1, 1); + } + return; + } + +// missing texture + if (s->flags & SURF_NOTEXTURE) + { + if (entalpha < 1) + { + glDepthMask(GL_FALSE); + glEnable(GL_BLEND); + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + glColor4f(1, 1, 1, entalpha); + } + GL_Bind (t->gltexture); + DrawGLPoly (s->polys); + rs_brushpasses++; + if (entalpha < 1) + { + glDepthMask(GL_TRUE); + glDisable(GL_BLEND); + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); + glColor3f(1, 1, 1); + } + return; + } + +// lightmapped poly + if (entalpha < 1) + { + glDepthMask(GL_FALSE); + glEnable(GL_BLEND); + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + glColor4f(1, 1, 1, entalpha); + } + else + glColor3f(1, 1, 1); + + if (s->flags & SURF_DRAWFENCE) + glEnable (GL_ALPHA_TEST); // Flip on alpha test + + if (gl_overbright.value) + { + if (gl_texture_env_combine && gl_mtexable) //case 1: texture and lightmap in one pass, overbright using texture combiners + { + GL_DisableMultitexture(); // selects TEXTURE0 + GL_Bind (t->gltexture); + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + GL_EnableMultitexture(); // selects TEXTURE1 + GL_Bind (lightmap_textures[s->lightmaptexturenum]); + R_RenderDynamicLightmaps (s); + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT); + glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_MODULATE); + glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_PREVIOUS_EXT); + glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, GL_TEXTURE); + glTexEnvf(GL_TEXTURE_ENV, GL_RGB_SCALE_EXT, 2.0f); + glBegin(GL_POLYGON); + v = s->polys->verts[0]; + for (i=0 ; ipolys->numverts ; i++, v+= VERTEXSIZE) + { + GL_MTexCoord2fFunc (GL_TEXTURE0_ARB, v[3], v[4]); + GL_MTexCoord2fFunc (GL_TEXTURE1_ARB, v[5], v[6]); + glVertex3fv (v); + } + glEnd (); + glTexEnvf(GL_TEXTURE_ENV, GL_RGB_SCALE_EXT, 1.0f); + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + GL_DisableMultitexture (); + rs_brushpasses++; + } + else if (entalpha < 1 || (s->flags & SURF_DRAWFENCE)) //case 2: can't do multipass if entity has alpha, so just draw the texture + { + GL_Bind (t->gltexture); + DrawGLPoly (s->polys); + rs_brushpasses++; + } + else //case 3: texture in one pass, lightmap in second pass using 2x modulation blend func, fog in third pass + { + //first pass -- texture with no fog + Fog_DisableGFog (); + GL_Bind (t->gltexture); + DrawGLPoly (s->polys); + Fog_EnableGFog (); + rs_brushpasses++; + + //second pass -- lightmap with black fog, modulate blended + R_RenderDynamicLightmaps (s); + GL_Bind (lightmap_textures[s->lightmaptexturenum]); + glDepthMask (GL_FALSE); + glEnable (GL_BLEND); + glBlendFunc(GL_DST_COLOR, GL_SRC_COLOR); //2x modulate + Fog_StartAdditive (); + glBegin (GL_POLYGON); + v = s->polys->verts[0]; + for (i=0 ; ipolys->numverts ; i++, v+= VERTEXSIZE) + { + glTexCoord2f (v[5], v[6]); + glVertex3fv (v); + } + glEnd (); + Fog_StopAdditive (); + rs_brushpasses++; + + //third pass -- black geo with normal fog, additive blended + if (Fog_GetDensity() > 0) + { + glBlendFunc(GL_ONE, GL_ONE); //add + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + glColor3f(0,0,0); + DrawGLPoly (s->polys); + glColor3f(1,1,1); + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); + rs_brushpasses++; + } + + glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glDisable (GL_BLEND); + glDepthMask (GL_TRUE); + } + } + else + { + if (gl_mtexable) //case 4: texture and lightmap in one pass, regular modulation + { + GL_DisableMultitexture(); // selects TEXTURE0 + GL_Bind (t->gltexture); + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + GL_EnableMultitexture(); // selects TEXTURE1 + GL_Bind (lightmap_textures[s->lightmaptexturenum]); + R_RenderDynamicLightmaps (s); + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + glBegin(GL_POLYGON); + v = s->polys->verts[0]; + for (i=0 ; ipolys->numverts ; i++, v+= VERTEXSIZE) + { + GL_MTexCoord2fFunc (GL_TEXTURE0_ARB, v[3], v[4]); + GL_MTexCoord2fFunc (GL_TEXTURE1_ARB, v[5], v[6]); + glVertex3fv (v); + } + glEnd (); + GL_DisableMultitexture (); + rs_brushpasses++; + } + else if (entalpha < 1 || (s->flags & SURF_DRAWFENCE)) //case 5: can't do multipass if entity has alpha, so just draw the texture + { + GL_Bind (t->gltexture); + DrawGLPoly (s->polys); + rs_brushpasses++; + } + else //case 6: texture in one pass, lightmap in a second pass, fog in third pass + { + //first pass -- texture with no fog + Fog_DisableGFog (); + GL_Bind (t->gltexture); + DrawGLPoly (s->polys); + Fog_EnableGFog (); + rs_brushpasses++; + + //second pass -- lightmap with black fog, modulate blended + R_RenderDynamicLightmaps (s); + GL_Bind (lightmap_textures[s->lightmaptexturenum]); + glDepthMask (GL_FALSE); + glEnable (GL_BLEND); + glBlendFunc (GL_ZERO, GL_SRC_COLOR); //modulate + Fog_StartAdditive (); + glBegin (GL_POLYGON); + v = s->polys->verts[0]; + for (i=0 ; ipolys->numverts ; i++, v+= VERTEXSIZE) + { + glTexCoord2f (v[5], v[6]); + glVertex3fv (v); + } + glEnd (); + Fog_StopAdditive (); + rs_brushpasses++; + + //third pass -- black geo with normal fog, additive blended + if (Fog_GetDensity() > 0) + { + glBlendFunc(GL_ONE, GL_ONE); //add + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + glColor3f(0,0,0); + DrawGLPoly (s->polys); + glColor3f(1,1,1); + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); + rs_brushpasses++; + } + + glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glDisable (GL_BLEND); + glDepthMask (GL_TRUE); + + } + } + if (entalpha < 1) + { + glDepthMask(GL_TRUE); + glDisable(GL_BLEND); + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); + glColor3f(1, 1, 1); + } + + if (s->flags & SURF_DRAWFENCE) + glDisable (GL_ALPHA_TEST); // Flip alpha test back off + +fullbrights: + if (gl_fullbrights.value && t->fullbright) + { + glDepthMask (GL_FALSE); + glEnable (GL_BLEND); + glBlendFunc (GL_ONE, GL_ONE); + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + glColor3f (entalpha, entalpha, entalpha); + GL_Bind (t->fullbright); + Fog_StartAdditive (); + DrawGLPoly (s->polys); + Fog_StopAdditive (); + glColor3f(1, 1, 1); + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); + glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glDisable (GL_BLEND); + glDepthMask (GL_TRUE); + rs_brushpasses++; + } +} +#endif +/* +================= +R_DrawBrushModel +================= +*/ +void R_DrawBrushModel (entity_t *e) +{ + int i, k; + msurface_t *psurf; + float dot; + mplane_t *pplane; + qmodel_t *clmodel; + + if (R_CullModelForEntity(e)) + return; + + currententity = e; + clmodel = e->model; + + VectorSubtract (r_refdef.vieworg, e->origin, modelorg); + if (e->angles[0] || e->angles[1] || e->angles[2]) + { + vec3_t temp; + vec3_t forward, right, up; + + VectorCopy (modelorg, temp); + AngleVectors (e->angles, forward, right, up); + modelorg[0] = DotProduct (temp, forward); + modelorg[1] = -DotProduct (temp, right); + modelorg[2] = DotProduct (temp, up); + } + + psurf = &clmodel->surfaces[clmodel->firstmodelsurface]; + +// calculate dynamic lighting for bmodel if it's not an +// instanced model + if (clmodel->firstmodelsurface != 0 && !gl_flashblend.value) + { + for (k=0 ; knodes + clmodel->hulls[0].firstclipnode); + } + } + + glPushMatrix (); + e->angles[0] = -e->angles[0]; // stupid quake bug + if (gl_zfix.value) + { + e->origin[0] -= DIST_EPSILON; + e->origin[1] -= DIST_EPSILON; + e->origin[2] -= DIST_EPSILON; + } + R_RotateForEntity (e->origin, e->angles); + if (gl_zfix.value) + { + e->origin[0] += DIST_EPSILON; + e->origin[1] += DIST_EPSILON; + e->origin[2] += DIST_EPSILON; + } + e->angles[0] = -e->angles[0]; // stupid quake bug + + R_ClearTextureChains (clmodel, chain_model); + for (i=0 ; inummodelsurfaces ; i++, psurf++) + { + pplane = psurf->plane; + dot = DotProduct (modelorg, pplane->normal) - pplane->dist; + if (((psurf->flags & SURF_PLANEBACK) && (dot < -BACKFACE_EPSILON)) || + (!(psurf->flags & SURF_PLANEBACK) && (dot > BACKFACE_EPSILON))) + { + R_ChainSurface (psurf, chain_model); + rs_brushpolys++; + } + } + + R_DrawTextureChains (clmodel, e, chain_model); + R_DrawTextureChains_Water (clmodel, e, chain_model); + + glPopMatrix (); +} + +/* +================= +R_DrawBrushModel_ShowTris -- johnfitz +================= +*/ +void R_DrawBrushModel_ShowTris (entity_t *e) +{ + int i; + msurface_t *psurf; + float dot; + mplane_t *pplane; + qmodel_t *clmodel; + glpoly_t *p; + + if (R_CullModelForEntity(e)) + return; + + currententity = e; + clmodel = e->model; + + VectorSubtract (r_refdef.vieworg, e->origin, modelorg); + if (e->angles[0] || e->angles[1] || e->angles[2]) + { + vec3_t temp; + vec3_t forward, right, up; + + VectorCopy (modelorg, temp); + AngleVectors (e->angles, forward, right, up); + modelorg[0] = DotProduct (temp, forward); + modelorg[1] = -DotProduct (temp, right); + modelorg[2] = DotProduct (temp, up); + } + + psurf = &clmodel->surfaces[clmodel->firstmodelsurface]; + + glPushMatrix (); + e->angles[0] = -e->angles[0]; // stupid quake bug + R_RotateForEntity (e->origin, e->angles); + e->angles[0] = -e->angles[0]; // stupid quake bug + + // + // draw it + // + for (i=0 ; inummodelsurfaces ; i++, psurf++) + { + pplane = psurf->plane; + dot = DotProduct (modelorg, pplane->normal) - pplane->dist; + if (((psurf->flags & SURF_PLANEBACK) && (dot < -BACKFACE_EPSILON)) || + (!(psurf->flags & SURF_PLANEBACK) && (dot > BACKFACE_EPSILON))) + { + if ((psurf->flags & SURF_DRAWTURB) && r_oldwater.value) + for (p = psurf->polys->next; p; p = p->next) + DrawGLTriangleFan (p); + else + DrawGLTriangleFan (psurf->polys); + } + } + + glPopMatrix (); +} + +/* +============================================================= + + LIGHTMAPS + +============================================================= +*/ + +/* +================ +R_RenderDynamicLightmaps +called during rendering +================ +*/ +void R_RenderDynamicLightmaps (msurface_t *fa) +{ + byte *base; + int maps; + glRect_t *theRect; + int smax, tmax; + + if (fa->flags & SURF_DRAWTILED) //johnfitz -- not a lightmapped surface + return; + + // add to lightmap chain + fa->polys->chain = lightmap[fa->lightmaptexturenum].polys; + lightmap[fa->lightmaptexturenum].polys = fa->polys; + + // check for lightmap modification + for (maps=0; maps < MAXLIGHTMAPS && fa->styles[maps] != 255; maps++) + if (d_lightstylevalue[fa->styles[maps]] != fa->cached_light[maps]) + goto dynamic; + + if (fa->dlightframe == r_framecount // dynamic this frame + || fa->cached_dlight) // dynamic previously + { +dynamic: + if (r_dynamic.value) + { + struct lightmap_s *lm = &lightmap[fa->lightmaptexturenum]; + lm->modified = true; + theRect = &lm->rectchange; + if (fa->light_t < theRect->t) { + if (theRect->h) + theRect->h += theRect->t - fa->light_t; + theRect->t = fa->light_t; + } + if (fa->light_s < theRect->l) { + if (theRect->w) + theRect->w += theRect->l - fa->light_s; + theRect->l = fa->light_s; + } + smax = (fa->extents[0]>>4)+1; + tmax = (fa->extents[1]>>4)+1; + if ((theRect->w + theRect->l) < (fa->light_s + smax)) + theRect->w = (fa->light_s-theRect->l)+smax; + if ((theRect->h + theRect->t) < (fa->light_t + tmax)) + theRect->h = (fa->light_t-theRect->t)+tmax; + base = lm->data; + base += fa->light_t * LMBLOCK_WIDTH * lightmap_bytes + fa->light_s * lightmap_bytes; + R_BuildLightMap (fa, base, LMBLOCK_WIDTH*lightmap_bytes); + } + } +} + +/* +======================== +AllocBlock -- returns a texture number and the position inside it +======================== +*/ +int AllocBlock (int w, int h, int *x, int *y) +{ + int i, j; + int best, best2; + int texnum; + + // ericw -- rather than searching starting at lightmap 0 every time, + // start at the last lightmap we allocated a surface in. + // This makes AllocBlock much faster on large levels (can shave off 3+ seconds + // of load time on a level with 180 lightmaps), at a cost of not quite packing + // lightmaps as tightly vs. not doing this (uses ~5% more lightmaps) + for (texnum=last_lightmap_allocated ; texnum= best) + break; + if (allocated[i+j] > best2) + best2 = allocated[i+j]; + } + if (j == w) + { // this is a valid spot + *x = i; + *y = best = best2; + } + } + + if (best + h > LMBLOCK_HEIGHT) + continue; + + for (i=0 ; iextents[0]>>4)+1; + tmax = (surf->extents[1]>>4)+1; + + surf->lightmaptexturenum = AllocBlock (smax, tmax, &surf->light_s, &surf->light_t); + base = lightmap[surf->lightmaptexturenum].data; + base += (surf->light_t * LMBLOCK_WIDTH + surf->light_s) * lightmap_bytes; + R_BuildLightMap (surf, base, LMBLOCK_WIDTH*lightmap_bytes); +} + +/* +================ +BuildSurfaceDisplayList -- called at level load time +================ +*/ +void BuildSurfaceDisplayList (msurface_t *fa) +{ + int i, lindex, lnumverts; + medge_t *pedges, *r_pedge; + float *vec; + float s, t; + glpoly_t *poly; + +// reconstruct the polygon + pedges = currentmodel->edges; + lnumverts = fa->numedges; + + // + // draw texture + // + poly = (glpoly_t *) Hunk_Alloc (sizeof(glpoly_t) + (lnumverts-4) * VERTEXSIZE*sizeof(float)); + poly->next = fa->polys; + fa->polys = poly; + poly->numverts = lnumverts; + + for (i=0 ; isurfedges[fa->firstedge + i]; + + if (lindex > 0) + { + r_pedge = &pedges[lindex]; + vec = r_pcurrentvertbase[r_pedge->v[0]].position; + } + else + { + r_pedge = &pedges[-lindex]; + vec = r_pcurrentvertbase[r_pedge->v[1]].position; + } + s = DotProduct (vec, fa->texinfo->vecs[0]) + fa->texinfo->vecs[0][3]; + s /= fa->texinfo->texture->width; + + t = DotProduct (vec, fa->texinfo->vecs[1]) + fa->texinfo->vecs[1][3]; + t /= fa->texinfo->texture->height; + + VectorCopy (vec, poly->verts[i]); + poly->verts[i][3] = s; + poly->verts[i][4] = t; + + // + // lightmap texture coordinates + // + s = DotProduct (vec, fa->texinfo->vecs[0]) + fa->texinfo->vecs[0][3]; + s -= fa->texturemins[0]; + s += fa->light_s*16; + s += 8; + s /= LMBLOCK_WIDTH*16; //fa->texinfo->texture->width; + + t = DotProduct (vec, fa->texinfo->vecs[1]) + fa->texinfo->vecs[1][3]; + t -= fa->texturemins[1]; + t += fa->light_t*16; + t += 8; + t /= LMBLOCK_HEIGHT*16; //fa->texinfo->texture->height; + + poly->verts[i][5] = s; + poly->verts[i][6] = t; + } + + //johnfitz -- removed gl_keeptjunctions code + + poly->numverts = lnumverts; +} + +/* +================== +GL_BuildLightmaps -- called at level load time + +Builds the lightmap texture +with all the surfaces from all brush models +================== +*/ +void GL_BuildLightmaps (void) +{ + char name[24]; + int i, j; + struct lightmap_s *lm; + qmodel_t *m; + + r_framecount = 1; // no dlightcache + + //Spike -- wipe out all the lightmap data (johnfitz -- the gltexture objects were already freed by Mod_ClearAll) + for (i=0; i < lightmap_count; i++) + free(lightmap[i].data); + free(lightmap); + lightmap = NULL; + last_lightmap_allocated = 0; + lightmap_count = 0; + + gl_lightmap_format = GL_RGBA;//FIXME: hardcoded for now! + + switch (gl_lightmap_format) + { + case GL_RGBA: + lightmap_bytes = 4; + break; + case GL_BGRA: + lightmap_bytes = 4; + break; + default: + Sys_Error ("GL_BuildLightmaps: bad lightmap format"); + } + + for (j=1 ; jname[0] == '*') + continue; + r_pcurrentvertbase = m->vertexes; + currentmodel = m; + for (i=0 ; inumsurfaces ; i++) + { + //johnfitz -- rewritten to use SURF_DRAWTILED instead of the sky/water flags + if (m->surfaces[i].flags & SURF_DRAWTILED) + continue; + GL_CreateSurfaceLightmap (m->surfaces + i); + BuildSurfaceDisplayList (m->surfaces + i); + //johnfitz + } + } + + // + // upload all lightmaps that were filled + // + for (i=0; imodified = false; + lm->rectchange.l = LMBLOCK_WIDTH; + lm->rectchange.t = LMBLOCK_HEIGHT; + lm->rectchange.w = 0; + lm->rectchange.h = 0; + + //johnfitz -- use texture manager + sprintf(name, "lightmap%07i",i); + lm->texture = TexMgr_LoadImage (cl.worldmodel, name, LMBLOCK_WIDTH, LMBLOCK_HEIGHT, + SRC_LIGHTMAP, lm->data, "", (src_offset_t)lm->data, TEXPREF_LINEAR | TEXPREF_NOPICMIP); + //johnfitz + } + + //johnfitz -- warn about exceeding old limits + //GLQuake limit was 64 textures of 128x128. Estimate how many 128x128 textures we would need + //given that we are using lightmap_count of LMBLOCK_WIDTH x LMBLOCK_HEIGHT + i = lightmap_count * ((LMBLOCK_WIDTH / 128) * (LMBLOCK_HEIGHT / 128)); + if (i > 64) + Con_DWarning("%i lightmaps exceeds standard limit of 64.\n",i); + //johnfitz +} + +/* +============================================================= + + VBO support + +============================================================= +*/ + +GLuint gl_bmodel_vbo = 0; + +void GL_DeleteBModelVertexBuffer (void) +{ + if (!(gl_vbo_able && gl_mtexable && gl_max_texture_units >= 3)) + return; + + GL_DeleteBuffersFunc (1, &gl_bmodel_vbo); + gl_bmodel_vbo = 0; + + GL_ClearBufferBindings (); +} + +/* +================== +GL_BuildBModelVertexBuffer + +Deletes gl_bmodel_vbo if it already exists, then rebuilds it with all +surfaces from world + all brush models +================== +*/ +void GL_BuildBModelVertexBuffer (void) +{ + unsigned int numverts, varray_bytes, varray_index; + int i, j; + qmodel_t *m; + float *varray; + + if (!(gl_vbo_able && gl_mtexable && gl_max_texture_units >= 3)) + return; + +// ask GL for a name for our VBO + GL_DeleteBuffersFunc (1, &gl_bmodel_vbo); + GL_GenBuffersFunc (1, &gl_bmodel_vbo); + +// count all verts in all models + numverts = 0; + for (j=1 ; jname[0] == '*' || m->type != mod_brush) + continue; + + for (i=0 ; inumsurfaces ; i++) + { + numverts += m->surfaces[i].numedges; + } + } + +// build vertex array + varray_bytes = VERTEXSIZE * sizeof(float) * numverts; + varray = (float *) malloc (varray_bytes); + varray_index = 0; + + for (j=1 ; jname[0] == '*' || m->type != mod_brush) + continue; + + for (i=0 ; inumsurfaces ; i++) + { + msurface_t *s = &m->surfaces[i]; + s->vbo_firstvert = varray_index; + memcpy (&varray[VERTEXSIZE * varray_index], s->polys->verts, VERTEXSIZE * sizeof(float) * s->numedges); + varray_index += s->numedges; + } + } + +// upload to GPU + GL_BindBufferFunc (GL_ARRAY_BUFFER, gl_bmodel_vbo); + GL_BufferDataFunc (GL_ARRAY_BUFFER, varray_bytes, varray, GL_STATIC_DRAW); + free (varray); + +// invalidate the cached bindings + GL_ClearBufferBindings (); +} + +/* +=============== +R_AddDynamicLights +=============== +*/ +void R_AddDynamicLights (msurface_t *surf) +{ + int lnum; + int sd, td; + float dist, rad, minlight; + vec3_t impact, local; + int s, t; + int i; + int smax, tmax; + mtexinfo_t *tex; + //johnfitz -- lit support via lordhavoc + float cred, cgreen, cblue, brightness; + unsigned *bl; + //johnfitz + + smax = (surf->extents[0]>>4)+1; + tmax = (surf->extents[1]>>4)+1; + tex = surf->texinfo; + + for (lnum=0 ; lnumdlightbits[lnum >> 5] & (1U << (lnum & 31)))) + continue; // not lit by this light + + rad = cl_dlights[lnum].radius; + dist = DotProduct (cl_dlights[lnum].origin, surf->plane->normal) - + surf->plane->dist; + rad -= fabs(dist); + minlight = cl_dlights[lnum].minlight; + if (rad < minlight) + continue; + minlight = rad - minlight; + + for (i=0 ; i<3 ; i++) + { + impact[i] = cl_dlights[lnum].origin[i] - + surf->plane->normal[i]*dist; + } + + local[0] = DotProduct (impact, tex->vecs[0]) + tex->vecs[0][3]; + local[1] = DotProduct (impact, tex->vecs[1]) + tex->vecs[1][3]; + + local[0] -= surf->texturemins[0]; + local[1] -= surf->texturemins[1]; + + //johnfitz -- lit support via lordhavoc + bl = blocklights; + cred = cl_dlights[lnum].color[0] * 256.0f; + cgreen = cl_dlights[lnum].color[1] * 256.0f; + cblue = cl_dlights[lnum].color[2] * 256.0f; + //johnfitz + for (t = 0 ; t td) + dist = sd + (td>>1); + else + dist = td + (sd>>1); + if (dist < minlight) + //johnfitz -- lit support via lordhavoc + { + brightness = rad - dist; + bl[0] += (int) (brightness * cred); + bl[1] += (int) (brightness * cgreen); + bl[2] += (int) (brightness * cblue); + } + bl += 3; + //johnfitz + } + } + } +} + + +/* +=============== +R_BuildLightMap -- johnfitz -- revised for lit support via lordhavoc + +Combine and scale multiple lightmaps into the 8.8 format in blocklights +=============== +*/ +void R_BuildLightMap (msurface_t *surf, byte *dest, int stride) +{ + int smax, tmax; + int r,g,b; + int i, j, size; + byte *lightmap; + unsigned scale; + int maps; + unsigned *bl; + + surf->cached_dlight = (surf->dlightframe == r_framecount); + + smax = (surf->extents[0]>>4)+1; + tmax = (surf->extents[1]>>4)+1; + size = smax*tmax; + lightmap = surf->samples; + + if (cl.worldmodel->lightdata) + { + // clear to no light + memset (&blocklights[0], 0, size * 3 * sizeof (unsigned int)); //johnfitz -- lit support via lordhavoc + + // add all the lightmaps + if (lightmap) + { + for (maps = 0 ; maps < MAXLIGHTMAPS && surf->styles[maps] != 255 ; + maps++) + { + scale = d_lightstylevalue[surf->styles[maps]]; + surf->cached_light[maps] = scale; // 8.8 fraction + //johnfitz -- lit support via lordhavoc + bl = blocklights; + for (i=0 ; idlightframe == r_framecount) + R_AddDynamicLights (surf); + } + else + { + // set to full bright if no light data + memset (&blocklights[0], 255, size * 3 * sizeof (unsigned int)); //johnfitz -- lit support via lordhavoc + } + +// bound, invert, and shift +// store: + switch (gl_lightmap_format) + { + case GL_RGBA: + stride -= smax * 4; + bl = blocklights; + for (i=0 ; i> 8; + g = *bl++ >> 8; + b = *bl++ >> 8; + } + else + { + r = *bl++ >> 7; + g = *bl++ >> 7; + b = *bl++ >> 7; + } + *dest++ = (r > 255)? 255 : r; + *dest++ = (g > 255)? 255 : g; + *dest++ = (b > 255)? 255 : b; + *dest++ = 255; + } + } + break; + case GL_BGRA: + stride -= smax * 4; + bl = blocklights; + for (i=0 ; i> 8; + g = *bl++ >> 8; + b = *bl++ >> 8; + } + else + { + r = *bl++ >> 7; + g = *bl++ >> 7; + b = *bl++ >> 7; + } + *dest++ = (b > 255)? 255 : b; + *dest++ = (g > 255)? 255 : g; + *dest++ = (r > 255)? 255 : r; + *dest++ = 255; + } + } + break; + default: + Sys_Error ("R_BuildLightMap: bad lightmap format"); + } +} + +/* +=============== +R_UploadLightmap -- johnfitz -- uploads the modified lightmap to opengl if necessary + +assumes lightmap texture is already bound +=============== +*/ +static void R_UploadLightmap(int lmap) +{ + struct lightmap_s *lm = &lightmap[lmap]; + + if (!lm->modified) + return; + + lm->modified = false; + + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, lm->rectchange.t, LMBLOCK_WIDTH, lm->rectchange.h, gl_lightmap_format, + GL_UNSIGNED_BYTE, lm->data+lm->rectchange.t*LMBLOCK_WIDTH*lightmap_bytes); + lm->rectchange.l = LMBLOCK_WIDTH; + lm->rectchange.t = LMBLOCK_HEIGHT; + lm->rectchange.h = 0; + lm->rectchange.w = 0; + + rs_dynamiclightmaps++; +} + +void R_UploadLightmaps (void) +{ + int lmap; + + for (lmap = 0; lmap < lightmap_count; lmap++) + { + if (!lightmap[lmap].modified) + continue; + + GL_Bind (lightmap[lmap].texture); + R_UploadLightmap(lmap); + } +} + +/* +================ +R_RebuildAllLightmaps -- johnfitz -- called when gl_overbright gets toggled +================ +*/ +void R_RebuildAllLightmaps (void) +{ + int i, j; + qmodel_t *mod; + msurface_t *fa; + byte *base; + + if (!cl.worldmodel) // is this the correct test? + return; + + //for each surface in each model, rebuild lightmap with new scale + for (i=1; isurfaces[mod->firstmodelsurface]; + for (j=0; jnummodelsurfaces; j++, fa++) + { + if (fa->flags & SURF_DRAWTILED) + continue; + base = lightmap[fa->lightmaptexturenum].data; + base += fa->light_t * LMBLOCK_WIDTH * lightmap_bytes + fa->light_s * lightmap_bytes; + R_BuildLightMap (fa, base, LMBLOCK_WIDTH*lightmap_bytes); + } + } + + //for each lightmap, upload it + for (i=0; i 255 ? 255 : r; + a = sharpness * (255 - r); + a = q_min(a,255); + return a; +} + +/* +=============== +R_InitParticleTextures -- johnfitz -- rewritten +=============== +*/ +void R_InitParticleTextures (void) +{ + int x,y; + static byte particle1_data[64*64*4]; + static byte particle2_data[2*2*4]; + static byte particle3_data[64*64*4]; + byte *dst; + + // particle texture 1 -- circle + dst = particle1_data; + for (x=0 ; x<64 ; x++) + for (y=0 ; y<64 ; y++) + { + *dst++ = 255; + *dst++ = 255; + *dst++ = 255; + *dst++ = R_ParticleTextureLookup(x, y, 8); + } + particletexture1 = TexMgr_LoadImage (NULL, "particle1", 64, 64, SRC_RGBA, particle1_data, "", (src_offset_t)particle1_data, TEXPREF_PERSIST | TEXPREF_ALPHA | TEXPREF_LINEAR); + + // particle texture 2 -- square + dst = particle2_data; + for (x=0 ; x<2 ; x++) + for (y=0 ; y<2 ; y++) + { + *dst++ = 255; + *dst++ = 255; + *dst++ = 255; + *dst++ = x || y ? 0 : 255; + } + particletexture2 = TexMgr_LoadImage (NULL, "particle2", 2, 2, SRC_RGBA, particle2_data, "", (src_offset_t)particle2_data, TEXPREF_PERSIST | TEXPREF_ALPHA | TEXPREF_NEAREST); + // particle texture 3 -- blob + dst = particle3_data; + for (x=0 ; x<64 ; x++) + for (y=0 ; y<64 ; y++) + { + *dst++ = 255; + *dst++ = 255; + *dst++ = 255; + *dst++ = R_ParticleTextureLookup(x, y, 2); + } + particletexture3 = TexMgr_LoadImage (NULL, "particle3", 64, 64, SRC_RGBA, particle3_data, "", (src_offset_t)particle3_data, TEXPREF_PERSIST | TEXPREF_ALPHA | TEXPREF_LINEAR); + + //set default + particletexture = particletexture1; + texturescalefactor = 1.27; +} + +/* +=============== +R_SetParticleTexture_f -- johnfitz +=============== +*/ +static void R_SetParticleTexture_f (cvar_t *var) +{ + switch ((int)(r_particles.value)) + { + case 1: + particletexture = particletexture1; + texturescalefactor = 1.27; + break; + case 2: + particletexture = particletexture2; + texturescalefactor = 1.0; + break; +// case 3: +// particletexture = particletexture3; +// texturescalefactor = 1.5; +// break; + } +} /* =============== @@ -62,57 +165,19 @@ void R_InitParticles (void) particles = (particle_t *) Hunk_AllocName (r_numparticles * sizeof(particle_t), "particles"); -} -#ifdef QUAKE2 -void R_DarkFieldParticles (entity_t *ent) -{ - int i, j, k; - particle_t *p; - float vel; - vec3_t dir; - vec3_t org; - - org[0] = ent->origin[0]; - org[1] = ent->origin[1]; - org[2] = ent->origin[2]; - for (i=-16 ; i<16 ; i+=8) - for (j=-16 ; j<16 ; j+=8) - for (k=0 ; k<32 ; k+=8) - { - if (!free_particles) - return; - p = free_particles; - free_particles = p->next; - p->next = active_particles; - active_particles = p; - - p->die = cl.time + 0.2 + (rand()&7) * 0.02; - p->color = 150 + rand()%6; - p->type = pt_slowgrav; - - dir[0] = j*8; - dir[1] = i*8; - dir[2] = k*8; - - p->org[0] = org[0] + i + (rand()&3); - p->org[1] = org[1] + j + (rand()&3); - p->org[2] = org[2] + k + (rand()&3); - - VectorNormalize (dir); - vel = 50 + (rand()&63); - VectorScale (dir, vel, p->vel); - } -} -#endif + Cvar_RegisterVariable (&r_particles); //johnfitz + Cvar_SetCallback (&r_particles, R_SetParticleTexture_f); + Cvar_RegisterVariable (&r_quadparticles); //johnfitz + R_InitParticleTextures (); //johnfitz +} /* =============== R_EntityParticles =============== */ - #define NUMVERTEXNORMALS 162 extern float r_avertexnormals[NUMVERTEXNORMALS][3]; vec3_t avelocities[NUMVERTEXNORMALS]; @@ -123,25 +188,29 @@ float timescale = 0.01; void R_EntityParticles (entity_t *ent) { - int count; - int i; + int i; particle_t *p; float angle; - float sr, sp, sy, cr, cp, cy; + float sp, sy, cp, cy; +// float sr, cr; +// int count; vec3_t forward; float dist; - - dist = 64; - count = 50; -if (!avelocities[0][0]) -{ -for (i=0 ; idie = cl.time + 0.01; p->color = 0x6f; p->type = pt_explode; - - p->org[0] = ent->origin[0] + r_avertexnormals[i][0]*dist + forward[0]*beamlength; - p->org[1] = ent->origin[1] + r_avertexnormals[i][1]*dist + forward[1]*beamlength; - p->org[2] = ent->origin[2] + r_avertexnormals[i][2]*dist + forward[2]*beamlength; + + p->org[0] = ent->origin[0] + r_avertexnormals[i][0]*dist + forward[0]*beamlength; + p->org[1] = ent->origin[1] + r_avertexnormals[i][1]*dist + forward[1]*beamlength; + p->org[2] = ent->origin[2] + r_avertexnormals[i][2]*dist + forward[2]*beamlength; } } - /* =============== R_ClearParticles @@ -183,7 +251,7 @@ R_ClearParticles void R_ClearParticles (void) { int i; - + free_particles = &particles[0]; active_particles = NULL; @@ -192,7 +260,11 @@ void R_ClearParticles (void) particles[r_numparticles-1].next = NULL; } - +/* +=============== +R_ReadPointFile_f +=============== +*/ void R_ReadPointFile_f (void) { FILE *f; @@ -200,26 +272,30 @@ void R_ReadPointFile_f (void) int r; int c; particle_t *p; - char name[MAX_OSPATH]; - - sprintf (name,"maps/%s.pts", sv.name); + char name[MAX_QPATH]; - COM_FOpenFile (name, &f); + if (cls.state != ca_connected) + return; // need an active map. + + q_snprintf (name, sizeof(name), "maps/%s.pts", cl.mapname); + + COM_FOpenFile (name, &f, NULL); if (!f) { Con_Printf ("couldn't open %s\n", name); return; } - + Con_Printf ("Reading %s...\n", name); c = 0; + org[0] = org[1] = org[2] = 0; // silence pesky compiler warnings for ( ;; ) { r = fscanf (f,"%f %f %f\n", &org[0], &org[1], &org[2]); if (r != 3) break; c++; - + if (!free_particles) { Con_Printf ("Not enough free particles\n"); @@ -229,7 +305,7 @@ void R_ReadPointFile_f (void) free_particles = p->next; p->next = active_particles; active_particles = p; - + p->die = 99999; p->color = (-c)&15; p->type = pt_static; @@ -252,33 +328,32 @@ void R_ParseParticleEffect (void) { vec3_t org, dir; int i, count, msgcount, color; - + for (i=0 ; i<3 ; i++) - org[i] = MSG_ReadCoord (); + org[i] = MSG_ReadCoord (cl.protocolflags); for (i=0 ; i<3 ; i++) dir[i] = MSG_ReadChar () * (1.0/16); msgcount = MSG_ReadByte (); color = MSG_ReadByte (); -if (msgcount == 255) - count = 1024; -else - count = msgcount; - + if (msgcount == 255) + count = 1024; + else + count = msgcount; + R_RunParticleEffect (org, dir, color, count); } - + /* =============== R_ParticleExplosion - =============== */ void R_ParticleExplosion (vec3_t org) { int i, j; particle_t *p; - + for (i=0 ; i<1024 ; i++) { if (!free_particles) @@ -315,7 +390,6 @@ void R_ParticleExplosion (vec3_t org) /* =============== R_ParticleExplosion2 - =============== */ void R_ParticleExplosion2 (vec3_t org, int colorStart, int colorLength) @@ -349,14 +423,13 @@ void R_ParticleExplosion2 (vec3_t org, int colorStart, int colorLength) /* =============== R_BlobExplosion - =============== */ void R_BlobExplosion (vec3_t org) { int i, j; particle_t *p; - + for (i=0 ; i<1024 ; i++) { if (!free_particles) @@ -394,14 +467,13 @@ void R_BlobExplosion (vec3_t org) /* =============== R_RunParticleEffect - =============== */ void R_RunParticleEffect (vec3_t org, vec3_t dir, int color, int count) { int i, j; particle_t *p; - + for (i=0 ; inext; p->next = active_particles; active_particles = p; - + p->die = cl.time + 2 + (rand()&31) * 0.02; p->color = 224 + (rand()&7); p->type = pt_slowgrav; - + dir[0] = j*8 + (rand()&7); dir[1] = i*8 + (rand()&7); dir[2] = 256; - + p->org[0] = org[0] + dir[0]; p->org[1] = org[1] + dir[1]; p->org[2] = org[2] + (rand()&63); - - VectorNormalize (dir); + + VectorNormalize (dir); vel = 50 + (rand()&63); VectorScale (dir, vel, p->vel); } @@ -495,7 +565,6 @@ void R_LavaSplash (vec3_t org) /* =============== R_TeleportSplash - =============== */ void R_TeleportSplash (vec3_t org) @@ -515,25 +584,32 @@ void R_TeleportSplash (vec3_t org) free_particles = p->next; p->next = active_particles; active_particles = p; - + p->die = cl.time + 0.2 + (rand()&7) * 0.02; p->color = 7 + (rand()&7); p->type = pt_slowgrav; - + dir[0] = j*8; dir[1] = i*8; dir[2] = k*8; - + p->org[0] = org[0] + i + (rand()&3); p->org[1] = org[1] + j + (rand()&3); p->org[2] = org[2] + k + (rand()&3); - - VectorNormalize (dir); + + VectorNormalize (dir); vel = 50 + (rand()&63); VectorScale (dir, vel, p->vel); } } +/* +=============== +R_RocketTrail + +FIXME -- rename function and use #defined types instead of numbers +=============== +*/ void R_RocketTrail (vec3_t start, vec3_t end, int type) { vec3_t vec; @@ -563,7 +639,7 @@ void R_RocketTrail (vec3_t start, vec3_t end, int type) free_particles = p->next; p->next = active_particles; active_particles = p; - + VectorCopy (vec3_origin, p->vel); p->die = cl.time + 2; @@ -600,7 +676,7 @@ void R_RocketTrail (vec3_t start, vec3_t end, int type) p->color = 52 + ((tracercount&4)<<1); else p->color = 230 + ((tracercount&4)<<1); - + tracercount++; VectorCopy (start, p->org); @@ -632,72 +708,31 @@ void R_RocketTrail (vec3_t start, vec3_t end, int type) p->org[j] = start[j] + ((rand()&15)-8); break; } - VectorAdd (start, vec, start); } } - /* =============== -R_DrawParticles +CL_RunParticles -- johnfitz -- all the particle behavior, separated from R_DrawParticles =============== */ -extern cvar_t sv_gravity; - -void R_DrawParticles (void) +void CL_RunParticles (void) { -#ifdef UQ_GLDEBUG particle_t *p, *kill; - float grav; int i; - float time2, time3; - float time1; - float dvel; - float frametime; - -#ifdef GLQUAKE - vec3_t up, right; - float scale; -#endif + float time1, time2, time3, dvel, frametime, grav; + extern cvar_t sv_gravity; - // jkrige - wireframe - if (gl_wireframe.value) - glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); - // jkrige - wireframe - -#ifdef GLQUAKE - - // jkrige - texture mode - //GL_Bind(particletexture); - if(gl_texturemode.value == 0.0f) - GL_Bind(particletexture_point); - else - GL_Bind(particletexture_linear); - // jkrige - texture mode - - glEnable (GL_BLEND); - glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); - glBegin (GL_TRIANGLES); - - VectorScale (vup, 1.5, up); - VectorScale (vright, 1.5, right); -#else - D_StartParticles (); - - VectorScale (vright, xscaleshrink, r_pright); - VectorScale (vup, yscaleshrink, r_pup); - VectorCopy (vpn, r_ppn); -#endif frametime = cl.time - cl.oldtime; time3 = frametime * 15; - time2 = frametime * 10; // 15; + time2 = frametime * 10; time1 = frametime * 5; grav = frametime * sv_gravity.value * 0.05; dvel = 4*frametime; - - for ( ;; ) + + for ( ;; ) { kill = active_particles; if (kill && kill->die < cl.time) @@ -725,28 +760,10 @@ void R_DrawParticles (void) break; } -#ifdef GLQUAKE - // hack a scale up to keep particles from disapearing - scale = (p->org[0] - r_origin[0])*vpn[0] + (p->org[1] - r_origin[1])*vpn[1] - + (p->org[2] - r_origin[2])*vpn[2]; - if (scale < 20) - scale = 1; - else - scale = 1 + scale * 0.004; - glColor3ubv ((byte *)&d_8to24table[(int)p->color]); - glTexCoord2f (0,0); - glVertex3fv (p->org); - glTexCoord2f (1,0); - glVertex3f (p->org[0] + up[0]*scale, p->org[1] + up[1]*scale, p->org[2] + up[2]*scale); - glTexCoord2f (0,1); - glVertex3f (p->org[0] + right[0]*scale, p->org[1] + right[1]*scale, p->org[2] + right[2]*scale); -#else - D_DrawParticle (p); -#endif p->org[0] += p->vel[0]*frametime; p->org[1] += p->vel[1]*frametime; p->org[2] += p->vel[2]*frametime; - + switch (p->type) { case pt_static: @@ -795,27 +812,214 @@ void R_DrawParticles (void) break; case pt_grav: -#ifdef QUAKE2 - p->vel[2] -= grav * 20; - break; -#endif case pt_slowgrav: p->vel[2] -= grav; break; } } +} + +/* +=============== +R_DrawParticles -- johnfitz -- moved all non-drawing code to CL_RunParticles +=============== +*/ +void R_DrawParticles (void) +{ + particle_t *p; + float scale; + vec3_t up, right, p_up, p_right, p_upright; //johnfitz -- p_ vectors + GLubyte color[4], *c; //johnfitz -- particle transparency + extern cvar_t r_particles; //johnfitz + //float alpha; //johnfitz -- particle transparency + + if (!r_particles.value) + return; + + //ericw -- avoid empty glBegin(),glEnd() pair below; causes issues on AMD + if (!active_particles) + return; + + VectorScale (vup, 1.5, up); + VectorScale (vright, 1.5, right); + + GL_Bind(particletexture); + glEnable (GL_BLEND); + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + glDepthMask (GL_FALSE); //johnfitz -- fix for particle z-buffer bug + + if (r_quadparticles.value) //johnitz -- quads save fillrate + { + glBegin (GL_QUADS); + for (p=active_particles ; p ; p=p->next) + { + // hack a scale up to keep particles from disapearing + scale = (p->org[0] - r_origin[0]) * vpn[0] + + (p->org[1] - r_origin[1]) * vpn[1] + + (p->org[2] - r_origin[2]) * vpn[2]; + if (scale < 20) + scale = 1 + 0.08; //johnfitz -- added .08 to be consistent + else + scale = 1 + scale * 0.004; + + scale /= 2.0; //quad is half the size of triangle + + scale *= texturescalefactor; //johnfitz -- compensate for apparent size of different particle textures + + //johnfitz -- particle transparency and fade out + c = (GLubyte *) &d_8to24table[(int)p->color]; + color[0] = c[0]; + color[1] = c[1]; + color[2] = c[2]; + //alpha = CLAMP(0, p->die + 0.5 - cl.time, 1); + color[3] = 255; //(int)(alpha * 255); + glColor4ubv(color); + //johnfitz + + glTexCoord2f (0,0); + glVertex3fv (p->org); + + glTexCoord2f (0.5,0); + VectorMA (p->org, scale, up, p_up); + glVertex3fv (p_up); + + glTexCoord2f (0.5,0.5); + VectorMA (p_up, scale, right, p_upright); + glVertex3fv (p_upright); + + glTexCoord2f (0,0.5); + VectorMA (p->org, scale, right, p_right); + glVertex3fv (p_right); + + rs_particles++; //johnfitz //FIXME: just use r_numparticles + } + glEnd (); + } + else //johnitz -- triangles save verts + { + glBegin (GL_TRIANGLES); + for (p=active_particles ; p ; p=p->next) + { + // hack a scale up to keep particles from disapearing + scale = (p->org[0] - r_origin[0]) * vpn[0] + + (p->org[1] - r_origin[1]) * vpn[1] + + (p->org[2] - r_origin[2]) * vpn[2]; + if (scale < 20) + scale = 1 + 0.08; //johnfitz -- added .08 to be consistent + else + scale = 1 + scale * 0.004; + + scale *= texturescalefactor; //johnfitz -- compensate for apparent size of different particle textures + + //johnfitz -- particle transparency and fade out + c = (GLubyte *) &d_8to24table[(int)p->color]; + color[0] = c[0]; + color[1] = c[1]; + color[2] = c[2]; + //alpha = CLAMP(0, p->die + 0.5 - cl.time, 1); + color[3] = 255; //(int)(alpha * 255); + glColor4ubv(color); + //johnfitz + + glTexCoord2f (0,0); + glVertex3fv (p->org); -#ifdef GLQUAKE - glEnd (); + glTexCoord2f (1,0); + VectorMA (p->org, scale, up, p_up); + glVertex3fv (p_up); + + glTexCoord2f (0,1); + VectorMA (p->org, scale, right, p_right); + glVertex3fv (p_right); + + rs_particles++; //johnfitz //FIXME: just use r_numparticles + } + glEnd (); + } + + glDepthMask (GL_TRUE); //johnfitz -- fix for particle z-buffer bug glDisable (GL_BLEND); glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); -#else - D_EndParticles (); -#endif - - // jkrige - wireframe - if (gl_wireframe.value) - glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); - // jkrige - wireframe -#endif // UQ_GLDEBUG + glColor3f(1,1,1); +} + + +/* +=============== +R_DrawParticles_ShowTris -- johnfitz +=============== +*/ +void R_DrawParticles_ShowTris (void) +{ + particle_t *p; + float scale; + vec3_t up, right, p_up, p_right, p_upright; + extern cvar_t r_particles; + + if (!r_particles.value) + return; + + VectorScale (vup, 1.5, up); + VectorScale (vright, 1.5, right); + + if (r_quadparticles.value) + { + for (p=active_particles ; p ; p=p->next) + { + glBegin (GL_TRIANGLE_FAN); + + // hack a scale up to keep particles from disapearing + scale = (p->org[0] - r_origin[0]) * vpn[0] + + (p->org[1] - r_origin[1]) * vpn[1] + + (p->org[2] - r_origin[2]) * vpn[2]; + if (scale < 20) + scale = 1 + 0.08; //johnfitz -- added .08 to be consistent + else + scale = 1 + scale * 0.004; + + scale /= 2.0; //quad is half the size of triangle + + scale *= texturescalefactor; //compensate for apparent size of different particle textures + + glVertex3fv (p->org); + + VectorMA (p->org, scale, up, p_up); + glVertex3fv (p_up); + + VectorMA (p_up, scale, right, p_upright); + glVertex3fv (p_upright); + + VectorMA (p->org, scale, right, p_right); + glVertex3fv (p_right); + + glEnd (); + } + } + else + { + glBegin (GL_TRIANGLES); + for (p=active_particles ; p ; p=p->next) + { + // hack a scale up to keep particles from disapearing + scale = (p->org[0] - r_origin[0]) * vpn[0] + + (p->org[1] - r_origin[1]) * vpn[1] + + (p->org[2] - r_origin[2]) * vpn[2]; + if (scale < 20) + scale = 1 + 0.08; //johnfitz -- added .08 to be consistent + else + scale = 1 + scale * 0.004; + + scale *= texturescalefactor; //compensate for apparent size of different particle textures + + glVertex3fv (p->org); + + VectorMA (p->org, scale, up, p_up); + glVertex3fv (p_up); + + VectorMA (p->org, scale, right, p_right); + glVertex3fv (p_right); + } + glEnd (); + } } + diff --git a/engine/Quake/r_sprite.c b/engine/Quake/r_sprite.c new file mode 100644 index 0000000..6765e97 --- /dev/null +++ b/engine/Quake/r_sprite.c @@ -0,0 +1,182 @@ +/* +Copyright (C) 1996-2001 Id Software, Inc. +Copyright (C) 2002-2009 John Fitzgibbons and others +Copyright (C) 2007-2008 Kristian Duske +Copyright (C) 2010-2014 QuakeSpasm developers + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +//r_sprite.c -- sprite model rendering + +#include "quakedef.h" + +/* +================ +R_GetSpriteFrame +================ +*/ +mspriteframe_t *R_GetSpriteFrame (entity_t *currentent) +{ + msprite_t *psprite; + mspritegroup_t *pspritegroup; + mspriteframe_t *pspriteframe; + int i, numframes, frame; + float *pintervals, fullinterval, targettime, time; + + psprite = (msprite_t *) currentent->model->cache.data; + frame = currentent->frame; + + if ((frame >= psprite->numframes) || (frame < 0)) + { + Con_DPrintf ("R_DrawSprite: no such frame %d for '%s'\n", frame, currentent->model->name); + frame = 0; + } + + if (psprite->frames[frame].type == SPR_SINGLE) + { + pspriteframe = psprite->frames[frame].frameptr; + } + else + { + pspritegroup = (mspritegroup_t *)psprite->frames[frame].frameptr; + pintervals = pspritegroup->intervals; + numframes = pspritegroup->numframes; + fullinterval = pintervals[numframes-1]; + + time = cl.time + currentent->syncbase; + + // when loading in Mod_LoadSpriteGroup, we guaranteed all interval values + // are positive, so we don't have to worry about division by 0 + targettime = time - ((int)(time / fullinterval)) * fullinterval; + + for (i=0 ; i<(numframes-1) ; i++) + { + if (pintervals[i] > targettime) + break; + } + + pspriteframe = pspritegroup->frames[i]; + } + + return pspriteframe; +} + +/* +================= +R_DrawSpriteModel -- johnfitz -- rewritten: now supports all orientations +================= +*/ +void R_DrawSpriteModel (entity_t *e) +{ + vec3_t point, v_forward, v_right, v_up; + msprite_t *psprite; + mspriteframe_t *frame; + float *s_up, *s_right; + float angle, sr, cr; + + //TODO: frustum cull it? + + frame = R_GetSpriteFrame (e); + psprite = (msprite_t *) currententity->model->cache.data; + + switch(psprite->type) + { + case SPR_VP_PARALLEL_UPRIGHT: //faces view plane, up is towards the heavens + v_up[0] = 0; + v_up[1] = 0; + v_up[2] = 1; + s_up = v_up; + s_right = vright; + break; + case SPR_FACING_UPRIGHT: //faces camera origin, up is towards the heavens + VectorSubtract(currententity->origin, r_origin, v_forward); + v_forward[2] = 0; + VectorNormalizeFast(v_forward); + v_right[0] = v_forward[1]; + v_right[1] = -v_forward[0]; + v_right[2] = 0; + v_up[0] = 0; + v_up[1] = 0; + v_up[2] = 1; + s_up = v_up; + s_right = v_right; + break; + case SPR_VP_PARALLEL: //faces view plane, up is towards the top of the screen + s_up = vup; + s_right = vright; + break; + case SPR_ORIENTED: //pitch yaw roll are independent of camera + AngleVectors (currententity->angles, v_forward, v_right, v_up); + s_up = v_up; + s_right = v_right; + break; + case SPR_VP_PARALLEL_ORIENTED: //faces view plane, but obeys roll value + angle = currententity->angles[ROLL] * M_PI_DIV_180; + sr = sin(angle); + cr = cos(angle); + v_right[0] = vright[0] * cr + vup[0] * sr; + v_right[1] = vright[1] * cr + vup[1] * sr; + v_right[2] = vright[2] * cr + vup[2] * sr; + v_up[0] = vright[0] * -sr + vup[0] * cr; + v_up[1] = vright[1] * -sr + vup[1] * cr; + v_up[2] = vright[2] * -sr + vup[2] * cr; + s_up = v_up; + s_right = v_right; + break; + default: + return; + } + + //johnfitz: offset decals + if (psprite->type == SPR_ORIENTED) + GL_PolygonOffset (OFFSET_DECAL); + + glColor3f (1,1,1); + + GL_DisableMultitexture(); + + GL_Bind(frame->gltexture); + + glEnable (GL_ALPHA_TEST); + glBegin (GL_TRIANGLE_FAN); //was GL_QUADS, but changed to support r_showtris + + glTexCoord2f (0, frame->tmax); + VectorMA (e->origin, frame->down, s_up, point); + VectorMA (point, frame->left, s_right, point); + glVertex3fv (point); + + glTexCoord2f (0, 0); + VectorMA (e->origin, frame->up, s_up, point); + VectorMA (point, frame->left, s_right, point); + glVertex3fv (point); + + glTexCoord2f (frame->smax, 0); + VectorMA (e->origin, frame->up, s_up, point); + VectorMA (point, frame->right, s_right, point); + glVertex3fv (point); + + glTexCoord2f (frame->smax, frame->tmax); + VectorMA (e->origin, frame->down, s_up, point); + VectorMA (point, frame->right, s_right, point); + glVertex3fv (point); + + glEnd (); + glDisable (GL_ALPHA_TEST); + + //johnfitz: offset decals + if (psprite->type == SPR_ORIENTED) + GL_PolygonOffset (OFFSET_NONE); +} diff --git a/engine/Quake/r_world.c b/engine/Quake/r_world.c new file mode 100644 index 0000000..de5b9f3 --- /dev/null +++ b/engine/Quake/r_world.c @@ -0,0 +1,1235 @@ +/* +Copyright (C) 1996-2001 Id Software, Inc. +Copyright (C) 2002-2009 John Fitzgibbons and others +Copyright (C) 2007-2008 Kristian Duske +Copyright (C) 2010-2014 QuakeSpasm developers + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ +// r_world.c: world model rendering + +#include "quakedef.h" + +extern cvar_t gl_fullbrights, r_drawflat, gl_overbright, r_oldwater, r_oldskyleaf, r_showtris; //johnfitz + +byte *SV_FatPVS (vec3_t org, qmodel_t *worldmodel); + +int vis_changed; //if true, force pvs to be refreshed + +//============================================================================== +// +// SETUP CHAINS +// +//============================================================================== + +/* +================ +R_ClearTextureChains -- ericw + +clears texture chains for all textures used by the given model, and also +clears the lightmap chains +================ +*/ +void R_ClearTextureChains (qmodel_t *mod, texchain_t chain) +{ + int i; + + // set all chains to null + for (i=0 ; inumtextures ; i++) + if (mod->textures[i]) + mod->textures[i]->texturechains[chain] = NULL; + + // clear lightmap chains + for (i=0 ; itexturechain = surf->texinfo->texture->texturechains[chain]; + surf->texinfo->texture->texturechains[chain] = surf; +} + +/* +=============== +R_MarkSurfaces -- johnfitz -- mark surfaces based on PVS and rebuild texture chains +=============== +*/ +void R_MarkSurfaces (void) +{ + byte *vis; + mleaf_t *leaf; + mnode_t *node; + msurface_t *surf, **mark; + int i, j; + qboolean nearwaterportal; + + // clear lightmap chains + for (i=0 ; ifirstmarksurface; i < r_viewleaf->nummarksurfaces; i++, mark++) + if ((*mark)->flags & SURF_DRAWTURB) + nearwaterportal = true; + + // choose vis data + if (r_novis.value || r_viewleaf->contents == CONTENTS_SOLID || r_viewleaf->contents == CONTENTS_SKY) + vis = Mod_NoVisPVS (cl.worldmodel); + else if (nearwaterportal) + vis = SV_FatPVS (r_origin, cl.worldmodel); + else + vis = Mod_LeafPVS (r_viewleaf, cl.worldmodel); + + // if surface chains don't need regenerating, just add static entities and return + if (r_oldviewleaf == r_viewleaf && !vis_changed && !nearwaterportal) + { + leaf = &cl.worldmodel->leafs[1]; + for (i=0 ; inumleafs ; i++, leaf++) + if (vis[i>>3] & (1<<(i&7))) + if (leaf->efrags) + R_StoreEfrags (&leaf->efrags); + return; + } + + vis_changed = false; + r_visframecount++; + r_oldviewleaf = r_viewleaf; + + // iterate through leaves, marking surfaces + leaf = &cl.worldmodel->leafs[1]; + for (i=0 ; inumleafs ; i++, leaf++) + { + if (vis[i>>3] & (1<<(i&7))) + { + if (r_oldskyleaf.value || leaf->contents != CONTENTS_SKY) + for (j=0, mark = leaf->firstmarksurface; jnummarksurfaces; j++, mark++) + (*mark)->visframe = r_visframecount; + + // add static models + if (leaf->efrags) + R_StoreEfrags (&leaf->efrags); + } + } + + // set all chains to null + for (i=0 ; inumtextures ; i++) + if (cl.worldmodel->textures[i]) + cl.worldmodel->textures[i]->texturechains[chain_world] = NULL; + + // rebuild chains + +#if 1 + //iterate through surfaces one node at a time to rebuild chains + //need to do it this way if we want to work with tyrann's skip removal tool + //becuase his tool doesn't actually remove the surfaces from the bsp surfaces lump + //nor does it remove references to them in each leaf's marksurfaces list + for (i=0, node = cl.worldmodel->nodes ; inumnodes ; i++, node++) + for (j=0, surf=&cl.worldmodel->surfaces[node->firstsurface] ; jnumsurfaces ; j++, surf++) + if (surf->visframe == r_visframecount) + { + R_ChainSurface(surf, chain_world); + } +#else + //the old way + surf = &cl.worldmodel->surfaces[cl.worldmodel->firstmodelsurface]; + for (i=0 ; inummodelsurfaces ; i++, surf++) + { + if (surf->visframe == r_visframecount) + { + R_ChainSurface(surf, chain_world); + } + } +#endif +} + +/* +================ +R_BackFaceCull -- johnfitz -- returns true if the surface is facing away from vieworg +================ +*/ +qboolean R_BackFaceCull (msurface_t *surf) +{ + double dot; + + switch (surf->plane->type) + { + case PLANE_X: + dot = r_refdef.vieworg[0] - surf->plane->dist; + break; + case PLANE_Y: + dot = r_refdef.vieworg[1] - surf->plane->dist; + break; + case PLANE_Z: + dot = r_refdef.vieworg[2] - surf->plane->dist; + break; + default: + dot = DotProduct (r_refdef.vieworg, surf->plane->normal) - surf->plane->dist; + break; + } + + if ((dot < 0) ^ !!(surf->flags & SURF_PLANEBACK)) + return true; + + return false; +} + +/* +================ +R_CullSurfaces -- johnfitz +================ +*/ +void R_CullSurfaces (void) +{ + msurface_t *s; + int i; + texture_t *t; + + if (!r_drawworld_cheatsafe) + return; + +// ericw -- instead of testing (s->visframe == r_visframecount) on all world +// surfaces, use the chained surfaces, which is exactly the same set of sufaces + for (i=0 ; inumtextures ; i++) + { + t = cl.worldmodel->textures[i]; + + if (!t || !t->texturechains[chain_world]) + continue; + + for (s = t->texturechains[chain_world]; s; s = s->texturechain) + { + if (R_CullBox(s->mins, s->maxs) || R_BackFaceCull (s)) + s->culled = true; + else + { + s->culled = false; + rs_brushpolys++; //count wpolys here + if (s->texinfo->texture->warpimage) + s->texinfo->texture->update_warp = true; + } + } + } +} + +/* +================ +R_BuildLightmapChains -- johnfitz -- used for r_lightmap 1 + +ericw -- now always used at the start of R_DrawTextureChains for the +mh dynamic lighting speedup +================ +*/ +void R_BuildLightmapChains (qmodel_t *model, texchain_t chain) +{ + texture_t *t; + msurface_t *s; + int i; + + // clear lightmap chains (already done in r_marksurfaces, but clearing them here to be safe becuase of r_stereo) + for (i=0 ; inumtextures ; i++) + { + t = model->textures[i]; + + if (!t || !t->texturechains[chain]) + continue; + + for (s = t->texturechains[chain]; s; s = s->texturechain) + if (!s->culled) + R_RenderDynamicLightmaps (s); + } +} + +//============================================================================== +// +// DRAW CHAINS +// +//============================================================================== + +/* +============= +R_BeginTransparentDrawing -- ericw +============= +*/ +static void R_BeginTransparentDrawing (float entalpha) +{ + if (entalpha < 1.0f) + { + glDepthMask (GL_FALSE); + glEnable (GL_BLEND); + glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + glColor4f (1,1,1,entalpha); + } +} + +/* +============= +R_EndTransparentDrawing -- ericw +============= +*/ +static void R_EndTransparentDrawing (float entalpha) +{ + if (entalpha < 1.0f) + { + glDepthMask (GL_TRUE); + glDisable (GL_BLEND); + glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); + glColor3f (1, 1, 1); + } +} + +/* +================ +R_DrawTextureChains_ShowTris -- johnfitz +================ +*/ +void R_DrawTextureChains_ShowTris (qmodel_t *model, texchain_t chain) +{ + int i; + msurface_t *s; + texture_t *t; + glpoly_t *p; + + for (i=0 ; inumtextures ; i++) + { + t = model->textures[i]; + if (!t) + continue; + + if (r_oldwater.value && t->texturechains[chain] && (t->texturechains[chain]->flags & SURF_DRAWTURB)) + { + for (s = t->texturechains[chain]; s; s = s->texturechain) + if (!s->culled) + for (p = s->polys->next; p; p = p->next) + { + DrawGLTriangleFan (p); + } + } + else + { + for (s = t->texturechains[chain]; s; s = s->texturechain) + if (!s->culled) + { + DrawGLTriangleFan (s->polys); + } + } + } +} + +/* +================ +R_DrawTextureChains_Drawflat -- johnfitz +================ +*/ +void R_DrawTextureChains_Drawflat (qmodel_t *model, texchain_t chain) +{ + int i; + msurface_t *s; + texture_t *t; + glpoly_t *p; + + for (i=0 ; inumtextures ; i++) + { + t = model->textures[i]; + if (!t) + continue; + + if (r_oldwater.value && t->texturechains[chain] && (t->texturechains[chain]->flags & SURF_DRAWTURB)) + { + for (s = t->texturechains[chain]; s; s = s->texturechain) + if (!s->culled) + for (p = s->polys->next; p; p = p->next) + { + srand((unsigned int) (uintptr_t) p); + glColor3f (rand()%256/255.0, rand()%256/255.0, rand()%256/255.0); + DrawGLPoly (p); + rs_brushpasses++; + } + } + else + { + for (s = t->texturechains[chain]; s; s = s->texturechain) + if (!s->culled) + { + srand((unsigned int) (uintptr_t) s->polys); + glColor3f (rand()%256/255.0, rand()%256/255.0, rand()%256/255.0); + DrawGLPoly (s->polys); + rs_brushpasses++; + } + } + } + glColor3f (1,1,1); + srand ((int) (cl.time * 1000)); +} + +/* +================ +R_DrawTextureChains_Glow -- johnfitz +================ +*/ +void R_DrawTextureChains_Glow (qmodel_t *model, entity_t *ent, texchain_t chain) +{ + int i; + msurface_t *s; + texture_t *t; + gltexture_t *glt; + qboolean bound; + + for (i=0 ; inumtextures ; i++) + { + t = model->textures[i]; + + if (!t || !t->texturechains[chain] || !(glt = R_TextureAnimation(t, ent != NULL ? ent->frame : 0)->fullbright)) + continue; + + bound = false; + + for (s = t->texturechains[chain]; s; s = s->texturechain) + if (!s->culled) + { + if (!bound) //only bind once we are sure we need this texture + { + GL_Bind (glt); + bound = true; + } + DrawGLPoly (s->polys); + rs_brushpasses++; + } + } +} + +//============================================================================== +// +// VBO SUPPORT +// +//============================================================================== + +static unsigned int R_NumTriangleIndicesForSurf (msurface_t *s) +{ + return 3 * (s->numedges - 2); +} + +/* +================ +R_TriangleIndicesForSurf + +Writes out the triangle indices needed to draw s as a triangle list. +The number of indices it will write is given by R_NumTriangleIndicesForSurf. +================ +*/ +static void R_TriangleIndicesForSurf (msurface_t *s, unsigned int *dest) +{ + int i; + for (i=2; inumedges; i++) + { + *dest++ = s->vbo_firstvert; + *dest++ = s->vbo_firstvert + i - 1; + *dest++ = s->vbo_firstvert + i; + } +} + +#define MAX_BATCH_SIZE 4096 + +static unsigned int vbo_indices[MAX_BATCH_SIZE]; +static unsigned int num_vbo_indices; + +/* +================ +R_ClearBatch +================ +*/ +static void R_ClearBatch () +{ + num_vbo_indices = 0; +} + +/* +================ +R_FlushBatch + +Draw the current batch if non-empty and clears it, ready for more R_BatchSurface calls. +================ +*/ +static void R_FlushBatch () +{ + if (num_vbo_indices > 0) + { + glDrawElements (GL_TRIANGLES, num_vbo_indices, GL_UNSIGNED_INT, vbo_indices); + num_vbo_indices = 0; + } +} + +/* +================ +R_BatchSurface + +Add the surface to the current batch, or just draw it immediately if we're not +using VBOs. +================ +*/ +static void R_BatchSurface (msurface_t *s) +{ + int num_surf_indices; + + num_surf_indices = R_NumTriangleIndicesForSurf (s); + + if (num_vbo_indices + num_surf_indices > MAX_BATCH_SIZE) + R_FlushBatch(); + + R_TriangleIndicesForSurf (s, &vbo_indices[num_vbo_indices]); + num_vbo_indices += num_surf_indices; +} + +/* +================ +R_DrawTextureChains_Multitexture -- johnfitz +================ +*/ +void R_DrawTextureChains_Multitexture (qmodel_t *model, entity_t *ent, texchain_t chain) +{ + int i, j; + msurface_t *s; + texture_t *t; + float *v; + qboolean bound; + + for (i=0 ; inumtextures ; i++) + { + t = model->textures[i]; + + if (!t || !t->texturechains[chain] || t->texturechains[chain]->flags & (SURF_DRAWTILED | SURF_NOTEXTURE)) + continue; + + bound = false; + for (s = t->texturechains[chain]; s; s = s->texturechain) + if (!s->culled) + { + if (!bound) //only bind once we are sure we need this texture + { + GL_Bind ((R_TextureAnimation(t, ent != NULL ? ent->frame : 0))->gltexture); + + if (t->texturechains[chain]->flags & SURF_DRAWFENCE) + glEnable (GL_ALPHA_TEST); // Flip alpha test back on + + GL_EnableMultitexture(); // selects TEXTURE1 + bound = true; + } + GL_Bind (lightmap[s->lightmaptexturenum].texture); + glBegin(GL_POLYGON); + v = s->polys->verts[0]; + for (j=0 ; jpolys->numverts ; j++, v+= VERTEXSIZE) + { + GL_MTexCoord2fFunc (GL_TEXTURE0_ARB, v[3], v[4]); + GL_MTexCoord2fFunc (GL_TEXTURE1_ARB, v[5], v[6]); + glVertex3fv (v); + } + glEnd (); + rs_brushpasses++; + } + GL_DisableMultitexture(); // selects TEXTURE0 + + if (bound && t->texturechains[chain]->flags & SURF_DRAWFENCE) + glDisable (GL_ALPHA_TEST); // Flip alpha test back off + } +} + +/* +================ +R_DrawTextureChains_NoTexture -- johnfitz + +draws surfs whose textures were missing from the BSP +================ +*/ +void R_DrawTextureChains_NoTexture (qmodel_t *model, texchain_t chain) +{ + int i; + msurface_t *s; + texture_t *t; + qboolean bound; + + for (i=0 ; inumtextures ; i++) + { + t = model->textures[i]; + + if (!t || !t->texturechains[chain] || !(t->texturechains[chain]->flags & SURF_NOTEXTURE)) + continue; + + bound = false; + + for (s = t->texturechains[chain]; s; s = s->texturechain) + if (!s->culled) + { + if (!bound) //only bind once we are sure we need this texture + { + GL_Bind (t->gltexture); + bound = true; + } + DrawGLPoly (s->polys); + rs_brushpasses++; + } + } +} + +/* +================ +R_DrawTextureChains_TextureOnly -- johnfitz +================ +*/ +void R_DrawTextureChains_TextureOnly (qmodel_t *model, entity_t *ent, texchain_t chain) +{ + int i; + msurface_t *s; + texture_t *t; + qboolean bound; + + for (i=0 ; inumtextures ; i++) + { + t = model->textures[i]; + + if (!t || !t->texturechains[chain] || t->texturechains[chain]->flags & (SURF_DRAWTURB | SURF_DRAWSKY)) + continue; + + bound = false; + + for (s = t->texturechains[chain]; s; s = s->texturechain) + if (!s->culled) + { + if (!bound) //only bind once we are sure we need this texture + { + GL_Bind ((R_TextureAnimation(t, ent != NULL ? ent->frame : 0))->gltexture); + + if (t->texturechains[chain]->flags & SURF_DRAWFENCE) + glEnable (GL_ALPHA_TEST); // Flip alpha test back on + + bound = true; + } + DrawGLPoly (s->polys); + rs_brushpasses++; + } + + if (bound && t->texturechains[chain]->flags & SURF_DRAWFENCE) + glDisable (GL_ALPHA_TEST); // Flip alpha test back off + } +} + +/* +================ +GL_WaterAlphaForEntitySurface -- ericw + +Returns the water alpha to use for the entity and surface combination. +================ +*/ +float GL_WaterAlphaForEntitySurface (entity_t *ent, msurface_t *s) +{ + float entalpha; + if (ent == NULL || ent->alpha == ENTALPHA_DEFAULT) + entalpha = GL_WaterAlphaForSurface(s); + else + entalpha = ENTALPHA_DECODE(ent->alpha); + return entalpha; +} + +/* +================ +R_DrawTextureChains_Water -- johnfitz +================ +*/ +void R_DrawTextureChains_Water (qmodel_t *model, entity_t *ent, texchain_t chain) +{ + int i; + msurface_t *s; + texture_t *t; + glpoly_t *p; + qboolean bound; + float entalpha; + + if (r_drawflat_cheatsafe || r_lightmap_cheatsafe) // ericw -- !r_drawworld_cheatsafe check moved to R_DrawWorld_Water () + return; + + if (r_oldwater.value) + { + for (i=0 ; inumtextures ; i++) + { + t = model->textures[i]; + if (!t || !t->texturechains[chain] || !(t->texturechains[chain]->flags & SURF_DRAWTURB)) + continue; + bound = false; + entalpha = 1.0f; + for (s = t->texturechains[chain]; s; s = s->texturechain) + if (!s->culled) + { + if (!bound) //only bind once we are sure we need this texture + { + entalpha = GL_WaterAlphaForEntitySurface (ent, s); + R_BeginTransparentDrawing (entalpha); + GL_Bind (t->gltexture); + bound = true; + } + for (p = s->polys->next; p; p = p->next) + { + DrawWaterPoly (p); + rs_brushpasses++; + } + } + R_EndTransparentDrawing (entalpha); + } + } + else + { + for (i=0 ; inumtextures ; i++) + { + t = model->textures[i]; + if (!t || !t->texturechains[chain] || !(t->texturechains[chain]->flags & SURF_DRAWTURB)) + continue; + bound = false; + entalpha = 1.0f; + for (s = t->texturechains[chain]; s; s = s->texturechain) + if (!s->culled) + { + if (!bound) //only bind once we are sure we need this texture + { + entalpha = GL_WaterAlphaForEntitySurface (ent, s); + R_BeginTransparentDrawing (entalpha); + GL_Bind (t->warpimage); + + if (model != cl.worldmodel) + { + // ericw -- this is copied from R_DrawSequentialPoly. + // If the poly is not part of the world we have to + // set this flag + t->update_warp = true; // FIXME: one frame too late! + } + + bound = true; + } + DrawGLPoly (s->polys); + rs_brushpasses++; + } + R_EndTransparentDrawing (entalpha); + } + } +} + +/* +================ +R_DrawTextureChains_White -- johnfitz -- draw sky and water as white polys when r_lightmap is 1 +================ +*/ +void R_DrawTextureChains_White (qmodel_t *model, texchain_t chain) +{ + int i; + msurface_t *s; + texture_t *t; + + glDisable (GL_TEXTURE_2D); + for (i=0 ; inumtextures ; i++) + { + t = model->textures[i]; + + if (!t || !t->texturechains[chain] || !(t->texturechains[chain]->flags & SURF_DRAWTILED)) + continue; + + for (s = t->texturechains[chain]; s; s = s->texturechain) + if (!s->culled) + { + DrawGLPoly (s->polys); + rs_brushpasses++; + } + } + glEnable (GL_TEXTURE_2D); +} + +/* +================ +R_DrawLightmapChains -- johnfitz -- R_BlendLightmaps stripped down to almost nothing +================ +*/ +void R_DrawLightmapChains (void) +{ + int i, j; + glpoly_t *p; + float *v; + + for (i=0 ; ichain) + { + glBegin (GL_POLYGON); + v = p->verts[0]; + for (j=0 ; jnumverts ; j++, v+= VERTEXSIZE) + { + glTexCoord2f (v[5], v[6]); + glVertex3fv (v); + } + glEnd (); + rs_brushpasses++; + } + } +} + +static GLuint r_world_program; + +// uniforms used in vert shader + +// uniforms used in frag shader +static GLuint texLoc; +static GLuint LMTexLoc; +static GLuint fullbrightTexLoc; +static GLuint useFullbrightTexLoc; +static GLuint useOverbrightLoc; +static GLuint useAlphaTestLoc; +static GLuint alphaLoc; + +#define vertAttrIndex 0 +#define texCoordsAttrIndex 1 +#define LMCoordsAttrIndex 2 + +/* +============= +GLWorld_CreateShaders +============= +*/ +void GLWorld_CreateShaders (void) +{ + const glsl_attrib_binding_t bindings[] = { + { "Vert", vertAttrIndex }, + { "TexCoords", texCoordsAttrIndex }, + { "LMCoords", LMCoordsAttrIndex } + }; + + const GLchar *vertSource = \ + "#version 110\n" + "\n" + "attribute vec3 Vert;\n" + "attribute vec2 TexCoords;\n" + "attribute vec2 LMCoords;\n" + "\n" + "varying float FogFragCoord;\n" + "\n" + "void main()\n" + "{\n" + " gl_TexCoord[0] = vec4(TexCoords, 0.0, 0.0);\n" + " gl_TexCoord[1] = vec4(LMCoords, 0.0, 0.0);\n" + " gl_Position = gl_ModelViewProjectionMatrix * vec4(Vert, 1.0);\n" + " FogFragCoord = gl_Position.w;\n" + "}\n"; + + const GLchar *fragSource = \ + "#version 110\n" + "\n" + "uniform sampler2D Tex;\n" + "uniform sampler2D LMTex;\n" + "uniform sampler2D FullbrightTex;\n" + "uniform bool UseFullbrightTex;\n" + "uniform bool UseOverbright;\n" + "uniform bool UseAlphaTest;\n" + "uniform float Alpha;\n" + "\n" + "varying float FogFragCoord;\n" + "\n" + "void main()\n" + "{\n" + " vec4 result = texture2D(Tex, gl_TexCoord[0].xy);\n" + " if (UseAlphaTest && (result.a < 0.666))\n" + " discard;\n" + " result *= texture2D(LMTex, gl_TexCoord[1].xy);\n" + " if (UseOverbright)\n" + " result.rgb *= 2.0;\n" + " if (UseFullbrightTex)\n" + " result += texture2D(FullbrightTex, gl_TexCoord[0].xy);\n" + " result = clamp(result, 0.0, 1.0);\n" + " float fog = exp(-gl_Fog.density * gl_Fog.density * FogFragCoord * FogFragCoord);\n" + " fog = clamp(fog, 0.0, 1.0);\n" + " result = mix(gl_Fog.color, result, fog);\n" + " result.a = Alpha;\n" // FIXME: This will make almost transparent things cut holes though heavy fog + " gl_FragColor = result;\n" + "}\n"; + + if (!gl_glsl_alias_able) + return; + + r_world_program = GL_CreateProgram (vertSource, fragSource, sizeof(bindings)/sizeof(bindings[0]), bindings); + + if (r_world_program != 0) + { + // get uniform locations + texLoc = GL_GetUniformLocation (&r_world_program, "Tex"); + LMTexLoc = GL_GetUniformLocation (&r_world_program, "LMTex"); + fullbrightTexLoc = GL_GetUniformLocation (&r_world_program, "FullbrightTex"); + useFullbrightTexLoc = GL_GetUniformLocation (&r_world_program, "UseFullbrightTex"); + useOverbrightLoc = GL_GetUniformLocation (&r_world_program, "UseOverbright"); + useAlphaTestLoc = GL_GetUniformLocation (&r_world_program, "UseAlphaTest"); + alphaLoc = GL_GetUniformLocation (&r_world_program, "Alpha"); + } +} + +extern GLuint gl_bmodel_vbo; + +/* +================ +R_DrawTextureChains_GLSL -- ericw + +Draw lightmapped surfaces with fulbrights in one pass, using VBO. +Requires 3 TMUs, OpenGL 2.0 +================ +*/ +void R_DrawTextureChains_GLSL (qmodel_t *model, entity_t *ent, texchain_t chain) +{ + int i; + msurface_t *s; + texture_t *t; + qboolean bound; + int lastlightmap; + gltexture_t *fullbright = NULL; + float entalpha; + + entalpha = (ent != NULL) ? ENTALPHA_DECODE(ent->alpha) : 1.0f; + +// enable blending / disable depth writes + if (entalpha < 1) + { + glDepthMask (GL_FALSE); + glEnable (GL_BLEND); + } + + GL_UseProgramFunc (r_world_program); + +// Bind the buffers + GL_BindBuffer (GL_ARRAY_BUFFER, gl_bmodel_vbo); + GL_BindBuffer (GL_ELEMENT_ARRAY_BUFFER, 0); // indices come from client memory! + + GL_EnableVertexAttribArrayFunc (vertAttrIndex); + GL_EnableVertexAttribArrayFunc (texCoordsAttrIndex); + GL_EnableVertexAttribArrayFunc (LMCoordsAttrIndex); + + GL_VertexAttribPointerFunc (vertAttrIndex, 3, GL_FLOAT, GL_FALSE, VERTEXSIZE * sizeof(float), ((float *)0)); + GL_VertexAttribPointerFunc (texCoordsAttrIndex, 2, GL_FLOAT, GL_FALSE, VERTEXSIZE * sizeof(float), ((float *)0) + 3); + GL_VertexAttribPointerFunc (LMCoordsAttrIndex, 2, GL_FLOAT, GL_FALSE, VERTEXSIZE * sizeof(float), ((float *)0) + 5); + +// set uniforms + GL_Uniform1iFunc (texLoc, 0); + GL_Uniform1iFunc (LMTexLoc, 1); + GL_Uniform1iFunc (fullbrightTexLoc, 2); + GL_Uniform1iFunc (useFullbrightTexLoc, 0); + GL_Uniform1iFunc (useOverbrightLoc, (int)gl_overbright.value); + GL_Uniform1iFunc (useAlphaTestLoc, 0); + GL_Uniform1fFunc (alphaLoc, entalpha); + + for (i=0 ; inumtextures ; i++) + { + t = model->textures[i]; + + if (!t || !t->texturechains[chain] || t->texturechains[chain]->flags & (SURF_DRAWTILED | SURF_NOTEXTURE)) + continue; + + // Enable/disable TMU 2 (fullbrights) + // FIXME: Move below to where we bind GL_TEXTURE0 + if (gl_fullbrights.value && (fullbright = R_TextureAnimation(t, ent != NULL ? ent->frame : 0)->fullbright)) + { + GL_SelectTexture (GL_TEXTURE2); + GL_Bind (fullbright); + GL_Uniform1iFunc (useFullbrightTexLoc, 1); + } + else + GL_Uniform1iFunc (useFullbrightTexLoc, 0); + + R_ClearBatch (); + + bound = false; + lastlightmap = 0; // avoid compiler warning + for (s = t->texturechains[chain]; s; s = s->texturechain) + if (!s->culled) + { + if (!bound) //only bind once we are sure we need this texture + { + GL_SelectTexture (GL_TEXTURE0); + GL_Bind ((R_TextureAnimation(t, ent != NULL ? ent->frame : 0))->gltexture); + + if (t->texturechains[chain]->flags & SURF_DRAWFENCE) + GL_Uniform1iFunc (useAlphaTestLoc, 1); // Flip alpha test back on + + bound = true; + lastlightmap = s->lightmaptexturenum; + } + + if (s->lightmaptexturenum != lastlightmap) + R_FlushBatch (); + + GL_SelectTexture (GL_TEXTURE1); + GL_Bind (lightmap[s->lightmaptexturenum].texture); + lastlightmap = s->lightmaptexturenum; + R_BatchSurface (s); + + rs_brushpasses++; + } + + R_FlushBatch (); + + if (bound && t->texturechains[chain]->flags & SURF_DRAWFENCE) + GL_Uniform1iFunc (useAlphaTestLoc, 0); // Flip alpha test back off + } + + // clean up + GL_DisableVertexAttribArrayFunc (vertAttrIndex); + GL_DisableVertexAttribArrayFunc (texCoordsAttrIndex); + GL_DisableVertexAttribArrayFunc (LMCoordsAttrIndex); + + GL_UseProgramFunc (0); + GL_SelectTexture (GL_TEXTURE0); + + if (entalpha < 1) + { + glDepthMask (GL_TRUE); + glDisable (GL_BLEND); + } +} + +/* +============= +R_DrawWorld -- johnfitz -- rewritten +============= +*/ +void R_DrawTextureChains (qmodel_t *model, entity_t *ent, texchain_t chain) +{ + float entalpha; + + if (ent != NULL) + entalpha = ENTALPHA_DECODE(ent->alpha); + else + entalpha = 1; + +// ericw -- the mh dynamic lightmap speedup: make a first pass through all +// surfaces we are going to draw, and rebuild any lightmaps that need it. +// this also chains surfaces by lightmap which is used by r_lightmap 1. +// the previous implementation of the speedup uploaded lightmaps one frame +// late which was visible under some conditions, this method avoids that. + R_BuildLightmapChains (model, chain); + R_UploadLightmaps (); + + if (r_drawflat_cheatsafe) + { + glDisable (GL_TEXTURE_2D); + R_DrawTextureChains_Drawflat (model, chain); + glEnable (GL_TEXTURE_2D); + return; + } + + if (r_fullbright_cheatsafe) + { + R_BeginTransparentDrawing (entalpha); + R_DrawTextureChains_TextureOnly (model, ent, chain); + R_EndTransparentDrawing (entalpha); + goto fullbrights; + } + + if (r_lightmap_cheatsafe) + { + if (!gl_overbright.value) + { + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + glColor3f(0.5, 0.5, 0.5); + } + R_DrawLightmapChains (); + if (!gl_overbright.value) + { + glColor3f(1,1,1); + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); + } + R_DrawTextureChains_White (model, chain); + return; + } + + R_BeginTransparentDrawing (entalpha); + + R_DrawTextureChains_NoTexture (model, chain); + + // OpenGL 2 fast path + if (r_world_program != 0) + { + R_EndTransparentDrawing (entalpha); + + R_DrawTextureChains_GLSL (model, ent, chain); + return; + } + + if (gl_overbright.value) + { + if (gl_texture_env_combine && gl_mtexable) //case 1: texture and lightmap in one pass, overbright using texture combiners + { + GL_EnableMultitexture (); + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT); + glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_MODULATE); + glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_PREVIOUS_EXT); + glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, GL_TEXTURE); + glTexEnvf(GL_TEXTURE_ENV, GL_RGB_SCALE_EXT, 2.0f); + GL_DisableMultitexture (); + R_DrawTextureChains_Multitexture (model, ent, chain); + GL_EnableMultitexture (); + glTexEnvf(GL_TEXTURE_ENV, GL_RGB_SCALE_EXT, 1.0f); + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + GL_DisableMultitexture (); + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); + } + else if (entalpha < 1) //case 2: can't do multipass if entity has alpha, so just draw the texture + { + R_DrawTextureChains_TextureOnly (model, ent, chain); + } + else //case 3: texture in one pass, lightmap in second pass using 2x modulation blend func, fog in third pass + { + //to make fog work with multipass lightmapping, need to do one pass + //with no fog, one modulate pass with black fog, and one additive + //pass with black geometry and normal fog + Fog_DisableGFog (); + R_DrawTextureChains_TextureOnly (model, ent, chain); + Fog_EnableGFog (); + glDepthMask (GL_FALSE); + glEnable (GL_BLEND); + glBlendFunc (GL_DST_COLOR, GL_SRC_COLOR); //2x modulate + Fog_StartAdditive (); + R_DrawLightmapChains (); + Fog_StopAdditive (); + if (Fog_GetDensity() > 0) + { + glBlendFunc(GL_ONE, GL_ONE); //add + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + glColor3f(0,0,0); + R_DrawTextureChains_TextureOnly (model, ent, chain); + glColor3f(1,1,1); + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); + } + glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glDisable (GL_BLEND); + glDepthMask (GL_TRUE); + } + } + else + { + if (gl_mtexable) //case 4: texture and lightmap in one pass, regular modulation + { + GL_EnableMultitexture (); + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + GL_DisableMultitexture (); + R_DrawTextureChains_Multitexture (model, ent, chain); + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); + } + else if (entalpha < 1) //case 5: can't do multipass if entity has alpha, so just draw the texture + { + R_DrawTextureChains_TextureOnly (model, ent, chain); + } + else //case 6: texture in one pass, lightmap in a second pass, fog in third pass + { + //to make fog work with multipass lightmapping, need to do one pass + //with no fog, one modulate pass with black fog, and one additive + //pass with black geometry and normal fog + Fog_DisableGFog (); + R_DrawTextureChains_TextureOnly (model, ent, chain); + Fog_EnableGFog (); + glDepthMask (GL_FALSE); + glEnable (GL_BLEND); + glBlendFunc(GL_ZERO, GL_SRC_COLOR); //modulate + Fog_StartAdditive (); + R_DrawLightmapChains (); + Fog_StopAdditive (); + if (Fog_GetDensity() > 0) + { + glBlendFunc(GL_ONE, GL_ONE); //add + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + glColor3f(0,0,0); + R_DrawTextureChains_TextureOnly (model, ent, chain); + glColor3f(1,1,1); + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); + } + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glDisable (GL_BLEND); + glDepthMask (GL_TRUE); + } + } + + R_EndTransparentDrawing (entalpha); + +fullbrights: + if (gl_fullbrights.value) + { + glDepthMask (GL_FALSE); + glEnable (GL_BLEND); + glBlendFunc (GL_ONE, GL_ONE); + glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + glColor3f (entalpha, entalpha, entalpha); + Fog_StartAdditive (); + R_DrawTextureChains_Glow (model, ent, chain); + Fog_StopAdditive (); + glColor3f (1, 1, 1); + glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); + glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glDisable (GL_BLEND); + glDepthMask (GL_TRUE); + } +} + +/* +============= +R_DrawWorld -- ericw -- moved from R_DrawTextureChains, which is no longer specific to the world. +============= +*/ +void R_DrawWorld (void) +{ + if (!r_drawworld_cheatsafe) + return; + + R_DrawTextureChains (cl.worldmodel, NULL, chain_world); +} + +/* +============= +R_DrawWorld_Water -- ericw -- moved from R_DrawTextureChains_Water, which is no longer specific to the world. +============= +*/ +void R_DrawWorld_Water (void) +{ + if (!r_drawworld_cheatsafe) + return; + + R_DrawTextureChains_Water (cl.worldmodel, NULL, chain_world); +} + +/* +============= +R_DrawWorld_ShowTris -- ericw -- moved from R_DrawTextureChains_ShowTris, which is no longer specific to the world. +============= +*/ +void R_DrawWorld_ShowTris (void) +{ + if (!r_drawworld_cheatsafe) + return; + + R_DrawTextureChains_ShowTris (cl.worldmodel, chain_world); +} diff --git a/engine/code/render.h b/engine/Quake/render.h similarity index 70% rename from engine/code/render.h rename to engine/Quake/render.h index f9fe1e2..4ecb973 100644 --- a/engine/code/render.h +++ b/engine/Quake/render.h @@ -1,5 +1,7 @@ /* -Copyright (C) 1996-1997 Id Software, Inc. +Copyright (C) 1996-2001 Id Software, Inc. +Copyright (C) 2002-2009 John Fitzgibbons and others +Copyright (C) 2010-2014 QuakeSpasm developers This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -8,7 +10,7 @@ of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. @@ -18,6 +20,9 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#ifndef _QUAKE_RENDER_H +#define _QUAKE_RENDER_H + // refresh.h -- public interface to refresh functions #define MAXCLIPPLANES 11 @@ -29,12 +34,17 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. typedef struct efrag_s { - struct mleaf_s *leaf; struct efrag_s *leafnext; struct entity_s *entity; - struct efrag_s *entnext; } efrag_t; +//johnfitz -- for lerping +#define LERP_MOVESTEP (1<<0) //this is a MOVETYPE_STEP entity, enable movement lerp +#define LERP_RESETANIM (1<<1) //disable anim lerping until next anim frame +#define LERP_RESETANIM2 (1<<2) //set this and previous flag to disable anim lerping for two anim frames +#define LERP_RESETMOVE (1<<3) //disable movement lerping until next origin/angles change +#define LERP_FINISH (1<<4) //use lerpfinish time from server update instead of assuming interval of 0.1 +//johnfitz typedef struct entity_s { @@ -45,28 +55,42 @@ typedef struct entity_s entity_state_t baseline; // to fill in defaults in updates double msgtime; // time of last update - vec3_t msg_origins[2]; // last two updates (0 is newest) + vec3_t msg_origins[2]; // last two updates (0 is newest) vec3_t origin; vec3_t msg_angles[2]; // last two updates (0 is newest) - vec3_t angles; - struct model_s *model; // NULL = no model + vec3_t angles; + struct qmodel_s *model; // NULL = no model struct efrag_s *efrag; // linked list of efrags int frame; float syncbase; // for client-side animations byte *colormap; - int effects; // light, particals, etc + int effects; // light, particles, etc int skinnum; // for Alias models int visframe; // last frame this entity was // found in an active leaf - + int dlightframe; // dynamic lighting int dlightbits; - + // FIXME: could turn these into a union int trivial_accept; struct mnode_s *topnode; // for bmodels, first world node // that splits bmodel, or NULL if // not split + + byte alpha; //johnfitz -- alpha + byte lerpflags; //johnfitz -- lerping + float lerpstart; //johnfitz -- animation lerping + float lerptime; //johnfitz -- animation lerping + float lerpfinish; //johnfitz -- lerping -- server sent us a more accurate interval, use it instead of 0.1 + short previouspose; //johnfitz -- animation lerping + short currentpose; //johnfitz -- animation lerping +// short futurepose; //johnfitz -- animation lerping + float movelerpstart; //johnfitz -- transform lerping + vec3_t previousorigin; //johnfitz -- transform lerping + vec3_t currentorigin; //johnfitz -- transform lerping + vec3_t previousangles; //johnfitz -- transform lerping + vec3_t currentangles; //johnfitz -- transform lerping } entity_t; // !!! if this is changed, it must be changed in asm_draw.h too !!! @@ -87,14 +111,14 @@ typedef struct // right and bottom edges, for clamping float fvrectright; // rightmost edge, for Alias clamping float fvrectbottom; // bottommost edge, for Alias clamping - float horizontalFieldOfView; // at Z = 1.0, this many X is visible + float horizontalFieldOfView; // at Z = 1.0, this many X is visible // 2.0 = 90 degrees float xOrigin; // should probably allways be 0.5 float yOrigin; // between be around 0.3 to 0.5 vec3_t vieworg; vec3_t viewangles; - + float fov_x, fov_y; int ambientlight; @@ -110,8 +134,6 @@ extern int reinit_surfcache; extern refdef_t r_refdef; extern vec3_t r_origin, vpn, vright, vup; -extern struct texture_s *r_notexture_mip; - void R_Init (void); void R_InitTextures (void); @@ -119,14 +141,10 @@ void R_InitEfrags (void); void R_RenderView (void); // must set r_refdef first void R_ViewChanged (vrect_t *pvrect, int lineadj, float aspect); // called whenever r_refdef or vid change -void R_InitSky (struct texture_s *mt); // called at level load - -// jkrige - 2D polyblend -void R_PolyBlend (void); -// jkrige - 2D polyblend +//void R_InitSky (struct texture_s *mt); // called at level load +void R_CheckEfrags (void); //johnfitz void R_AddEfrags (entity_t *ent); -void R_RemoveEfrags (entity_t *ent); void R_NewMap (void); @@ -134,10 +152,6 @@ void R_NewMap (void); void R_ParseParticleEffect (void); void R_RunParticleEffect (vec3_t org, vec3_t dir, int color, int count); void R_RocketTrail (vec3_t start, vec3_t end, int type); - -#ifdef QUAKE2 -void R_DarkFieldParticles (entity_t *ent); -#endif void R_EntityParticles (entity_t *ent); void R_BlobExplosion (vec3_t org); void R_ParticleExplosion (vec3_t org); @@ -160,3 +174,5 @@ void D_DeleteSurfaceCache (void); void D_InitCaches (void *buffer, int size); void R_SetVrect (vrect_t *pvrect, vrect_t *pvrectin, int lineadj); +#endif /* _QUAKE_RENDER_H */ + diff --git a/engine/code/resource.h b/engine/Quake/resource.h similarity index 55% rename from engine/code/resource.h rename to engine/Quake/resource.h index 4406ad3..d31f0fa 100644 --- a/engine/code/resource.h +++ b/engine/Quake/resource.h @@ -1,19 +1,26 @@ +#ifndef _QUAKE_RESOURCE_H +#define _QUAKE_RESOURCE_H + //{{NO_DEPENDENCIES}} -// Microsoft Visual C++ generated include file. +// Microsoft Developer Studio generated include file. // Used by winquake.rc // +#define IDS_STRING1 1 #define IDI_ICON2 1 #define IDD_DIALOG1 108 -#define IDB_BITMAP1 111 -#define IDB_QUAKE1 111 +#define IDD_PROGRESS 109 +#define IDC_PROGRESS 1000 // Next default values for new objects // #ifdef APSTUDIO_INVOKED #ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_NEXT_RESOURCE_VALUE 112 +#define _APS_NEXT_RESOURCE_VALUE 113 #define _APS_NEXT_COMMAND_VALUE 40001 #define _APS_NEXT_CONTROL_VALUE 1004 #define _APS_NEXT_SYMED_VALUE 101 #endif #endif + +#endif /* _QUAKE_RESOURCE_H */ + diff --git a/engine/code/sbar.c b/engine/Quake/sbar.c similarity index 51% rename from engine/code/sbar.c rename to engine/Quake/sbar.c index c1f3995..9c68780 100644 --- a/engine/code/sbar.c +++ b/engine/Quake/sbar.c @@ -1,5 +1,7 @@ /* -Copyright (C) 1996-1997 Id Software, Inc. +Copyright (C) 1996-2001 Id Software, Inc. +Copyright (C) 2002-2009 John Fitzgibbons and others +Copyright (C) 2010-2014 QuakeSpasm developers This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -8,7 +10,7 @@ of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. @@ -21,50 +23,45 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "quakedef.h" -#ifdef _WIN32 -#include "winquake.h" -#endif - -// jkrige - always draw sbar -//int sb_updates; // if >= vid.numpages, no update needed -// jkrige - always draw sbar +int sb_updates; // if >= vid.numpages, no update needed #define STAT_MINUS 10 // num frame for '-' stats digit + qpic_t *sb_nums[2][11]; qpic_t *sb_colon, *sb_slash; qpic_t *sb_ibar; qpic_t *sb_sbar; qpic_t *sb_scorebar; -qpic_t *sb_weapons[7][8]; // 0 is active, 1 is owned, 2-5 are flashes -qpic_t *sb_ammo[4]; +qpic_t *sb_weapons[7][8]; // 0 is active, 1 is owned, 2-5 are flashes +qpic_t *sb_ammo[4]; qpic_t *sb_sigil[4]; qpic_t *sb_armor[3]; qpic_t *sb_items[32]; -qpic_t *sb_faces[7][2]; // 0 is gibbed, 1 is dead, 2-6 are alive +qpic_t *sb_faces[7][2]; // 0 is gibbed, 1 is dead, 2-6 are alive // 0 is static, 1 is temporary animation -qpic_t *sb_face_invis; -qpic_t *sb_face_quad; -qpic_t *sb_face_invuln; -qpic_t *sb_face_invis_invuln; +qpic_t *sb_face_invis; +qpic_t *sb_face_quad; +qpic_t *sb_face_invuln; +qpic_t *sb_face_invis_invuln; qboolean sb_showscores; -int sb_lines; // scan lines to draw +int sb_lines; // scan lines to draw -qpic_t *rsb_invbar[2]; -qpic_t *rsb_weapons[5]; -qpic_t *rsb_items[2]; -qpic_t *rsb_ammo[3]; -qpic_t *rsb_teambord; // PGM 01/19/97 - team color border +qpic_t *rsb_invbar[2]; +qpic_t *rsb_weapons[5]; +qpic_t *rsb_items[2]; +qpic_t *rsb_ammo[3]; +qpic_t *rsb_teambord; // PGM 01/19/97 - team color border //MED 01/04/97 added two more weapons + 3 alternates for grenade launcher -qpic_t *hsb_weapons[7][5]; // 0 is active, 1 is owned, 2-5 are flashes +qpic_t *hsb_weapons[7][5]; // 0 is active, 1 is owned, 2-5 are flashes //MED 01/04/97 added array to simplify weapon parsing -int hipweapons[4] = {HIT_LASER_CANNON_BIT,HIT_MJOLNIR_BIT,4,HIT_PROXIMITY_GUN_BIT}; +int hipweapons[4] = {HIT_LASER_CANNON_BIT,HIT_MJOLNIR_BIT,4,HIT_PROXIMITY_GUN_BIT}; //MED 01/04/97 added hipnotic items array -qpic_t *hsb_items[2]; +qpic_t *hsb_items[2]; void Sbar_MiniDeathmatchOverlay (void); void Sbar_DeathmatchOverlay (void); @@ -82,7 +79,7 @@ void Sbar_ShowScores (void) if (sb_showscores) return; sb_showscores = true; - //sb_updates = 0; // jkrige - always draw sbar + sb_updates = 0; } /* @@ -95,7 +92,7 @@ Tab key up void Sbar_DontShowScores (void) { sb_showscores = false; - //sb_updates = 0; // jkrige - always draw sbar + sb_updates = 0; } /* @@ -103,23 +100,21 @@ void Sbar_DontShowScores (void) Sbar_Changed =============== */ -// jkrige - always draw sbar -/*void Sbar_Changed (void) +void Sbar_Changed (void) { sb_updates = 0; // update next frame -}*/ -// jkrige - always draw sbar +} /* =============== -Sbar_Init +Sbar_LoadPics -- johnfitz -- load all the sbar pics =============== */ -void Sbar_Init (void) +void Sbar_LoadPics (void) { int i; - for (i=0 ; i<10 ; i++) + for (i = 0; i < 10; i++) { sb_nums[0][i] = Draw_PicFromWad (va("num_%i",i)); sb_nums[1][i] = Draw_PicFromWad (va("anum_%i",i)); @@ -147,7 +142,7 @@ void Sbar_Init (void) sb_weapons[1][5] = Draw_PicFromWad ("inv2_srlaunch"); sb_weapons[1][6] = Draw_PicFromWad ("inv2_lightng"); - for (i=0 ; i<5 ; i++) + for (i = 0; i < 5; i++) { sb_weapons[2+i][0] = Draw_PicFromWad (va("inva%i_shotgun",i+1)); sb_weapons[2+i][1] = Draw_PicFromWad (va("inva%i_sshotgun",i+1)); @@ -195,9 +190,6 @@ void Sbar_Init (void) sb_face_invis_invuln = Draw_PicFromWad ("face_inv2"); sb_face_quad = Draw_PicFromWad ("face_quad"); - Cmd_AddCommand ("+showscores", Sbar_ShowScores); - Cmd_AddCommand ("-showscores", Sbar_DontShowScores); - sb_sbar = Draw_PicFromWad ("sbar"); sb_ibar = Draw_PicFromWad ("ibar"); sb_scorebar = Draw_PicFromWad ("scorebar"); @@ -205,29 +197,29 @@ void Sbar_Init (void) //MED 01/04/97 added new hipnotic weapons if (hipnotic) { - hsb_weapons[0][0] = Draw_PicFromWad ("inv_laser"); - hsb_weapons[0][1] = Draw_PicFromWad ("inv_mjolnir"); - hsb_weapons[0][2] = Draw_PicFromWad ("inv_gren_prox"); - hsb_weapons[0][3] = Draw_PicFromWad ("inv_prox_gren"); - hsb_weapons[0][4] = Draw_PicFromWad ("inv_prox"); - - hsb_weapons[1][0] = Draw_PicFromWad ("inv2_laser"); - hsb_weapons[1][1] = Draw_PicFromWad ("inv2_mjolnir"); - hsb_weapons[1][2] = Draw_PicFromWad ("inv2_gren_prox"); - hsb_weapons[1][3] = Draw_PicFromWad ("inv2_prox_gren"); - hsb_weapons[1][4] = Draw_PicFromWad ("inv2_prox"); - - for (i=0 ; i<5 ; i++) - { - hsb_weapons[2+i][0] = Draw_PicFromWad (va("inva%i_laser",i+1)); - hsb_weapons[2+i][1] = Draw_PicFromWad (va("inva%i_mjolnir",i+1)); - hsb_weapons[2+i][2] = Draw_PicFromWad (va("inva%i_gren_prox",i+1)); - hsb_weapons[2+i][3] = Draw_PicFromWad (va("inva%i_prox_gren",i+1)); - hsb_weapons[2+i][4] = Draw_PicFromWad (va("inva%i_prox",i+1)); - } - - hsb_items[0] = Draw_PicFromWad ("sb_wsuit"); - hsb_items[1] = Draw_PicFromWad ("sb_eshld"); + hsb_weapons[0][0] = Draw_PicFromWad ("inv_laser"); + hsb_weapons[0][1] = Draw_PicFromWad ("inv_mjolnir"); + hsb_weapons[0][2] = Draw_PicFromWad ("inv_gren_prox"); + hsb_weapons[0][3] = Draw_PicFromWad ("inv_prox_gren"); + hsb_weapons[0][4] = Draw_PicFromWad ("inv_prox"); + + hsb_weapons[1][0] = Draw_PicFromWad ("inv2_laser"); + hsb_weapons[1][1] = Draw_PicFromWad ("inv2_mjolnir"); + hsb_weapons[1][2] = Draw_PicFromWad ("inv2_gren_prox"); + hsb_weapons[1][3] = Draw_PicFromWad ("inv2_prox_gren"); + hsb_weapons[1][4] = Draw_PicFromWad ("inv2_prox"); + + for (i = 0; i < 5; i++) + { + hsb_weapons[2+i][0] = Draw_PicFromWad (va("inva%i_laser",i+1)); + hsb_weapons[2+i][1] = Draw_PicFromWad (va("inva%i_mjolnir",i+1)); + hsb_weapons[2+i][2] = Draw_PicFromWad (va("inva%i_gren_prox",i+1)); + hsb_weapons[2+i][3] = Draw_PicFromWad (va("inva%i_prox_gren",i+1)); + hsb_weapons[2+i][4] = Draw_PicFromWad (va("inva%i_prox",i+1)); + } + + hsb_items[0] = Draw_PicFromWad ("sb_wsuit"); + hsb_items[1] = Draw_PicFromWad ("sb_eshld"); } if (rogue) @@ -242,10 +234,10 @@ void Sbar_Init (void) rsb_weapons[4] = Draw_PicFromWad ("r_plasma"); rsb_items[0] = Draw_PicFromWad ("r_shield1"); - rsb_items[1] = Draw_PicFromWad ("r_agrav1"); + rsb_items[1] = Draw_PicFromWad ("r_agrav1"); // PGM 01/19/97 - team color border - rsb_teambord = Draw_PicFromWad ("r_teambord"); + rsb_teambord = Draw_PicFromWad ("r_teambord"); // PGM 01/19/97 - team color border rsb_ammo[0] = Draw_PicFromWad ("r_ammolava"); @@ -254,6 +246,19 @@ void Sbar_Init (void) } } +/* +=============== +Sbar_Init -- johnfitz -- rewritten +=============== +*/ +void Sbar_Init (void) +{ + Cmd_AddCommand ("+showscores", Sbar_ShowScores); + Cmd_AddCommand ("-showscores", Sbar_DontShowScores); + + Sbar_LoadPics (); +} + //============================================================================= @@ -261,56 +266,79 @@ void Sbar_Init (void) /* ============= -Sbar_DrawPic +Sbar_DrawPic -- johnfitz -- rewritten now that GL_SetCanvas is doing the work ============= */ void Sbar_DrawPic (int x, int y, qpic_t *pic) { - if (cl.gametype == GAME_DEATHMATCH) - Draw_Pic (x + ((vid.width - 320)>>1), y + (vid.height-SBAR_HEIGHT), pic); // jkrige - uncommented ((vid.width - 320)>>1) - else - Draw_Pic (x + ((vid.width - 320)>>1), y + (vid.height-SBAR_HEIGHT), pic); + Draw_Pic (x, y + 24, pic); } /* ============= -Sbar_DrawTransPic +Sbar_DrawPicAlpha -- johnfitz ============= */ -void Sbar_DrawTransPic (int x, int y, qpic_t *pic) +void Sbar_DrawPicAlpha (int x, int y, qpic_t *pic, float alpha) { - if (cl.gametype == GAME_DEATHMATCH) - Draw_TransPic (x + ((vid.width - 320)>>1), y + (vid.height-SBAR_HEIGHT), pic); // jkrige - uncommented ((vid.width - 320)>>1) - else - Draw_TransPic (x + ((vid.width - 320)>>1), y + (vid.height-SBAR_HEIGHT), pic); + glDisable (GL_ALPHA_TEST); + glEnable (GL_BLEND); + glColor4f(1,1,1,alpha); + Draw_Pic (x, y + 24, pic); + glColor4f(1,1,1,1); // ericw -- changed from glColor3f to work around intel 855 bug with "r_oldwater 0" and "scr_sbaralpha 0" + glDisable (GL_BLEND); + glEnable (GL_ALPHA_TEST); } /* ================ -Sbar_DrawCharacter - -Draws one solid graphics character +Sbar_DrawCharacter -- johnfitz -- rewritten now that GL_SetCanvas is doing the work ================ */ void Sbar_DrawCharacter (int x, int y, int num) { - if (cl.gametype == GAME_DEATHMATCH) - Draw_Character (x + ((vid.width - 320)>>1) + 4, y + vid.height-SBAR_HEIGHT, num); // jkrige - uncommented ((vid.width - 320)>>1) - else - Draw_Character (x + ((vid.width - 320)>>1) + 4, y + vid.height-SBAR_HEIGHT, num); + Draw_Character (x, y + 24, num); } /* ================ -Sbar_DrawString +Sbar_DrawString -- johnfitz -- rewritten now that GL_SetCanvas is doing the work ================ */ -void Sbar_DrawString (int x, int y, char *str) +void Sbar_DrawString (int x, int y, const char *str) { - if (cl.gametype == GAME_DEATHMATCH) - Draw_String (x + ((vid.width - 320)>>1), y + vid.height-SBAR_HEIGHT, str); // jkrige - uncommented ((vid.width - 320)>>1) - else - Draw_String (x + ((vid.width - 320)>>1), y + vid.height-SBAR_HEIGHT, str); + Draw_String (x, y + 24, str); +} + +/* +=============== +Sbar_DrawScrollString -- johnfitz + +scroll the string inside a glscissor region +=============== +*/ +void Sbar_DrawScrollString (int x, int y, int width, const char *str) +{ + float scale; + int len, ofs, left; + + scale = CLAMP (1.0, scr_sbarscale.value, (float)glwidth / 320.0); + left = x * scale; + if (cl.gametype != GAME_DEATHMATCH) + left += (((float)glwidth - 320.0 * scale) / 2); + + glEnable (GL_SCISSOR_TEST); + glScissor (left, 0, width * scale, glheight); + + len = strlen(str)*8 + 40; + ofs = ((int)(realtime*30))%len; + Sbar_DrawString (x - ofs, y, str); + Sbar_DrawCharacter (x - ofs + len - 32, y, '/'); + Sbar_DrawCharacter (x - ofs + len - 24, y, '/'); + Sbar_DrawCharacter (x - ofs + len - 16, y, '/'); + Sbar_DrawString (x - ofs + len, y, str); + + glDisable (GL_SCISSOR_TEST); } /* @@ -321,8 +349,8 @@ Sbar_itoa int Sbar_itoa (int num, char *buf) { char *str; - int pow10; - int dig; + int pow10; + int dig; str = buf; @@ -333,7 +361,7 @@ int Sbar_itoa (int num, char *buf) } for (pow10 = 10 ; num >= pow10 ; pow10 *= 10) - ; + ; do { @@ -356,9 +384,11 @@ Sbar_DrawNum */ void Sbar_DrawNum (int x, int y, int num, int digits, int color) { - char str[12]; - char *ptr; - int l, frame; + char str[12]; + char *ptr; + int l, frame; + + num = q_min(999,num); //johnfitz -- cap high values rather than truncating number l = Sbar_itoa (num, str); ptr = str; @@ -374,7 +404,7 @@ void Sbar_DrawNum (int x, int y, int num, int digits, int color) else frame = *ptr -'0'; - Sbar_DrawTransPic (x,y,sb_nums[color][frame]); + Sbar_DrawPic (x,y,sb_nums[color][frame]); //johnfitz -- DrawTransPic is obsolete x += 24; ptr++; } @@ -384,7 +414,7 @@ void Sbar_DrawNum (int x, int y, int num, int digits, int color) int fragsort[MAX_SCOREBOARD]; -char scoreboardtext[MAX_SCOREBOARD][20]; +char scoreboardtext[MAX_SCOREBOARD][20]; int scoreboardtop[MAX_SCOREBOARD]; int scoreboardbottom[MAX_SCOREBOARD]; int scoreboardcount[MAX_SCOREBOARD]; @@ -401,7 +431,7 @@ void Sbar_SortFrags (void) // sort by frags scoreboardlines = 0; - for (i=0 ; i 40) + Sbar_DrawScrollString (0, 4, 320, str); + else + Sbar_DrawString (160 - len*4, 4, str); + return; + } minutes = cl.time / 60; seconds = cl.time - 60*minutes; tens = seconds / 10; units = seconds - 10*tens; - sprintf (str,"Time :%3i:%i%i", minutes, tens, units); - Sbar_DrawString (184, 4, str); + sprintf (str,"%i:%i%i", minutes, tens, units); + Sbar_DrawString (160 - strlen(str)*4, 12, str); -// draw level name - l = strlen (cl.levelname); - Sbar_DrawString (232 - l*4, 12, cl.levelname); + len = strlen (cl.levelname); + if (len > 40) + Sbar_DrawScrollString (0, 4, 320, cl.levelname); + else + Sbar_DrawString (160 - len*4, 4, cl.levelname); } /* @@ -496,51 +542,6 @@ void Sbar_DrawScoreboard (void) Sbar_SoloScoreboard (); if (cl.gametype == GAME_DEATHMATCH) Sbar_DeathmatchOverlay (); -#if 0 - int i, j, c; - int x, y; - int l; - int top, bottom; - scoreboard_t *s; - - if (cl.gametype != GAME_DEATHMATCH) - { - Sbar_SoloScoreboard (); - return; - } - - Sbar_UpdateScoreboard (); - - l = scoreboardlines <= 6 ? scoreboardlines : 6; - - for (i=0 ; iname[0]) - continue; - - // draw background - top = s->colors & 0xf0; - bottom = (s->colors & 15)<<4; - top = Sbar_ColorForMap (top); - bottom = Sbar_ColorForMap (bottom); - - Draw_Fill ( x*8+10 + ((vid.width - 320)>>1), y + vid.height - SBAR_HEIGHT, 28, 4, top); - Draw_Fill ( x*8+10 + ((vid.width - 320)>>1), y+4 + vid.height - SBAR_HEIGHT, 28, 4, bottom); - - // draw text - for (j=0 ; j<20 ; j++) - { - c = scoreboardtext[i][j]; - if (c == 0 || c == ' ') - continue; - Sbar_DrawCharacter ( (x+j)*8, y, c); - } - } -#endif } //============================================================================= @@ -552,25 +553,25 @@ Sbar_DrawInventory */ void Sbar_DrawInventory (void) { - int i; + int i, val; char num[6]; float time; - int flashon; + int flashon; if (rogue) { if ( cl.stats[STAT_ACTIVEWEAPON] >= RIT_LAVA_NAILGUN ) - Sbar_DrawPic (0, -24, rsb_invbar[0]); + Sbar_DrawPicAlpha (0, -24, rsb_invbar[0], scr_sbaralpha.value); //johnfitz -- scr_sbaralpha else - Sbar_DrawPic (0, -24, rsb_invbar[1]); + Sbar_DrawPicAlpha (0, -24, rsb_invbar[1], scr_sbaralpha.value); //johnfitz -- scr_sbaralpha } else { - Sbar_DrawPic (0, -24, sb_ibar); + Sbar_DrawPicAlpha (0, -24, sb_ibar, scr_sbaralpha.value); //johnfitz -- scr_sbaralpha } // weapons - for (i=0 ; i<7 ; i++) + for (i = 0; i < 7; i++) { if (cl.items & (IT_SHOTGUN< 1) - // sb_updates = 0; // force update to remove flash - // jkrige - always draw sbar + if (flashon > 1) + sb_updates = 0; // force update to remove flash } } // MED 01/04/97 // hipnotic weapons - if (hipnotic) - { - int grenadeflashing=0; - for (i=0 ; i<4 ; i++) - { - if (cl.items & (1<= 10) - { - if ( cl.stats[STAT_ACTIVEWEAPON] == (1< 1) - // sb_updates = 0; // force update to remove flash - // jkrige - always draw sbar - } - } - } + if (hipnotic) + { + int grenadeflashing = 0; + for (i = 0; i < 4; i++) + { + if (cl.items & (1<= 10) + { + if (cl.stats[STAT_ACTIVEWEAPON] == (1< 1) + sb_updates = 0; // force update to remove flash + } + } + } if (rogue) { @@ -671,110 +668,102 @@ void Sbar_DrawInventory (void) } // ammo counts - for (i=0 ; i<4 ; i++) + for (i = 0; i < 4; i++) { - sprintf (num, "%3i",cl.stats[STAT_SHELLS+i] ); + val = cl.stats[STAT_SHELLS+i]; + val = (val < 0)? 0 : q_min(999,val);//johnfitz -- cap displayed value to 999 + sprintf (num, "%3i", val); if (num[0] != ' ') - Sbar_DrawCharacter ( (6*i+1)*8 - 2, -24, 18 + num[0] - '0'); + Sbar_DrawCharacter ( (6*i+1)*8 + 2, -24, 18 + num[0] - '0'); if (num[1] != ' ') - Sbar_DrawCharacter ( (6*i+2)*8 - 2, -24, 18 + num[1] - '0'); + Sbar_DrawCharacter ( (6*i+2)*8 + 2, -24, 18 + num[1] - '0'); if (num[2] != ' ') - Sbar_DrawCharacter ( (6*i+3)*8 - 2, -24, 18 + num[2] - '0'); + Sbar_DrawCharacter ( (6*i+3)*8 + 2, -24, 18 + num[2] - '0'); } flashon = 0; - // items - for (i=0 ; i<6 ; i++) - if (cl.items & (1<<(17+i))) - { - time = cl.item_gettime[17+i]; - if (time && time > cl.time - 2 && flashon ) - { // flash frame - //sb_updates = 0; // jkrige - always draw sbar - } - else - { - //MED 01/04/97 changed keys - if (!hipnotic || (i>1)) - { - Sbar_DrawPic (192 + i*16, -16, sb_items[i]); - } - } - - // jkrige - always draw sbar - //if (time && time > cl.time - 2) - // sb_updates = 0; - // jkrige - always draw sbar - - } - //MED 01/04/97 added hipnotic items - // hipnotic items - if (hipnotic) - { - for (i=0 ; i<2 ; i++) - if (cl.items & (1<<(24+i))) - { - time = cl.item_gettime[24+i]; - if (time && time > cl.time - 2 && flashon ) - { // flash frame - //sb_updates = 0; - } - else - { - Sbar_DrawPic (288 + i*16, -16, hsb_items[i]); - } - - // jkrige - always draw sbar - //if (time && time > cl.time - 2) - // sb_updates = 0; - // jkrige - always draw sbar - } - } + // items + for (i = 0; i < 6; i++) + { + if (cl.items & (1<<(17+i))) + { + time = cl.item_gettime[17+i]; + if (time && time > cl.time - 2 && flashon) + { // flash frame + sb_updates = 0; + } + else + { + //MED 01/04/97 changed keys + if (!hipnotic || (i > 1)) + { + Sbar_DrawPic (192 + i*16, -16, sb_items[i]); + } + } + if (time && time > cl.time - 2) + sb_updates = 0; + } + } + //MED 01/04/97 added hipnotic items + // hipnotic items + if (hipnotic) + { + for (i = 0; i < 2; i++) + { + if (cl.items & (1<<(24+i))) + { + time = cl.item_gettime[24+i]; + if (time && time > cl.time - 2 && flashon ) + { // flash frame + sb_updates = 0; + } + else + { + Sbar_DrawPic (288 + i*16, -16, hsb_items[i]); + } + if (time && time > cl.time - 2) + sb_updates = 0; + } + } + } if (rogue) { // new rogue items - for (i=0 ; i<2 ; i++) + for (i = 0; i < 2; i++) { if (cl.items & (1<<(29+i))) { time = cl.item_gettime[29+i]; - - if (time && time > cl.time - 2 && flashon ) + if (time && time > cl.time - 2 && flashon) { // flash frame - //sb_updates = 0; // jkrige - always draw sbar + sb_updates = 0; } else { Sbar_DrawPic (288 + i*16, -16, rsb_items[i]); } - - // jkrige - always draw sbar - //if (time && time > cl.time - 2) - // sb_updates = 0; - // jkrige - always draw sbar + if (time && time > cl.time - 2) + sb_updates = 0; } } } else { // sigils - for (i=0 ; i<4 ; i++) + for (i = 0; i < 4; i++) { if (cl.items & (1<<(28+i))) { time = cl.item_gettime[28+i]; - if (time && time > cl.time - 2 && flashon ) + if (time && time > cl.time - 2 && flashon) { // flash frame - //sb_updates = 0; // jkrige - always draw sbar + sb_updates = 0; } else Sbar_DrawPic (320-32 + i*8, -16, sb_sigil[i]); - - // jkrige - always draw sbar - //if (time && time > cl.time - 2) - // sb_updates = 0; - // jkrige - always draw sbar + if (time && time > cl.time - 2) + sb_updates = 0; } } } @@ -784,60 +773,48 @@ void Sbar_DrawInventory (void) /* =============== -Sbar_DrawFrags +Sbar_DrawFrags -- johnfitz -- heavy revision =============== */ void Sbar_DrawFrags (void) { - int i, k, l; - int top, bottom; - int x, y, f; - int xofs; - char num[12]; + int numscores, i, x, color; + char num[12]; scoreboard_t *s; Sbar_SortFrags (); // draw the text - l = scoreboardlines <= 4 ? scoreboardlines : 4; - - x = 23; - //if (cl.gametype == GAME_DEATHMATCH) // jkrige - uncommented ((vid.width - 320)>>1) - // xofs = 0; - //else - xofs = (vid.width - 320)>>1; - y = vid.height - SBAR_HEIGHT - 23; + numscores = q_min(scoreboardlines, 4); - for (i=0 ; iname[0]) continue; - // draw background - top = s->colors & 0xf0; - bottom = (s->colors & 15)<<4; - top = Sbar_ColorForMap (top); - bottom = Sbar_ColorForMap (bottom); - - Draw_Fill (xofs + x*8 + 10, y, 28, 4, top); - Draw_Fill (xofs + x*8 + 10, y+4, 28, 3, bottom); + // top color + color = s->colors & 0xf0; + color = Sbar_ColorForMap (color); + Draw_Fill (x + 10, 1, 28, 4, color, 1); - // draw number - f = s->frags; - sprintf (num, "%3i",f); + // bottom color + color = (s->colors & 15)<<4; + color = Sbar_ColorForMap (color); + Draw_Fill (x + 10, 5, 28, 3, color, 1); - Sbar_DrawCharacter ( (x+1)*8 , -24, num[0]); - Sbar_DrawCharacter ( (x+2)*8 , -24, num[1]); - Sbar_DrawCharacter ( (x+3)*8 , -24, num[2]); + // number + sprintf (num, "%3i", s->frags); + Sbar_DrawCharacter (x + 12, -24, num[0]); + Sbar_DrawCharacter (x + 20, -24, num[1]); + Sbar_DrawCharacter (x + 28, -24, num[2]); - if (k == cl.viewentity - 1) + // brackets + if (fragsort[i] == cl.viewentity - 1) { - Sbar_DrawCharacter (x*8+2, -24, 16); - Sbar_DrawCharacter ( (x+4)*8-4, -24, 17); + Sbar_DrawCharacter (x + 6, -24, 16); + Sbar_DrawCharacter (x + 32, -24, 17); } - x+=4; } } @@ -851,20 +828,17 @@ Sbar_DrawFace */ void Sbar_DrawFace (void) { - int f, anim; + int f, anim; // PGM 01/19/97 - team color drawing // PGM 03/02/97 - fixed so color swatch only appears in CTF modes - if (rogue && - (cl.maxclients != 1) && - (teamplay.value>3) && - (teamplay.value<7)) + if (rogue && (cl.maxclients != 1) && (teamplay.value>3) && (teamplay.value<7)) { - int top, bottom; - int xofs; - char num[12]; + int top, bottom; + int xofs; + char num[12]; scoreboard_t *s; - + s = &cl.scores[cl.viewentity - 1]; // draw background top = s->colors & 0xf0; @@ -872,41 +846,41 @@ void Sbar_DrawFace (void) top = Sbar_ColorForMap (top); bottom = Sbar_ColorForMap (bottom); - //if (cl.gametype == GAME_DEATHMATCH) // jkrige - uncommented ((vid.width - 320)>>1) - // xofs = 113; - //else + if (cl.gametype == GAME_DEATHMATCH) + xofs = 113; + else xofs = ((vid.width - 320)>>1) + 113; Sbar_DrawPic (112, 0, rsb_teambord); - Draw_Fill (xofs, vid.height-SBAR_HEIGHT+3, 22, 9, top); - Draw_Fill (xofs, vid.height-SBAR_HEIGHT+12, 22, 9, bottom); + Draw_Fill (xofs, /*vid.height-*/24+3, 22, 9, top, 1); //johnfitz -- sbar coords are now relative + Draw_Fill (xofs, /*vid.height-*/24+12, 22, 9, bottom, 1); //johnfitz -- sbar coords are now relative // draw number f = s->frags; sprintf (num, "%3i",f); - if (top==8) + if (top == 8) { if (num[0] != ' ') - Sbar_DrawCharacter(109, 3, 18 + num[0] - '0'); + Sbar_DrawCharacter(113, 3, 18 + num[0] - '0'); if (num[1] != ' ') - Sbar_DrawCharacter(116, 3, 18 + num[1] - '0'); + Sbar_DrawCharacter(120, 3, 18 + num[1] - '0'); if (num[2] != ' ') - Sbar_DrawCharacter(123, 3, 18 + num[2] - '0'); + Sbar_DrawCharacter(127, 3, 18 + num[2] - '0'); } else { - Sbar_DrawCharacter ( 109, 3, num[0]); - Sbar_DrawCharacter ( 116, 3, num[1]); - Sbar_DrawCharacter ( 123, 3, num[2]); + Sbar_DrawCharacter (113, 3, num[0]); + Sbar_DrawCharacter (120, 3, num[1]); + Sbar_DrawCharacter (127, 3, num[2]); } - + return; } // PGM 01/19/97 - team color drawing - if ( (cl.items & (IT_INVISIBILITY | IT_INVULNERABILITY) ) - == (IT_INVISIBILITY | IT_INVULNERABILITY) ) + if ((cl.items & (IT_INVISIBILITY | IT_INVULNERABILITY)) + == (IT_INVISIBILITY | IT_INVULNERABILITY)) { Sbar_DrawPic (112, 0, sb_face_invis_invuln); return; @@ -931,14 +905,13 @@ void Sbar_DrawFace (void) f = 4; else f = cl.stats[STAT_HEALTH] / 20; + if (f < 0) // in case we ever decide to draw when health <= 0 + f = 0; if (cl.time <= cl.faceanimtime) { anim = 1; - - // jkrige - always draw sbar - //sb_updates = 0; // make sure the anim gets drawn over - // jkrige - always draw sbar + sb_updates = 0; // make sure the anim gets drawn over } else anim = 0; @@ -952,26 +925,41 @@ Sbar_Draw */ void Sbar_Draw (void) { + float w; //johnfitz + if (scr_con_current == vid.height) return; // console is full screen - // jkrige - always draw sbar - //if (sb_updates >= vid.numpages) - // return; - // jkrige - always draw sbar + if (cl.intermission) + return; //johnfitz -- never draw sbar during intermission - scr_copyeverything = 1; + if (sb_updates >= vid.numpages && !gl_clear.value && scr_sbaralpha.value >= 1 //johnfitz -- gl_clear, scr_sbaralpha + && !(gl_glsl_gamma_able && vid_gamma.value != 1)) //ericw -- must draw sbar every frame if doing glsl gamma + return; - // jkrige - always draw sbar - //sb_updates++; - // jkrige - always draw sbar + sb_updates++; - // jkrige - scale2d - //if (sb_lines && vid.width > 320) - // Draw_TileClear (0, vid.height - sb_lines, vid.width, sb_lines); - // jkrige - scale2d + GL_SetCanvas (CANVAS_DEFAULT); //johnfitz - if (sb_lines > 24) + //johnfitz -- don't waste fillrate by clearing the area behind the sbar + w = CLAMP (320.0f, scr_sbarscale.value * 320.0f, (float)glwidth); + if (sb_lines && glwidth > w) + { + if (scr_sbaralpha.value < 1) + Draw_TileClear (0, glheight - sb_lines, glwidth, sb_lines); + if (cl.gametype == GAME_DEATHMATCH) + Draw_TileClear (w, glheight - sb_lines, glwidth - w, sb_lines); + else + { + Draw_TileClear (0, glheight - sb_lines, (glwidth - w) / 2.0f, sb_lines); + Draw_TileClear ((glwidth - w) / 2.0f + w, glheight - sb_lines, (glwidth - w) / 2.0f, sb_lines); + } + } + //johnfitz + + GL_SetCanvas (CANVAS_SBAR); //johnfitz + + if (scr_viewsize.value < 110) //johnfitz -- check viewsize instead of sb_lines { Sbar_DrawInventory (); if (cl.maxclients != 1) @@ -980,24 +968,24 @@ void Sbar_Draw (void) if (sb_showscores || cl.stats[STAT_HEALTH] <= 0) { - Sbar_DrawPic(0, 0, sb_scorebar); + Sbar_DrawPicAlpha (0, 0, sb_scorebar, scr_sbaralpha.value); //johnfitz -- scr_sbaralpha Sbar_DrawScoreboard (); - //sb_updates = 0; // jkrige - always draw sbar + sb_updates = 0; } - else if (sb_lines) + else if (scr_viewsize.value < 120) //johnfitz -- check viewsize instead of sb_lines { - Sbar_DrawPic(0, 0, sb_sbar); + Sbar_DrawPicAlpha (0, 0, sb_sbar, scr_sbaralpha.value); //johnfitz -- scr_sbaralpha // keys (hipnotic only) - //MED 01/04/97 moved keys here so they would not be overwritten - if (hipnotic) - { - if (cl.items & IT_KEY1) - Sbar_DrawPic (209, 3, sb_items[0]); - if (cl.items & IT_KEY2) - Sbar_DrawPic (209, 12, sb_items[1]); - } - // armor + //MED 01/04/97 moved keys here so they would not be overwritten + if (hipnotic) + { + if (cl.items & IT_KEY1) + Sbar_DrawPic (209, 3, sb_items[0]); + if (cl.items & IT_KEY2) + Sbar_DrawPic (209, 12, sb_items[1]); + } + // armor if (cl.items & IT_INVULNERABILITY) { Sbar_DrawNum (24, 0, 666, 3, 1); @@ -1070,11 +1058,9 @@ void Sbar_Draw (void) cl.stats[STAT_AMMO] <= 10); } - if (vid.width > 320) - { - if (cl.gametype == GAME_DEATHMATCH) + //johnfitz -- removed the vid.width > 320 check here + if (cl.gametype == GAME_DEATHMATCH) Sbar_MiniDeathmatchOverlay (); - } } //============================================================================= @@ -1087,9 +1073,9 @@ Sbar_IntermissionNumber */ void Sbar_IntermissionNumber (int x, int y, int num, int digits, int color) { - char str[12]; - char *ptr; - int l, frame; + char str[12]; + char *ptr; + int l, frame; l = Sbar_itoa (num, str); ptr = str; @@ -1105,7 +1091,7 @@ void Sbar_IntermissionNumber (int x, int y, int num, int digits, int color) else frame = *ptr -'0'; - Draw_TransPic (x,y,sb_nums[color][frame]); + Draw_Pic (x,y,sb_nums[color][frame]); //johnfitz -- stretched menus x += 24; ptr++; } @@ -1119,15 +1105,14 @@ Sbar_DeathmatchOverlay */ void Sbar_DeathmatchOverlay (void) { - qpic_t *pic; - int i, k, l; - int top, bottom; - int x, y, f; - char num[12]; + qpic_t *pic; + int i, k, l; + int top, bottom; + int x, y, f; + char num[12]; scoreboard_t *s; - scr_copyeverything = 1; - scr_fullupdate = 0; + GL_SetCanvas (CANVAS_MENU); //johnfitz pic = Draw_CachePic ("gfx/ranking.lmp"); M_DrawPic ((320-pic->width)/2, 8, pic); @@ -1138,9 +1123,9 @@ void Sbar_DeathmatchOverlay (void) // draw the text l = scoreboardlines; - x = 80 + ((vid.width - 320)>>1); + x = 80; //johnfitz -- simplified becuase some positioning is handled elsewhere y = 40; - for (i=0 ; ifrags; sprintf (num, "%3i",f); - Draw_Character ( x+8 , y, num[0]); - Draw_Character ( x+16 , y, num[1]); - Draw_Character ( x+24 , y, num[2]); + Draw_Character ( x+8 , y, num[0]); //johnfitz -- stretched overlays + Draw_Character ( x+16 , y, num[1]); //johnfitz -- stretched overlays + Draw_Character ( x+24 , y, num[2]); //johnfitz -- stretched overlays if (k == cl.viewentity - 1) - Draw_Character ( x - 8, y, 12); + Draw_Character ( x - 8, y, 12); //johnfitz -- stretched overlays #if 0 { @@ -1181,211 +1166,147 @@ void Sbar_DeathmatchOverlay (void) sprintf (num, "%3i:%i%i", minutes, tens, units); - Draw_String ( x+48 , y, num); + M_Print ( x+48 , y, num); //johnfitz -- was Draw_String, changed for stretched overlays } #endif // draw name - Draw_String (x+64, y, s->name); + M_Print (x+64, y, s->name); //johnfitz -- was Draw_String, changed for stretched overlays y += 10; } + + GL_SetCanvas (CANVAS_SBAR); //johnfitz } /* ================== -Sbar_DeathmatchOverlay - +Sbar_MiniDeathmatchOverlay ================== */ void Sbar_MiniDeathmatchOverlay (void) { - qpic_t *pic; - int i, k, l; - int top, bottom; - int x, y, f; - char num[12]; + int i, k, top, bottom, x, y, f, numlines; + char num[12]; + float scale; //johnfitz scoreboard_t *s; - int numlines; - if (vid.width < 512 || !sb_lines) - return; + scale = CLAMP (1.0, scr_sbarscale.value, (float)glwidth / 320.0); //johnfitz - scr_copyeverything = 1; - scr_fullupdate = 0; + //MAX_SCOREBOARDNAME = 32, so total width for this overlay plus sbar is 632, but we can cut off some i guess + if (glwidth/scale < 512 || scr_viewsize.value >= 120) //johnfitz -- test should consider scr_sbarscale + return; // scores Sbar_SortFrags (); // draw the text - l = scoreboardlines; - y = vid.height - sb_lines-16; // jkrige - viewsize & statusbar (added -16) - numlines = sb_lines/8; - if (numlines < 3) - return; + numlines = (scr_viewsize.value >= 110) ? 3 : 6; //johnfitz //find us for (i = 0; i < scoreboardlines; i++) if (fragsort[i] == cl.viewentity - 1) break; - - if (i == scoreboardlines) // we're not there - i = 0; - else // figure out start - i = i - numlines/2; - - if (i > scoreboardlines - numlines) - i = scoreboardlines - numlines; - if (i < 0) - i = 0; - - x = vid.width / 2; // jkrige - viewsize & statusbar (was 324) - for (/* */; i < scoreboardlines && y < vid.height - 8 ; i++) + if (i == scoreboardlines) // we're not there + i = 0; + else // figure out start + i = i - numlines/2; + if (i > scoreboardlines - numlines) + i = scoreboardlines - numlines; + if (i < 0) + i = 0; + + x = 324; + y = (scr_viewsize.value >= 110) ? 24 : 0; //johnfitz -- start at the right place + for ( ; i < scoreboardlines && y <= 48; i++, y+=8) //johnfitz -- change y init, test, inc { k = fragsort[i]; s = &cl.scores[k]; if (!s->name[0]) continue; - // draw background + // colors top = s->colors & 0xf0; bottom = (s->colors & 15)<<4; top = Sbar_ColorForMap (top); bottom = Sbar_ColorForMap (bottom); - Draw_Fill ( x, y+1, 40, 3, top); - Draw_Fill ( x, y+4, 40, 4, bottom); + Draw_Fill (x, y+1, 40, 4, top, 1); + Draw_Fill (x, y+5, 40, 3, bottom, 1); - // draw number + // number f = s->frags; sprintf (num, "%3i",f); + Draw_Character (x+ 8, y, num[0]); + Draw_Character (x+16, y, num[1]); + Draw_Character (x+24, y, num[2]); - Draw_Character ( x+8 , y, num[0]); - Draw_Character ( x+16 , y, num[1]); - Draw_Character ( x+24 , y, num[2]); - - if (k == cl.viewentity - 1) { - Draw_Character ( x, y, 16); - Draw_Character ( x + 32, y, 17); + // brackets + if (k == cl.viewentity - 1) + { + Draw_Character (x, y, 16); + Draw_Character (x+32, y, 17); } -#if 0 -{ - int total; - int n, minutes, tens, units; - - // draw time - total = cl.completed_time - s->entertime; - minutes = (int)total/60; - n = total - minutes*60; - tens = n/10; - units = n%10; - - sprintf (num, "%3i:%i%i", minutes, tens, units); - - Draw_String ( x+48 , y, num); -} -#endif - - // draw name + // name Draw_String (x+48, y, s->name); - - y += 8; } } /* ================== Sbar_IntermissionOverlay - ================== */ void Sbar_IntermissionOverlay (void) { qpic_t *pic; - int dig; - int num; - - // jkrige - centered intermission - int cx = vid.width / 2; - int cy = vid.height / 2; - // jkrige - centered intermission - - - scr_copyeverything = 1; - scr_fullupdate = 0; + int dig; + int num; if (cl.gametype == GAME_DEATHMATCH) { Sbar_DeathmatchOverlay (); return; } - - // jkrige - centered intermission - /*pic = Draw_CachePic ("gfx/complete.lmp"); - Draw_Pic (64, 24, pic); - - pic = Draw_CachePic ("gfx/inter.lmp"); - Draw_TransPic (0, 56, pic);*/ + GL_SetCanvas (CANVAS_MENU); //johnfitz pic = Draw_CachePic ("gfx/complete.lmp"); - Draw_Pic (cx-94, cy - 96, pic); - + Draw_Pic (64, 24, pic); + pic = Draw_CachePic ("gfx/inter.lmp"); - Draw_TransPic (cx-160, cy - 64, pic); - // jkrige - centered intermission + Draw_Pic (0, 56, pic); -// time dig = cl.completed_time/60; - - // jkrige - centered intermission - //Sbar_IntermissionNumber (160, 64, dig, 3, 0); - Sbar_IntermissionNumber (cx, cy - 56, dig, 3, 0); - // jkrige - centered intermission - + Sbar_IntermissionNumber (152, 64, dig, 3, 0); //johnfitz -- was 160 num = cl.completed_time - dig*60; + Draw_Pic (224,64,sb_colon); //johnfitz -- was 234 + Draw_Pic (240,64,sb_nums[0][num/10]); //johnfitz -- was 246 + Draw_Pic (264,64,sb_nums[0][num%10]); //johnfitz -- was 266 - // jkrige - centered intermission - /*Draw_TransPic (234,64,sb_colon); - Draw_TransPic (246,64,sb_nums[0][num/10]); - Draw_TransPic (266,64,sb_nums[0][num%10]); - - Sbar_IntermissionNumber (160, 104, cl.stats[STAT_SECRETS], 3, 0); - Draw_TransPic (232,104,sb_slash); - Sbar_IntermissionNumber (240, 104, cl.stats[STAT_TOTALSECRETS], 3, 0); - - Sbar_IntermissionNumber (160, 144, cl.stats[STAT_MONSTERS], 3, 0); - Draw_TransPic (232,144,sb_slash); - Sbar_IntermissionNumber (240, 144, cl.stats[STAT_TOTALMONSTERS], 3, 0);*/ - - Draw_TransPic (cx+74, cy-56, sb_colon); - Draw_TransPic (cx+86, cy-56, sb_nums[0][num/10]); - Draw_TransPic (cx+106, cy-56, sb_nums[0][num%10]); - - Sbar_IntermissionNumber (cx, cy-16, cl.stats[STAT_SECRETS], 3, 0); - Draw_TransPic (cx+72, cy-16, sb_slash); - Sbar_IntermissionNumber (cx+80, cy-16, cl.stats[STAT_TOTALSECRETS], 3, 0); - - Sbar_IntermissionNumber (cx, cy+24, cl.stats[STAT_MONSTERS], 3, 0); - Draw_TransPic (cx+72, cy+24, sb_slash); - Sbar_IntermissionNumber (cx+80, cy+24, cl.stats[STAT_TOTALMONSTERS], 3, 0); - // jkrige - centered intermission + Sbar_IntermissionNumber (152, 104, cl.stats[STAT_SECRETS], 3, 0); //johnfitz -- was 160 + Draw_Pic (224,104,sb_slash); //johnfitz -- was 232 + Sbar_IntermissionNumber (240, 104, cl.stats[STAT_TOTALSECRETS], 3, 0); //johnfitz -- was 248 + + Sbar_IntermissionNumber (152, 144, cl.stats[STAT_MONSTERS], 3, 0); //johnfitz -- was 160 + Draw_Pic (224,144,sb_slash); //johnfitz -- was 232 + Sbar_IntermissionNumber (240, 144, cl.stats[STAT_TOTALMONSTERS], 3, 0); //johnfitz -- was 248 } /* ================== Sbar_FinaleOverlay - ================== */ void Sbar_FinaleOverlay (void) { qpic_t *pic; - scr_copyeverything = 1; + GL_SetCanvas (CANVAS_MENU); //johnfitz pic = Draw_CachePic ("gfx/finale.lmp"); - Draw_TransPic ( (vid.width-pic->width)/2, 16, pic); + Draw_Pic ( (320 - pic->width)/2, 16, pic); //johnfitz -- stretched menus } + diff --git a/engine/code/sbar.h b/engine/Quake/sbar.h similarity index 77% rename from engine/code/sbar.h rename to engine/Quake/sbar.h index 682c184..bce73b5 100644 --- a/engine/code/sbar.h +++ b/engine/Quake/sbar.h @@ -1,5 +1,7 @@ /* -Copyright (C) 1996-1997 Id Software, Inc. +Copyright (C) 1996-2001 Id Software, Inc. +Copyright (C) 2002-2009 John Fitzgibbons and others +Copyright (C) 2010-2014 QuakeSpasm developers This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -8,7 +10,7 @@ of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. @@ -18,19 +20,19 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#ifndef _QUAKE_SBAR_H +#define _QUAKE_SBAR_H + // the status bar is only redrawn if something has changed, but if anything // does, the entire thing will be redrawn for the next vid.numpages frames. -#define SBAR_HEIGHT 24 - extern int sb_lines; // scan lines to draw void Sbar_Init (void); +void Sbar_LoadPics (void); -// jkrige - always draw sbar -//void Sbar_Changed (void); +void Sbar_Changed (void); // call whenever any of the client stats represented on the sbar changes -// jkrige - always draw sbar void Sbar_Draw (void); // called every frame by screen @@ -39,3 +41,6 @@ void Sbar_IntermissionOverlay (void); // called each frame after the level has been completed void Sbar_FinaleOverlay (void); + +#endif /* _QUAKE_SBAR_H */ + diff --git a/engine/code/screen.h b/engine/Quake/screen.h similarity index 55% rename from engine/code/screen.h rename to engine/Quake/screen.h index cdb7b51..73c888c 100644 --- a/engine/code/screen.h +++ b/engine/Quake/screen.h @@ -1,5 +1,7 @@ /* -Copyright (C) 1996-1997 Id Software, Inc. +Copyright (C) 1996-2001 Id Software, Inc. +Copyright (C) 2002-2009 John Fitzgibbons and others +Copyright (C) 2010-2014 QuakeSpasm developers This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -8,7 +10,7 @@ of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. @@ -17,9 +19,14 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +#ifndef _QUAKE_SCREEN_H +#define _QUAKE_SCREEN_H + // screen.h void SCR_Init (void); +void SCR_LoadPics (void); void SCR_UpdateScreen (void); @@ -27,17 +34,16 @@ void SCR_UpdateScreen (void); void SCR_SizeUp (void); void SCR_SizeDown (void); void SCR_BringDownConsole (void); -void SCR_CenterPrint (char *str); +void SCR_CenterPrint (const char *str); void SCR_BeginLoadingPlaque (void); void SCR_EndLoadingPlaque (void); -int SCR_ModalMessage (char *text); +int SCR_ModalMessage (const char *text, float timeout); //johnfitz -- added timeout extern float scr_con_current; extern float scr_conlines; // lines of console to display -extern int scr_fullupdate; // set to 0 to force full redraw extern int sb_lines; extern int clearnotify; // set to 0 whenever notify text is drawn @@ -46,10 +52,33 @@ extern qboolean scr_skipupdate; extern cvar_t scr_viewsize; -// only the refresh window will be updated unless these variables are flagged -extern int scr_copytop; -extern int scr_copyeverything; - -extern qboolean block_drawing; +extern cvar_t scr_sbaralpha; //johnfitz void SCR_UpdateWholeScreen (void); + +//johnfitz -- stuff for 2d drawing control +typedef enum { + CANVAS_NONE, + CANVAS_DEFAULT, + CANVAS_CONSOLE, + CANVAS_MENU, + CANVAS_SBAR, + CANVAS_WARPIMAGE, + CANVAS_CROSSHAIR, + CANVAS_BOTTOMLEFT, + CANVAS_BOTTOMRIGHT, + CANVAS_TOPRIGHT, + CANVAS_INVALID = -1 +} canvastype; +extern cvar_t scr_menuscale; +extern cvar_t scr_sbarscale; +extern cvar_t scr_conwidth; +extern cvar_t scr_conscale; +extern cvar_t scr_scale; +extern cvar_t scr_crosshairscale; +//johnfitz + +extern int scr_tileclear_updates; //johnfitz + +#endif /* _QUAKE_SCREEN_H */ + diff --git a/engine/code/server.h b/engine/Quake/server.h similarity index 79% rename from engine/code/server.h rename to engine/Quake/server.h index a27e84d..7eb3f51 100644 --- a/engine/code/server.h +++ b/engine/Quake/server.h @@ -1,5 +1,7 @@ /* -Copyright (C) 1996-1997 Id Software, Inc. +Copyright (C) 1996-2001 Id Software, Inc. +Copyright (C) 2002-2009 John Fitzgibbons and others +Copyright (C) 2010-2014 QuakeSpasm developers This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -8,7 +10,7 @@ of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. @@ -17,6 +19,10 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +#ifndef _QUAKE_SERVER_H +#define _QUAKE_SERVER_H + // server.h typedef struct @@ -40,25 +46,17 @@ typedef struct qboolean loadgame; // handle connections specially double time; - + int lastcheck; // used by PF_checkclient double lastchecktime; - - char name[64]; // map name - // jkrige - skybox - char skybox[128]; - // jkrige - skybox - -#ifdef QUAKE2 - char startspot[64]; -#endif + char name[64]; // map name char modelname[64]; // maps/.bsp, for model_precache[0] - struct model_s *worldmodel; - char *model_precache[MAX_MODELS]; // NULL terminated - struct model_s *models[MAX_MODELS]; - char *sound_precache[MAX_SOUNDS]; // NULL terminated - char *lightstyles[MAX_LIGHTSTYLES]; + struct qmodel_s *worldmodel; + const char *model_precache[MAX_MODELS]; // NULL terminated + struct qmodel_s *models[MAX_MODELS]; + const char *sound_precache[MAX_SOUNDS]; // NULL terminated + const char *lightstyles[MAX_LIGHTSTYLES]; int num_edicts; int max_edicts; edict_t *edicts; // can NOT be array indexed, because @@ -73,7 +71,10 @@ typedef struct byte reliable_datagram_buf[MAX_DATAGRAM]; sizebuf_t signon; - byte signon_buf[8192]; + byte signon_buf[MAX_MSGLEN-2]; //johnfitz -- was 8192, now uses MAX_MSGLEN + + unsigned protocol; //johnfitz + unsigned protocolflags; } server_t; @@ -85,7 +86,6 @@ typedef struct client_s qboolean active; // false = client is free qboolean spawned; // false = don't send datagrams qboolean dropasap; // has been told to go to another level - qboolean privileged; // can execute any host command qboolean sendsignon; // only valid before spawned double last_message; // reliable messages must be sent @@ -102,14 +102,14 @@ typedef struct client_s edict_t *edict; // EDICT_NUM(clientnum+1) char name[32]; // for printing to other people int colors; - + float ping_times[NUM_PING_TIMES]; int num_pings; // ping_times[num_pings%NUM_PING_TIMES] // spawn parms are carried from level to level float spawn_parms[NUM_SPAWN_PARMS]; -// client known data for deltas +// client known data for deltas int old_frags; } client_t; @@ -128,10 +128,6 @@ typedef struct client_s #define MOVETYPE_NOCLIP 8 #define MOVETYPE_FLYMISSILE 9 // extra size to monsters #define MOVETYPE_BOUNCE 10 -#ifdef QUAKE2 -#define MOVETYPE_BOUNCEMISSILE 11 // bounce w/o gravity -#define MOVETYPE_FOLLOW 12 // track movement of aiment -#endif // edict->solid values #define SOLID_NOT 0 // no interaction with other objects @@ -164,10 +160,6 @@ typedef struct client_s #define FL_PARTIALGROUND 1024 // not all corners are valid #define FL_WATERJUMP 2048 // player jumping out of water #define FL_JUMPRELEASED 4096 // for jump debouncing -#ifdef QUAKE2 -#define FL_FLASHLIGHT 8192 -#define FL_ARCHIVE_OVERRIDE 1048576 -#endif // entity effects @@ -175,29 +167,12 @@ typedef struct client_s #define EF_MUZZLEFLASH 2 #define EF_BRIGHTLIGHT 4 #define EF_DIMLIGHT 8 -#ifdef QUAKE2 -#define EF_DARKLIGHT 16 -#define EF_DARKFIELD 32 -#define EF_LIGHT 64 -#define EF_NODRAW 128 -#endif #define SPAWNFLAG_NOT_EASY 256 #define SPAWNFLAG_NOT_MEDIUM 512 #define SPAWNFLAG_NOT_HARD 1024 #define SPAWNFLAG_NOT_DEATHMATCH 2048 -#ifdef QUAKE2 -// server flags -#define SFL_EPISODE_1 1 -#define SFL_EPISODE_2 2 -#define SFL_EPISODE_3 4 -#define SFL_EPISODE_4 8 -#define SFL_NEW_UNIT 16 -#define SFL_NEW_EPISODE 32 -#define SFL_CROSS_TRIGGERS 65280 -#endif - //============================================================================ extern cvar_t teamplay; @@ -212,10 +187,6 @@ extern server_t sv; // local server extern client_t *host_client; -extern jmp_buf host_abortserver; - -extern double host_time; - extern edict_t *sv_player; //=========================================================== @@ -223,7 +194,7 @@ extern edict_t *sv_player; void SV_Init (void); void SV_StartParticle (vec3_t org, vec3_t dir, int color, int count); -void SV_StartSound (edict_t *entity, int channel, char *sample, int volume, +void SV_StartSound (edict_t *entity, int channel, const char *sample, int volume, float attenuation); void SV_DropClient (qboolean crash); @@ -231,7 +202,7 @@ void SV_DropClient (qboolean crash); void SV_SendClientMessages (void); void SV_ClearDatagram (void); -int SV_ModelIndex (char *name); +int SV_ModelIndex (const char *name); void SV_SetIdealPitch (void); @@ -240,8 +211,8 @@ void SV_AddUpdates (void); void SV_ClientThink (void); void SV_AddClientToServer (struct qsocket_s *ret); -void SV_ClientPrintf (char *fmt, ...); -void SV_BroadcastPrintf (char *fmt, ...); +void SV_ClientPrintf (const char *fmt, ...) FUNC_PRINTF(1,2); +void SV_BroadcastPrintf (const char *fmt, ...) FUNC_PRINTF(1,2); void SV_Physics (void); @@ -255,8 +226,7 @@ void SV_MoveToGoal (void); void SV_CheckForNewClients (void); void SV_RunClients (void); void SV_SaveSpawnparms (); -#ifdef QUAKE2 -void SV_SpawnServer (char *server, char *startspot); -#else -void SV_SpawnServer (char *server); -#endif +void SV_SpawnServer (const char *server); + +#endif /* _QUAKE_SERVER_H */ + diff --git a/engine/Quake/snd_codec.c b/engine/Quake/snd_codec.c new file mode 100644 index 0000000..dc37fb6 --- /dev/null +++ b/engine/Quake/snd_codec.c @@ -0,0 +1,318 @@ +/* + * Audio Codecs: Adapted from ioquake3 with changes. + * For now, only handles streaming music, not sound effects. + * + * Copyright (C) 1999-2005 Id Software, Inc. + * Copyright (C) 2005 Stuart Dalton + * Copyright (C) 2010-2012 O.Sezer + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#include "quakedef.h" +#include "snd_codec.h" +#include "snd_codeci.h" + +/* headers for individual codecs */ +#include "snd_mikmod.h" +#include "snd_xmp.h" +#include "snd_umx.h" +#include "snd_wave.h" +#include "snd_flac.h" +#include "snd_mp3.h" +#include "snd_vorbis.h" +#include "snd_opus.h" + + +static snd_codec_t *codecs; + +/* +================= +S_CodecRegister +================= +*/ +static void S_CodecRegister(snd_codec_t *codec) +{ + codec->next = codecs; + codecs = codec; +} + +/* +================= +S_CodecInit +================= +*/ +void S_CodecInit (void) +{ + snd_codec_t *codec; + codecs = NULL; + + /* Register in the inverse order + * of codec choice preference: */ +#ifdef USE_CODEC_UMX + S_CodecRegister(&umx_codec); +#endif +#ifdef USE_CODEC_MIKMOD + S_CodecRegister(&mikmod_codec); +#endif +#ifdef USE_CODEC_XMP + S_CodecRegister(&xmp_codec); +#endif +#ifdef USE_CODEC_WAVE + S_CodecRegister(&wav_codec); +#endif +#ifdef USE_CODEC_FLAC + S_CodecRegister(&flac_codec); +#endif +#ifdef USE_CODEC_MP3 + S_CodecRegister(&mp3_codec); +#endif +#ifdef USE_CODEC_VORBIS + S_CodecRegister(&vorbis_codec); +#endif +#ifdef USE_CODEC_OPUS + S_CodecRegister(&opus_codec); +#endif + + codec = codecs; + while (codec) + { + codec->initialize(); + codec = codec->next; + } +} + +/* +================= +S_CodecShutdown +================= +*/ +void S_CodecShutdown (void) +{ + snd_codec_t *codec = codecs; + while (codec) + { + codec->shutdown(); + codec = codec->next; + } + codecs = NULL; +} + +/* +================= +S_CodecOpenStream +================= +*/ +snd_stream_t *S_CodecOpenStreamType (const char *filename, unsigned int type) +{ + snd_codec_t *codec; + snd_stream_t *stream; + + if (type == CODECTYPE_NONE) + { + Con_Printf("Bad type for %s\n", filename); + return NULL; + } + + codec = codecs; + while (codec) + { + if (type == codec->type) + break; + codec = codec->next; + } + if (!codec) + { + Con_Printf("Unknown type for %s\n", filename); + return NULL; + } + stream = S_CodecUtilOpen(filename, codec); + if (stream) { + if (codec->codec_open(stream)) + stream->status = STREAM_PLAY; + else S_CodecUtilClose(&stream); + } + return stream; +} + +snd_stream_t *S_CodecOpenStreamExt (const char *filename) +{ + snd_codec_t *codec; + snd_stream_t *stream; + const char *ext; + + ext = COM_FileGetExtension(filename); + if (! *ext) + { + Con_Printf("No extension for %s\n", filename); + return NULL; + } + + codec = codecs; + while (codec) + { + if (!q_strcasecmp(ext, codec->ext)) + break; + codec = codec->next; + } + if (!codec) + { + Con_Printf("Unknown extension for %s\n", filename); + return NULL; + } + stream = S_CodecUtilOpen(filename, codec); + if (stream) { + if (codec->codec_open(stream)) + stream->status = STREAM_PLAY; + else S_CodecUtilClose(&stream); + } + return stream; +} + +snd_stream_t *S_CodecOpenStreamAny (const char *filename) +{ + snd_codec_t *codec; + snd_stream_t *stream; + const char *ext; + + ext = COM_FileGetExtension(filename); + if (! *ext) /* try all available */ + { + char tmp[MAX_QPATH]; + + codec = codecs; + while (codec) + { + q_snprintf(tmp, sizeof(tmp), "%s.%s", filename, codec->ext); + stream = S_CodecUtilOpen(tmp, codec); + if (stream) { + if (codec->codec_open(stream)) { + stream->status = STREAM_PLAY; + return stream; + } + S_CodecUtilClose(&stream); + } + codec = codec->next; + } + + return NULL; + } + else /* use the name as is */ + { + codec = codecs; + while (codec) + { + if (!q_strcasecmp(ext, codec->ext)) + break; + codec = codec->next; + } + if (!codec) + { + Con_Printf("Unknown extension for %s\n", filename); + return NULL; + } + stream = S_CodecUtilOpen(filename, codec); + if (stream) { + if (codec->codec_open(stream)) + stream->status = STREAM_PLAY; + else S_CodecUtilClose(&stream); + } + return stream; + } +} + +qboolean S_CodecForwardStream (snd_stream_t *stream, unsigned int type) +{ + snd_codec_t *codec = codecs; + + while (codec) + { + if (type == codec->type) + break; + codec = codec->next; + } + if (!codec) return false; + stream->codec = codec; + return codec->codec_open(stream); +} + +void S_CodecCloseStream (snd_stream_t *stream) +{ + stream->status = STREAM_NONE; + stream->codec->codec_close(stream); +} + +int S_CodecRewindStream (snd_stream_t *stream) +{ + return stream->codec->codec_rewind(stream); +} + +int S_CodecReadStream (snd_stream_t *stream, int bytes, void *buffer) +{ + return stream->codec->codec_read(stream, bytes, buffer); +} + +/* Util functions (used by codecs) */ + +snd_stream_t *S_CodecUtilOpen(const char *filename, snd_codec_t *codec) +{ + snd_stream_t *stream; + FILE *handle; + qboolean pak; + long length; + + /* Try to open the file */ + length = (long) COM_FOpenFile(filename, &handle, NULL); + pak = file_from_pak; + if (length == -1) + { + Con_DPrintf("Couldn't open %s\n", filename); + return NULL; + } + + /* Allocate a stream, Z_Malloc zeroes its content */ + stream = (snd_stream_t *) Z_Malloc(sizeof(snd_stream_t)); + stream->codec = codec; + stream->fh.file = handle; + stream->fh.start = ftell(handle); + stream->fh.pos = 0; + stream->fh.length = length; + stream->fh.pak = stream->pak = pak; + q_strlcpy(stream->name, filename, MAX_QPATH); + + return stream; +} + +void S_CodecUtilClose(snd_stream_t **stream) +{ + fclose((*stream)->fh.file); + Z_Free(*stream); + *stream = NULL; +} + +int S_CodecIsAvailable (unsigned int type) +{ + snd_codec_t *codec = codecs; + while (codec) + { + if (type == codec->type) + return codec->initialized; + codec = codec->next; + } + return -1; +} + diff --git a/engine/Quake/snd_codec.h b/engine/Quake/snd_codec.h new file mode 100644 index 0000000..657b0b2 --- /dev/null +++ b/engine/Quake/snd_codec.h @@ -0,0 +1,104 @@ +/* + * Audio Codecs: Adapted from ioquake3 with changes. + * For now, only handles streaming music, not sound effects. + * + * Copyright (C) 1999-2005 Id Software, Inc. + * Copyright (C) 2005 Stuart Dalton + * Copyright (C) 2010-2012 O.Sezer + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifndef _SND_CODEC_H_ +#define _SND_CODEC_H_ + +typedef struct snd_info_s +{ + int rate; + int bits, width; + int channels; + int samples; + int blocksize; + int size; + int dataofs; +} snd_info_t; + +typedef enum { + STREAM_NONE = -1, + STREAM_INIT, + STREAM_PAUSE, + STREAM_PLAY +} stream_status_t; + +typedef struct snd_codec_s snd_codec_t; + +typedef struct snd_stream_s +{ + fshandle_t fh; + qboolean pak; + char name[MAX_QPATH]; /* name of the source file */ + snd_info_t info; + stream_status_t status; + snd_codec_t *codec; /* codec handling this stream */ + void *priv; /* data private to the codec. */ +} snd_stream_t; + + +void S_CodecInit (void); +void S_CodecShutdown (void); + +/* Callers of the following S_CodecOpenStream* functions + * are reponsible for attaching any path to the filename */ + +snd_stream_t *S_CodecOpenStreamType (const char *filename, unsigned int type); + /* Decides according to the required type. */ + +snd_stream_t *S_CodecOpenStreamAny (const char *filename); + /* Decides according to file extension. if the + * name has no extension, try all available. */ + +snd_stream_t *S_CodecOpenStreamExt (const char *filename); + /* Decides according to file extension. the name + * MUST have an extension. */ + +void S_CodecCloseStream (snd_stream_t *stream); +int S_CodecReadStream (snd_stream_t *stream, int bytes, void *buffer); +int S_CodecRewindStream (snd_stream_t *stream); + +snd_stream_t *S_CodecUtilOpen(const char *filename, snd_codec_t *codec); +void S_CodecUtilClose(snd_stream_t **stream); + + +#define CODECTYPE_NONE 0 +#define CODECTYPE_MID (1U << 0) +#define CODECTYPE_MOD (1U << 1) +#define CODECTYPE_FLAC (1U << 2) +#define CODECTYPE_WAV (1U << 3) +#define CODECTYPE_MP3 (1U << 4) +#define CODECTYPE_VORBIS (1U << 5) +#define CODECTYPE_OPUS (1U << 6) +#define CODECTYPE_UMX (1U << 7) + +#define CODECTYPE_WAVE CODECTYPE_WAV +#define CODECTYPE_MIDI CODECTYPE_MID + +int S_CodecIsAvailable (unsigned int type); + /* return 1 if available, 0 if codec failed init + * or -1 if no such codec is present. */ + +#endif /* _SND_CODEC_H_ */ + diff --git a/engine/Quake/snd_codeci.h b/engine/Quake/snd_codeci.h new file mode 100644 index 0000000..feedb61 --- /dev/null +++ b/engine/Quake/snd_codeci.h @@ -0,0 +1,55 @@ +/* + * Audio Codecs: Adapted from ioquake3 with changes. + * For now, only handles streaming music, not sound effects. + * + * Copyright (C) 1999-2005 Id Software, Inc. + * Copyright (C) 2005 Stuart Dalton + * Copyright (C) 2010-2012 O.Sezer + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifndef _SND_CODECI_H_ +#define _SND_CODECI_H_ + +/* Codec internals */ +typedef qboolean (*CODEC_INIT)(void); +typedef void (*CODEC_SHUTDOWN)(void); +typedef qboolean (*CODEC_OPEN)(snd_stream_t *stream); +typedef int (*CODEC_READ)(snd_stream_t *stream, int bytes, void *buffer); +typedef int (*CODEC_REWIND)(snd_stream_t *stream); +typedef void (*CODEC_CLOSE)(snd_stream_t *stream); + +struct snd_codec_s +{ + unsigned int type; /* handled data type. (1U << n) */ + qboolean initialized; /* init succeedded */ + const char *ext; /* expected extension */ + CODEC_INIT initialize; + CODEC_SHUTDOWN shutdown; + CODEC_OPEN codec_open; + CODEC_READ codec_read; + CODEC_REWIND codec_rewind; + CODEC_CLOSE codec_close; + snd_codec_t *next; +}; + +qboolean S_CodecForwardStream (snd_stream_t *stream, unsigned int type); + /* Forward a stream to another codec of 'type' type. */ + +#endif /* _SND_CODECI_H_ */ + diff --git a/engine/Quake/snd_dma.c b/engine/Quake/snd_dma.c new file mode 100644 index 0000000..cc5df69 --- /dev/null +++ b/engine/Quake/snd_dma.c @@ -0,0 +1,1070 @@ +/* +Copyright (C) 1996-2001 Id Software, Inc. +Copyright (C) 2002-2009 John Fitzgibbons and others +Copyright (C) 2007-2008 Kristian Duske +Copyright (C) 2010-2011 O. Sezer +Copyright (C) 2010-2014 QuakeSpasm developers + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +// snd_dma.c -- main control for any streaming sound output device + +#include "quakedef.h" +#include "snd_codec.h" +#include "bgmusic.h" + +static void S_Play (void); +static void S_PlayVol (void); +static void S_SoundList (void); +static void S_Update_ (void); +void S_StopAllSounds (qboolean clear); +static void S_StopAllSoundsC (void); + +// ======================================================================= +// Internal sound data & structures +// ======================================================================= + +channel_t snd_channels[MAX_CHANNELS]; +int total_channels; + +static int snd_blocked = 0; +static qboolean snd_initialized = false; + +static dma_t sn; +volatile dma_t *shm = NULL; + +vec3_t listener_origin; +vec3_t listener_forward; +vec3_t listener_right; +vec3_t listener_up; + +#define sound_nominal_clip_dist 1000.0 + +int soundtime; // sample PAIRS +int paintedtime; // sample PAIRS + +int s_rawend; +portable_samplepair_t s_rawsamples[MAX_RAW_SAMPLES]; + + +#define MAX_SFX 1024 +static sfx_t *known_sfx = NULL; // hunk allocated [MAX_SFX] +static int num_sfx; + +static sfx_t *ambient_sfx[NUM_AMBIENTS]; + +static qboolean sound_started = false; + +cvar_t bgmvolume = {"bgmvolume", "1", CVAR_ARCHIVE}; +cvar_t sfxvolume = {"volume", "0.7", CVAR_ARCHIVE}; + +cvar_t precache = {"precache", "1", CVAR_NONE}; +cvar_t loadas8bit = {"loadas8bit", "0", CVAR_NONE}; + +cvar_t sndspeed = {"sndspeed", "11025", CVAR_NONE}; +cvar_t snd_mixspeed = {"snd_mixspeed", "44100", CVAR_NONE}; + +#if defined(_WIN32) +#define SND_FILTERQUALITY_DEFAULT "5" +#else +#define SND_FILTERQUALITY_DEFAULT "1" +#endif + +cvar_t snd_filterquality = {"snd_filterquality", SND_FILTERQUALITY_DEFAULT, + CVAR_NONE}; + +static cvar_t nosound = {"nosound", "0", CVAR_NONE}; +static cvar_t ambient_level = {"ambient_level", "0.3", CVAR_NONE}; +static cvar_t ambient_fade = {"ambient_fade", "100", CVAR_NONE}; +static cvar_t snd_noextraupdate = {"snd_noextraupdate", "0", CVAR_NONE}; +static cvar_t snd_show = {"snd_show", "0", CVAR_NONE}; +static cvar_t _snd_mixahead = {"_snd_mixahead", "0.1", CVAR_ARCHIVE}; + + +static void S_SoundInfo_f (void) +{ + if (!sound_started || !shm) + { + Con_Printf ("sound system not started\n"); + return; + } + + Con_Printf("%d bit, %s, %d Hz\n", shm->samplebits, + (shm->channels == 2) ? "stereo" : "mono", shm->speed); + Con_Printf("%5d samples\n", shm->samples); + Con_Printf("%5d samplepos\n", shm->samplepos); + Con_Printf("%5d submission_chunk\n", shm->submission_chunk); + Con_Printf("%5d total_channels\n", total_channels); + Con_Printf("%p dma buffer\n", shm->buffer); +} + + +static void SND_Callback_sfxvolume (cvar_t *var) +{ + SND_InitScaletable (); +} + +static void SND_Callback_snd_filterquality (cvar_t *var) +{ + if (snd_filterquality.value < 1 || snd_filterquality.value > 5) + { + Con_Printf ("snd_filterquality must be between 1 and 5\n"); + Cvar_SetQuick (&snd_filterquality, SND_FILTERQUALITY_DEFAULT); + } +} + +/* +================ +S_Startup +================ +*/ +void S_Startup (void) +{ + if (!snd_initialized) + return; + + sound_started = SNDDMA_Init(&sn); + + if (!sound_started) + { + Con_Printf("Failed initializing sound\n"); + } + else + { + Con_Printf("Audio: %d bit, %s, %d Hz\n", + shm->samplebits, + (shm->channels == 2) ? "stereo" : "mono", + shm->speed); + } +} + + +/* +================ +S_Init +================ +*/ +void S_Init (void) +{ + int i; + + if (snd_initialized) + { + Con_Printf("Sound is already initialized\n"); + return; + } + + Cvar_RegisterVariable(&nosound); + Cvar_RegisterVariable(&sfxvolume); + Cvar_RegisterVariable(&precache); + Cvar_RegisterVariable(&loadas8bit); + Cvar_RegisterVariable(&bgmvolume); + Cvar_RegisterVariable(&ambient_level); + Cvar_RegisterVariable(&ambient_fade); + Cvar_RegisterVariable(&snd_noextraupdate); + Cvar_RegisterVariable(&snd_show); + Cvar_RegisterVariable(&_snd_mixahead); + Cvar_RegisterVariable(&sndspeed); + Cvar_RegisterVariable(&snd_mixspeed); + Cvar_RegisterVariable(&snd_filterquality); + + if (safemode || COM_CheckParm("-nosound")) + return; + + Con_Printf("\nSound Initialization\n"); + + Cmd_AddCommand("play", S_Play); + Cmd_AddCommand("playvol", S_PlayVol); + Cmd_AddCommand("stopsound", S_StopAllSoundsC); + Cmd_AddCommand("soundlist", S_SoundList); + Cmd_AddCommand("soundinfo", S_SoundInfo_f); + + i = COM_CheckParm("-sndspeed"); + if (i && i < com_argc-1) + { + Cvar_SetQuick (&sndspeed, com_argv[i+1]); + } + + i = COM_CheckParm("-mixspeed"); + if (i && i < com_argc-1) + { + Cvar_SetQuick (&snd_mixspeed, com_argv[i+1]); + } + + if (host_parms->memsize < 0x800000) + { + Cvar_SetQuick (&loadas8bit, "1"); + Con_Printf ("loading all sounds as 8bit\n"); + } + + Cvar_SetCallback(&sfxvolume, SND_Callback_sfxvolume); + Cvar_SetCallback(&snd_filterquality, &SND_Callback_snd_filterquality); + + SND_InitScaletable (); + + known_sfx = (sfx_t *) Hunk_AllocName (MAX_SFX*sizeof(sfx_t), "sfx_t"); + num_sfx = 0; + + snd_initialized = true; + + S_Startup (); + if (sound_started == 0) + return; + +// provides a tick sound until washed clean +// if (shm->buffer) +// shm->buffer[4] = shm->buffer[5] = 0x7f; // force a pop for debugging + + ambient_sfx[AMBIENT_WATER] = S_PrecacheSound ("ambience/water1.wav"); + ambient_sfx[AMBIENT_SKY] = S_PrecacheSound ("ambience/wind2.wav"); + + S_CodecInit (); + + S_StopAllSounds (true); +} + + +// ======================================================================= +// Shutdown sound engine +// ======================================================================= +void S_Shutdown (void) +{ + if (!sound_started) + return; + + sound_started = 0; + snd_blocked = 0; + + S_CodecShutdown(); + + SNDDMA_Shutdown(); + shm = NULL; +} + + +// ======================================================================= +// Load a sound +// ======================================================================= + +/* +================== +S_FindName + +================== +*/ +static sfx_t *S_FindName (const char *name) +{ + int i; + sfx_t *sfx; + + if (!name) + Sys_Error ("S_FindName: NULL"); + + if (Q_strlen(name) >= MAX_QPATH) + Sys_Error ("Sound name too long: %s", name); + +// see if already loaded + for (i = 0; i < num_sfx; i++) + { + if (!Q_strcmp(known_sfx[i].name, name)) + { + return &known_sfx[i]; + } + } + + if (num_sfx == MAX_SFX) + Sys_Error ("S_FindName: out of sfx_t"); + + sfx = &known_sfx[i]; + q_strlcpy (sfx->name, name, sizeof(sfx->name)); + + num_sfx++; + + return sfx; +} + + +/* +================== +S_TouchSound + +================== +*/ +void S_TouchSound (const char *name) +{ + sfx_t *sfx; + + if (!sound_started) + return; + + sfx = S_FindName (name); + Cache_Check (&sfx->cache); +} + +/* +================== +S_PrecacheSound + +================== +*/ +sfx_t *S_PrecacheSound (const char *name) +{ + sfx_t *sfx; + + if (!sound_started || nosound.value) + return NULL; + + sfx = S_FindName (name); + +// cache it in + if (precache.value) + S_LoadSound (sfx); + + return sfx; +} + + +//============================================================================= + +/* +================= +SND_PickChannel + +picks a channel based on priorities, empty slots, number of channels +================= +*/ +channel_t *SND_PickChannel (int entnum, int entchannel) +{ + int ch_idx; + int first_to_die; + int life_left; + +// Check for replacement sound, or find the best one to replace + first_to_die = -1; + life_left = 0x7fffffff; + for (ch_idx = NUM_AMBIENTS; ch_idx < NUM_AMBIENTS + MAX_DYNAMIC_CHANNELS; ch_idx++) + { + if (entchannel != 0 // channel 0 never overrides + && snd_channels[ch_idx].entnum == entnum + && (snd_channels[ch_idx].entchannel == entchannel || entchannel == -1) ) + { // always override sound from same entity + first_to_die = ch_idx; + break; + } + + // don't let monster sounds override player sounds + if (snd_channels[ch_idx].entnum == cl.viewentity && entnum != cl.viewentity && snd_channels[ch_idx].sfx) + continue; + + if (snd_channels[ch_idx].end - paintedtime < life_left) + { + life_left = snd_channels[ch_idx].end - paintedtime; + first_to_die = ch_idx; + } + } + + if (first_to_die == -1) + return NULL; + + if (snd_channels[first_to_die].sfx) + snd_channels[first_to_die].sfx = NULL; + + return &snd_channels[first_to_die]; +} + +/* +================= +SND_Spatialize + +spatializes a channel +================= +*/ +void SND_Spatialize (channel_t *ch) +{ + vec_t dot; + vec_t dist; + vec_t lscale, rscale, scale; + vec3_t source_vec; + +// anything coming from the view entity will always be full volume + if (ch->entnum == cl.viewentity) + { + ch->leftvol = ch->master_vol; + ch->rightvol = ch->master_vol; + return; + } + +// calculate stereo seperation and distance attenuation + VectorSubtract(ch->origin, listener_origin, source_vec); + dist = VectorNormalize(source_vec) * ch->dist_mult; + dot = DotProduct(listener_right, source_vec); + + if (shm->channels == 1) + { + rscale = 1.0; + lscale = 1.0; + } + else + { + rscale = 1.0 + dot; + lscale = 1.0 - dot; + } + +// add in distance effect + scale = (1.0 - dist) * rscale; + ch->rightvol = (int) (ch->master_vol * scale); + if (ch->rightvol < 0) + ch->rightvol = 0; + + scale = (1.0 - dist) * lscale; + ch->leftvol = (int) (ch->master_vol * scale); + if (ch->leftvol < 0) + ch->leftvol = 0; +} + + +// ======================================================================= +// Start a sound effect +// ======================================================================= + +void S_StartSound (int entnum, int entchannel, sfx_t *sfx, vec3_t origin, float fvol, float attenuation) +{ + channel_t *target_chan, *check; + sfxcache_t *sc; + int ch_idx; + int skip; + + if (!sound_started) + return; + + if (!sfx) + return; + + if (nosound.value) + return; + +// pick a channel to play on + target_chan = SND_PickChannel(entnum, entchannel); + if (!target_chan) + return; + +// spatialize + memset (target_chan, 0, sizeof(*target_chan)); + VectorCopy(origin, target_chan->origin); + target_chan->dist_mult = attenuation / sound_nominal_clip_dist; + target_chan->master_vol = (int) (fvol * 255); + target_chan->entnum = entnum; + target_chan->entchannel = entchannel; + SND_Spatialize(target_chan); + + if (!target_chan->leftvol && !target_chan->rightvol) + return; // not audible at all + +// new channel + sc = S_LoadSound (sfx); + if (!sc) + { + target_chan->sfx = NULL; + return; // couldn't load the sound's data + } + + target_chan->sfx = sfx; + target_chan->pos = 0.0; + target_chan->end = paintedtime + sc->length; + +// if an identical sound has also been started this frame, offset the pos +// a bit to keep it from just making the first one louder + check = &snd_channels[NUM_AMBIENTS]; + for (ch_idx = NUM_AMBIENTS; ch_idx < NUM_AMBIENTS + MAX_DYNAMIC_CHANNELS; ch_idx++, check++) + { + if (check == target_chan) + continue; + if (check->sfx == sfx && !check->pos) + { + /* + skip = rand () % (int)(0.1 * shm->speed); + if (skip >= target_chan->end) + skip = target_chan->end - 1; + */ + /* LordHavoc: fixed skip calculations */ + skip = 0.1 * shm->speed; /* 0.1 * sc->speed */ + if (skip > sc->length) + skip = sc->length; + if (skip > 0) + skip = rand() % skip; + target_chan->pos += skip; + target_chan->end -= skip; + break; + } + } +} + +void S_StopSound (int entnum, int entchannel) +{ + int i; + + for (i = 0; i < MAX_DYNAMIC_CHANNELS; i++) + { + if (snd_channels[i].entnum == entnum + && snd_channels[i].entchannel == entchannel) + { + snd_channels[i].end = 0; + snd_channels[i].sfx = NULL; + return; + } + } +} + +void S_StopAllSounds (qboolean clear) +{ + int i; + + if (!sound_started) + return; + + total_channels = MAX_DYNAMIC_CHANNELS + NUM_AMBIENTS; // no statics + + for (i = 0; i < MAX_CHANNELS; i++) + { + if (snd_channels[i].sfx) + snd_channels[i].sfx = NULL; + } + + memset(snd_channels, 0, MAX_CHANNELS * sizeof(channel_t)); + + if (clear) + S_ClearBuffer (); +} + +static void S_StopAllSoundsC (void) +{ + S_StopAllSounds (true); +} + +void S_ClearBuffer (void) +{ + int clear; + + if (!sound_started || !shm) + return; + + SNDDMA_LockBuffer (); + if (! shm->buffer) + return; + + s_rawend = 0; + + if (shm->samplebits == 8 && !shm->signed8) + clear = 0x80; + else + clear = 0; + + memset(shm->buffer, clear, shm->samples * shm->samplebits / 8); + + SNDDMA_Submit (); +} + + +/* +================= +S_StaticSound +================= +*/ +void S_StaticSound (sfx_t *sfx, vec3_t origin, float vol, float attenuation) +{ + channel_t *ss; + sfxcache_t *sc; + + if (!sfx) + return; + + if (total_channels == MAX_CHANNELS) + { + Con_Printf ("total_channels == MAX_CHANNELS\n"); + return; + } + + ss = &snd_channels[total_channels]; + total_channels++; + + sc = S_LoadSound (sfx); + if (!sc) + return; + + if (sc->loopstart == -1) + { + Con_Printf ("Sound %s not looped\n", sfx->name); + return; + } + + ss->sfx = sfx; + VectorCopy (origin, ss->origin); + ss->master_vol = (int)vol; + ss->dist_mult = (attenuation / 64) / sound_nominal_clip_dist; + ss->end = paintedtime + sc->length; + + SND_Spatialize (ss); +} + + +//============================================================================= + +/* +=================== +S_UpdateAmbientSounds +=================== +*/ +static void S_UpdateAmbientSounds (void) +{ + mleaf_t *l; + int vol, ambient_channel; + channel_t *chan; + +// no ambients when disconnected + if (cls.state != ca_connected) + return; +// calc ambient sound levels + if (!cl.worldmodel) + return; + + l = Mod_PointInLeaf (listener_origin, cl.worldmodel); + if (!l || !ambient_level.value) + { + for (ambient_channel = 0; ambient_channel < NUM_AMBIENTS; ambient_channel++) + snd_channels[ambient_channel].sfx = NULL; + return; + } + + for (ambient_channel = 0; ambient_channel < NUM_AMBIENTS; ambient_channel++) + { + chan = &snd_channels[ambient_channel]; + chan->sfx = ambient_sfx[ambient_channel]; + + vol = (int) (ambient_level.value * l->ambient_sound_level[ambient_channel]); + if (vol < 8) + vol = 0; + + // don't adjust volume too fast + if (chan->master_vol < vol) + { + chan->master_vol += (int) (host_frametime * ambient_fade.value); + if (chan->master_vol > vol) + chan->master_vol = vol; + } + else if (chan->master_vol > vol) + { + chan->master_vol -= (int) (host_frametime * ambient_fade.value); + if (chan->master_vol < vol) + chan->master_vol = vol; + } + + chan->leftvol = chan->rightvol = chan->master_vol; + } +} + + +/* +=================== +S_RawSamples (from QuakeII) + +Streaming music support. Byte swapping +of data must be handled by the codec. +Expects data in signed 16 bit, or unsigned +8 bit format. +=================== +*/ +void S_RawSamples (int samples, int rate, int width, int channels, byte *data, float volume) +{ + int i; + int src, dst; + float scale; + int intVolume; + + if (s_rawend < paintedtime) + s_rawend = paintedtime; + + scale = (float) rate / shm->speed; + intVolume = (int) (256 * volume); + + if (channels == 2 && width == 2) + { + for (i = 0; ; i++) + { + src = i * scale; + if (src >= samples) + break; + dst = s_rawend & (MAX_RAW_SAMPLES - 1); + s_rawend++; + s_rawsamples [dst].left = ((short *) data)[src * 2] * intVolume; + s_rawsamples [dst].right = ((short *) data)[src * 2 + 1] * intVolume; + } + } + else if (channels == 1 && width == 2) + { + for (i = 0; ; i++) + { + src = i * scale; + if (src >= samples) + break; + dst = s_rawend & (MAX_RAW_SAMPLES - 1); + s_rawend++; + s_rawsamples [dst].left = ((short *) data)[src] * intVolume; + s_rawsamples [dst].right = ((short *) data)[src] * intVolume; + } + } + else if (channels == 2 && width == 1) + { + intVolume *= 256; + + for (i = 0; ; i++) + { + src = i * scale; + if (src >= samples) + break; + dst = s_rawend & (MAX_RAW_SAMPLES - 1); + s_rawend++; + // s_rawsamples [dst].left = ((signed char *) data)[src * 2] * intVolume; + // s_rawsamples [dst].right = ((signed char *) data)[src * 2 + 1] * intVolume; + s_rawsamples [dst].left = (((byte *) data)[src * 2] - 128) * intVolume; + s_rawsamples [dst].right = (((byte *) data)[src * 2 + 1] - 128) * intVolume; + } + } + else if (channels == 1 && width == 1) + { + intVolume *= 256; + + for (i = 0; ; i++) + { + src = i * scale; + if (src >= samples) + break; + dst = s_rawend & (MAX_RAW_SAMPLES - 1); + s_rawend++; + // s_rawsamples [dst].left = ((signed char *) data)[src] * intVolume; + // s_rawsamples [dst].right = ((signed char *) data)[src] * intVolume; + s_rawsamples [dst].left = (((byte *) data)[src] - 128) * intVolume; + s_rawsamples [dst].right = (((byte *) data)[src] - 128) * intVolume; + } + } +} + +/* +============ +S_Update + +Called once each time through the main loop +============ +*/ +void S_Update (vec3_t origin, vec3_t forward, vec3_t right, vec3_t up) +{ + int i, j; + int total; + channel_t *ch; + channel_t *combine; + + if (!sound_started || (snd_blocked > 0)) + return; + + VectorCopy(origin, listener_origin); + VectorCopy(forward, listener_forward); + VectorCopy(right, listener_right); + VectorCopy(up, listener_up); + +// update general area ambient sound sources + S_UpdateAmbientSounds (); + + combine = NULL; + +// update spatialization for static and dynamic sounds + ch = snd_channels + NUM_AMBIENTS; + for (i = NUM_AMBIENTS; i < total_channels; i++, ch++) + { + if (!ch->sfx) + continue; + SND_Spatialize(ch); // respatialize channel + if (!ch->leftvol && !ch->rightvol) + continue; + + // try to combine static sounds with a previous channel of the same + // sound effect so we don't mix five torches every frame + + if (i >= MAX_DYNAMIC_CHANNELS + NUM_AMBIENTS) + { + // see if it can just use the last one + if (combine && combine->sfx == ch->sfx) + { + combine->leftvol += ch->leftvol; + combine->rightvol += ch->rightvol; + ch->leftvol = ch->rightvol = 0; + continue; + } + // search for one + combine = snd_channels + MAX_DYNAMIC_CHANNELS + NUM_AMBIENTS; + for (j = MAX_DYNAMIC_CHANNELS + NUM_AMBIENTS; j < i; j++, combine++) + { + if (combine->sfx == ch->sfx) + break; + } + + if (j == total_channels) + { + combine = NULL; + } + else + { + if (combine != ch) + { + combine->leftvol += ch->leftvol; + combine->rightvol += ch->rightvol; + ch->leftvol = ch->rightvol = 0; + } + continue; + } + } + } + +// +// debugging output +// + if (snd_show.value) + { + total = 0; + ch = snd_channels; + for (i = 0; i < total_channels; i++, ch++) + { + if (ch->sfx && (ch->leftvol || ch->rightvol) ) + { + // Con_Printf ("%3i %3i %s\n", ch->leftvol, ch->rightvol, ch->sfx->name); + total++; + } + } + + Con_Printf ("----(%i)----\n", total); + } + +// add raw data from streamed samples +// BGM_Update(); // moved to the main loop just before S_Update () + +// mix some sound + S_Update_(); +} + +static void GetSoundtime (void) +{ + int samplepos; + static int buffers; + static int oldsamplepos; + int fullsamples; + + fullsamples = shm->samples / shm->channels; + +// it is possible to miscount buffers if it has wrapped twice between +// calls to S_Update. Oh well. + samplepos = SNDDMA_GetDMAPos(); + + if (samplepos < oldsamplepos) + { + buffers++; // buffer wrapped + + if (paintedtime > 0x40000000) + { // time to chop things off to avoid 32 bit limits + buffers = 0; + paintedtime = fullsamples; + S_StopAllSounds (true); + } + } + oldsamplepos = samplepos; + + soundtime = buffers*fullsamples + samplepos/shm->channels; +} + +void S_ExtraUpdate (void) +{ + if (snd_noextraupdate.value) + return; // don't pollute timings + S_Update_(); +} + +static void S_Update_ (void) +{ + unsigned int endtime; + int samps; + + if (!sound_started || (snd_blocked > 0)) + return; + + SNDDMA_LockBuffer (); + if (! shm->buffer) + return; + +// Updates DMA time + GetSoundtime(); + +// check to make sure that we haven't overshot + if (paintedtime < soundtime) + { + // Con_Printf ("S_Update_ : overflow\n"); + paintedtime = soundtime; + } + +// mix ahead of current position + endtime = soundtime + (unsigned int)(_snd_mixahead.value * shm->speed); + samps = shm->samples >> (shm->channels - 1); + endtime = q_min(endtime, (unsigned int)(soundtime + samps)); + + S_PaintChannels (endtime); + + SNDDMA_Submit (); +} + +void S_BlockSound (void) +{ +/* FIXME: do we really need the blocking at the + * driver level? + */ + if (sound_started && snd_blocked == 0) /* ++snd_blocked == 1 */ + { + snd_blocked = 1; + S_ClearBuffer (); + if (shm) + SNDDMA_BlockSound(); + } +} + +void S_UnblockSound (void) +{ + if (!sound_started || !snd_blocked) + return; + if (snd_blocked == 1) /* --snd_blocked == 0 */ + { + snd_blocked = 0; + SNDDMA_UnblockSound(); + S_ClearBuffer (); + } +} + +/* +=============================================================================== + +console functions + +=============================================================================== +*/ + +static void S_Play (void) +{ + static int hash = 345; + int i; + char name[256]; + sfx_t *sfx; + + i = 1; + while (i < Cmd_Argc()) + { + q_strlcpy(name, Cmd_Argv(i), sizeof(name)); + if (!Q_strrchr(Cmd_Argv(i), '.')) + { + q_strlcat(name, ".wav", sizeof(name)); + } + sfx = S_PrecacheSound(name); + S_StartSound(hash++, 0, sfx, listener_origin, 1.0, 1.0); + i++; + } +} + +static void S_PlayVol (void) +{ + static int hash = 543; + int i; + float vol; + char name[256]; + sfx_t *sfx; + + i = 1; + while (i < Cmd_Argc()) + { + q_strlcpy(name, Cmd_Argv(i), sizeof(name)); + if (!Q_strrchr(Cmd_Argv(i), '.')) + { + q_strlcat(name, ".wav", sizeof(name)); + } + sfx = S_PrecacheSound(name); + vol = Q_atof(Cmd_Argv(i + 1)); + S_StartSound(hash++, 0, sfx, listener_origin, vol, 1.0); + i += 2; + } +} + +static void S_SoundList (void) +{ + int i; + sfx_t *sfx; + sfxcache_t *sc; + int size, total; + + total = 0; + for (sfx = known_sfx, i = 0; i < num_sfx; i++, sfx++) + { + sc = (sfxcache_t *) Cache_Check (&sfx->cache); + if (!sc) + continue; + size = sc->length*sc->width*(sc->stereo + 1); + total += size; + if (sc->loopstart >= 0) + Con_SafePrintf ("L"); //johnfitz -- was Con_Printf + else + Con_SafePrintf (" "); //johnfitz -- was Con_Printf + Con_SafePrintf("(%2db) %6i : %s\n", sc->width*8, size, sfx->name); //johnfitz -- was Con_Printf + } + Con_Printf ("%i sounds, %i bytes\n", num_sfx, total); //johnfitz -- added count +} + + +void S_LocalSound (const char *name) +{ + sfx_t *sfx; + + if (nosound.value) + return; + if (!sound_started) + return; + + sfx = S_PrecacheSound (name); + if (!sfx) + { + Con_Printf ("S_LocalSound: can't cache %s\n", name); + return; + } + S_StartSound (cl.viewentity, -1, sfx, vec3_origin, 1, 1); +} + + +void S_ClearPrecache (void) +{ +} + + +void S_BeginPrecaching (void) +{ +} + + +void S_EndPrecaching (void) +{ +} + diff --git a/engine/Quake/snd_flac.c b/engine/Quake/snd_flac.c new file mode 100644 index 0000000..b5417b3 --- /dev/null +++ b/engine/Quake/snd_flac.c @@ -0,0 +1,390 @@ +/* + * fLaC streaming music support, loosely based QuakeForge implementation + * with modifications. requires libFLAC >= 1.0.4 at compile and runtime. + * + * Copyright (C) 2005 Bill Currie + * Copyright (C) 2013 O.Sezer + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#include "quakedef.h" + +#if defined(USE_CODEC_FLAC) +#include "snd_codec.h" +#include "snd_codeci.h" +#include "snd_flac.h" + +#undef LEGACY_FLAC +#include +/* FLAC 1.1.3 has FLAC_API_VERSION_CURRENT == 8 */ +#if !defined(FLAC_API_VERSION_CURRENT) || ((FLAC_API_VERSION_CURRENT+0) < 8) +#define LEGACY_FLAC +#include +#endif + +#ifdef LEGACY_FLAC +#define FLAC__StreamDecoder FLAC__SeekableStreamDecoder +#define FLAC__StreamDecoderReadStatus FLAC__SeekableStreamDecoderReadStatus +#define FLAC__StreamDecoderSeekStatus FLAC__SeekableStreamDecoderSeekStatus +#define FLAC__StreamDecoderTellStatus FLAC__SeekableStreamDecoderTellStatus +#define FLAC__StreamDecoderLengthStatus FLAC__SeekableStreamDecoderLengthStatus + +#define FLAC__stream_decoder_new FLAC__seekable_stream_decoder_new +#define FLAC__stream_decoder_finish FLAC__seekable_stream_decoder_finish +#define FLAC__stream_decoder_delete FLAC__seekable_stream_decoder_delete +#define FLAC__stream_decoder_process_single FLAC__seekable_stream_decoder_process_single +#define FLAC__stream_decoder_seek_absolute FLAC__seekable_stream_decoder_seek_absolute +#define FLAC__stream_decoder_process_until_end_of_metadata FLAC__seekable_stream_decoder_process_until_end_of_metadata +#define FLAC__stream_decoder_get_state FLAC__seekable_stream_decoder_get_state + +#define FLAC__STREAM_DECODER_INIT_STATUS_OK FLAC__SEEKABLE_STREAM_DECODER_OK +#define FLAC__STREAM_DECODER_READ_STATUS_CONTINUE FLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_OK +#define FLAC__STREAM_DECODER_READ_STATUS_ABORT FLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_ERROR +#define FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM FLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_OK /* !!! */ +#define FLAC__STREAM_DECODER_WRITE_STATUS_ABORT FLAC__STREAM_DECODER_WRITE_STATUS_ABORT +#define FLAC__STREAM_DECODER_SEEK_STATUS_OK FLAC__SEEKABLE_STREAM_DECODER_SEEK_STATUS_OK +#define FLAC__STREAM_DECODER_SEEK_STATUS_ERROR FLAC__SEEKABLE_STREAM_DECODER_SEEK_STATUS_ERROR +#define FLAC__STREAM_DECODER_TELL_STATUS_OK FLAC__SEEKABLE_STREAM_DECODER_TELL_STATUS_OK +#define FLAC__STREAM_DECODER_TELL_STATUS_ERROR FLAC__SEEKABLE_STREAM_DECODER_TELL_STATUS_ERROR +#define FLAC__STREAM_DECODER_LENGTH_STATUS_OK FLAC__SEEKABLE_STREAM_DECODER_LENGTH_STATUS_OK +typedef unsigned FLAC_SIZE_T; +#else +typedef size_t FLAC_SIZE_T; +#endif + +typedef struct { + FLAC__StreamDecoder *decoder; + fshandle_t *file; + snd_info_t *info; + byte *buffer; + int size, pos, error; +} flacfile_t; + +/* CALLBACK FUNCTIONS: */ +static void +flac_error_func (const FLAC__StreamDecoder *decoder, + FLAC__StreamDecoderErrorStatus status, void *client_data) +{ + flacfile_t *ff = (flacfile_t *) client_data; + ff->error = -1; + Con_Printf ("FLAC: decoder error %i\n", status); +} + +static FLAC__StreamDecoderReadStatus +flac_read_func (const FLAC__StreamDecoder *decoder, FLAC__byte buffer[], + FLAC_SIZE_T *bytes, void *client_data) +{ + flacfile_t *ff = (flacfile_t *) client_data; + if (*bytes > 0) + { + *bytes = FS_fread(buffer, 1, *bytes, ff->file); + if (FS_ferror(ff->file)) + return FLAC__STREAM_DECODER_READ_STATUS_ABORT; + if (*bytes == 0) + return FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM; + return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE; + } + return FLAC__STREAM_DECODER_READ_STATUS_ABORT; +} + +static FLAC__StreamDecoderSeekStatus +flac_seek_func (const FLAC__StreamDecoder *decoder, + FLAC__uint64 absolute_byte_offset, void *client_data) +{ + flacfile_t *ff = (flacfile_t *) client_data; + if (FS_fseek(ff->file, (long)absolute_byte_offset, SEEK_SET) < 0) + return FLAC__STREAM_DECODER_SEEK_STATUS_ERROR; + return FLAC__STREAM_DECODER_SEEK_STATUS_OK; +} + +static FLAC__StreamDecoderTellStatus +flac_tell_func (const FLAC__StreamDecoder *decoder, + FLAC__uint64 *absolute_byte_offset, void *client_data) +{ + flacfile_t *ff = (flacfile_t *) client_data; + long pos = FS_ftell (ff->file); + if (pos < 0) return FLAC__STREAM_DECODER_TELL_STATUS_ERROR; + *absolute_byte_offset = (FLAC__uint64) pos; + return FLAC__STREAM_DECODER_TELL_STATUS_OK; +} + +static FLAC__StreamDecoderLengthStatus +flac_length_func (const FLAC__StreamDecoder *decoder, + FLAC__uint64 *stream_length, void *client_data) +{ + flacfile_t *ff = (flacfile_t *) client_data; + *stream_length = (FLAC__uint64) FS_filelength (ff->file); + return FLAC__STREAM_DECODER_LENGTH_STATUS_OK; +} + +static FLAC__bool +flac_eof_func (const FLAC__StreamDecoder *decoder, void *client_data) +{ + flacfile_t *ff = (flacfile_t *) client_data; + if (FS_feof (ff->file)) return true; + return false; +} + +static FLAC__StreamDecoderWriteStatus +flac_write_func (const FLAC__StreamDecoder *decoder, + const FLAC__Frame *frame, const FLAC__int32 * const buffer[], + void *client_data) +{ + flacfile_t *ff = (flacfile_t *) client_data; + + if (!ff->buffer) { + ff->buffer = (byte *) malloc (ff->info->blocksize * ff->info->channels * ff->info->width); + if (!ff->buffer) { + ff->error = -1; /* needn't set this here, but... */ + Con_Printf("Insufficient memory for fLaC audio\n"); + return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT; + } + } + + if (ff->info->channels == 1) + { + unsigned i; + const FLAC__int32 *in = buffer[0]; + + if (ff->info->bits == 8) + { + byte *out = ff->buffer; + for (i = 0; i < frame->header.blocksize; i++) + *out++ = *in++ + 128; + } + else + { + short *out = (short *) ff->buffer; + for (i = 0; i < frame->header.blocksize; i++) + *out++ = *in++; + } + } + else + { + unsigned i; + const FLAC__int32 *li = buffer[0]; + const FLAC__int32 *ri = buffer[1]; + + if (ff->info->bits == 8) + { + char *lo = (char *) ff->buffer + 0; + char *ro = (char *) ff->buffer + 1; + for (i = 0; i < frame->header.blocksize; i++, lo++, ro++) + { + *lo++ = *li++ + 128; + *ro++ = *ri++ + 128; + } + } + else + { + short *lo = (short *) ff->buffer + 0; + short *ro = (short *) ff->buffer + 1; + for (i = 0; i < frame->header.blocksize; i++, lo++, ro++) + { + *lo++ = *li++; + *ro++ = *ri++; + } + } + } + + ff->size = frame->header.blocksize * ff->info->width * ff->info->channels; + ff->pos = 0; + return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE; +} + +static void +flac_meta_func (const FLAC__StreamDecoder *decoder, + const FLAC__StreamMetadata *metadata, void *client_data) +{ + flacfile_t *ff = (flacfile_t *) client_data; + if (metadata->type == FLAC__METADATA_TYPE_STREAMINFO) + { + ff->info->rate = metadata->data.stream_info.sample_rate; + ff->info->bits = metadata->data.stream_info.bits_per_sample; + ff->info->width = ff->info->bits / 8; + ff->info->channels = metadata->data.stream_info.channels; + ff->info->blocksize = metadata->data.stream_info.max_blocksize; + ff->info->dataofs = 0; /* got the STREAMINFO metadata */ + } +} + + +static qboolean S_FLAC_CodecInitialize (void) +{ + return true; +} + +static void S_FLAC_CodecShutdown (void) +{ +} + +static qboolean S_FLAC_CodecOpenStream (snd_stream_t *stream) +{ + flacfile_t *ff; + int rc; + + ff = (flacfile_t *) Z_Malloc(sizeof(flacfile_t)); + + ff->decoder = FLAC__stream_decoder_new (); + if (ff->decoder == NULL) + { + Con_Printf("Unable to create fLaC decoder\n"); + goto _fail; + } + + stream->priv = ff; + ff->info = & stream->info; + ff->file = & stream->fh; + ff->info->dataofs = -1; /* check for STREAMINFO metadata existence */ + +#ifdef LEGACY_FLAC + FLAC__seekable_stream_decoder_set_error_callback (ff->decoder, flac_error_func); + FLAC__seekable_stream_decoder_set_read_callback (ff->decoder, flac_read_func); + FLAC__seekable_stream_decoder_set_seek_callback (ff->decoder, flac_seek_func); + FLAC__seekable_stream_decoder_set_tell_callback (ff->decoder, flac_tell_func); + FLAC__seekable_stream_decoder_set_length_callback (ff->decoder, flac_length_func); + FLAC__seekable_stream_decoder_set_eof_callback (ff->decoder, flac_eof_func); + FLAC__seekable_stream_decoder_set_write_callback (ff->decoder, flac_write_func); + FLAC__seekable_stream_decoder_set_metadata_callback (ff->decoder, flac_meta_func); + FLAC__seekable_stream_decoder_set_client_data (ff->decoder, ff); + rc = FLAC__seekable_stream_decoder_init (ff->decoder); +#else + rc = FLAC__stream_decoder_init_stream(ff->decoder, + flac_read_func, + flac_seek_func, + flac_tell_func, + flac_length_func, + flac_eof_func, + flac_write_func, + flac_meta_func, + flac_error_func, + ff); +#endif + if (rc != FLAC__STREAM_DECODER_INIT_STATUS_OK) /* unlikely */ + { + Con_Printf ("FLAC: decoder init error %i\n", rc); + goto _fail; + } + + rc = FLAC__stream_decoder_process_until_end_of_metadata (ff->decoder); + if (rc == false || ff->error) + { + rc = FLAC__stream_decoder_get_state(ff->decoder); + Con_Printf("%s not a valid flac file? (decoder state %i)\n", + stream->name, rc); + goto _fail; + } + + if (ff->info->dataofs < 0) + { + Con_Printf("%s has no STREAMINFO\n", stream->name); + goto _fail; + } + if (ff->info->bits != 8 && ff->info->bits != 16) + { + Con_Printf("%s is not 8 or 16 bit\n", stream->name); + goto _fail; + } + if (ff->info->channels != 1 && ff->info->channels != 2) + { + Con_Printf("Unsupported number of channels %d in %s\n", + ff->info->channels, stream->name); + goto _fail; + } + + return true; + +_fail: + if (ff->decoder) + { + FLAC__stream_decoder_finish (ff->decoder); + FLAC__stream_decoder_delete (ff->decoder); + } + Z_Free(ff); + return false; +} + +static int S_FLAC_CodecReadStream (snd_stream_t *stream, int len, void *buffer) +{ + flacfile_t *ff = (flacfile_t *) stream->priv; + byte *buf = (byte *) buffer; + int count = 0; + + while (len) { + int res = 0; + if (ff->size == ff->pos) + FLAC__stream_decoder_process_single (ff->decoder); + if (ff->error) return -1; + res = ff->size - ff->pos; + if (res > len) + res = len; + if (res > 0) { + memcpy (buf, ff->buffer + ff->pos, res); + count += res; + len -= res; + buf += res; + ff->pos += res; + } else if (res < 0) { /* error */ + return -1; + } else { + Con_DPrintf ("FLAC: EOF\n"); + break; + } + } + return count; +} + +static void S_FLAC_CodecCloseStream (snd_stream_t *stream) +{ + flacfile_t *ff = (flacfile_t *) stream->priv; + + FLAC__stream_decoder_finish (ff->decoder); + FLAC__stream_decoder_delete (ff->decoder); + + if (ff->buffer) + free(ff->buffer); + Z_Free(ff); + + S_CodecUtilClose(&stream); +} + +static int S_FLAC_CodecRewindStream (snd_stream_t *stream) +{ + flacfile_t *ff = (flacfile_t *) stream->priv; + + ff->pos = ff->size = 0; + if (FLAC__stream_decoder_seek_absolute(ff->decoder, 0)) return 0; + return -1; +} + +snd_codec_t flac_codec = +{ + CODECTYPE_FLAC, + true, /* always available. */ + "flac", + S_FLAC_CodecInitialize, + S_FLAC_CodecShutdown, + S_FLAC_CodecOpenStream, + S_FLAC_CodecReadStream, + S_FLAC_CodecRewindStream, + S_FLAC_CodecCloseStream, + NULL +}; + +#endif /* USE_CODEC_FLAC */ + diff --git a/engine/Quake/snd_flac.h b/engine/Quake/snd_flac.h new file mode 100644 index 0000000..4cedf82 --- /dev/null +++ b/engine/Quake/snd_flac.h @@ -0,0 +1,13 @@ +/* fLaC streaming music support. */ + +#if !defined(_SND_FLAC_H_) +#define _SND_FLAC_H_ 1 + +#if defined(USE_CODEC_FLAC) + +extern snd_codec_t flac_codec; + +#endif /* USE_CODEC_FLAC */ + +#endif /* ! _SND_FLAC_H_ */ + diff --git a/engine/code/snd_mem.c b/engine/Quake/snd_mem.c similarity index 64% rename from engine/code/snd_mem.c rename to engine/Quake/snd_mem.c index eb6d41c..239e020 100644 --- a/engine/code/snd_mem.c +++ b/engine/Quake/snd_mem.c @@ -1,5 +1,6 @@ /* -Copyright (C) 1996-1997 Id Software, Inc. +Copyright (C) 1996-2001 Id Software, Inc. +Copyright (C) 2010-2011 O. Sezer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -8,7 +9,7 @@ of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. @@ -21,16 +22,12 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "quakedef.h" -int cache_full_cycle; - -byte *S_Alloc (int size); - /* ================ ResampleSfx ================ */ -void ResampleSfx (sfx_t *sfx, int inrate, int inwidth, byte *data) +static void ResampleSfx (sfx_t *sfx, int inrate, int inwidth, byte *data) { int outcount; int srcsample; @@ -38,8 +35,8 @@ void ResampleSfx (sfx_t *sfx, int inrate, int inwidth, byte *data) int i; int sample, samplefrac, fracstep; sfxcache_t *sc; - - sc = Cache_Check (&sfx->cache); + + sc = (sfxcache_t *) Cache_Check (&sfx->cache); if (!sc) return; @@ -62,16 +59,15 @@ void ResampleSfx (sfx_t *sfx, int inrate, int inwidth, byte *data) if (stepscale == 1 && inwidth == 1 && sc->width == 1) { // fast special case - for (i=0 ; idata)[i] - = (int)( (unsigned char)(data[i]) - 128); + for (i = 0; i < outcount; i++) + ((signed char *)sc->data)[i] = (int)( (unsigned char)(data[i]) - 128); } else { // general case samplefrac = 0; fracstep = stepscale*256; - for (i=0 ; i> 8; samplefrac += fracstep; @@ -96,7 +92,7 @@ S_LoadSound */ sfxcache_t *S_LoadSound (sfx_t *s) { - char namebuffer[256]; + char namebuffer[256]; byte *data; wavinfo_t info; int len; @@ -105,18 +101,19 @@ sfxcache_t *S_LoadSound (sfx_t *s) byte stackbuf[1*1024]; // avoid dirtying the cache heap // see if still in memory - sc = Cache_Check (&s->cache); + sc = (sfxcache_t *) Cache_Check (&s->cache); if (sc) return sc; -//Con_Printf ("S_LoadSound: %x\n", (int)stackbuf); +// Con_Printf ("S_LoadSound: %x\n", (int)stackbuf); + // load it in - Q_strcpy(namebuffer, "sound/"); - Q_strcat(namebuffer, s->name); + q_strlcpy(namebuffer, "sound/", sizeof(namebuffer)); + q_strlcat(namebuffer, s->name, sizeof(namebuffer)); // Con_Printf ("loading %s\n",namebuffer); - data = COM_LoadStackFile(namebuffer, stackbuf, sizeof(stackbuf)); + data = COM_LoadStackFile(namebuffer, stackbuf, sizeof(stackbuf), NULL); if (!data) { @@ -131,15 +128,27 @@ sfxcache_t *S_LoadSound (sfx_t *s) return NULL; } - stepscale = (float)info.rate / shm->speed; + if (info.width != 1 && info.width != 2) + { + Con_Printf("%s is not 8 or 16 bit\n", s->name); + return NULL; + } + + stepscale = (float)info.rate / shm->speed; len = info.samples / stepscale; len = len * info.width * info.channels; - sc = Cache_Alloc ( &s->cache, len + sizeof(sfxcache_t), s->name); + if (info.samples == 0 || len == 0) + { + Con_Printf("%s has zero samples\n", s->name); + return NULL; + } + + sc = (sfxcache_t *) Cache_Alloc ( &s->cache, len + sizeof(sfxcache_t), s->name); if (!sc) return NULL; - + sc->length = info.samples; sc->loopstart = info.loopstart; sc->speed = info.rate; @@ -161,15 +170,13 @@ WAV loading =============================================================================== */ +static byte *data_p; +static byte *iff_end; +static byte *last_chunk; +static byte *iff_data; +static int iff_chunk_len; -byte *data_p; -byte *iff_end; -byte *last_chunk; -byte *iff_data; -int iff_chunk_len; - - -short GetLittleShort(void) +static short GetLittleShort (void) { short val = 0; val = *data_p; @@ -178,7 +185,7 @@ short GetLittleShort(void) return val; } -int GetLittleLong(void) +static int GetLittleLong (void) { int val = 0; val = *data_p; @@ -189,107 +196,111 @@ int GetLittleLong(void) return val; } -void FindNextChunk(char *name) +static void FindNextChunk (const char *name) { while (1) { - data_p=last_chunk; - - if (data_p >= iff_end) - { // didn't find the chunk + // Need at least 8 bytes for a chunk + if (last_chunk + 8 >= iff_end) + { data_p = NULL; return; } - - data_p += 4; + + data_p = last_chunk + 4; iff_chunk_len = GetLittleLong(); - if (iff_chunk_len < 0) + if (iff_chunk_len < 0 || iff_chunk_len > iff_end - data_p) { data_p = NULL; + Con_DPrintf2("bad \"%s\" chunk length (%d)\n", name, iff_chunk_len); return; } -// if (iff_chunk_len > 1024*1024) -// Sys_Error ("FindNextChunk: %i length is past the 1 meg sanity limit", iff_chunk_len); + last_chunk = data_p + ((iff_chunk_len + 1) & ~1); data_p -= 8; - last_chunk = data_p + 8 + ( (iff_chunk_len + 1) & ~1 ); - if (!Q_strncmp(data_p, name, 4)) + if (!Q_strncmp((char *)data_p, name, 4)) return; } } -void FindChunk(char *name) +static void FindChunk (const char *name) { last_chunk = iff_data; FindNextChunk (name); } - -void DumpChunks(void) +#if 0 +static void DumpChunks (void) { char str[5]; - + str[4] = 0; - data_p=iff_data; + data_p = iff_data; do { memcpy (str, data_p, 4); data_p += 4; iff_chunk_len = GetLittleLong(); - Con_Printf ("0x%x : %s (%d)\n", (intptr_t)(data_p - 4), str, iff_chunk_len); + Con_Printf ("0x%x : %s (%d)\n", (int)(data_p - 4), str, iff_chunk_len); data_p += (iff_chunk_len + 1) & ~1; } while (data_p < iff_end); } +#endif /* ============ GetWavinfo ============ */ -wavinfo_t GetWavinfo (char *name, byte *wav, int wavlength) +wavinfo_t GetWavinfo (const char *name, byte *wav, int wavlength) { wavinfo_t info; - int i; - int format; - int samples; + int i; + int format; + int samples; memset (&info, 0, sizeof(info)); if (!wav) return info; - + iff_data = wav; iff_end = wav + wavlength; // find "RIFF" chunk FindChunk("RIFF"); - if (!(data_p && !Q_strncmp(data_p+8, "WAVE", 4))) + if (!(data_p && !Q_strncmp((char *)data_p + 8, "WAVE", 4))) { - Con_Printf("Missing RIFF/WAVE chunks\n"); + Con_Printf("%s missing RIFF/WAVE chunks\n", name); return info; } // get "fmt " chunk iff_data = data_p + 12; -// DumpChunks (); +#if 0 + DumpChunks (); +#endif FindChunk("fmt "); if (!data_p) { - Con_Printf("Missing fmt chunk\n"); + Con_Printf("%s is missing fmt chunk\n", name); return info; } data_p += 8; format = GetLittleShort(); - if (format != 1) + if (format != WAV_FORMAT_PCM) { - Con_Printf("Microsoft PCM format only\n"); + Con_Printf("%s is not Microsoft PCM format\n", name); return info; } info.channels = GetLittleShort(); info.rate = GetLittleLong(); - data_p += 4+2; - info.width = GetLittleShort() / 8; + data_p += 4 + 2; + i = GetLittleShort(); + if (i != 8 && i != 16) + return info; + info.width = i / 8; // get cue chunk FindChunk("cue "); @@ -297,18 +308,18 @@ wavinfo_t GetWavinfo (char *name, byte *wav, int wavlength) { data_p += 32; info.loopstart = GetLittleLong(); -// Con_Printf("loopstart=%d\n", sfx->loopstart); + // Con_Printf("loopstart=%d\n", sfx->loopstart); // if the next chunk is a LIST chunk, look for a cue length marker FindNextChunk ("LIST"); if (data_p) { - if (!strncmp (data_p + 28, "mark", 4)) + if (!strncmp((char *)data_p + 28, "mark", 4)) { // this is not a proper parse, but it works with cooledit... data_p += 24; - i = GetLittleLong (); // samples in loop + i = GetLittleLong(); // samples in loop info.samples = info.loopstart + i; -// Con_Printf("looped length: %i\n", i); + // Con_Printf("looped length: %i\n", i); } } } @@ -319,23 +330,23 @@ wavinfo_t GetWavinfo (char *name, byte *wav, int wavlength) FindChunk("data"); if (!data_p) { - Con_Printf("Missing data chunk\n"); + Con_Printf("%s is missing data chunk\n", name); return info; } data_p += 4; - samples = GetLittleLong () / info.width; + samples = GetLittleLong() / info.width; if (info.samples) { if (samples < info.samples) - Sys_Error ("Sound %s has a bad loop length", name); + Sys_Error ("%s has a bad loop length", name); } else info.samples = samples; info.dataofs = data_p - wav; - + return info; } diff --git a/engine/Quake/snd_mikmod.c b/engine/Quake/snd_mikmod.c new file mode 100644 index 0000000..2327181 --- /dev/null +++ b/engine/Quake/snd_mikmod.c @@ -0,0 +1,204 @@ +/* + * tracker music (module file) decoding support using libmikmod + * Copyright (C) 2013 O.Sezer + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "quakedef.h" + +#if defined(USE_CODEC_MIKMOD) +#include "snd_codec.h" +#include "snd_codeci.h" +#include "snd_mikmod.h" +#include + +#if ((LIBMIKMOD_VERSION+0) < 0x030105) +#error libmikmod version is way too old and unusable. +#endif +#if (LIBMIKMOD_VERSION < 0x030107) /* ancient libmikmod */ +#define S_MIKMOD_initlib(c) MikMod_Init() +#else +#define S_MIKMOD_initlib(c) MikMod_Init(c) +#endif + +#ifndef DMODE_NOISEREDUCTION +#define DMODE_NOISEREDUCTION 0x1000 /* Low pass filtering */ +#endif +#ifndef DMODE_SIMDMIXER +#define DMODE_SIMDMIXER 0x0800 /* enable SIMD mixing */ +#endif + +typedef struct _mik_priv { +/* struct MREADER in libmikmod <= 3.2.0-beta2 + * doesn't have iobase members. adding them here + * so that if we compile against 3.2.0-beta2, we + * can still run OK against 3.2.0b3 and newer. */ + struct MREADER reader; + long iobase, prev_iobase; + fshandle_t *fh; + MODULE *module; +} mik_priv_t; + +static int MIK_Seek (MREADER *r, long ofs, int whence) +{ + return FS_fseek(((mik_priv_t *)r)->fh, ofs, whence); +} + +static long MIK_Tell (MREADER *r) +{ + return FS_ftell(((mik_priv_t *)r)->fh); +} + +static BOOL MIK_Read (MREADER *r, void *ptr, size_t siz) +{ + return !!FS_fread(ptr, siz, 1, ((mik_priv_t *)r)->fh); +} + +static int MIK_Get (MREADER *r) +{ + return FS_fgetc(((mik_priv_t *)r)->fh); +} + +static BOOL MIK_Eof (MREADER *r) +{ + return FS_feof(((mik_priv_t *)r)->fh); +} + +static qboolean S_MIKMOD_CodecInitialize (void) +{ + if (mikmod_codec.initialized) + return true; + + /* set mode flags to only we like: */ + md_mode = 0; + if ((shm->samplebits / 8) == 2) + md_mode |= DMODE_16BITS; + if (shm->channels == 2) + md_mode |= DMODE_STEREO; + md_mode |= DMODE_SOFT_MUSIC; /* this is a software-only mixer */ + + /* md_mixfreq is UWORD, so something like 96000 isn't OK */ + md_mixfreq = (shm->speed < 65536)? shm->speed : 48000; + + /* keeping md_device as 0 which is default (auto-detect: we + * only register drv_nos, and it will be the only one found.) + * md_pansep (stereo channels separation) default 128 is OK. + * no reverbation (md_reverb 0 (up to 15)) is OK. + * md_musicvolume and md_sndfxvolume defaults are 128: OK. */ + /* just tone down overall volume md_volume from 128 to 96? */ + md_volume = 96; + + MikMod_RegisterDriver(&drv_nos); /* only need the "nosound" driver, none else */ + MikMod_RegisterAllLoaders(); + if (S_MIKMOD_initlib(NULL)) + { + Con_DPrintf("Could not initialize MikMod: %s\n", MikMod_strerror(MikMod_errno)); + return false; + } + + /* this can't get set with drv_nos, but whatever, be safe: */ + md_mode &= ~DMODE_SIMDMIXER; /* SIMD mixer is buggy when combined with HQMIXER */ + + mikmod_codec.initialized = true; + return true; +} + +static void S_MIKMOD_CodecShutdown (void) +{ + if (mikmod_codec.initialized) + { + mikmod_codec.initialized = false; + MikMod_Exit(); + } +} + +static qboolean S_MIKMOD_CodecOpenStream (snd_stream_t *stream) +{ + mik_priv_t *priv; + + stream->priv = Z_Malloc(sizeof(mik_priv_t)); + priv = (mik_priv_t *) stream->priv; + priv->reader.Seek = MIK_Seek; + priv->reader.Tell = MIK_Tell; + priv->reader.Read = MIK_Read; + priv->reader.Get = MIK_Get; + priv->reader.Eof = MIK_Eof; + priv->fh = &stream->fh; + + priv->module = Player_LoadGeneric((MREADER *)stream->priv, 64, 0); + if (!priv->module) + { + Con_DPrintf("Could not load module: %s\n", MikMod_strerror(MikMod_errno)); + Z_Free(stream->priv); + return false; + } + + /* keep default values of fadeout (0: don't fade out volume during when last + * position of the module is being played), extspd (1: do process Protracker + * extended speed effect), panflag (1: do process panning effects), wrap (0: + * don't wrap to restart position when module is finished) are OK with us as + * set internally by libmikmod::Player_Init(). */ + /* just change the loop setting to 0, i.e. don't process in-module loops: */ + priv->module->loop = 0; + Player_Start(priv->module); + + stream->info.rate = md_mixfreq; + stream->info.bits = (md_mode & DMODE_16BITS)? 16: 8; + stream->info.width = stream->info.bits / 8; + stream->info.channels = (md_mode & DMODE_STEREO)? 2 : 1; +/* Con_DPrintf("Playing %s (%d chn)\n", priv->module->songname, priv->module->numchn);*/ + + return true; +} + +static int S_MIKMOD_CodecReadStream (snd_stream_t *stream, int bytes, void *buffer) +{ + if (!Player_Active()) + return 0; + return (int) VC_WriteBytes((SBYTE *)buffer, bytes); +} + +static void S_MIKMOD_CodecCloseStream (snd_stream_t *stream) +{ + Player_Stop(); + Player_Free(((mik_priv_t *)stream->priv)->module); + Z_Free(stream->priv); + S_CodecUtilClose(&stream); +} + +static int S_MIKMOD_CodecRewindStream (snd_stream_t *stream) +{ + Player_SetPosition (0); + return 0; +} + +snd_codec_t mikmod_codec = +{ + CODECTYPE_MOD, + false, + "s3m", + S_MIKMOD_CodecInitialize, + S_MIKMOD_CodecShutdown, + S_MIKMOD_CodecOpenStream, + S_MIKMOD_CodecReadStream, + S_MIKMOD_CodecRewindStream, + S_MIKMOD_CodecCloseStream, + NULL +}; + +#endif /* USE_CODEC_MIKMOD */ + diff --git a/engine/Quake/snd_mikmod.h b/engine/Quake/snd_mikmod.h new file mode 100644 index 0000000..9f0338b --- /dev/null +++ b/engine/Quake/snd_mikmod.h @@ -0,0 +1,13 @@ +/* module tracker decoding support using libmikmod */ + +#if !defined(_SND_MIKMOD_H_) +#define _SND_MIKMOD_H_ + +#if defined(USE_CODEC_MIKMOD) + +extern snd_codec_t mikmod_codec; + +#endif /* USE_CODEC_MIKMOD */ + +#endif /* ! _SND_MIKMOD_H_ */ + diff --git a/engine/Quake/snd_mix.c b/engine/Quake/snd_mix.c new file mode 100644 index 0000000..8dc3e02 --- /dev/null +++ b/engine/Quake/snd_mix.c @@ -0,0 +1,527 @@ +/* +Copyright (C) 1996-2001 Id Software, Inc. +Copyright (C) 2010-2011 O. Sezer +Copyright (C) 2010-2014 QuakeSpasm developers + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ +// snd_mix.c -- portable code to mix sounds for snd_dma.c + +#include "quakedef.h" + +#define PAINTBUFFER_SIZE 2048 +portable_samplepair_t paintbuffer[PAINTBUFFER_SIZE]; +int snd_scaletable[32][256]; +int *snd_p, snd_linear_count; +short *snd_out; + +static int snd_vol; + +static void Snd_WriteLinearBlastStereo16 (void) +{ + int i; + int val; + + for (i = 0; i < snd_linear_count; i += 2) + { + val = snd_p[i] / 256; + if (val > 0x7fff) + snd_out[i] = 0x7fff; + else if (val < (short)0x8000) + snd_out[i] = (short)0x8000; + else + snd_out[i] = val; + + val = snd_p[i+1] / 256; + if (val > 0x7fff) + snd_out[i+1] = 0x7fff; + else if (val < (short)0x8000) + snd_out[i+1] = (short)0x8000; + else + snd_out[i+1] = val; + } +} + +static void S_TransferStereo16 (int endtime) +{ + int lpos; + int lpaintedtime; + + snd_p = (int *) paintbuffer; + lpaintedtime = paintedtime; + + while (lpaintedtime < endtime) + { + // handle recirculating buffer issues + lpos = lpaintedtime & ((shm->samples >> 1) - 1); + + snd_out = (short *)shm->buffer + (lpos << 1); + + snd_linear_count = (shm->samples >> 1) - lpos; + if (lpaintedtime + snd_linear_count > endtime) + snd_linear_count = endtime - lpaintedtime; + + snd_linear_count <<= 1; + + // write a linear blast of samples + Snd_WriteLinearBlastStereo16 (); + + snd_p += snd_linear_count; + lpaintedtime += (snd_linear_count >> 1); + } +} + +static void S_TransferPaintBuffer (int endtime) +{ + int out_idx, out_mask; + int count, step, val; + int *p; + + if (shm->samplebits == 16 && shm->channels == 2) + { + S_TransferStereo16 (endtime); + return; + } + + p = (int *) paintbuffer; + count = (endtime - paintedtime) * shm->channels; + out_mask = shm->samples - 1; + out_idx = paintedtime * shm->channels & out_mask; + step = 3 - shm->channels; + + if (shm->samplebits == 16) + { + short *out = (short *)shm->buffer; + while (count--) + { + val = *p / 256; + p+= step; + if (val > 0x7fff) + val = 0x7fff; + else if (val < (short)0x8000) + val = (short)0x8000; + out[out_idx] = val; + out_idx = (out_idx + 1) & out_mask; + } + } + else if (shm->samplebits == 8 && !shm->signed8) + { + unsigned char *out = shm->buffer; + while (count--) + { + val = *p / 256; + p+= step; + if (val > 0x7fff) + val = 0x7fff; + else if (val < (short)0x8000) + val = (short)0x8000; + out[out_idx] = (val / 256) + 128; + out_idx = (out_idx + 1) & out_mask; + } + } + else if (shm->samplebits == 8) /* S8 format, e.g. with Amiga AHI */ + { + signed char *out = (signed char *) shm->buffer; + while (count--) + { + val = *p / 256; + p+= step; + if (val > 0x7fff) + val = 0x7fff; + else if (val < (short)0x8000) + val = (short)0x8000; + out[out_idx] = (val / 256); + out_idx = (out_idx + 1) & out_mask; + } + } +} + +/* +============== +S_MakeBlackmanWindowKernel + +Makes a lowpass filter kernel, from equation 16-4 in +"The Scientist and Engineer's Guide to Digital Signal Processing" + +M is the kernel size (not counting the center point), must be even +kernel has room for M+1 floats +f_c is the filter cutoff frequency, as a fraction of the samplerate +============== +*/ +static void S_MakeBlackmanWindowKernel(float *kernel, int M, float f_c) +{ + int i; + for (i = 0; i <= M; i++) + { + if (i == M/2) + { + kernel[i] = 2 * M_PI * f_c; + } + else + { + kernel[i] = ( sin(2 * M_PI * f_c * (i - M/2.0)) / (i - (M/2.0)) ) + * (0.42 - 0.5*cos(2 * M_PI * i / (double)M) + + 0.08*cos(4 * M_PI * i / (double)M) ); + } + } + +// normalize the kernel so all of the values sum to 1 + { + float sum = 0; + for (i = 0; i <= M; i++) + { + sum += kernel[i]; + } + + for (i = 0; i <= M; i++) + { + kernel[i] /= sum; + } + } +} + +typedef struct { + float *memory; // kernelsize floats + float *kernel; // kernelsize floats + int kernelsize; // M+1, rounded up to be a multiple of 16 + int M; // M value used to make kernel, even + int parity; // 0-3 + float f_c; // cutoff frequency, [0..1], fraction of sample rate +} filter_t; + +static void S_UpdateFilter(filter_t *filter, int M, float f_c) +{ + if (filter->f_c != f_c || filter->M != M) + { + if (filter->memory != NULL) free(filter->memory); + if (filter->kernel != NULL) free(filter->kernel); + + filter->M = M; + filter->f_c = f_c; + + filter->parity = 0; + // M + 1 rounded up to the next multiple of 16 + filter->kernelsize = (M + 1) + 16 - ((M + 1) % 16); + filter->memory = (float *) calloc(filter->kernelsize, sizeof(float)); + filter->kernel = (float *) calloc(filter->kernelsize, sizeof(float)); + + S_MakeBlackmanWindowKernel(filter->kernel, M, f_c); + } +} + +/* +============== +S_ApplyFilter + +Lowpass-filter the given buffer containing 44100Hz audio. + +As an optimization, it decimates the audio to 11025Hz (setting every sample +position that's not a multiple of 4 to 0), then convoluting with the filter +kernel is 4x faster, because we can skip 3/4 of the input samples that are +known to be 0 and skip 3/4 of the filter kernel. +============== +*/ +static void S_ApplyFilter(filter_t *filter, int *data, int stride, int count) +{ + int i, j; + float *input; + const int kernelsize = filter->kernelsize; + const float *kernel = filter->kernel; + int parity; + + input = (float *) malloc(sizeof(float) * (filter->kernelsize + count)); + +// set up the input buffer +// memory holds the previous filter->kernelsize samples of input. + memcpy(input, filter->memory, filter->kernelsize * sizeof(float)); + + for (i=0; ikernelsize+i] = data[i * stride] / (32768.0 * 256.0); + } + +// copy out the last filter->kernelsize samples to 'memory' for next time + memcpy(filter->memory, input + count, filter->kernelsize * sizeof(float)); + +// apply the filter + parity = filter->parity; + + for (i=0; iparity = parity; + + free(input); +} + +/* +============== +S_LowpassFilter + +lowpass filters 24-bit integer samples in 'data' (stored in 32-bit ints). +assumes 44100Hz sample rate, and lowpasses at around 5kHz +memory should be a zero-filled filter_t struct +============== +*/ +static void S_LowpassFilter(int *data, int stride, int count, + filter_t *memory) +{ + int M; + float bw, f_c; + + switch ((int)snd_filterquality.value) + { + case 1: + M = 126; bw = 0.900; break; + case 2: + M = 150; bw = 0.915; break; + case 3: + M = 174; bw = 0.930; break; + case 4: + M = 198; bw = 0.945; break; + case 5: + default: + M = 222; bw = 0.960; break; + } + + f_c = (bw * 11025 / 2.0) / 44100.0; + + S_UpdateFilter(memory, M, f_c); + S_ApplyFilter(memory, data, stride, count); +} + +/* +=============================================================================== + +CHANNEL MIXING + +=============================================================================== +*/ + +static void SND_PaintChannelFrom8 (channel_t *ch, sfxcache_t *sc, int endtime, int paintbufferstart); +static void SND_PaintChannelFrom16 (channel_t *ch, sfxcache_t *sc, int endtime, int paintbufferstart); + +void S_PaintChannels (int endtime) +{ + int i; + int end, ltime, count; + channel_t *ch; + sfxcache_t *sc; + + snd_vol = sfxvolume.value * 256; + + while (paintedtime < endtime) + { + // if paintbuffer is smaller than DMA buffer + end = endtime; + if (endtime - paintedtime > PAINTBUFFER_SIZE) + end = paintedtime + PAINTBUFFER_SIZE; + + // clear the paint buffer + memset(paintbuffer, 0, (end - paintedtime) * sizeof(portable_samplepair_t)); + + // paint in the channels. + ch = snd_channels; + for (i = 0; i < total_channels; i++, ch++) + { + if (!ch->sfx) + continue; + if (!ch->leftvol && !ch->rightvol) + continue; + sc = S_LoadSound (ch->sfx); + if (!sc) + continue; + + ltime = paintedtime; + + while (ltime < end) + { // paint up to end + if (ch->end < end) + count = ch->end - ltime; + else + count = end - ltime; + + if (count > 0) + { + // the last param to SND_PaintChannelFrom is the index + // to start painting to in the paintbuffer, usually 0. + if (sc->width == 1) + SND_PaintChannelFrom8(ch, sc, count, ltime - paintedtime); + else + SND_PaintChannelFrom16(ch, sc, count, ltime - paintedtime); + + ltime += count; + } + + // if at end of loop, restart + if (ltime >= ch->end) + { + if (sc->loopstart >= 0) + { + ch->pos = sc->loopstart; + ch->end = ltime + sc->length - ch->pos; + } + else + { // channel just stopped + ch->sfx = NULL; + break; + } + } + } + } + + // clip each sample to 0dB, then reduce by 6dB (to leave some headroom for + // the lowpass filter and the music). the lowpass will smooth out the + // clipping + for (i=0; ispeed == 44100) + { + static filter_t memory_l, memory_r; + S_LowpassFilter((int *)paintbuffer, 2, end - paintedtime, &memory_l); + S_LowpassFilter(((int *)paintbuffer) + 1, 2, end - paintedtime, &memory_r); + } + + // paint in the music + if (s_rawend >= paintedtime) + { // copy from the streaming sound source + int s; + int stop; + + stop = (end < s_rawend) ? end : s_rawend; + + for (i = paintedtime; i < stop; i++) + { + s = i & (MAX_RAW_SAMPLES - 1); + // lower music by 6db to match sfx + paintbuffer[i - paintedtime].left += s_rawsamples[s].left / 2; + paintbuffer[i - paintedtime].right += s_rawsamples[s].right / 2; + } + // if (i != end) + // Con_Printf ("partial stream\n"); + // else + // Con_Printf ("full stream\n"); + } + + // transfer out according to DMA format + S_TransferPaintBuffer(end); + paintedtime = end; + } +} + +void SND_InitScaletable (void) +{ + int i, j; + int scale; + + for (i = 0; i < 32; i++) + { + scale = i * 8 * 256 * sfxvolume.value; + for (j = 0; j < 256; j++) + { + /* When compiling with gcc-4.1.0 at optimisations O1 and + higher, the tricky signed char type conversion is not + guaranteed. Therefore we explicity calculate the signed + value from the index as required. From Kevin Shanahan. + See: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=26719 + */ + // snd_scaletable[i][j] = ((signed char)j) * scale; + snd_scaletable[i][j] = ((j < 128) ? j : j - 256) * scale; + } + } +} + + +static void SND_PaintChannelFrom8 (channel_t *ch, sfxcache_t *sc, int count, int paintbufferstart) +{ + int data; + int *lscale, *rscale; + unsigned char *sfx; + int i; + + if (ch->leftvol > 255) + ch->leftvol = 255; + if (ch->rightvol > 255) + ch->rightvol = 255; + + lscale = snd_scaletable[ch->leftvol >> 3]; + rscale = snd_scaletable[ch->rightvol >> 3]; + sfx = (unsigned char *)sc->data + ch->pos; + + for (i = 0; i < count; i++) + { + data = sfx[i]; + paintbuffer[paintbufferstart + i].left += lscale[data]; + paintbuffer[paintbufferstart + i].right += rscale[data]; + } + + ch->pos += count; +} + +static void SND_PaintChannelFrom16 (channel_t *ch, sfxcache_t *sc, int count, int paintbufferstart) +{ + int data; + int left, right; + int leftvol, rightvol; + signed short *sfx; + int i; + + leftvol = ch->leftvol * snd_vol; + rightvol = ch->rightvol * snd_vol; + leftvol /= 256; + rightvol /= 256; + sfx = (signed short *)sc->data + ch->pos; + + for (i = 0; i < count; i++) + { + data = sfx[i]; + // this was causing integer overflow as observed in quakespasm + // with the warpspasm mod moved >>8 to left/right volume above. + // left = (data * leftvol) >> 8; + // right = (data * rightvol) >> 8; + left = data * leftvol; + right = data * rightvol; + paintbuffer[paintbufferstart + i].left += left; + paintbuffer[paintbufferstart + i].right += right; + } + + ch->pos += count; +} + diff --git a/engine/Quake/snd_mp3.c b/engine/Quake/snd_mp3.c new file mode 100644 index 0000000..d13aaca --- /dev/null +++ b/engine/Quake/snd_mp3.c @@ -0,0 +1,663 @@ +/* + * MP3 decoding support using libmad: Adapted from the SoX library at + * http://sourceforge.net/projects/sox/, LGPLv2, Copyright (c) 2007-2009 + * SoX contributors, written by Fabrizio Gennari , + * with the decoding part based on the decoder tutorial program madlld + * written by Bertrand Petit (BSD license, see at + * http://www.bsd-dk.dk/~elrond/audio/madlld/). The tag identification + * functions were initially adapted from GPL-licensed libid3tag library + * (see at http://www.underbit.com/products/mad/) then rephrased further. + * Adapted for use in Quake and Hexen II game engines by O.Sezer: + * Copyright (C) 2010-2019 O.Sezer + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "quakedef.h" + +#if defined(USE_CODEC_MP3) +#include "snd_codec.h" +#include "snd_codeci.h" +#include "snd_mp3.h" +#include + +/* Under Windows, importing data from DLLs is a dicey proposition. This is true + * when using dlopen, but also true if linking directly against the DLL if the + * header does not mark the data as __declspec(dllexport), which mad.h does not. + * Sidestep the issue by defining our own mad_timer_zero. This is needed because + * mad_timer_zero is used in some of the mad.h macros. + */ +#define mad_timer_zero mad_timer_zero_stub +static mad_timer_t const mad_timer_zero_stub = {0, 0}; + +/* MAD returns values with MAD_F_FRACBITS (28) bits of precision, though it's + not certain that all of them are meaningful. Default to 16 bits to + align with most users expectation of output file should be 16 bits. */ +#define MP3_MAD_SAMPLEBITS 16 +#define MP3_MAD_SAMPLEWIDTH 2 +#define MP3_BUFFER_SIZE (5 * 8192) + +/* Private data */ +typedef struct _mp3_priv_t +{ + unsigned char mp3_buffer[MP3_BUFFER_SIZE]; + struct mad_stream Stream; + struct mad_frame Frame; + struct mad_synth Synth; + mad_timer_t Timer; + ptrdiff_t cursamp; + size_t FrameCount; +} mp3_priv_t; + +/* http://id3.org/ID3v1 : 3 bytes "TAG" identifier and 125 bytes tag data */ +static inline qboolean tag_is_id3v1(const unsigned char *data, size_t length) +{ + if (length >= 3 && + data[0] == 'T' && data[1] == 'A' && data[2] == 'G') + { + return true; + } + return false; +} + +/* ID3v1 extended tag: just before ID3v1, always 227 bytes. + * https://www.getid3.org/phpBB3/viewtopic.php?t=1202 + * https://en.wikipedia.org/wiki/ID3v1#Enhanced_tag + * Not an official standard, is only supported by few programs. */ +static inline qboolean tag_is_id3v1ext(const unsigned char *data, size_t length) +{ + if (length >= 4 && + data[0] == 'T' && data[1] == 'A' && data[2] == 'G' && data[3] == '+') + { + return true; + } + return false; +} + +#define ID3_TAG_FLAG_FOOTERPRESENT 0x10 +static inline qboolean tag_is_id3v2(const unsigned char *data, size_t length) +{ + /* ID3v2 header is 10 bytes: http://id3.org/id3v2.4.0-structure */ + if (length >= 10 && + /* bytes 0-2: "ID3" identifier */ + (data[0] == 'I' && data[1] == 'D' && data[2] == '3') && + /* bytes 3-4: version num (major,revision), each byte always less than 0xff. */ + data[3] < 0xff && data[4] < 0xff && + /* bytes 6-9 are the ID3v2 tag size: a 32 bit 'synchsafe' integer, i.e. the + * highest bit 7 in each byte zeroed. i.e.: 7 bit information in each byte -> + * effectively a 28 bit value. */ + data[6] < 0x80 && data[7] < 0x80 && data[8] < 0x80 && data[9] < 0x80) + { + return true; + } + return false; +} + +static inline long get_id3v2_len(const unsigned char *data, long datalen) +{ + /* size is a 'synchsafe' integer (see above) */ + long taglen = (long)((data[6]<<21) + (data[7]<<14) + (data[8]<<7) + data[9]); + taglen += 10; /* header size */ + /* ID3v2 header[5] is flags (bits 4-7 only, 0-3 are zero). + * bit 4 set: footer is present (a copy of the header but + * with "3DI" as ident.) */ + if (data[5] & ID3_TAG_FLAG_FOOTERPRESENT) + taglen += 10; + for ( ; taglen < datalen && !data[taglen]; ++taglen) + ; /* consume optional padding (always zeroes) */ + return taglen; +} + +/* http://wiki.hydrogenaud.io/index.php?title=APEv1_specification + * http://wiki.hydrogenaud.io/index.php?title=APEv2_specification + * Header/footer is 32 bytes: bytes 0-7 ident, bytes 8-11 version, + * bytes 12-17 size. bytes 24-31 are reserved: must be all zeroes. + */ +static inline qboolean tag_is_apetag(const unsigned char *data, size_t length) +{ + unsigned int v; + + if (length < 32) return false; + if (memcmp(data,"APETAGEX",8) != 0) + return false; + v = (data[11]<<24) | (data[10]<<16) | (data[9]<<8) | data[8]; + if (v != 2000U && v != 1000U) + return false; + v = 0; + if (memcmp(&data[24],&v,4) != 0 || memcmp(&data[28],&v,4) != 0) + return false; + return true; +} + +static inline long get_ape_len(const unsigned char *data, long datalen, unsigned int *version) +{ + long taglen = (long)((data[15]<<24) | (data[14]<<16) | (data[13]<<8) | data[12]); + *version = (data[11]<<24) | (data[10]<<16) | (data[9]<<8) | data[8]; + return taglen; /* caller will handle the additional v2 header length */ +} + +static int skip_tags_first(snd_stream_t *stream, unsigned char *buf, size_t bufsize) +{ + long len; size_t readsize; + + readsize = FS_fread(buf, 1, bufsize, &stream->fh); + if (!readsize || FS_ferror(&stream->fh)) + return -1; + + /* ID3v2 tag is at the start */ + if (tag_is_id3v2(buf, readsize)) + { + len = get_id3v2_len(buf, (long)readsize); + if (len >= stream->fh.length) return -1; + /* hack the fshandle_t start pos and length members */ + stream->fh.start += len; + stream->fh.length -= len; + FS_rewind(&stream->fh); + Con_DPrintf("MP3: skipped %ld bytes ID3v2 tag\n", len); + } + /* APE tag _might_ be at the start: read the header */ + else if (tag_is_apetag(buf, readsize)) + { + unsigned int v; + len = get_ape_len(buf, (long)readsize, &v); + len += 32; /* we're at top: have a header. */ + if (len >= stream->fh.length) return -1; + /* hack the fshandle_t start pos and length members */ + stream->fh.start += len; + stream->fh.length -= len; + FS_rewind(&stream->fh); + Con_DPrintf("MP3: skipped %ld bytes APEv2 tag\n", len); + } + + /* ID3v1 tag is at the end */ + if (stream->fh.length < 128) + goto ape; + FS_fseek(&stream->fh, -128, SEEK_END); + readsize = FS_fread(buf, 1, 128, &stream->fh); + FS_rewind(&stream->fh); + if (readsize != 128) return -1; + if (tag_is_id3v1(buf, 128)) + { + /* hack fshandle_t->length */ + stream->fh.length -= 128; + Con_DPrintf("MP3: skipped ID3v1 tag\n"); + + /* APE tag may be before the ID3v1: read the footer */ + if (stream->fh.length < 32) + goto end; + FS_fseek(&stream->fh, -32, SEEK_END); + readsize = FS_fread(buf, 1, 32, &stream->fh); + FS_rewind(&stream->fh); + if (readsize != 32) return -1; + if (tag_is_apetag(buf, 32)) + { + unsigned int v; + len = get_ape_len(buf, (long)readsize, &v); + if (v == 2000U) len += 32; /* header */ + if (len >= stream->fh.length) return -1; + if (v == 2000U) { /* verify header : */ + FS_fseek(&stream->fh, -len, SEEK_END); + readsize = FS_fread(buf, 1, 32, &stream->fh); + FS_rewind(&stream->fh); + if (readsize != 32) return -1; + if (!tag_is_apetag(buf, 32)) return -1; + } + /* hack fshandle_t->length */ + stream->fh.length -= len; + Con_DPrintf("MP3: skipped %ld bytes APEv%u tag\n", len, v/1000); + goto end; + } + /* extended ID3v1 just before the ID3v1 tag? (unlikely) */ + if (stream->fh.length < 227) + goto end; + FS_fseek(&stream->fh, -227, SEEK_END); + readsize = FS_fread(buf, 1, 227, &stream->fh); + FS_rewind(&stream->fh); + if (readsize != 227) return -1; + if (tag_is_id3v1ext(buf, 227)) + { + /* hack fshandle_t->length */ + stream->fh.length -= 227; + Con_DPrintf("MP3: skipped ID3v1 extended tag\n"); + goto end; + } + } + ape: /* APE tag may be at the end: read the footer */ + if (stream->fh.length >= 32) + { + FS_fseek(&stream->fh, -32, SEEK_END); + readsize = FS_fread(buf, 1, 32, &stream->fh); + FS_rewind(&stream->fh); + if (readsize != 32) return -1; + if (tag_is_apetag(buf, 32)) + { + unsigned int v; + len = get_ape_len(buf, (long)readsize, &v); + if (v == 2000U) len += 32; /* header */ + if (len >= stream->fh.length) return -1; + if (v == 2000U) { /* verify header : */ + FS_fseek(&stream->fh, -len, SEEK_END); + readsize = FS_fread(buf, 1, 32, &stream->fh); + FS_rewind(&stream->fh); + if (readsize != 32) return -1; + if (!tag_is_apetag(buf, 32)) return -1; + } + /* hack fshandle_t->length */ + stream->fh.length -= len; + Con_DPrintf("MP3: skipped %ld bytes APEv%u tag\n", len, v/1000); + } + } + + end: + return (stream->fh.length > 0)? 0: -1; +} + +/* (Re)fill the stream buffer that is to be decoded. If any data + * still exists in the buffer then they are first shifted to be + * front of the stream buffer. */ +static int mp3_inputdata(snd_stream_t *stream) +{ + mp3_priv_t *p = (mp3_priv_t *) stream->priv; + size_t bytes_read; + size_t remaining; + + remaining = p->Stream.bufend - p->Stream.next_frame; + + /* libmad does not consume all the buffer it's given. Some + * data, part of a truncated frame, is left unused at the + * end of the buffer. That data must be put back at the + * beginning of the buffer and taken in account for + * refilling the buffer. This means that the input buffer + * must be large enough to hold a complete frame at the + * highest observable bit-rate (currently 448 kb/s). + * TODO: Is 2016 bytes the size of the largest frame? + * (448000*(1152/32000))/8 + */ + memmove(p->mp3_buffer, p->Stream.next_frame, remaining); + + bytes_read = FS_fread(p->mp3_buffer + remaining, 1, + MP3_BUFFER_SIZE - remaining, &stream->fh); + if (bytes_read == 0) + return -1; + + mad_stream_buffer(&p->Stream, p->mp3_buffer, bytes_read+remaining); + p->Stream.error = MAD_ERROR_NONE; + + return 0; +} + +static int mp3_startread(snd_stream_t *stream) +{ + mp3_priv_t *p = (mp3_priv_t *) stream->priv; + size_t ReadSize; + + /* skip tags known to be at start or end and adjust the file */ + if (skip_tags_first(stream, p->mp3_buffer, MP3_BUFFER_SIZE) < 0) + return -1; + + mad_stream_init(&p->Stream); + mad_frame_init(&p->Frame); + mad_synth_init(&p->Synth); + mad_timer_reset(&p->Timer); + + /* Decode at least one valid frame to find out the input + * format. The decoded frame will be saved off so that it + * can be processed later. + */ + ReadSize = FS_fread(p->mp3_buffer, 1, MP3_BUFFER_SIZE, &stream->fh); + if (!ReadSize || FS_ferror(&stream->fh)) + return -1; + + mad_stream_buffer(&p->Stream, p->mp3_buffer, ReadSize); + + /* Find a valid frame before starting up. This makes sure + * that we have a valid MP3 and also skips past ID3v2 tags + * at the beginning of the audio file. + */ + p->Stream.error = MAD_ERROR_NONE; + while (mad_frame_decode(&p->Frame,&p->Stream)) + { + /* check whether input buffer needs a refill */ + if (p->Stream.error == MAD_ERROR_BUFLEN) + { + if (mp3_inputdata(stream) == -1) + return -1;/* EOF with no valid data */ + + continue; + } + + /* We know that a valid frame hasn't been found yet + * so help libmad out and go back into frame seek mode. + */ + mad_stream_sync(&p->Stream); + p->Stream.error = MAD_ERROR_NONE; + } + + if (p->Stream.error) + { + Con_Printf("MP3: No valid MP3 frame found\n"); + return -1; + } + + switch(p->Frame.header.mode) + { + case MAD_MODE_SINGLE_CHANNEL: + case MAD_MODE_DUAL_CHANNEL: + case MAD_MODE_JOINT_STEREO: + case MAD_MODE_STEREO: + stream->info.channels = MAD_NCHANNELS(&p->Frame.header); + break; + default: + Con_Printf("MP3: Cannot determine number of channels\n"); + return -1; + } + + p->FrameCount = 1; + + mad_timer_add(&p->Timer,p->Frame.header.duration); + mad_synth_frame(&p->Synth,&p->Frame); + stream->info.rate = p->Synth.pcm.samplerate; + stream->info.bits = MP3_MAD_SAMPLEBITS; + stream->info.width = MP3_MAD_SAMPLEWIDTH; + + p->cursamp = 0; + + return 0; +} + +/* Read up to len samples from p->Synth + * If needed, read some more MP3 data, decode them and synth them + * Place in buf[]. + * Return number of samples read. */ +static int mp3_decode(snd_stream_t *stream, byte *buf, int len) +{ + mp3_priv_t *p = (mp3_priv_t *) stream->priv; + int donow, i, done = 0; + mad_fixed_t sample; + int chan, x; + + do + { + x = (p->Synth.pcm.length - p->cursamp) * stream->info.channels; + donow = q_min(len, x); + i = 0; + while (i < donow) + { + for (chan = 0; chan < stream->info.channels; chan++) + { + sample = p->Synth.pcm.samples[chan][p->cursamp]; + /* convert from fixed to short, + * write in host-endian format. */ + if (sample <= -MAD_F_ONE) + sample = -0x7FFF; + else if (sample >= MAD_F_ONE) + sample = 0x7FFF; + else + sample >>= (MAD_F_FRACBITS + 1 - 16); + if (host_bigendian) + { + *buf++ = (sample >> 8) & 0xFF; + *buf++ = sample & 0xFF; + } + else /* assumed LITTLE_ENDIAN. */ + { + *buf++ = sample & 0xFF; + *buf++ = (sample >> 8) & 0xFF; + } + i++; + } + p->cursamp++; + } + + len -= donow; + done += donow; + + if (len == 0) + break; + + /* check whether input buffer needs a refill */ + if (p->Stream.error == MAD_ERROR_BUFLEN) + { + if (mp3_inputdata(stream) == -1) + { + /* check feof() ?? */ + Con_DPrintf("mp3 EOF\n"); + break; + } + } + + if (mad_frame_decode(&p->Frame, &p->Stream)) + { + if (MAD_RECOVERABLE(p->Stream.error)) + { + mad_stream_sync(&p->Stream); /* to frame seek mode */ + continue; + } + else + { + if (p->Stream.error == MAD_ERROR_BUFLEN) + continue; + else + { + Con_Printf("MP3: unrecoverable frame level error (%s)\n", + mad_stream_errorstr(&p->Stream)); + break; + } + } + } + p->FrameCount++; + mad_timer_add(&p->Timer, p->Frame.header.duration); + mad_synth_frame(&p->Synth, &p->Frame); + p->cursamp = 0; + } while (1); + + return done; +} + +static int mp3_stopread(snd_stream_t *stream) +{ + mp3_priv_t *p = (mp3_priv_t*) stream->priv; + + mad_synth_finish(&p->Synth); + mad_frame_finish(&p->Frame); + mad_stream_finish(&p->Stream); + + return 0; +} + +static int mp3_madseek(snd_stream_t *stream, unsigned long offset) +{ + mp3_priv_t *p = (mp3_priv_t *) stream->priv; + size_t initial_bitrate = p->Frame.header.bitrate; + size_t consumed = 0; + int vbr = 0; /* Variable Bit Rate, bool */ + qboolean depadded = false; + unsigned long to_skip_samples = 0; + + /* Reset all */ + FS_rewind(&stream->fh); + mad_timer_reset(&p->Timer); + p->FrameCount = 0; + + /* They where opened in startread */ + mad_synth_finish(&p->Synth); + mad_frame_finish(&p->Frame); + mad_stream_finish(&p->Stream); + + mad_stream_init(&p->Stream); + mad_frame_init(&p->Frame); + mad_synth_init(&p->Synth); + + offset /= stream->info.channels; + to_skip_samples = offset; + + while (1) /* Read data from the MP3 file */ + { + int bytes_read, padding = 0; + size_t leftover = p->Stream.bufend - p->Stream.next_frame; + + memcpy(p->mp3_buffer, p->Stream.this_frame, leftover); + bytes_read = FS_fread(p->mp3_buffer + leftover, (size_t) 1, + MP3_BUFFER_SIZE - leftover, &stream->fh); + if (bytes_read <= 0) + { + Con_DPrintf("seek failure. unexpected EOF (frames=%lu leftover=%lu)\n", + (unsigned long)p->FrameCount, (unsigned long)leftover); + break; + } + for ( ; !depadded && padding < bytes_read && !p->mp3_buffer[padding]; ++padding) + ; + depadded = true; + mad_stream_buffer(&p->Stream, p->mp3_buffer + padding, leftover + bytes_read - padding); + + while (1) /* Decode frame headers */ + { + static unsigned short samples; + p->Stream.error = MAD_ERROR_NONE; + + /* Not an audio frame */ + if (mad_header_decode(&p->Frame.header, &p->Stream) == -1) + { + if (p->Stream.error == MAD_ERROR_BUFLEN) + break; /* Normal behaviour; get some more data from the file */ + if (!MAD_RECOVERABLE(p->Stream.error)) + { + Con_DPrintf("unrecoverable MAD error\n"); + break; + } + if (p->Stream.error == MAD_ERROR_LOSTSYNC) + { + Con_DPrintf("MAD lost sync\n"); + } + else + { + Con_DPrintf("recoverable MAD error\n"); + } + continue; + } + + consumed += p->Stream.next_frame - p->Stream.this_frame; + vbr |= (p->Frame.header.bitrate != initial_bitrate); + + samples = 32 * MAD_NSBSAMPLES(&p->Frame.header); + + p->FrameCount++; + mad_timer_add(&p->Timer, p->Frame.header.duration); + + if (to_skip_samples <= samples) + { + mad_frame_decode(&p->Frame,&p->Stream); + mad_synth_frame(&p->Synth, &p->Frame); + p->cursamp = to_skip_samples; + return 0; + } + else to_skip_samples -= samples; + + /* If not VBR, we can extrapolate frame size */ + if (p->FrameCount == 64 && !vbr) + { + p->FrameCount = offset / samples; + to_skip_samples = offset % samples; + if (0 != FS_fseek(&stream->fh, (p->FrameCount * consumed / 64), SEEK_SET)) + return -1; + + /* Reset Stream for refilling buffer */ + mad_stream_finish(&p->Stream); + mad_stream_init(&p->Stream); + break; + } + } + } + + return -1; +} + +static qboolean S_MP3_CodecInitialize (void) +{ + return true; +} + +static void S_MP3_CodecShutdown (void) +{ +} + +static qboolean S_MP3_CodecOpenStream (snd_stream_t *stream) +{ + int err; + + stream->priv = calloc(1, sizeof(mp3_priv_t)); + if (!stream->priv) + { + Con_Printf("Insufficient memory for MP3 audio\n"); + return false; + } + err = mp3_startread(stream); + if (err != 0) + { + Con_Printf("%s is not a valid mp3 file\n", stream->name); + } + else if (stream->info.channels != 1 && stream->info.channels != 2) + { + Con_Printf("Unsupported number of channels %d in %s\n", + stream->info.channels, stream->name); + } + else + { + return true; + } + free(stream->priv); + return false; +} + +static int S_MP3_CodecReadStream (snd_stream_t *stream, int bytes, void *buffer) +{ + int res = mp3_decode(stream, (byte *)buffer, bytes / stream->info.width); + return res * stream->info.width; +} + +static void S_MP3_CodecCloseStream (snd_stream_t *stream) +{ + mp3_stopread(stream); + free(stream->priv); + S_CodecUtilClose(&stream); +} + +static int S_MP3_CodecRewindStream (snd_stream_t *stream) +{ + /* + mp3_stopread(stream); + FS_rewind(&stream->fh); + return mp3_startread(stream); + */ + return mp3_madseek(stream, 0); +} + +snd_codec_t mp3_codec = +{ + CODECTYPE_MP3, + true, /* always available. */ + "mp3", + S_MP3_CodecInitialize, + S_MP3_CodecShutdown, + S_MP3_CodecOpenStream, + S_MP3_CodecReadStream, + S_MP3_CodecRewindStream, + S_MP3_CodecCloseStream, + NULL +}; + +#endif /* USE_CODEC_MP3 */ + diff --git a/engine/Quake/snd_mp3.h b/engine/Quake/snd_mp3.h new file mode 100644 index 0000000..d54ae4d --- /dev/null +++ b/engine/Quake/snd_mp3.h @@ -0,0 +1,13 @@ +/* MP3 decoding support using libmad or libmpg123. */ + +#if !defined(_SND_MP3_H_) +#define _SND_MP3_H_ + +#if defined(USE_CODEC_MP3) + +extern snd_codec_t mp3_codec; + +#endif /* USE_CODEC_MP3 */ + +#endif /* ! _SND_MP3_H_ */ + diff --git a/engine/Quake/snd_mpg123.c b/engine/Quake/snd_mpg123.c new file mode 100644 index 0000000..85c65e1 --- /dev/null +++ b/engine/Quake/snd_mpg123.c @@ -0,0 +1,228 @@ +/* + * MP3 decoding support using libmpg123, loosely based on an SDL_mixer + * See: http://bubu.lv/changeset/4/public/libs/SDL/generated/SDL_mixer + * + * Copyright (C) 2011-2012 O.Sezer + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "quakedef.h" + +#if defined(USE_CODEC_MP3) +#include "snd_codec.h" +#include "snd_codeci.h" +#include "snd_mp3.h" +#include + +#define MPG123_DEF_SSIZE_T /* we do define ssize_t in our stdinc.h */ +#include + +#if !defined(MPG123_API_VERSION) || (MPG123_API_VERSION < 24) +#error minimum required libmpg123 version is 1.12.0 (api version 24) +#endif /* MPG123_API_VERSION */ + +/* Private data */ +typedef struct _mp3_priv_t +{ + int handle_newed, handle_opened; + mpg123_handle* handle; +} mp3_priv_t; + +/* CALLBACK FUNCTIONS: */ +/* CAREFUL: libmpg123 expects POSIX read() and lseek() behavior, + * however our FS_fread() and FS_fseek() return fread() and fseek() + * compatible values. */ + +static ssize_t mp3_read (void *f, void *buf, size_t size) +{ + ssize_t ret = (ssize_t) FS_fread(buf, 1, size, (fshandle_t *)f); + if (ret == 0 && errno != 0) + ret = -1; + return ret; +} + +static off_t mp3_seek (void *f, off_t offset, int whence) +{ + if (f == NULL) return (-1); + if (FS_fseek((fshandle_t *)f, (long) offset, whence) < 0) + return (off_t)-1; + return (off_t) FS_ftell((fshandle_t *)f); +} + +static qboolean S_MP3_CodecInitialize (void) +{ + if (!mp3_codec.initialized) + { + if (mpg123_init() != MPG123_OK) + { + Con_Printf ("Could not initialize mpg123\n"); + return false; + } + mp3_codec.initialized = true; + return true; + } + + return true; +} + +static void S_MP3_CodecShutdown (void) +{ + if (mp3_codec.initialized) + { + mp3_codec.initialized = false; + mpg123_exit(); + } +} + +static qboolean S_MP3_CodecOpenStream (snd_stream_t *stream) +{ + long rate = 0; + int encoding = 0, channels = 0; + mp3_priv_t *priv = NULL; + + stream->priv = Z_Malloc(sizeof(mp3_priv_t)); + priv = (mp3_priv_t *) stream->priv; + priv->handle = mpg123_new(NULL, NULL); + if (priv->handle == NULL) + { + Con_Printf("Unable to allocate mpg123 handle\n"); + goto _fail; + } + priv->handle_newed = 1; + + if (mpg123_replace_reader_handle(priv->handle, mp3_read, mp3_seek, NULL) != MPG123_OK || + mpg123_open_handle(priv->handle, &stream->fh) != MPG123_OK) + { + Con_Printf("Unable to open mpg123 handle\n"); + goto _fail; + } + priv->handle_opened = 1; + + if (mpg123_getformat(priv->handle, &rate, &channels, &encoding) != MPG123_OK) + { + Con_Printf("Unable to retrieve mpg123 format for %s\n", stream->name); + goto _fail; + } + + switch (channels) + { + case MPG123_MONO: + stream->info.channels = 1; + break; + case MPG123_STEREO: + stream->info.channels = 2; + break; + default: + Con_Printf("Unsupported number of channels %d in %s\n", channels, stream->name); + goto _fail; + } + + stream->info.rate = rate; + + switch (encoding) + { + case MPG123_ENC_UNSIGNED_8: + stream->info.bits = 8; + stream->info.width = 1; + break; + case MPG123_ENC_SIGNED_8: + /* unsupported: force mpg123 to convert */ + stream->info.bits = 8; + stream->info.width = 1; + encoding = MPG123_ENC_UNSIGNED_8; + break; + case MPG123_ENC_SIGNED_16: + stream->info.bits = 16; + stream->info.width = 2; + break; + case MPG123_ENC_UNSIGNED_16: + default: + /* unsupported: force mpg123 to convert */ + stream->info.bits = 16; + stream->info.width = 2; + encoding = MPG123_ENC_SIGNED_16; + break; + } + if (mpg123_format_support(priv->handle, rate, encoding) == 0) + { + Con_Printf("Unsupported format for %s\n", stream->name); + goto _fail; + } + mpg123_format_none(priv->handle); + mpg123_format(priv->handle, rate, channels, encoding); + + return true; +_fail: + if (priv) + { + if (priv->handle_opened) + mpg123_close(priv->handle); + if (priv->handle_newed) + mpg123_delete(priv->handle); + Z_Free(stream->priv); + } + return false; +} + +static int S_MP3_CodecReadStream (snd_stream_t *stream, int bytes, void *buffer) +{ + mp3_priv_t *priv = (mp3_priv_t *) stream->priv; + size_t bytes_read = 0; + int res = mpg123_read (priv->handle, (unsigned char *)buffer, (size_t)bytes, &bytes_read); + switch (res) + { + case MPG123_DONE: + Con_DPrintf("mp3 EOF\n"); + case MPG123_OK: + return (int)bytes_read; + } + return -1; /* error */ +} + +static void S_MP3_CodecCloseStream (snd_stream_t *stream) +{ + mp3_priv_t *priv = (mp3_priv_t *) stream->priv; + mpg123_close(priv->handle); + mpg123_delete(priv->handle); + Z_Free(stream->priv); + S_CodecUtilClose(&stream); +} + +static int S_MP3_CodecRewindStream (snd_stream_t *stream) +{ + mp3_priv_t *priv = (mp3_priv_t *) stream->priv; + off_t res = mpg123_seek(priv->handle, 0, SEEK_SET); + if (res >= 0) return (0); + return res; +} + +snd_codec_t mp3_codec = +{ + CODECTYPE_MP3, + false, + "mp3", + S_MP3_CodecInitialize, + S_MP3_CodecShutdown, + S_MP3_CodecOpenStream, + S_MP3_CodecReadStream, + S_MP3_CodecRewindStream, + S_MP3_CodecCloseStream, + NULL +}; + +#endif /* USE_CODEC_MP3 */ + diff --git a/engine/Quake/snd_opus.c b/engine/Quake/snd_opus.c new file mode 100644 index 0000000..a2148e9 --- /dev/null +++ b/engine/Quake/snd_opus.c @@ -0,0 +1,210 @@ +/* + * Ogg/Opus streaming music support, loosely based on several open source + * Quake engine based projects with many modifications. + * + * Copyright (C) 2012-2013 O.Sezer + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#include "quakedef.h" + +#if defined(USE_CODEC_OPUS) +#include "snd_codec.h" +#include "snd_codeci.h" +#include "snd_opus.h" + +#include +#include + + +/* CALLBACK FUNCTIONS: */ + +static int opc_fclose (void *f) +{ + return 0; /* we fclose() elsewhere. */ +} + +static int opc_fread (void *f, unsigned char *buf, int size) +{ + int ret; + + if (size < 0) + { + errno = EINVAL; + return -1; + } + + ret = (int) FS_fread(buf, 1, (size_t)size, (fshandle_t *)f); + if (ret == 0 && errno != 0) + ret = -1; + return ret; +} + +static int opc_fseek (void *f, opus_int64 off, int whence) +{ + if (f == NULL) return (-1); + return FS_fseek((fshandle_t *)f, (long) off, whence); +} + +static opus_int64 opc_ftell (void *f) +{ + return (opus_int64) FS_ftell((fshandle_t *)f); +} + +static const OpusFileCallbacks opc_qfs = +{ + (int (*)(void *, unsigned char *, int)) opc_fread, + (int (*)(void *, opus_int64, int)) opc_fseek, + (opus_int64 (*)(void *)) opc_ftell, + (int (*)(void *)) opc_fclose +}; + +static qboolean S_OPUS_CodecInitialize (void) +{ + return true; +} + +static void S_OPUS_CodecShutdown (void) +{ +} + +static qboolean S_OPUS_CodecOpenStream (snd_stream_t *stream) +{ + OggOpusFile *opFile; + const OpusHead *op_info; + long numstreams; + int res; + + opFile = op_open_callbacks(&stream->fh, &opc_qfs, NULL, 0, &res); + if (!opFile) + { + Con_Printf("%s is not a valid Opus file (error %i).\n", + stream->name, res); + goto _fail; + } + + stream->priv = opFile; + + if (!op_seekable(opFile)) + { + Con_Printf("Opus stream %s not seekable.\n", stream->name); + goto _fail; + } + + op_info = op_head(opFile, -1); + if (!op_info) + { + Con_Printf("Unable to get stream information for %s.\n", stream->name); + goto _fail; + } + + /* FIXME: handle section changes */ + numstreams = op_info->stream_count; + if (numstreams != 1) + { + Con_Printf("More than one (%ld) stream in %s\n", + (long)op_info->stream_count, stream->name); + goto _fail; + } + + if (op_info->channel_count != 1 && op_info->channel_count != 2) + { + Con_Printf("Unsupported number of channels %d in %s\n", + op_info->channel_count, stream->name); + goto _fail; + } + + /* All Opus audio is coded at 48 kHz, and should also be decoded + * at 48 kHz for playback: info->input_sample_rate only tells us + * the sampling rate of the original input before opus encoding. + * S_RawSamples() shall already downsample this, as necessary. */ + stream->info.rate = 48000; + stream->info.channels = op_info->channel_count; + /* op_read() yields 16-bit output using native endian ordering: */ + stream->info.bits = 16; + stream->info.width = 2; + + return true; +_fail: + if (opFile) + op_free(opFile); + return false; +} + +static int S_OPUS_CodecReadStream (snd_stream_t *stream, int bytes, void *buffer) +{ + int section; /* FIXME: handle section changes */ + int cnt, res, rem; + opus_int16 * ptr; + + rem = bytes / stream->info.width; + if (rem / stream->info.channels <= 0) + return 0; + + cnt = 0; + ptr = (opus_int16 *) buffer; + while (1) + { + /* op_read() yields 16-bit output using native endian ordering. returns + * the number of samples read per channel on success, or a negative value + * on failure. */ + res = op_read((OggOpusFile *)stream->priv, ptr, rem, §ion); + if (res <= 0) + break; + cnt += res; + res *= stream->info.channels; + rem -= res; + if (rem <= 0) + break; + ptr += res; + } + + if (res < 0) + return res; + + cnt *= (stream->info.channels * stream->info.width); + return cnt; +} + +static void S_OPUS_CodecCloseStream (snd_stream_t *stream) +{ + op_free((OggOpusFile *)stream->priv); + S_CodecUtilClose(&stream); +} + +static int S_OPUS_CodecRewindStream (snd_stream_t *stream) +{ + return op_pcm_seek ((OggOpusFile *)stream->priv, 0); +} + +snd_codec_t opus_codec = +{ + CODECTYPE_OPUS, + true, /* always available. */ + "opus", + S_OPUS_CodecInitialize, + S_OPUS_CodecShutdown, + S_OPUS_CodecOpenStream, + S_OPUS_CodecReadStream, + S_OPUS_CodecRewindStream, + S_OPUS_CodecCloseStream, + NULL +}; + +#endif /* USE_CODEC_OPUS */ + diff --git a/engine/Quake/snd_opus.h b/engine/Quake/snd_opus.h new file mode 100644 index 0000000..4c2a25f --- /dev/null +++ b/engine/Quake/snd_opus.h @@ -0,0 +1,13 @@ +/* Ogg/Opus streaming music support. */ + +#if !defined(_SND_OPUS_H_) +#define _SND_OPUS_H_ 1 + +#if defined(USE_CODEC_OPUS) + +extern snd_codec_t opus_codec; + +#endif /* USE_CODEC_OPUS */ + +#endif /* ! _SND_OPUS_H_ */ + diff --git a/engine/Quake/snd_sdl.c b/engine/Quake/snd_sdl.c new file mode 100644 index 0000000..6e0791b --- /dev/null +++ b/engine/Quake/snd_sdl.c @@ -0,0 +1,212 @@ +/* + * snd_sdl.c - SDL audio driver for Hexen II: Hammer of Thyrion (uHexen2) + * based on implementations found in the quakeforge and ioquake3 projects. + * + * Copyright (C) 1999-2005 Id Software, Inc. + * Copyright (C) 2005-2012 O.Sezer + * Copyright (C) 2010-2014 QuakeSpasm developers + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "quakedef.h" + +#if defined(SDL_FRAMEWORK) || defined(NO_SDL_CONFIG) +#if defined(USE_SDL2) +#include +#else +#include +#endif +#else +#include "SDL.h" +#endif + +static int buffersize; + + +static void SDLCALL paint_audio (void *unused, Uint8 *stream, int len) +{ + int pos, tobufend; + int len1, len2; + + if (!shm) + { /* shouldn't happen, but just in case */ + memset(stream, 0, len); + return; + } + + pos = (shm->samplepos * (shm->samplebits / 8)); + if (pos >= buffersize) + shm->samplepos = pos = 0; + + tobufend = buffersize - pos; /* bytes to buffer's end. */ + len1 = len; + len2 = 0; + + if (len1 > tobufend) + { + len1 = tobufend; + len2 = len - len1; + } + + memcpy(stream, shm->buffer + pos, len1); + + if (len2 <= 0) + { + shm->samplepos += (len1 / (shm->samplebits / 8)); + } + else + { /* wraparound? */ + memcpy(stream + len1, shm->buffer, len2); + shm->samplepos = (len2 / (shm->samplebits / 8)); + } + + if (shm->samplepos >= buffersize) + shm->samplepos = 0; +} + +qboolean SNDDMA_Init (dma_t *dma) +{ + SDL_AudioSpec desired; + int tmp, val; + char drivername[128]; + + if (SDL_InitSubSystem(SDL_INIT_AUDIO) < 0) + { + Con_Printf("Couldn't init SDL audio: %s\n", SDL_GetError()); + return false; + } + + /* Set up the desired format */ + desired.freq = snd_mixspeed.value; + desired.format = (loadas8bit.value) ? AUDIO_U8 : AUDIO_S16SYS; + desired.channels = 2; /* = desired_channels; */ + if (desired.freq <= 11025) + desired.samples = 256; + else if (desired.freq <= 22050) + desired.samples = 512; + else if (desired.freq <= 44100) + desired.samples = 1024; + else if (desired.freq <= 56000) + desired.samples = 2048; /* for 48 kHz */ + else + desired.samples = 4096; /* for 96 kHz */ + desired.callback = paint_audio; + desired.userdata = NULL; + + /* Open the audio device */ + if (SDL_OpenAudio(&desired, NULL) == -1) + { + Con_Printf("Couldn't open SDL audio: %s\n", SDL_GetError()); + SDL_QuitSubSystem(SDL_INIT_AUDIO); + return false; + } + + memset ((void *) dma, 0, sizeof(dma_t)); + shm = dma; + + /* Fill the audio DMA information block */ + /* Since we passed NULL as the 'obtained' spec to SDL_OpenAudio(), + * SDL will convert to hardware format for us if needed, hence we + * directly use the desired values here. */ + shm->samplebits = (desired.format & 0xFF); /* first byte of format is bits */ + shm->signed8 = (desired.format == AUDIO_S8); + shm->speed = desired.freq; + shm->channels = desired.channels; + tmp = (desired.samples * desired.channels) * 10; + if (tmp & (tmp - 1)) + { /* make it a power of two */ + val = 1; + while (val < tmp) + val <<= 1; + + tmp = val; + } + shm->samples = tmp; + shm->samplepos = 0; + shm->submission_chunk = 1; + + Con_Printf ("SDL audio spec : %d Hz, %d samples, %d channels\n", + desired.freq, desired.samples, desired.channels); +#if defined(USE_SDL2) + { + const char *driver = SDL_GetCurrentAudioDriver(); + const char *device = SDL_GetAudioDeviceName(0, SDL_FALSE); + q_snprintf(drivername, sizeof(drivername), "%s - %s", + driver != NULL ? driver : "(UNKNOWN)", + device != NULL ? device : "(UNKNOWN)"); + } +#else + if (SDL_AudioDriverName(drivername, sizeof(drivername)) == NULL) + strcpy(drivername, "(UNKNOWN)"); +#endif + buffersize = shm->samples * (shm->samplebits / 8); + Con_Printf ("SDL audio driver: %s, %d bytes buffer\n", drivername, buffersize); + + shm->buffer = (unsigned char *) calloc (1, buffersize); + if (!shm->buffer) + { + SDL_CloseAudio(); + SDL_QuitSubSystem(SDL_INIT_AUDIO); + shm = NULL; + Con_Printf ("Failed allocating memory for SDL audio\n"); + return false; + } + + SDL_PauseAudio(0); + + return true; +} + +int SNDDMA_GetDMAPos (void) +{ + return shm->samplepos; +} + +void SNDDMA_Shutdown (void) +{ + if (shm) + { + Con_Printf ("Shutting down SDL sound\n"); + SDL_CloseAudio(); + SDL_QuitSubSystem(SDL_INIT_AUDIO); + if (shm->buffer) + free (shm->buffer); + shm->buffer = NULL; + shm = NULL; + } +} + +void SNDDMA_LockBuffer (void) +{ + SDL_LockAudio (); +} + +void SNDDMA_Submit (void) +{ + SDL_UnlockAudio(); +} + +void SNDDMA_BlockSound (void) +{ + SDL_PauseAudio(1); +} + +void SNDDMA_UnblockSound (void) +{ + SDL_PauseAudio(0); +} + diff --git a/engine/Quake/snd_umx.c b/engine/Quake/snd_umx.c new file mode 100644 index 0000000..6cda61f --- /dev/null +++ b/engine/Quake/snd_umx.c @@ -0,0 +1,407 @@ +/* + * Unreal UMX container support. + * UPKG parsing partially based on Unreal Media Ripper (UMR) v0.3 + * by Andy Ward , with additional updates + * by O. Sezer - see git repo at https://github.com/sezero/umr/ + * + * The cheaper way, i.e. linear search of music object like libxmp + * and libmodplug does, is possible. With this however we're using + * the embedded offset, size and object type directly from the umx + * file, and I feel safer with it. + * + * Copyright (C) 2013 O. Sezer + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "quakedef.h" + +#if defined(USE_CODEC_UMX) +#include "snd_codec.h" +#include "snd_codeci.h" +#include "snd_umx.h" + +typedef int32_t fci_t; /* FCompactIndex */ + +#define UPKG_HDR_TAG 0x9e2a83c1 + +struct _genhist { /* for upkg versions >= 68 */ + int32_t export_count; + int32_t name_count; +}; + +struct upkg_hdr { + uint32_t tag; /* UPKG_HDR_TAG */ + int32_t file_version; + uint32_t pkg_flags; + int32_t name_count; /* number of names in name table (>= 0) */ + int32_t name_offset; /* offset to name table (>= 0) */ + int32_t export_count; /* num. exports in export table (>= 0) */ + int32_t export_offset; /* offset to export table (>= 0) */ + int32_t import_count; /* num. imports in export table (>= 0) */ + int32_t import_offset; /* offset to import table (>= 0) */ + + /* number of GUIDs in heritage table (>= 1) and table's offset: + * only with versions < 68. */ + int32_t heritage_count; + int32_t heritage_offset; + /* with versions >= 68: a GUID, a dword for generation count + * and export_count and name_count dwords for each generation: */ + uint32_t guid[4]; + int32_t generation_count; +#define UPKG_HDR_SIZE 64 /* 64 bytes up until here */ + /*struct _genhist *gen;*/ +}; +/*COMPILE_TIME_ASSERT(upkg_hdr, offsetof(struct upkg_hdr, gen) == UPKG_HDR_SIZE);*/ +COMPILE_TIME_ASSERT(upkg_hdr, sizeof(struct upkg_hdr) == UPKG_HDR_SIZE); + +#define UMUSIC_IT 0 +#define UMUSIC_S3M 1 +#define UMUSIC_XM 2 +#define UMUSIC_MOD 3 +#define UMUSIC_WAV 4 +#define UMUSIC_MP2 5 + +static const char *mustype[] = { + "IT", "S3M", "XM", "MOD", + "WAV", "MP2", NULL +}; + +/* decode an FCompactIndex. + * original documentation by Tim Sweeney was at + * http://unreal.epicgames.com/Packages.htm + * also see Unreal Wiki: + * http://wiki.beyondunreal.com/Legacy:Package_File_Format/Data_Details + */ +static fci_t get_fci (const char *in, int *pos) +{ + int32_t a; + int size; + + size = 1; + a = in[0] & 0x3f; + + if (in[0] & 0x40) { + size++; + a |= (in[1] & 0x7f) << 6; + + if (in[1] & 0x80) { + size++; + a |= (in[2] & 0x7f) << 13; + + if (in[2] & 0x80) { + size++; + a |= (in[3] & 0x7f) << 20; + + if (in[3] & 0x80) { + size++; + a |= (in[4] & 0x3f) << 27; + } + } + } + } + + if (in[0] & 0x80) + a = -a; + + *pos += size; + + return a; +} + +static int get_objtype (fshandle_t *f, int32_t ofs, int type) +{ + char sig[16]; +_retry: + FS_fseek(f, ofs, SEEK_SET); + FS_fread(sig, 16, 1, f); + if (type == UMUSIC_IT) { + if (memcmp(sig, "IMPM", 4) == 0) + return UMUSIC_IT; + return -1; + } + if (type == UMUSIC_XM) { + if (memcmp(sig, "Extended Module:", 16) != 0) + return -1; + FS_fread(sig, 16, 1, f); + if (sig[0] != ' ') return -1; + FS_fread(sig, 16, 1, f); + if (sig[5] != 0x1a) return -1; + return UMUSIC_XM; + } + if (type == UMUSIC_MP2) { + unsigned char *p = (unsigned char *)sig; + uint16_t u = ((p[0] << 8) | p[1]) & 0xFFFE; + if (u == 0xFFFC || u == 0xFFF4) + return UMUSIC_MP2; + return -1; + } + if (type == UMUSIC_WAV) { + if (memcmp(sig, "RIFF", 4) == 0 && memcmp(&sig[8], "WAVE", 4) == 0) + return UMUSIC_WAV; + return -1; + } + + FS_fseek(f, ofs + 44, SEEK_SET); + FS_fread(sig, 4, 1, f); + if (type == UMUSIC_S3M) { + if (memcmp(sig, "SCRM", 4) == 0) + return UMUSIC_S3M; + /*return -1;*/ + /* SpaceMarines.umx and Starseek.umx from Return to NaPali + * report as "s3m" whereas the actual music format is "it" */ + type = UMUSIC_IT; + goto _retry; + } + + FS_fseek(f, ofs + 1080, SEEK_SET); + FS_fread(sig, 4, 1, f); + if (type == UMUSIC_MOD) { + if (memcmp(sig, "M.K.", 4) == 0 || memcmp(sig, "M!K!", 4) == 0) + return UMUSIC_MOD; + return -1; + } + + return -1; +} + +static int read_export (fshandle_t *f, const struct upkg_hdr *hdr, + int32_t *ofs, int32_t *objsize) +{ + char buf[40]; + int idx = 0, t; + + FS_fseek(f, *ofs, SEEK_SET); + if (FS_fread(buf, 4, 10, f) < 10) + return -1; + + if (hdr->file_version < 40) idx += 8; /* 00 00 00 00 00 00 00 00 */ + if (hdr->file_version < 60) idx += 16; /* 81 00 00 00 00 00 FF FF FF FF FF FF FF FF 00 00 */ + get_fci(&buf[idx], &idx); /* skip junk */ + t = get_fci(&buf[idx], &idx); /* type_name */ + if (hdr->file_version > 61) idx += 4; /* skip export size */ + *objsize = get_fci(&buf[idx], &idx); + *ofs += idx; /* offset for real data */ + + return t; /* return type_name index */ +} + +static int read_typname(fshandle_t *f, const struct upkg_hdr *hdr, + int idx, char *out) +{ + int i, s; + long l; + char buf[64]; + + if (idx >= hdr->name_count) return -1; + buf[63] = '\0'; + for (i = 0, l = 0; i <= idx; i++) { + FS_fseek(f, hdr->name_offset + l, SEEK_SET); + FS_fread(buf, 1, 63, f); + if (hdr->file_version >= 64) { + s = *(signed char *)buf; /* numchars *including* terminator */ + if (s <= 0 || s > 64) return -1; + l += s + 5; /* 1 for buf[0], 4 for int32_t name_flags */ + } else { + l += (long)strlen(buf); + l += 5; /* 1 for terminator, 4 for int32_t name_flags */ + } + } + + strcpy(out, (hdr->file_version >= 64)? &buf[1] : buf); + return 0; +} + +static int probe_umx (fshandle_t *f, const struct upkg_hdr *hdr, + int32_t *ofs, int32_t *objsize) +{ + int i, idx, t; + int32_t s, pos; + long fsiz; + char buf[64]; + + idx = 0; + fsiz = FS_filelength (f); + + /* Find the offset and size of the first IT, S3M or XM + * by parsing the exports table. The umx files should + * have only one export. Kran32.umx from Unreal has two, + * but both pointing to the same music. */ + if (hdr->export_offset >= fsiz) return -1; + memset(buf, 0, 64); + FS_fseek(f, hdr->export_offset, SEEK_SET); + FS_fread(buf, 1, 64, f); + + get_fci(&buf[idx], &idx); /* skip class_index */ + get_fci(&buf[idx], &idx); /* skip super_index */ + if (hdr->file_version >= 60) idx += 4; /* skip int32 package_index */ + get_fci(&buf[idx], &idx); /* skip object_name */ + idx += 4; /* skip int32 object_flags */ + + s = get_fci(&buf[idx], &idx); /* get serial_size */ + if (s <= 0) return -1; + pos = get_fci(&buf[idx],&idx); /* get serial_offset */ + if (pos < 0 || pos > fsiz - 40) return -1; + + if ((t = read_export(f, hdr, &pos, &s)) < 0) return -1; + if (s <= 0 || s > fsiz - pos) return -1; + + if (read_typname(f, hdr, t, buf) < 0) return -1; + for (i = 0; mustype[i] != NULL; i++) { + if (!q_strcasecmp(buf, mustype[i])) { + t = i; + break; + } + } + if (mustype[i] == NULL) return -1; + if ((t = get_objtype(f, pos, t)) < 0) return -1; + + *ofs = pos; + *objsize = s; + return t; +} + +static int32_t probe_header (void *header) +{ + struct upkg_hdr *hdr; + unsigned char *p; + uint32_t *swp; + int i; + + /* byte swap the header - all members are 32 bit LE values */ + p = (unsigned char *) header; + swp = (uint32_t *) header; + for (i = 0; i < UPKG_HDR_SIZE/4; i++, p += 4) { + swp[i] = p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24); + } + + hdr = (struct upkg_hdr *) header; + if (hdr->tag != UPKG_HDR_TAG) { + Con_DPrintf("Unknown header tag 0x%x\n", hdr->tag); + return -1; + } + if (hdr->name_count < 0 || + hdr->name_offset < 0 || + hdr->export_count < 0 || + hdr->export_offset < 0 || + hdr->import_count < 0 || + hdr->import_offset < 0 ) { + Con_DPrintf("Negative values in header\n"); + return -1; + } + + switch (hdr->file_version) { + case 35: case 37: /* Unreal beta - */ + case 40: case 41: /* 1998 */ + case 61:/* Unreal */ + case 62:/* Unreal Tournament */ + case 63:/* Return to NaPali */ + case 64:/* Unreal Tournament */ + case 66:/* Unreal Tournament */ + case 68:/* Unreal Tournament */ + case 69:/* Tactical Ops */ + case 75:/* Harry Potter and the Philosopher's Stone */ + case 76: /* mpeg layer II data */ + case 83:/* Mobile Forces */ + return 0; + } + + Con_DPrintf("Unknown upkg version %d\n", hdr->file_version); + return -1; +} + +static int process_upkg (fshandle_t *f, int32_t *ofs, int32_t *objsize) +{ + char header[UPKG_HDR_SIZE]; + + if (FS_fread(header, 1, UPKG_HDR_SIZE, f) < UPKG_HDR_SIZE) + return -1; + if (probe_header(header) < 0) + return -1; + + return probe_umx(f, (struct upkg_hdr *)header, ofs, objsize); +} + +static qboolean S_UMX_CodecInitialize (void) +{ + return true; +} + +static void S_UMX_CodecShutdown (void) +{ +} + +static qboolean S_UMX_CodecOpenStream (snd_stream_t *stream) +{ + int type; + int32_t ofs = 0, size = 0; + + type = process_upkg(&stream->fh, &ofs, &size); + if (type < 0) { + Con_DPrintf("%s: unrecognized umx\n", stream->name); + return false; + } + + Con_DPrintf("%s: %s data @ 0x%x, %d bytes\n", stream->name, mustype[type], ofs, size); + /* hack the fshandle_t start pos and length members so + * that only the relevant data is accessed from now on */ + stream->fh.start += ofs; + stream->fh.length = size; + FS_fseek(&stream->fh, 0, SEEK_SET); + + switch (type) { + case UMUSIC_IT: + case UMUSIC_S3M: + case UMUSIC_XM: + case UMUSIC_MOD: return S_CodecForwardStream(stream, CODECTYPE_MOD); + case UMUSIC_WAV: return S_CodecForwardStream(stream, CODECTYPE_WAV); + case UMUSIC_MP2: return S_CodecForwardStream(stream, CODECTYPE_MP3); + } + + return false; +} + +static int S_UMX_CodecReadStream (snd_stream_t *stream, int bytes, void *buffer) +{ + return -1; +} + +static void S_UMX_CodecCloseStream (snd_stream_t *stream) +{ + S_CodecUtilClose(&stream); +} + +static int S_UMX_CodecRewindStream (snd_stream_t *stream) +{ + return -1; +} + +snd_codec_t umx_codec = +{ + CODECTYPE_UMX, + true, /* always available. */ + "umx", + S_UMX_CodecInitialize, + S_UMX_CodecShutdown, + S_UMX_CodecOpenStream, + S_UMX_CodecReadStream, + S_UMX_CodecRewindStream, + S_UMX_CodecCloseStream, + NULL +}; + +#endif /* USE_CODEC_UMX */ + diff --git a/engine/Quake/snd_umx.h b/engine/Quake/snd_umx.h new file mode 100644 index 0000000..da3107d --- /dev/null +++ b/engine/Quake/snd_umx.h @@ -0,0 +1,12 @@ +/* Unreal UMX format support */ +#if !defined(_SND_UMX_H_) +#define _SND_UMX_H_ + +#if defined(USE_CODEC_UMX) + +extern snd_codec_t umx_codec; + +#endif /* USE_CODEC_UMX */ + +#endif /* ! _SND_UMX_H_ */ + diff --git a/engine/Quake/snd_vorbis.c b/engine/Quake/snd_vorbis.c new file mode 100644 index 0000000..16985dc --- /dev/null +++ b/engine/Quake/snd_vorbis.c @@ -0,0 +1,204 @@ +/* + * Ogg/Vorbis streaming music support, loosely based on several open source + * Quake engine based projects with many modifications. + * + * Copyright (C) 2010-2012 O.Sezer + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#include "quakedef.h" + +#if defined(USE_CODEC_VORBIS) +#include "snd_codec.h" +#include "snd_codeci.h" +#include "snd_vorbis.h" + +#define OV_EXCLUDE_STATIC_CALLBACKS +#if defined(VORBIS_USE_TREMOR) +/* for Tremor / Vorbisfile api differences, + * see doc/diff.html in the Tremor package. */ +#include +#else +#include +#endif + +/* Vorbis codec can return the samples in a number of different + * formats, we use the standard signed short format. */ +#define VORBIS_SAMPLEBITS 16 +#define VORBIS_SAMPLEWIDTH 2 +#define VORBIS_SIGNED_DATA 1 + +/* CALLBACK FUNCTIONS: */ + +static int ovc_fclose (void *f) +{ + return 0; /* we fclose() elsewhere. */ +} + +static int ovc_fseek (void *f, ogg_int64_t off, int whence) +{ + if (f == NULL) return (-1); + return FS_fseek((fshandle_t *)f, (long) off, whence); +} + +static ov_callbacks ovc_qfs = +{ + (size_t (*)(void *, size_t, size_t, void *)) FS_fread, + (int (*)(void *, ogg_int64_t, int)) ovc_fseek, + (int (*)(void *)) ovc_fclose, + (long (*)(void *)) FS_ftell +}; + +static qboolean S_VORBIS_CodecInitialize (void) +{ + return true; +} + +static void S_VORBIS_CodecShutdown (void) +{ +} + +static qboolean S_VORBIS_CodecOpenStream (snd_stream_t *stream) +{ + OggVorbis_File *ovFile; + vorbis_info *ovf_info; + long numstreams; + int res; + + ovFile = (OggVorbis_File *) Z_Malloc(sizeof(OggVorbis_File)); + stream->priv = ovFile; + res = ov_open_callbacks(&stream->fh, ovFile, NULL, 0, ovc_qfs); + if (res != 0) + { + Con_Printf("%s is not a valid Ogg Vorbis file (error %i).\n", + stream->name, res); + goto _fail; + } + + if (!ov_seekable(ovFile)) + { + Con_Printf("Stream %s not seekable.\n", stream->name); + goto _fail; + } + + ovf_info = ov_info(ovFile, 0); + if (!ovf_info) + { + Con_Printf("Unable to get stream info for %s.\n", stream->name); + goto _fail; + } + + /* FIXME: handle section changes */ + numstreams = ov_streams(ovFile); + if (numstreams != 1) + { + Con_Printf("More than one (%ld) stream in %s.\n", + numstreams, stream->name); + goto _fail; + } + + if (ovf_info->channels != 1 && ovf_info->channels != 2) + { + Con_Printf("Unsupported number of channels %d in %s\n", + ovf_info->channels, stream->name); + goto _fail; + } + + stream->info.rate = ovf_info->rate; + stream->info.channels = ovf_info->channels; + stream->info.bits = VORBIS_SAMPLEBITS; + stream->info.width = VORBIS_SAMPLEWIDTH; + + return true; +_fail: + if (res == 0) + ov_clear(ovFile); + Z_Free(ovFile); + return false; +} + +static int S_VORBIS_CodecReadStream (snd_stream_t *stream, int bytes, void *buffer) +{ + int section; /* FIXME: handle section changes */ + int cnt, res, rem; + char * ptr; + + cnt = 0; rem = bytes; + ptr = (char *) buffer; + while (1) + { + /* # ov_read() from libvorbisfile returns the decoded PCM audio + * in requested endianness, signedness and word size. + * # ov_read() from Tremor (libvorbisidec) returns decoded audio + * always in host-endian, signed 16 bit PCM format. + * # For both of the libraries, if the audio is multichannel, + * the channels are interleaved in the output buffer. + */ + res = ov_read( (OggVorbis_File *)stream->priv, ptr, rem, +#ifndef VORBIS_USE_TREMOR + host_bigendian, + VORBIS_SAMPLEWIDTH, + VORBIS_SIGNED_DATA, +#endif + §ion ); + if (res <= 0) + break; + rem -= res; + cnt += res; + if (rem <= 0) + break; + ptr += res; + } + + if (res < 0) + return res; + return cnt; +} + +static void S_VORBIS_CodecCloseStream (snd_stream_t *stream) +{ + ov_clear((OggVorbis_File *)stream->priv); + Z_Free(stream->priv); + S_CodecUtilClose(&stream); +} + +static int S_VORBIS_CodecRewindStream (snd_stream_t *stream) +{ +/* for libvorbisfile, the ov_time_seek() position argument + * is seconds as doubles, whereas for Tremor libvorbisidec + * it is milliseconds as 64 bit integers. + */ + return ov_time_seek ((OggVorbis_File *)stream->priv, 0); +} + +snd_codec_t vorbis_codec = +{ + CODECTYPE_VORBIS, + true, /* always available. */ + "ogg", + S_VORBIS_CodecInitialize, + S_VORBIS_CodecShutdown, + S_VORBIS_CodecOpenStream, + S_VORBIS_CodecReadStream, + S_VORBIS_CodecRewindStream, + S_VORBIS_CodecCloseStream, + NULL +}; + +#endif /* USE_CODEC_VORBIS */ + diff --git a/engine/Quake/snd_vorbis.h b/engine/Quake/snd_vorbis.h new file mode 100644 index 0000000..0f1cc9e --- /dev/null +++ b/engine/Quake/snd_vorbis.h @@ -0,0 +1,13 @@ +/* Ogg/Vorbis streaming music support. */ + +#if !defined(_SND_VORBIS_H_) +#define _SND_VORBIS_H_ 1 + +#if defined(USE_CODEC_VORBIS) + +extern snd_codec_t vorbis_codec; + +#endif /* USE_CODEC_VORBIS */ + +#endif /* ! _SND_VORBIS_H_ */ + diff --git a/engine/Quake/snd_wave.c b/engine/Quake/snd_wave.c new file mode 100644 index 0000000..b31011a --- /dev/null +++ b/engine/Quake/snd_wave.c @@ -0,0 +1,276 @@ +/* + * WAV streaming music support. Adapted from ioquake3 with changes. + * + * Copyright (C) 1999-2005 Id Software, Inc. + * Copyright (C) 2005 Stuart Dalton + * Copyright (C) 2010-2012 O.Sezer + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#include "quakedef.h" + +#if defined(USE_CODEC_WAVE) +#include "snd_codec.h" +#include "snd_codeci.h" +#include "snd_wave.h" + +/* +================= +FGetLittleLong +================= +*/ +static int FGetLittleLong (FILE *f) +{ + int v; + + fread(&v, 1, sizeof(v), f); + + return LittleLong(v); +} + +/* +================= +FGetLittleShort +================= +*/ +static short FGetLittleShort(FILE *f) +{ + short v; + + fread(&v, 1, sizeof(v), f); + + return LittleShort(v); +} + +/* +================= +WAV_ReadChunkInfo +================= +*/ +static int WAV_ReadChunkInfo(FILE *f, char *name) +{ + int len, r; + + name[4] = 0; + + r = fread(name, 1, 4, f); + if (r != 4) + return -1; + + len = FGetLittleLong(f); + if (len < 0) + { + Con_Printf("WAV: Negative chunk length\n"); + return -1; + } + + return len; +} + +/* +================= +WAV_FindRIFFChunk + +Returns the length of the data in the chunk, or -1 if not found +================= +*/ +static int WAV_FindRIFFChunk(FILE *f, const char *chunk) +{ + char name[5]; + int len; + + while ((len = WAV_ReadChunkInfo(f, name)) >= 0) + { + /* If this is the right chunk, return */ + if (!strncmp(name, chunk, 4)) + return len; + len = ((len + 1) & ~1); /* pad by 2 . */ + + /* Not the right chunk - skip it */ + fseek(f, len, SEEK_CUR); + } + + return -1; +} + +/* +================= +WAV_ReadRIFFHeader +================= +*/ +static qboolean WAV_ReadRIFFHeader(const char *name, FILE *file, snd_info_t *info) +{ + char dump[16]; + int wav_format; + int fmtlen = 0; + + if (fread(dump, 1, 12, file) < 12 || + strncmp(dump, "RIFF", 4) != 0 || + strncmp(&dump[8], "WAVE", 4) != 0) + { + Con_Printf("%s is missing RIFF/WAVE chunks\n", name); + return false; + } + + /* Scan for the format chunk */ + if ((fmtlen = WAV_FindRIFFChunk(file, "fmt ")) < 0) + { + Con_Printf("%s is missing fmt chunk\n", name); + return false; + } + + /* Save the parameters */ + wav_format = FGetLittleShort(file); + if (wav_format != WAV_FORMAT_PCM) + { + Con_Printf("%s is not Microsoft PCM format\n", name); + return false; + } + + info->channels = FGetLittleShort(file); + info->rate = FGetLittleLong(file); + FGetLittleLong(file); + FGetLittleShort(file); + info->bits = FGetLittleShort(file); + + if (info->bits != 8 && info->bits != 16) + { + Con_Printf("%s is not 8 or 16 bit\n", name); + return false; + } + + info->width = info->bits / 8; + info->dataofs = 0; + + /* Skip the rest of the format chunk if required */ + if (fmtlen > 16) + { + fmtlen -= 16; + fseek(file, fmtlen, SEEK_CUR); + } + + /* Scan for the data chunk */ + if ((info->size = WAV_FindRIFFChunk(file, "data")) < 0) + { + Con_Printf("%s is missing data chunk\n", name); + return false; + } + + if (info->channels != 1 && info->channels != 2) + { + Con_Printf("Unsupported number of channels %d in %s\n", + info->channels, name); + return false; + } + info->samples = (info->size / info->width) / info->channels; + if (info->samples == 0) + { + Con_Printf("%s has zero samples\n", name); + return false; + } + + return true; +} + +/* +================= +S_WAV_CodecOpenStream +================= +*/ +static qboolean S_WAV_CodecOpenStream(snd_stream_t *stream) +{ + long start = stream->fh.start; + + /* Read the RIFF header */ + /* The file reads are sequential, therefore no need + * for the FS_*() functions: We will manipulate the + * file by ourselves from now on. */ + if (!WAV_ReadRIFFHeader(stream->name, stream->fh.file, &stream->info)) + return false; + + stream->fh.start = ftell(stream->fh.file); /* reset to data position */ + if (stream->fh.start - start + stream->info.size > stream->fh.length) + { + Con_Printf("%s data size mismatch\n", stream->name); + return false; + } + + return true; +} + +/* +================= +S_WAV_CodecReadStream +================= +*/ +int S_WAV_CodecReadStream(snd_stream_t *stream, int bytes, void *buffer) +{ + int remaining = stream->info.size - stream->fh.pos; + int i, samples; + + if (remaining <= 0) + return 0; + if (bytes > remaining) + bytes = remaining; + stream->fh.pos += bytes; + fread(buffer, 1, bytes, stream->fh.file); + if (stream->info.width == 2) + { + samples = bytes / 2; + for (i = 0; i < samples; i++) + ((short *)buffer)[i] = LittleShort( ((short *)buffer)[i] ); + } + return bytes; +} + +static void S_WAV_CodecCloseStream (snd_stream_t *stream) +{ + S_CodecUtilClose(&stream); +} + +static int S_WAV_CodecRewindStream (snd_stream_t *stream) +{ + FS_rewind(&stream->fh); + return 0; +} + +static qboolean S_WAV_CodecInitialize (void) +{ + return true; +} + +static void S_WAV_CodecShutdown (void) +{ +} + +snd_codec_t wav_codec = +{ + CODECTYPE_WAVE, + true, /* always available. */ + "wav", + S_WAV_CodecInitialize, + S_WAV_CodecShutdown, + S_WAV_CodecOpenStream, + S_WAV_CodecReadStream, + S_WAV_CodecRewindStream, + S_WAV_CodecCloseStream, + NULL +}; + +#endif /* USE_CODEC_WAVE */ + diff --git a/engine/Quake/snd_wave.h b/engine/Quake/snd_wave.h new file mode 100644 index 0000000..7f7f50b --- /dev/null +++ b/engine/Quake/snd_wave.h @@ -0,0 +1,13 @@ +/* WAV streaming music support. */ + +#if !defined(_SND_WAVE_H_) +#define _SND_WAVE_H_ + +#if defined(USE_CODEC_WAVE) + +extern snd_codec_t wav_codec; + +#endif /* USE_CODEC_WAVE */ + +#endif /* ! _SND_WAVE_H_ */ + diff --git a/engine/Quake/snd_xmp.c b/engine/Quake/snd_xmp.c new file mode 100644 index 0000000..27b55a5 --- /dev/null +++ b/engine/Quake/snd_xmp.c @@ -0,0 +1,168 @@ +/* tracker music (module file) decoding support using libxmp >= v4.2.0 + * https://sourceforge.net/projects/xmp/ + * https://github.com/cmatsuoka/libxmp.git + * + * Copyright (C) 2016 O.Sezer + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "quakedef.h" + +#if defined(USE_CODEC_XMP) +#include "snd_codec.h" +#include "snd_codeci.h" +#include "snd_xmp.h" +#if defined(_WIN32) && defined(XMP_NO_DLL) +#define BUILDING_STATIC +#endif +#include +#if ((XMP_VERCODE+0) < 0x040200) +#error libxmp version 4.2 or newer is required +#endif + +static int S_XMP_StartPlay (snd_stream_t *stream) +{ + int fmt = 0; + + if (stream->info.channels == 1) + fmt |= XMP_FORMAT_MONO; + if (stream->info.width == 1) + fmt |= XMP_FORMAT_8BIT|XMP_FORMAT_UNSIGNED; + + return xmp_start_player((xmp_context)stream->priv, stream->info.rate, fmt); +} + +static qboolean S_XMP_CodecInitialize (void) +{ + return true; +} + +static void S_XMP_CodecShutdown (void) +{ +} + +static qboolean S_XMP_CodecOpenStream (snd_stream_t *stream) +{ +/* need to load the whole file into memory and pass it to libxmp + * using xmp_load_module_from_memory() which requires libxmp >= 4.2. + * libxmp-4.0/4.1 only have xmp_load_module() which accepts a file + * name which isn't good with files in containers like paks, etc. */ + xmp_context c; + byte *moddata; + long len; + int mark; + + c = xmp_create_context(); + if (c == NULL) + return false; + + len = FS_filelength (&stream->fh); + mark = Hunk_LowMark(); + moddata = (byte *) Hunk_Alloc(len); + FS_fread(moddata, 1, len, &stream->fh); + if (xmp_load_module_from_memory(c, moddata, len) != 0) + { + Con_DPrintf("Could not load module %s\n", stream->name); + goto err1; + } + + Hunk_FreeToLowMark(mark); /* free original file data */ + stream->priv = c; + if (shm->speed > XMP_MAX_SRATE) + stream->info.rate = 44100; + else if (shm->speed < XMP_MIN_SRATE) + stream->info.rate = 11025; + else stream->info.rate = shm->speed; + stream->info.bits = shm->samplebits; + stream->info.width = stream->info.bits / 8; + stream->info.channels = shm->channels; + + if (S_XMP_StartPlay(stream) != 0) + goto err2; + /* percentual left/right channel separation, default is 70. */ + if (stream->info.channels == 2) + if (xmp_set_player(c, XMP_PLAYER_MIX, 100) != 0) + goto err3; + /* interpolation type, default is XMP_INTERP_LINEAR */ + if (xmp_set_player(c, XMP_PLAYER_INTERP, XMP_INTERP_SPLINE) != 0) + goto err3; + + return true; + +err3: xmp_end_player(c); +err2: xmp_release_module(c); +err1: xmp_free_context(c); + return false; +} + +static int S_XMP_CodecReadStream (snd_stream_t *stream, int bytes, void *buffer) +{ + int r; + /* xmp_play_buffer() requires libxmp >= 4.1. it will write + * native-endian pcm data to the buffer. if the data write + * is partial, the rest of the buffer will be zero-filled. + * the last param is the number that the current sequence of + * the song will be looped at max. */ + r = xmp_play_buffer((xmp_context)stream->priv, buffer, bytes, 1); + if (r == 0) { + return bytes; + } + if (r == -XMP_END) { + Con_DPrintf("XMP EOF\n"); + return 0; + } + return -1; +} + +static void S_XMP_CodecCloseStream (snd_stream_t *stream) +{ + xmp_context c = (xmp_context)stream->priv; + xmp_end_player(c); + xmp_release_module(c); + xmp_free_context(c); + S_CodecUtilClose(&stream); +} + +static int S_XMP_CodecRewindStream (snd_stream_t *stream) +{ + int ret; + + ret = S_XMP_StartPlay(stream); + if (ret < 0) return ret; + + /*ret = xmp_set_position((xmp_context)stream->priv, 0);*/ + ret = xmp_seek_time((xmp_context)stream->priv, 0); + if (ret < 0) return ret; + + return 0; +} + +snd_codec_t xmp_codec = +{ + CODECTYPE_MOD, + true, /* always available. */ + "s3m", + S_XMP_CodecInitialize, + S_XMP_CodecShutdown, + S_XMP_CodecOpenStream, + S_XMP_CodecReadStream, + S_XMP_CodecRewindStream, + S_XMP_CodecCloseStream, + NULL +}; + +#endif /* USE_CODEC_XMP */ diff --git a/engine/Quake/snd_xmp.h b/engine/Quake/snd_xmp.h new file mode 100644 index 0000000..9516a49 --- /dev/null +++ b/engine/Quake/snd_xmp.h @@ -0,0 +1,12 @@ +/* module tracker decoding support using libxmp */ +#if !defined(_SND_XMP_H_) +#define _SND_XMP_H_ + +#if defined(USE_CODEC_XMP) + +extern snd_codec_t xmp_codec; + +#endif /* USE_CODEC_XMP */ + +#endif /* ! _SND_XMP_H_ */ + diff --git a/engine/code/spritegn.h b/engine/Quake/spritegn.h similarity index 92% rename from engine/code/spritegn.h rename to engine/Quake/spritegn.h index b192b54..1065052 100644 --- a/engine/code/spritegn.h +++ b/engine/Quake/spritegn.h @@ -1,5 +1,6 @@ /* -Copyright (C) 1996-1997 Id Software, Inc. +Copyright (C) 1996-2001 Id Software, Inc. +Copyright (C) 2002-2009 John Fitzgibbons and others This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -8,7 +9,7 @@ of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. @@ -17,6 +18,10 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +#ifndef __SPRITEGEN_H +#define __SPRITEGEN_H + // // spritegn.h: header file for sprite generation program // @@ -108,3 +113,5 @@ typedef struct { #define IDSPRITEHEADER (('P'<<24)+('S'<<16)+('D'<<8)+'I') // little-endian "IDSP" +#endif /* __SPRITEGEN_H */ + diff --git a/engine/Quake/stb_image_write.h b/engine/Quake/stb_image_write.h new file mode 100644 index 0000000..d590443 --- /dev/null +++ b/engine/Quake/stb_image_write.h @@ -0,0 +1,684 @@ +/* QuakeSpasm: kept only the jpg writer, the only thing we use, and removed all others. */ + +/* stb_image_write - v1.07 - public domain - http://nothings.org/stb/stb_image_write.h + writes out PNG/BMP/TGA/JPEG/HDR images to C stdio - Sean Barrett 2010-2015 + no warranty implied; use at your own risk + + Before #including, + + #define STB_IMAGE_WRITE_IMPLEMENTATION + + in the file that you want to have the implementation. + + Will probably not work correctly with strict-aliasing optimizations. + +ABOUT: + + This header file is a library for writing images to C stdio. It could be + adapted to write to memory or a general streaming interface; let me know. + + The PNG output is not optimal; it is 20-50% larger than the file + written by a decent optimizing implementation. This library is designed + for source code compactness and simplicity, not optimal image file size + or run-time performance. + +BUILDING: + + You can #define STBIW_ASSERT(x) before the #include to avoid using assert.h. + You can #define STBIW_MALLOC(), STBIW_REALLOC(), and STBIW_FREE() to replace + malloc,realloc,free. + You can define STBIW_MEMMOVE() to replace memmove() + +USAGE: + + There are four functions, one for each image file format: + + int stbi_write_png(char const *filename, int w, int h, int comp, const void *data, int stride_in_bytes); + int stbi_write_bmp(char const *filename, int w, int h, int comp, const void *data); + int stbi_write_tga(char const *filename, int w, int h, int comp, const void *data); + int stbi_write_hdr(char const *filename, int w, int h, int comp, const float *data); + int stbi_write_jpg(char const *filename, int w, int h, int comp, const float *data); + + There are also four equivalent functions that use an arbitrary write function. You are + expected to open/close your file-equivalent before and after calling these: + + int stbi_write_png_to_func(stbi_write_func *func, void *context, int w, int h, int comp, const void *data, int stride_in_bytes); + int stbi_write_bmp_to_func(stbi_write_func *func, void *context, int w, int h, int comp, const void *data); + int stbi_write_tga_to_func(stbi_write_func *func, void *context, int w, int h, int comp, const void *data); + int stbi_write_hdr_to_func(stbi_write_func *func, void *context, int w, int h, int comp, const float *data); + int stbi_write_jpg_to_func(stbi_write_func *func, void *context, int x, int y, int comp, const void *data, int quality); + + where the callback is: + void stbi_write_func(void *context, void *data, int size); + + You can define STBI_WRITE_NO_STDIO to disable the file variant of these + functions, so the library will not use stdio.h at all. However, this will + also disable HDR writing, because it requires stdio for formatted output. + + Each function returns 0 on failure and non-0 on success. + + The functions create an image file defined by the parameters. The image + is a rectangle of pixels stored from left-to-right, top-to-bottom. + Each pixel contains 'comp' channels of data stored interleaved with 8-bits + per channel, in the following order: 1=Y, 2=YA, 3=RGB, 4=RGBA. (Y is + monochrome color.) The rectangle is 'w' pixels wide and 'h' pixels tall. + The *data pointer points to the first byte of the top-left-most pixel. + For PNG, "stride_in_bytes" is the distance in bytes from the first byte of + a row of pixels to the first byte of the next row of pixels. + + PNG creates output files with the same number of components as the input. + The BMP format expands Y to RGB in the file format and does not + output alpha. + + PNG supports writing rectangles of data even when the bytes storing rows of + data are not consecutive in memory (e.g. sub-rectangles of a larger image), + by supplying the stride between the beginning of adjacent rows. The other + formats do not. (Thus you cannot write a native-format BMP through the BMP + writer, both because it is in BGR order and because it may have padding + at the end of the line.) + + HDR expects linear float data. Since the format is always 32-bit rgb(e) + data, alpha (if provided) is discarded, and for monochrome data it is + replicated across all three channels. + + TGA supports RLE or non-RLE compressed data. To use non-RLE-compressed + data, set the global variable 'stbi_write_tga_with_rle' to 0. + + JPEG does ignore alpha channels in input data; quality is between 1 and 100. + Higher quality looks better but results in a bigger image. + JPEG baseline (no JPEG progressive). + +CREDITS: + + PNG/BMP/TGA + Sean Barrett + HDR + Baldur Karlsson + TGA monochrome: + Jean-Sebastien Guay + misc enhancements: + Tim Kelsey + TGA RLE + Alan Hickman + initial file IO callback implementation + Emmanuel Julien + JPEG + Jon Olick (original jo_jpeg.cpp code) + Daniel Gibson + bugfixes: + github:Chribba + Guillaume Chereau + github:jry2 + github:romigrou + Sergio Gonzalez + Jonas Karlsson + Filip Wasil + Thatcher Ulrich + github:poppolopoppo + Patrick Boettcher + +LICENSE + + See end of file for license information. + +*/ + +#ifndef INCLUDE_STB_IMAGE_WRITE_H +#define INCLUDE_STB_IMAGE_WRITE_H + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef STB_IMAGE_WRITE_STATIC +#define STBIWDEF static +#else +#define STBIWDEF extern +#endif + +#ifndef STBI_WRITE_NO_STDIO +STBIWDEF int stbi_write_jpg(char const *filename, int x, int y, int comp, const void *data, int quality); +#endif + +typedef void stbi_write_func(void *context, void *data, int size); + +#if 0 /* not used in QuakeSpasm */ +STBIWDEF int stbi_write_jpg_to_func(stbi_write_func *func, void *context, int x, int y, int comp, const void *data, int quality); +#endif + +#ifdef __cplusplus +} +#endif + +#endif//INCLUDE_STB_IMAGE_WRITE_H + +#ifdef STB_IMAGE_WRITE_IMPLEMENTATION + +#ifdef _WIN32 + #ifndef _CRT_SECURE_NO_WARNINGS + #define _CRT_SECURE_NO_WARNINGS + #endif + #ifndef _CRT_NONSTDC_NO_DEPRECATE + #define _CRT_NONSTDC_NO_DEPRECATE + #endif +#endif + +#ifndef STBI_WRITE_NO_STDIO +#include +#endif // STBI_WRITE_NO_STDIO + +#include +#include +#include +#include + +#if defined(STBIW_MALLOC) && defined(STBIW_FREE) && (defined(STBIW_REALLOC) || defined(STBIW_REALLOC_SIZED)) +// ok +#elif !defined(STBIW_MALLOC) && !defined(STBIW_FREE) && !defined(STBIW_REALLOC) && !defined(STBIW_REALLOC_SIZED) +// ok +#else +#error "Must define all or none of STBIW_MALLOC, STBIW_FREE, and STBIW_REALLOC (or STBIW_REALLOC_SIZED)." +#endif + +#ifndef STBIW_MALLOC +#define STBIW_MALLOC(sz) malloc(sz) +#define STBIW_REALLOC(p,newsz) realloc(p,newsz) +#define STBIW_FREE(p) free(p) +#endif + +#ifndef STBIW_REALLOC_SIZED +#define STBIW_REALLOC_SIZED(p,oldsz,newsz) STBIW_REALLOC(p,newsz) +#endif + + +#ifndef STBIW_MEMMOVE +#define STBIW_MEMMOVE(a,b,sz) memmove(a,b,sz) +#endif + + +#ifndef STBIW_ASSERT +#include +#define STBIW_ASSERT(x) assert(x) +#endif + +#define STBIW_UCHAR(x) (unsigned char) ((x) & 0xff) + +typedef struct +{ + stbi_write_func *func; + void *context; +} stbi__write_context; + +// initialize a callback-based context +static void stbi__start_write_callbacks(stbi__write_context *s, stbi_write_func *c, void *context) +{ + s->func = c; + s->context = context; +} + +#ifndef STBI_WRITE_NO_STDIO + +static void stbi__stdio_write(void *context, void *data, int size) +{ + fwrite(data,1,size,(FILE*) context); +} + +static int stbi__start_write_file(stbi__write_context *s, const char *filename) +{ + FILE *f = fopen(filename, "wb"); + stbi__start_write_callbacks(s, stbi__stdio_write, (void *) f); + return f != NULL; +} + +static void stbi__end_write_file(stbi__write_context *s) +{ + fclose((FILE *)s->context); +} + +#endif // !STBI_WRITE_NO_STDIO + +typedef unsigned int stbiw_uint32; +typedef int stb_image_write_test[sizeof(stbiw_uint32)==4 ? 1 : -1]; + +static void stbiw__putc(stbi__write_context *s, unsigned char c) +{ + s->func(s->context, &c, 1); +} + +/* *************************************************************************** + * + * JPEG writer + * + * This is based on Jon Olick's jo_jpeg.cpp: + * public domain Simple, Minimalistic JPEG writer - http://www.jonolick.com/code.html + */ + +static const unsigned char stbiw__jpg_ZigZag[] = { 0,1,5,6,14,15,27,28,2,4,7,13,16,26,29,42,3,8,12,17,25,30,41,43,9,11,18, + 24,31,40,44,53,10,19,23,32,39,45,52,54,20,22,33,38,46,51,55,60,21,34,37,47,50,56,59,61,35,36,48,49,57,58,62,63 }; + +static void stbiw__jpg_writeBits(stbi__write_context *s, int *bitBufP, int *bitCntP, const unsigned short *bs) { + int bitBuf = *bitBufP, bitCnt = *bitCntP; + bitCnt += bs[1]; + bitBuf |= bs[0] << (24 - bitCnt); + while(bitCnt >= 8) { + unsigned char c = (bitBuf >> 16) & 255; + stbiw__putc(s, c); + if(c == 255) { + stbiw__putc(s, 0); + } + bitBuf <<= 8; + bitCnt -= 8; + } + *bitBufP = bitBuf; + *bitCntP = bitCnt; +} + +static void stbiw__jpg_DCT(float *d0p, float *d1p, float *d2p, float *d3p, float *d4p, float *d5p, float *d6p, float *d7p) { + float d0 = *d0p, d1 = *d1p, d2 = *d2p, d3 = *d3p, d4 = *d4p, d5 = *d5p, d6 = *d6p, d7 = *d7p; + float z1, z2, z3, z4, z5, z11, z13; + + float tmp0 = d0 + d7; + float tmp7 = d0 - d7; + float tmp1 = d1 + d6; + float tmp6 = d1 - d6; + float tmp2 = d2 + d5; + float tmp5 = d2 - d5; + float tmp3 = d3 + d4; + float tmp4 = d3 - d4; + + // Even part + float tmp10 = tmp0 + tmp3; // phase 2 + float tmp13 = tmp0 - tmp3; + float tmp11 = tmp1 + tmp2; + float tmp12 = tmp1 - tmp2; + + d0 = tmp10 + tmp11; // phase 3 + d4 = tmp10 - tmp11; + + z1 = (tmp12 + tmp13) * 0.707106781f; // c4 + d2 = tmp13 + z1; // phase 5 + d6 = tmp13 - z1; + + // Odd part + tmp10 = tmp4 + tmp5; // phase 2 + tmp11 = tmp5 + tmp6; + tmp12 = tmp6 + tmp7; + + // The rotator is modified from fig 4-8 to avoid extra negations. + z5 = (tmp10 - tmp12) * 0.382683433f; // c6 + z2 = tmp10 * 0.541196100f + z5; // c2-c6 + z4 = tmp12 * 1.306562965f + z5; // c2+c6 + z3 = tmp11 * 0.707106781f; // c4 + + z11 = tmp7 + z3; // phase 5 + z13 = tmp7 - z3; + + *d5p = z13 + z2; // phase 6 + *d3p = z13 - z2; + *d1p = z11 + z4; + *d7p = z11 - z4; + + *d0p = d0; *d2p = d2; *d4p = d4; *d6p = d6; +} + +static void stbiw__jpg_calcBits(int val, unsigned short bits[2]) { + int tmp1 = val < 0 ? -val : val; + val = val < 0 ? val-1 : val; + bits[1] = 1; + while(tmp1 >>= 1) { + ++bits[1]; + } + bits[0] = val & ((1<0)&&(DU[end0pos]==0); --end0pos) { + } + // end0pos = first element in reverse order !=0 + if(end0pos == 0) { + stbiw__jpg_writeBits(s, bitBuf, bitCnt, EOB); + return DU[0]; + } + for(i = 1; i <= end0pos; ++i) { + int startpos = i; + int nrzeroes; + unsigned short bits[2]; + for (; DU[i]==0 && i<=end0pos; ++i) { + } + nrzeroes = i-startpos; + if ( nrzeroes >= 16 ) { + int lng = nrzeroes>>4; + int nrmarker; + for (nrmarker=1; nrmarker <= lng; ++nrmarker) + stbiw__jpg_writeBits(s, bitBuf, bitCnt, M16zeroes); + nrzeroes &= 15; + } + stbiw__jpg_calcBits(DU[i], bits); + stbiw__jpg_writeBits(s, bitBuf, bitCnt, HTAC[(nrzeroes<<4)+bits[1]]); + stbiw__jpg_writeBits(s, bitBuf, bitCnt, bits); + } + if(end0pos != 63) { + stbiw__jpg_writeBits(s, bitBuf, bitCnt, EOB); + } + return DU[0]; +} + +static int stbi_write_jpg_core(stbi__write_context *s, int width, int height, int comp, const void* data, int quality) { + // Constants that don't pollute global namespace + static const unsigned char std_dc_luminance_nrcodes[] = {0,0,1,5,1,1,1,1,1,1,0,0,0,0,0,0,0}; + static const unsigned char std_dc_luminance_values[] = {0,1,2,3,4,5,6,7,8,9,10,11}; + static const unsigned char std_ac_luminance_nrcodes[] = {0,0,2,1,3,3,2,4,3,5,5,4,4,0,0,1,0x7d}; + static const unsigned char std_ac_luminance_values[] = { + 0x01,0x02,0x03,0x00,0x04,0x11,0x05,0x12,0x21,0x31,0x41,0x06,0x13,0x51,0x61,0x07,0x22,0x71,0x14,0x32,0x81,0x91,0xa1,0x08, + 0x23,0x42,0xb1,0xc1,0x15,0x52,0xd1,0xf0,0x24,0x33,0x62,0x72,0x82,0x09,0x0a,0x16,0x17,0x18,0x19,0x1a,0x25,0x26,0x27,0x28, + 0x29,0x2a,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4a,0x53,0x54,0x55,0x56,0x57,0x58,0x59, + 0x5a,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7a,0x83,0x84,0x85,0x86,0x87,0x88,0x89, + 0x8a,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9a,0xa2,0xa3,0xa4,0xa5,0xa6,0xa7,0xa8,0xa9,0xaa,0xb2,0xb3,0xb4,0xb5,0xb6, + 0xb7,0xb8,0xb9,0xba,0xc2,0xc3,0xc4,0xc5,0xc6,0xc7,0xc8,0xc9,0xca,0xd2,0xd3,0xd4,0xd5,0xd6,0xd7,0xd8,0xd9,0xda,0xe1,0xe2, + 0xe3,0xe4,0xe5,0xe6,0xe7,0xe8,0xe9,0xea,0xf1,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7,0xf8,0xf9,0xfa + }; + static const unsigned char std_dc_chrominance_nrcodes[] = {0,0,3,1,1,1,1,1,1,1,1,1,0,0,0,0,0}; + static const unsigned char std_dc_chrominance_values[] = {0,1,2,3,4,5,6,7,8,9,10,11}; + static const unsigned char std_ac_chrominance_nrcodes[] = {0,0,2,1,2,4,4,3,4,7,5,4,4,0,1,2,0x77}; + static const unsigned char std_ac_chrominance_values[] = { + 0x00,0x01,0x02,0x03,0x11,0x04,0x05,0x21,0x31,0x06,0x12,0x41,0x51,0x07,0x61,0x71,0x13,0x22,0x32,0x81,0x08,0x14,0x42,0x91, + 0xa1,0xb1,0xc1,0x09,0x23,0x33,0x52,0xf0,0x15,0x62,0x72,0xd1,0x0a,0x16,0x24,0x34,0xe1,0x25,0xf1,0x17,0x18,0x19,0x1a,0x26, + 0x27,0x28,0x29,0x2a,0x35,0x36,0x37,0x38,0x39,0x3a,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4a,0x53,0x54,0x55,0x56,0x57,0x58, + 0x59,0x5a,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7a,0x82,0x83,0x84,0x85,0x86,0x87, + 0x88,0x89,0x8a,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9a,0xa2,0xa3,0xa4,0xa5,0xa6,0xa7,0xa8,0xa9,0xaa,0xb2,0xb3,0xb4, + 0xb5,0xb6,0xb7,0xb8,0xb9,0xba,0xc2,0xc3,0xc4,0xc5,0xc6,0xc7,0xc8,0xc9,0xca,0xd2,0xd3,0xd4,0xd5,0xd6,0xd7,0xd8,0xd9,0xda, + 0xe2,0xe3,0xe4,0xe5,0xe6,0xe7,0xe8,0xe9,0xea,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7,0xf8,0xf9,0xfa + }; + // Huffman tables + static const unsigned short YDC_HT[256][2] = { {0,2},{2,3},{3,3},{4,3},{5,3},{6,3},{14,4},{30,5},{62,6},{126,7},{254,8},{510,9}}; + static const unsigned short UVDC_HT[256][2] = { {0,2},{1,2},{2,2},{6,3},{14,4},{30,5},{62,6},{126,7},{254,8},{510,9},{1022,10},{2046,11}}; + static const unsigned short YAC_HT[256][2] = { + {10,4},{0,2},{1,2},{4,3},{11,4},{26,5},{120,7},{248,8},{1014,10},{65410,16},{65411,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {12,4},{27,5},{121,7},{502,9},{2038,11},{65412,16},{65413,16},{65414,16},{65415,16},{65416,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {28,5},{249,8},{1015,10},{4084,12},{65417,16},{65418,16},{65419,16},{65420,16},{65421,16},{65422,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {58,6},{503,9},{4085,12},{65423,16},{65424,16},{65425,16},{65426,16},{65427,16},{65428,16},{65429,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {59,6},{1016,10},{65430,16},{65431,16},{65432,16},{65433,16},{65434,16},{65435,16},{65436,16},{65437,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {122,7},{2039,11},{65438,16},{65439,16},{65440,16},{65441,16},{65442,16},{65443,16},{65444,16},{65445,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {123,7},{4086,12},{65446,16},{65447,16},{65448,16},{65449,16},{65450,16},{65451,16},{65452,16},{65453,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {250,8},{4087,12},{65454,16},{65455,16},{65456,16},{65457,16},{65458,16},{65459,16},{65460,16},{65461,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {504,9},{32704,15},{65462,16},{65463,16},{65464,16},{65465,16},{65466,16},{65467,16},{65468,16},{65469,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {505,9},{65470,16},{65471,16},{65472,16},{65473,16},{65474,16},{65475,16},{65476,16},{65477,16},{65478,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {506,9},{65479,16},{65480,16},{65481,16},{65482,16},{65483,16},{65484,16},{65485,16},{65486,16},{65487,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {1017,10},{65488,16},{65489,16},{65490,16},{65491,16},{65492,16},{65493,16},{65494,16},{65495,16},{65496,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {1018,10},{65497,16},{65498,16},{65499,16},{65500,16},{65501,16},{65502,16},{65503,16},{65504,16},{65505,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {2040,11},{65506,16},{65507,16},{65508,16},{65509,16},{65510,16},{65511,16},{65512,16},{65513,16},{65514,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {65515,16},{65516,16},{65517,16},{65518,16},{65519,16},{65520,16},{65521,16},{65522,16},{65523,16},{65524,16},{0,0},{0,0},{0,0},{0,0},{0,0}, + {2041,11},{65525,16},{65526,16},{65527,16},{65528,16},{65529,16},{65530,16},{65531,16},{65532,16},{65533,16},{65534,16},{0,0},{0,0},{0,0},{0,0},{0,0} + }; + static const unsigned short UVAC_HT[256][2] = { + {0,2},{1,2},{4,3},{10,4},{24,5},{25,5},{56,6},{120,7},{500,9},{1014,10},{4084,12},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {11,4},{57,6},{246,8},{501,9},{2038,11},{4085,12},{65416,16},{65417,16},{65418,16},{65419,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {26,5},{247,8},{1015,10},{4086,12},{32706,15},{65420,16},{65421,16},{65422,16},{65423,16},{65424,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {27,5},{248,8},{1016,10},{4087,12},{65425,16},{65426,16},{65427,16},{65428,16},{65429,16},{65430,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {58,6},{502,9},{65431,16},{65432,16},{65433,16},{65434,16},{65435,16},{65436,16},{65437,16},{65438,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {59,6},{1017,10},{65439,16},{65440,16},{65441,16},{65442,16},{65443,16},{65444,16},{65445,16},{65446,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {121,7},{2039,11},{65447,16},{65448,16},{65449,16},{65450,16},{65451,16},{65452,16},{65453,16},{65454,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {122,7},{2040,11},{65455,16},{65456,16},{65457,16},{65458,16},{65459,16},{65460,16},{65461,16},{65462,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {249,8},{65463,16},{65464,16},{65465,16},{65466,16},{65467,16},{65468,16},{65469,16},{65470,16},{65471,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {503,9},{65472,16},{65473,16},{65474,16},{65475,16},{65476,16},{65477,16},{65478,16},{65479,16},{65480,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {504,9},{65481,16},{65482,16},{65483,16},{65484,16},{65485,16},{65486,16},{65487,16},{65488,16},{65489,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {505,9},{65490,16},{65491,16},{65492,16},{65493,16},{65494,16},{65495,16},{65496,16},{65497,16},{65498,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {506,9},{65499,16},{65500,16},{65501,16},{65502,16},{65503,16},{65504,16},{65505,16},{65506,16},{65507,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {2041,11},{65508,16},{65509,16},{65510,16},{65511,16},{65512,16},{65513,16},{65514,16},{65515,16},{65516,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {16352,14},{65517,16},{65518,16},{65519,16},{65520,16},{65521,16},{65522,16},{65523,16},{65524,16},{65525,16},{0,0},{0,0},{0,0},{0,0},{0,0}, + {1018,10},{32707,15},{65526,16},{65527,16},{65528,16},{65529,16},{65530,16},{65531,16},{65532,16},{65533,16},{65534,16},{0,0},{0,0},{0,0},{0,0},{0,0} + }; + static const int YQT[] = {16,11,10,16,24,40,51,61,12,12,14,19,26,58,60,55,14,13,16,24,40,57,69,56,14,17,22,29,51,87,80,62,18,22, + 37,56,68,109,103,77,24,35,55,64,81,104,113,92,49,64,78,87,103,121,120,101,72,92,95,98,112,100,103,99}; + static const int UVQT[] = {17,18,24,47,99,99,99,99,18,21,26,66,99,99,99,99,24,26,56,99,99,99,99,99,47,66,99,99,99,99,99,99, + 99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99}; + static const float aasf[] = { 1.0f * 2.828427125f, 1.387039845f * 2.828427125f, 1.306562965f * 2.828427125f, 1.175875602f * 2.828427125f, + 1.0f * 2.828427125f, 0.785694958f * 2.828427125f, 0.541196100f * 2.828427125f, 0.275899379f * 2.828427125f }; + + int row, col, i, k; + float fdtbl_Y[64], fdtbl_UV[64]; + unsigned char YTable[64], UVTable[64]; + + if(!data || !width || !height || comp > 4 || comp < 1) { + return 0; + } + + quality = quality ? quality : 90; + quality = quality < 1 ? 1 : quality > 100 ? 100 : quality; + quality = quality < 50 ? 5000 / quality : 200 - quality * 2; + + for(i = 0; i < 64; ++i) { + int uvti, yti = (YQT[i]*quality+50)/100; + YTable[stbiw__jpg_ZigZag[i]] = (unsigned char) (yti < 1 ? 1 : yti > 255 ? 255 : yti); + uvti = (UVQT[i]*quality+50)/100; + UVTable[stbiw__jpg_ZigZag[i]] = (unsigned char) (uvti < 1 ? 1 : uvti > 255 ? 255 : uvti); + } + + for(row = 0, k = 0; row < 8; ++row) { + for(col = 0; col < 8; ++col, ++k) { + fdtbl_Y[k] = 1 / (YTable [stbiw__jpg_ZigZag[k]] * aasf[row] * aasf[col]); + fdtbl_UV[k] = 1 / (UVTable[stbiw__jpg_ZigZag[k]] * aasf[row] * aasf[col]); + } + } + + // Write Headers + { + static const unsigned char head0[] = { 0xFF,0xD8,0xFF,0xE0,0,0x10,'J','F','I','F',0,1,1,0,0,1,0,1,0,0,0xFF,0xDB,0,0x84,0 }; + static const unsigned char head2[] = { 0xFF,0xDA,0,0xC,3,1,0,2,0x11,3,0x11,0,0x3F,0 }; + unsigned char head1[] = { 0xFF,0xC0,0,0x11,8, /*[5]*/0,/*[6]*/0,/*[7]*/0,/*[8]*/0, + 3,1,0x11,0,2,0x11,1,3,0x11,1,0xFF,0xC4,0x01,0xA2,0 }; + head1[5] = (unsigned char)(height>>8); + head1[6] = STBIW_UCHAR(height); + head1[7] = (unsigned char)(width>>8); + head1[8] = STBIW_UCHAR(width); + s->func(s->context, (void*)head0, sizeof(head0)); + s->func(s->context, (void*)YTable, sizeof(YTable)); + stbiw__putc(s, 1); + s->func(s->context, UVTable, sizeof(UVTable)); + s->func(s->context, (void*)head1, sizeof(head1)); + s->func(s->context, (void*)(std_dc_luminance_nrcodes+1), sizeof(std_dc_luminance_nrcodes)-1); + s->func(s->context, (void*)std_dc_luminance_values, sizeof(std_dc_luminance_values)); + stbiw__putc(s, 0x10); // HTYACinfo + s->func(s->context, (void*)(std_ac_luminance_nrcodes+1), sizeof(std_ac_luminance_nrcodes)-1); + s->func(s->context, (void*)std_ac_luminance_values, sizeof(std_ac_luminance_values)); + stbiw__putc(s, 1); // HTUDCinfo + s->func(s->context, (void*)(std_dc_chrominance_nrcodes+1), sizeof(std_dc_chrominance_nrcodes)-1); + s->func(s->context, (void*)std_dc_chrominance_values, sizeof(std_dc_chrominance_values)); + stbiw__putc(s, 0x11); // HTUACinfo + s->func(s->context, (void*)(std_ac_chrominance_nrcodes+1), sizeof(std_ac_chrominance_nrcodes)-1); + s->func(s->context, (void*)std_ac_chrominance_values, sizeof(std_ac_chrominance_values)); + s->func(s->context, (void*)head2, sizeof(head2)); + } + + // Encode 8x8 macroblocks + { + static const unsigned short fillBits[] = {0x7F, 7}; + const unsigned char *imageData = (const unsigned char *)data; + int DCY=0, DCU=0, DCV=0; + int bitBuf=0, bitCnt=0; + // comp == 2 is grey+alpha (alpha is ignored) + int ofsG = comp > 2 ? 1 : 0, ofsB = comp > 2 ? 2 : 0; + int x, y, pos; + for(y = 0; y < height; y += 8) { + for(x = 0; x < width; x += 8) { + float YDU[64], UDU[64], VDU[64]; + for(row = y, pos = 0; row < y+8; ++row) { + for(col = x; col < x+8; ++col, ++pos) { + int p = row*width*comp + col*comp; + float r, g, b; + if(row >= height) { + p -= width*comp*(row+1 - height); + } + if(col >= width) { + p -= comp*(col+1 - width); + } + + r = imageData[p+0]; + g = imageData[p+ofsG]; + b = imageData[p+ofsB]; + YDU[pos]=+0.29900f*r+0.58700f*g+0.11400f*b-128; + UDU[pos]=-0.16874f*r-0.33126f*g+0.50000f*b; + VDU[pos]=+0.50000f*r-0.41869f*g-0.08131f*b; + } + } + + DCY = stbiw__jpg_processDU(s, &bitBuf, &bitCnt, YDU, fdtbl_Y, DCY, YDC_HT, YAC_HT); + DCU = stbiw__jpg_processDU(s, &bitBuf, &bitCnt, UDU, fdtbl_UV, DCU, UVDC_HT, UVAC_HT); + DCV = stbiw__jpg_processDU(s, &bitBuf, &bitCnt, VDU, fdtbl_UV, DCV, UVDC_HT, UVAC_HT); + } + } + + // Do the bit alignment of the EOI marker + stbiw__jpg_writeBits(s, &bitBuf, &bitCnt, fillBits); + } + + // EOI + stbiw__putc(s, 0xFF); + stbiw__putc(s, 0xD9); + + return 1; +} + +#if 0 /* not used in QuakeSpasm */ +STBIWDEF int stbi_write_jpg_to_func(stbi_write_func *func, void *context, int x, int y, int comp, const void *data, int quality) +{ + stbi__write_context s; + stbi__start_write_callbacks(&s, func, context); + return stbi_write_jpg_core(&s, x, y, comp, (void *) data, quality); +} +#endif + + +#ifndef STBI_WRITE_NO_STDIO +STBIWDEF int stbi_write_jpg(char const *filename, int x, int y, int comp, const void *data, int quality) +{ + stbi__write_context s; + if (stbi__start_write_file(&s,filename)) { + int r = stbi_write_jpg_core(&s, x, y, comp, data, quality); + stbi__end_write_file(&s); + return r; + } else + return 0; +} +#endif + +#endif // STB_IMAGE_WRITE_IMPLEMENTATION + +/* Revision history + 1.07 (2017-07-24) + doc fix + 1.06 (2017-07-23) + writing JPEG (using Jon Olick's code) + 1.05 ??? + 1.04 (2017-03-03) + monochrome BMP expansion + 1.03 ??? + 1.02 (2016-04-02) + avoid allocating large structures on the stack + 1.01 (2016-01-16) + STBIW_REALLOC_SIZED: support allocators with no realloc support + avoid race-condition in crc initialization + minor compile issues + 1.00 (2015-09-14) + installable file IO function + 0.99 (2015-09-13) + warning fixes; TGA rle support + 0.98 (2015-04-08) + added STBIW_MALLOC, STBIW_ASSERT etc + 0.97 (2015-01-18) + fixed HDR asserts, rewrote HDR rle logic + 0.96 (2015-01-17) + add HDR output + fix monochrome BMP + 0.95 (2014-08-17) + add monochrome TGA output + 0.94 (2014-05-31) + rename private functions to avoid conflicts with stb_image.h + 0.93 (2014-05-27) + warning fixes + 0.92 (2010-08-01) + casts to unsigned char to fix warnings + 0.91 (2010-07-17) + first public release + 0.90 first internal release +*/ + +/* +------------------------------------------------------------------------------ +This software is available under 2 licenses -- choose whichever you prefer. +------------------------------------------------------------------------------ +ALTERNATIVE A - MIT License +Copyright (c) 2017 Sean Barrett +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +------------------------------------------------------------------------------ +ALTERNATIVE B - Public Domain (www.unlicense.org) +This is free and unencumbered software released into the public domain. +Anyone is free to copy, modify, publish, use, compile, sell, or distribute this +software, either in source code form or as a compiled binary, for any purpose, +commercial or non-commercial, and by any means. +In jurisdictions that recognize copyright laws, the author or authors of this +software dedicate any and all copyright interest in the software to the public +domain. We make this dedication for the benefit of the public at large and to +the detriment of our heirs and successors. We intend this dedication to be an +overt act of relinquishment in perpetuity of all present and future rights to +this software under copyright law. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +------------------------------------------------------------------------------ +*/ diff --git a/engine/Quake/strl_fn.h b/engine/Quake/strl_fn.h new file mode 100644 index 0000000..af7fc14 --- /dev/null +++ b/engine/Quake/strl_fn.h @@ -0,0 +1,11 @@ +/* header file for BSD strlcat and strlcpy */ + +#ifndef __STRLFUNCS_H +#define __STRLFUNCS_H + +/* use our own copies of strlcpy and strlcat taken from OpenBSD */ +extern size_t q_strlcpy (char *dst, const char *src, size_t size); +extern size_t q_strlcat (char *dst, const char *src, size_t size); + +#endif /* __STRLFUNCS_H */ + diff --git a/engine/Quake/strlcat.c b/engine/Quake/strlcat.c new file mode 100644 index 0000000..48b91f6 --- /dev/null +++ b/engine/Quake/strlcat.c @@ -0,0 +1,59 @@ +/* $OpenBSD: strlcat.c,v 1.13 2005/08/08 08:05:37 espie Exp $ */ + +/* + * Copyright (c) 1998 Todd C. Miller + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include + +#include "strl_fn.h" + +/* + * Appends src to string dst of size siz (unlike strncat, siz is the + * full size of dst, not space left). At most siz-1 characters + * will be copied. Always NUL terminates (unless siz <= strlen(dst)). + * Returns strlen(src) + MIN(siz, strlen(initial dst)). + * If retval >= siz, truncation occurred. + */ + +size_t +q_strlcat (char *dst, const char *src, size_t siz) +{ + char *d = dst; + const char *s = src; + size_t n = siz; + size_t dlen; + + /* Find the end of dst and adjust bytes left but don't go past end */ + while (n-- != 0 && *d != '\0') + d++; + dlen = d - dst; + n = siz - dlen; + + if (n == 0) + return(dlen + strlen(s)); + while (*s != '\0') { + if (n != 1) { + *d++ = *s; + n--; + } + s++; + } + *d = '\0'; + + return(dlen + (s - src)); /* count does not include NUL */ +} + diff --git a/engine/Quake/strlcpy.c b/engine/Quake/strlcpy.c new file mode 100644 index 0000000..754e70d --- /dev/null +++ b/engine/Quake/strlcpy.c @@ -0,0 +1,55 @@ +/* $OpenBSD: strlcpy.c,v 1.11 2006/05/05 15:27:38 millert Exp $ */ + +/* + * Copyright (c) 1998 Todd C. Miller + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include + +#include "strl_fn.h" + +/* + * Copy src to string dst of size siz. At most siz-1 characters + * will be copied. Always NUL terminates (unless siz == 0). + * Returns strlen(src); if retval >= siz, truncation occurred. + */ + +size_t +q_strlcpy (char *dst, const char *src, size_t siz) +{ + char *d = dst; + const char *s = src; + size_t n = siz; + + /* Copy as many bytes as will fit */ + if (n != 0) { + while (--n != 0) { + if ((*d++ = *s++) == '\0') + break; + } + } + + /* Not enough room in dst, add NUL and traverse rest of src */ + if (n == 0) { + if (siz != 0) + *d = '\0'; /* NUL-terminate dst */ + while (*s++) + ; + } + + return(s - src - 1); /* count does not include NUL */ +} + diff --git a/engine/code/sv_main.c b/engine/Quake/sv_main.c similarity index 61% rename from engine/code/sv_main.c rename to engine/Quake/sv_main.c index ea2599a..91deeac 100644 --- a/engine/code/sv_main.c +++ b/engine/Quake/sv_main.c @@ -1,5 +1,7 @@ /* -Copyright (C) 1996-1997 Id Software, Inc. +Copyright (C) 1996-2001 Id Software, Inc. +Copyright (C) 2002-2009 John Fitzgibbons and others +Copyright (C) 2010-2014 QuakeSpasm developers This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -8,7 +10,7 @@ of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. @@ -21,19 +23,48 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "quakedef.h" -server_t sv; +server_t sv; server_static_t svs; -char localmodels[MAX_MODELS][5]; // inline model names for precache +static char localmodels[MAX_MODELS][8]; // inline model names for precache -// jkrige - configurable fps caps -// dedicated server FPS cap, default 20 (no need to run at higher speed). -// Note: listen servers (including SP) will run at a different cap, defined by cl_maxfps. -cvar_t sv_fps = {"sv_fps", "20", true}; -// jkrige - configurable fps caps +int sv_protocol = PROTOCOL_FITZQUAKE; //johnfitz + +extern qboolean pr_alpha_supported; //johnfitz //============================================================================ +/* +=============== +SV_Protocol_f +=============== +*/ +void SV_Protocol_f (void) +{ + int i; + + switch (Cmd_Argc()) + { + case 1: + Con_Printf ("\"sv_protocol\" is \"%i\"\n", sv_protocol); + break; + case 2: + i = atoi(Cmd_Argv(1)); + if (i != PROTOCOL_NETQUAKE && i != PROTOCOL_FITZQUAKE && i != PROTOCOL_RMQ) + Con_Printf ("sv_protocol must be %i or %i or %i\n", PROTOCOL_NETQUAKE, PROTOCOL_FITZQUAKE, PROTOCOL_RMQ); + else + { + sv_protocol = i; + if (sv.active) + Con_Printf ("changes will not take effect until the next level load.\n"); + } + break; + default: + Con_SafePrintf ("usage: sv_protocol \n"); + break; + } +} + /* =============== SV_Init @@ -42,9 +73,11 @@ SV_Init void SV_Init (void) { int i; + const char *p; extern cvar_t sv_maxvelocity; extern cvar_t sv_gravity; extern cvar_t sv_nostep; + extern cvar_t sv_freezenonclients; extern cvar_t sv_friction; extern cvar_t sv_edgefriction; extern cvar_t sv_stopspeed; @@ -52,24 +85,51 @@ void SV_Init (void) extern cvar_t sv_accelerate; extern cvar_t sv_idealpitchscale; extern cvar_t sv_aim; + extern cvar_t sv_altnoclip; //johnfitz + + sv.edicts = NULL; // ericw -- sv.edicts switched to use malloc() Cvar_RegisterVariable (&sv_maxvelocity); Cvar_RegisterVariable (&sv_gravity); Cvar_RegisterVariable (&sv_friction); + Cvar_SetCallback (&sv_gravity, Host_Callback_Notify); + Cvar_SetCallback (&sv_friction, Host_Callback_Notify); Cvar_RegisterVariable (&sv_edgefriction); Cvar_RegisterVariable (&sv_stopspeed); Cvar_RegisterVariable (&sv_maxspeed); + Cvar_SetCallback (&sv_maxspeed, Host_Callback_Notify); Cvar_RegisterVariable (&sv_accelerate); Cvar_RegisterVariable (&sv_idealpitchscale); Cvar_RegisterVariable (&sv_aim); Cvar_RegisterVariable (&sv_nostep); + Cvar_RegisterVariable (&sv_freezenonclients); + Cvar_RegisterVariable (&sv_altnoclip); //johnfitz - // jkrige - configurable fps caps - Cvar_RegisterVariable(&sv_fps); - // jkrige - configurable fps caps + Cmd_AddCommand ("sv_protocol", &SV_Protocol_f); //johnfitz for (i=0 ; i MAX_DATAGRAM-16) - return; + return; MSG_WriteByte (&sv.datagram, svc_particle); - MSG_WriteCoord (&sv.datagram, org[0]); - MSG_WriteCoord (&sv.datagram, org[1]); - MSG_WriteCoord (&sv.datagram, org[2]); + MSG_WriteCoord (&sv.datagram, org[0], sv.protocolflags); + MSG_WriteCoord (&sv.datagram, org[1], sv.protocolflags); + MSG_WriteCoord (&sv.datagram, org[2], sv.protocolflags); for (i=0 ; i<3 ; i++) { v = dir[i]*16; @@ -108,9 +168,9 @@ void SV_StartParticle (vec3_t org, vec3_t dir, int color, int count) } MSG_WriteByte (&sv.datagram, count); MSG_WriteByte (&sv.datagram, color); -} +} -/* +/* ================== SV_StartSound @@ -124,42 +184,38 @@ An attenuation of 0 will play full volume everywhere in the level. Larger attenuations will drop off. (max 4 attenuation) ================== -*/ -void SV_StartSound (edict_t *entity, int channel, char *sample, int volume, - float attenuation) -{ - int sound_num; - int field_mask; - int i; - int ent; - +*/ +void SV_StartSound (edict_t *entity, int channel, const char *sample, int volume, float attenuation) +{ + int sound_num, ent; + int i, field_mask; + if (volume < 0 || volume > 255) - Sys_Error ("SV_StartSound: volume = %i", volume); + Host_Error ("SV_StartSound: volume = %i", volume); if (attenuation < 0 || attenuation > 4) - Sys_Error ("SV_StartSound: attenuation = %f", attenuation); + Host_Error ("SV_StartSound: attenuation = %f", attenuation); if (channel < 0 || channel > 7) - Sys_Error ("SV_StartSound: channel = %i", channel); + Host_Error ("SV_StartSound: channel = %i", channel); if (sv.datagram.cursize > MAX_DATAGRAM-16) - return; + return; // find precache number for sound - for (sound_num=1 ; sound_num= 8192) + { + if (sv.protocol == PROTOCOL_NETQUAKE) + return; //don't send any info protocol can't support + else + field_mask |= SND_LARGEENTITY; + } + if (sound_num >= 256 || channel >= 8) + { + if (sv.protocol == PROTOCOL_NETQUAKE) + return; //don't send any info protocol can't support + else + field_mask |= SND_LARGESOUND; + } + //johnfitz + // directed messages go only to the entity the are targeted on MSG_WriteByte (&sv.datagram, svc_sound); MSG_WriteByte (&sv.datagram, field_mask); @@ -174,11 +247,24 @@ void SV_StartSound (edict_t *entity, int channel, char *sample, int volume, MSG_WriteByte (&sv.datagram, volume); if (field_mask & SND_ATTENUATION) MSG_WriteByte (&sv.datagram, attenuation*64); - MSG_WriteShort (&sv.datagram, channel); - MSG_WriteByte (&sv.datagram, sound_num); - for (i=0 ; i<3 ; i++) - MSG_WriteCoord (&sv.datagram, entity->v.origin[i]+0.5*(entity->v.mins[i]+entity->v.maxs[i])); -} + + //johnfitz -- PROTOCOL_FITZQUAKE + if (field_mask & SND_LARGEENTITY) + { + MSG_WriteShort (&sv.datagram, ent); + MSG_WriteByte (&sv.datagram, channel); + } + else + MSG_WriteShort (&sv.datagram, (ent<<3) | channel); + if (field_mask & SND_LARGESOUND) + MSG_WriteShort (&sv.datagram, sound_num); + else + MSG_WriteByte (&sv.datagram, sound_num); + //johnfitz + + for (i = 0; i < 3; i++) + MSG_WriteCoord (&sv.datagram, entity->v.origin[i]+0.5*(entity->v.mins[i]+entity->v.maxs[i]), sv.protocolflags); +} /* ============================================================================== @@ -198,15 +284,23 @@ This will be sent on the initial connection and upon each server load. */ void SV_SendServerinfo (client_t *client) { - char **s; + const char **s; char message[2048]; + int i; //johnfitz MSG_WriteByte (&client->message, svc_print); - sprintf (message, "%c\nVERSION %4.2f SERVER (%i CRC)", 2, QUAKE_VERSION, pr_crc); + sprintf (message, "%c\nFITZQUAKE %1.2f SERVER (%i CRC)\n", 2, FITZQUAKE_VERSION, pr_crc); //johnfitz -- include fitzquake version MSG_WriteString (&client->message,message); MSG_WriteByte (&client->message, svc_serverinfo); - MSG_WriteLong (&client->message, PROTOCOL_VERSION); + MSG_WriteLong (&client->message, sv.protocol); //johnfitz -- sv.protocol instead of PROTOCOL_VERSION + + if (sv.protocol == PROTOCOL_RMQ) + { + // mh - now send protocol flags so that the client knows the protocol features to expect + MSG_WriteLong (&client->message, sv.protocolflags); + } + MSG_WriteByte (&client->message, svs.maxclients); if (!coop.value && deathmatch.value) @@ -214,29 +308,26 @@ void SV_SendServerinfo (client_t *client) else MSG_WriteByte (&client->message, GAME_COOP); - sprintf (message, PR_GetString(sv.edicts->v.message)); - - MSG_WriteString (&client->message,message); + MSG_WriteString (&client->message, PR_GetString(sv.edicts->v.message)); - for (s = sv.model_precache+1 ; *s ; s++) - MSG_WriteString (&client->message, *s); + //johnfitz -- only send the first 256 model and sound precaches if protocol is 15 + for (i=0,s = sv.model_precache+1 ; *s; s++,i++) + if (sv.protocol != PROTOCOL_NETQUAKE || i < 256) + MSG_WriteString (&client->message, *s); MSG_WriteByte (&client->message, 0); - for (s = sv.sound_precache+1 ; *s ; s++) - MSG_WriteString (&client->message, *s); + for (i=0,s = sv.sound_precache+1 ; *s ; s++,i++) + if (sv.protocol != PROTOCOL_NETQUAKE || i < 256) + MSG_WriteString (&client->message, *s); MSG_WriteByte (&client->message, 0); + //johnfitz // send music MSG_WriteByte (&client->message, svc_cdtrack); MSG_WriteByte (&client->message, sv.edicts->v.sounds); MSG_WriteByte (&client->message, sv.edicts->v.sounds); - // jkrige - skybox - MSG_WriteByte (&client->message, svc_skybox); - MSG_WriteString (&client->message, sv.skybox); - // jkrige - skybox - -// set view +// set view MSG_WriteByte (&client->message, svc_setview); MSG_WriteShort (&client->message, NUM_FOR_EDICT(client->edict)); @@ -266,15 +357,15 @@ void SV_ConnectClient (int clientnum) client = svs.clients + clientnum; - Con_DPrintf ("Client %s connected\n", client->netconnection->address); + Con_DPrintf ("Client %s connected\n", NET_QSocketGetAddressString(client->netconnection)); edictnum = clientnum+1; ent = EDICT_NUM(edictnum); - + // set up the client_t netconnection = client->netconnection; - + if (sv.loadgame) memcpy (spawn_parms, client->spawn_parms, sizeof(spawn_parms)); memset (client, 0, sizeof(*client)); @@ -288,12 +379,6 @@ void SV_ConnectClient (int clientnum) client->message.maxsize = sizeof(client->msgbuf); client->message.allowoverflow = true; // we can catch it -#ifdef IDGODS - client->privileged = IsID(&client->netconnection->addr); -#else - client->privileged = false; -#endif - if (sv.loadgame) memcpy (client->spawn_parms, spawn_parms, sizeof(spawn_parms)); else @@ -318,7 +403,7 @@ void SV_CheckForNewClients (void) { struct qsocket_s *ret; int i; - + // // check for new connections // @@ -328,24 +413,23 @@ void SV_CheckForNewClients (void) if (!ret) break; - // + // // init a new client structure - // + // for (i=0 ; icontents != CONTENTS_SOLID) { - pvs = Mod_LeafPVS ( (mleaf_t *)node, sv.worldmodel); + pvs = Mod_LeafPVS ( (mleaf_t *)node, worldmodel); //johnfitz -- worldmodel as a parameter for (i=0 ; iplane; d = DotProduct (org, plane->normal) - plane->dist; if (d > 8) @@ -408,7 +493,7 @@ void SV_AddToFatPVS (vec3_t org, mnode_t *node) node = node->children[1]; else { // go down both - SV_AddToFatPVS (org, node->children[0]); + SV_AddToFatPVS (org, node->children[0], worldmodel); //johnfitz -- worldmodel as a parameter node = node->children[1]; } } @@ -422,16 +507,46 @@ Calculates a PVS that is the inclusive or of all leafs within 8 pixels of the given point. ============= */ -byte *SV_FatPVS (vec3_t org) +byte *SV_FatPVS (vec3_t org, qmodel_t *worldmodel) //johnfitz -- added worldmodel as a parameter { - fatbytes = (sv.worldmodel->numleafs+31)>>3; + fatbytes = (worldmodel->numleafs+7)>>3; // ericw -- was +31, assumed to be a bug/typo + if (fatpvs == NULL || fatbytes > fatpvs_capacity) + { + fatpvs_capacity = fatbytes; + fatpvs = (byte *) realloc (fatpvs, fatpvs_capacity); + if (!fatpvs) + Sys_Error ("SV_FatPVS: realloc() failed on %d bytes", fatpvs_capacity); + } + Q_memset (fatpvs, 0, fatbytes); - SV_AddToFatPVS (org, sv.worldmodel->nodes); + SV_AddToFatPVS (org, worldmodel->nodes, worldmodel); //johnfitz -- worldmodel as a parameter return fatpvs; } -//============================================================================= +/* +============= +SV_VisibleToClient -- johnfitz + +PVS test encapsulated in a nice function +============= +*/ +qboolean SV_VisibleToClient (edict_t *client, edict_t *test, qmodel_t *worldmodel) +{ + byte *pvs; + vec3_t org; + int i; + + VectorAdd (client->v.origin, client->v.view_ofs, org); + pvs = SV_FatPVS (org, worldmodel); + for (i=0 ; i < test->num_leafs ; i++) + if (pvs[test->leafnums[i] >> 3] & (1 << (test->leafnums[i]&7) )) + return true; + + return false; +} + +//============================================================================= /* ============= @@ -450,42 +565,55 @@ void SV_WriteEntitiesToClient (edict_t *clent, sizebuf_t *msg) // find the client's PVS VectorAdd (clent->v.origin, clent->v.view_ofs, org); - pvs = SV_FatPVS (org); + pvs = SV_FatPVS (org, sv.worldmodel); // send over all entities (excpet the client) that touch the pvs ent = NEXT_EDICT(sv.edicts); for (e=1 ; ev.effects == EF_NODRAW) - continue; -#endif -// ignore if not touching a PV leaf if (ent != clent) // clent is ALLWAYS sent { -// ignore ents without visible models + // ignore ents without visible models if (!ent->v.modelindex || !PR_GetString(ent->v.model)[0]) continue; + //johnfitz -- don't send model>255 entities if protocol is 15 + if (sv.protocol == PROTOCOL_NETQUAKE && (int)ent->v.modelindex & 0xFF00) + continue; + + // ignore if not touching a PV leaf for (i=0 ; i < ent->num_leafs ; i++) if (pvs[ent->leafnums[i] >> 3] & (1 << (ent->leafnums[i]&7) )) break; - - if (i == ent->num_leafs) + + // ericw -- added ent->num_leafs < MAX_ENT_LEAFS condition. + // + // if ent->num_leafs == MAX_ENT_LEAFS, the ent is visible from too many leafs + // for us to say whether it's in the PVS, so don't try to vis cull it. + // this commonly happens with rotators, because they often have huge bboxes + // spanning the entire map, or really tall lifts, etc. + if (i == ent->num_leafs && ent->num_leafs < MAX_ENT_LEAFS) continue; // not visible } - if (msg->maxsize - msg->cursize < 16) + //johnfitz -- max size for protocol 15 is 18 bytes, not 16 as originally + //assumed here. And, for protocol 85 the max size is actually 24 bytes. + if (msg->cursize + 24 > msg->maxsize) { - Con_Printf ("packet overflow\n"); - return; + //johnfitz -- less spammy overflow message + if (!dev_overflows.packetsize || dev_overflows.packetsize + CONSOLE_RESPAM_TIME < realtime ) + { + Con_Printf ("Packet overflow!\n"); + dev_overflows.packetsize = realtime; + } + goto stats; + //johnfitz } // send an update bits = 0; - + for (i=0 ; i<3 ; i++) { miss = ent->v.origin[i] - ent->baseline.origin[i]; @@ -495,44 +623,80 @@ void SV_WriteEntitiesToClient (edict_t *clent, sizebuf_t *msg) if ( ent->v.angles[0] != ent->baseline.angles[0] ) bits |= U_ANGLE1; - + if ( ent->v.angles[1] != ent->baseline.angles[1] ) bits |= U_ANGLE2; - + if ( ent->v.angles[2] != ent->baseline.angles[2] ) bits |= U_ANGLE3; - + if (ent->v.movetype == MOVETYPE_STEP) - bits |= U_NOLERP; // don't mess up the step animation - + bits |= U_STEP; // don't mess up the step animation + if (ent->baseline.colormap != ent->v.colormap) bits |= U_COLORMAP; - + if (ent->baseline.skin != ent->v.skin) bits |= U_SKIN; - + if (ent->baseline.frame != ent->v.frame) bits |= U_FRAME; - + if (ent->baseline.effects != ent->v.effects) bits |= U_EFFECTS; - + if (ent->baseline.modelindex != ent->v.modelindex) bits |= U_MODEL; + //johnfitz -- alpha + if (pr_alpha_supported) + { + // TODO: find a cleaner place to put this code + eval_t *val; + val = GetEdictFieldValue(ent, "alpha"); + if (val) + ent->alpha = ENTALPHA_ENCODE(val->_float); + } + + //don't send invisible entities unless they have effects + if (ent->alpha == ENTALPHA_ZERO && !ent->v.effects) + continue; + //johnfitz + + //johnfitz -- PROTOCOL_FITZQUAKE + if (sv.protocol != PROTOCOL_NETQUAKE) + { + + if (ent->baseline.alpha != ent->alpha) bits |= U_ALPHA; + if (bits & U_FRAME && (int)ent->v.frame & 0xFF00) bits |= U_FRAME2; + if (bits & U_MODEL && (int)ent->v.modelindex & 0xFF00) bits |= U_MODEL2; + if (ent->sendinterval) bits |= U_LERPFINISH; + if (bits >= 65536) bits |= U_EXTEND1; + if (bits >= 16777216) bits |= U_EXTEND2; + } + //johnfitz + if (e >= 256) bits |= U_LONGENTITY; - + if (bits >= 256) bits |= U_MOREBITS; // // write the message // - MSG_WriteByte (msg,bits | U_SIGNAL); - + MSG_WriteByte (msg, bits | U_SIGNAL); + if (bits & U_MOREBITS) MSG_WriteByte (msg, bits>>8); + + //johnfitz -- PROTOCOL_FITZQUAKE + if (bits & U_EXTEND1) + MSG_WriteByte(msg, bits>>16); + if (bits & U_EXTEND2) + MSG_WriteByte(msg, bits>>24); + //johnfitz + if (bits & U_LONGENTITY) MSG_WriteShort (msg,e); else @@ -549,18 +713,37 @@ void SV_WriteEntitiesToClient (edict_t *clent, sizebuf_t *msg) if (bits & U_EFFECTS) MSG_WriteByte (msg, ent->v.effects); if (bits & U_ORIGIN1) - MSG_WriteCoord (msg, ent->v.origin[0]); + MSG_WriteCoord (msg, ent->v.origin[0], sv.protocolflags); if (bits & U_ANGLE1) - MSG_WriteAngle(msg, ent->v.angles[0]); + MSG_WriteAngle(msg, ent->v.angles[0], sv.protocolflags); if (bits & U_ORIGIN2) - MSG_WriteCoord (msg, ent->v.origin[1]); + MSG_WriteCoord (msg, ent->v.origin[1], sv.protocolflags); if (bits & U_ANGLE2) - MSG_WriteAngle(msg, ent->v.angles[1]); + MSG_WriteAngle(msg, ent->v.angles[1], sv.protocolflags); if (bits & U_ORIGIN3) - MSG_WriteCoord (msg, ent->v.origin[2]); + MSG_WriteCoord (msg, ent->v.origin[2], sv.protocolflags); if (bits & U_ANGLE3) - MSG_WriteAngle(msg, ent->v.angles[2]); + MSG_WriteAngle(msg, ent->v.angles[2], sv.protocolflags); + + //johnfitz -- PROTOCOL_FITZQUAKE + if (bits & U_ALPHA) + MSG_WriteByte(msg, ent->alpha); + if (bits & U_FRAME2) + MSG_WriteByte(msg, (int)ent->v.frame >> 8); + if (bits & U_MODEL2) + MSG_WriteByte(msg, (int)ent->v.modelindex >> 8); + if (bits & U_LERPFINISH) + MSG_WriteByte(msg, (byte)(Q_rint((ent->v.nextthink-sv.time)*255))); + //johnfitz } + + //johnfitz -- devstats +stats: + if (msg->cursize > 1024 && dev_peakstats.packetsize <= 1024) + Con_DWarning ("%i byte packet exceeds standard limit of 1024 (max = %d).\n", msg->cursize, msg->maxsize); + dev_stats.packetsize = msg->cursize; + dev_peakstats.packetsize = q_max(msg->cursize, dev_peakstats.packetsize); + //johnfitz } /* @@ -573,13 +756,12 @@ void SV_CleanupEnts (void) { int e; edict_t *ent; - + ent = NEXT_EDICT(sv.edicts); for (e=1 ; ev.effects = (int)ent->v.effects & ~EF_MUZZLEFLASH; } - } /* @@ -594,9 +776,7 @@ void SV_WriteClientdataToMessage (edict_t *ent, sizebuf_t *msg) int i; edict_t *other; int items; -#ifndef QUAKE2 eval_t *val; -#endif // // send a damage message @@ -608,8 +788,8 @@ void SV_WriteClientdataToMessage (edict_t *ent, sizebuf_t *msg) MSG_WriteByte (msg, ent->v.dmg_save); MSG_WriteByte (msg, ent->v.dmg_take); for (i=0 ; i<3 ; i++) - MSG_WriteCoord (msg, other->v.origin[i] + 0.5*(other->v.mins[i] + other->v.maxs[i])); - + MSG_WriteCoord (msg, other->v.origin[i] + 0.5*(other->v.mins[i] + other->v.maxs[i]), sv.protocolflags ); + ent->v.dmg_take = 0; ent->v.dmg_save = 0; } @@ -624,39 +804,35 @@ void SV_WriteClientdataToMessage (edict_t *ent, sizebuf_t *msg) { MSG_WriteByte (msg, svc_setangle); for (i=0 ; i < 3 ; i++) - MSG_WriteAngle (msg, ent->v.angles[i] ); + MSG_WriteAngle (msg, ent->v.angles[i], sv.protocolflags ); ent->v.fixangle = 0; } bits = 0; - + if (ent->v.view_ofs[2] != DEFAULT_VIEWHEIGHT) bits |= SU_VIEWHEIGHT; - + if (ent->v.idealpitch) bits |= SU_IDEALPITCH; // stuff the sigil bits into the high bits of items for sbar, or else // mix in items2 -#ifdef QUAKE2 - items = (int)ent->v.items | ((int)ent->v.items2 << 23); -#else val = GetEdictFieldValue(ent, "items2"); if (val) items = (int)ent->v.items | ((int)val->_float << 23); else items = (int)ent->v.items | ((int)pr_global_struct->serverflags << 28); -#endif bits |= SU_ITEMS; - + if ( (int)ent->v.flags & FL_ONGROUND) bits |= SU_ONGROUND; - + if ( ent->v.waterlevel >= 2) bits |= SU_INWATER; - + for (i=0 ; i<3 ; i++) { if (ent->v.punchangle[i]) @@ -664,7 +840,7 @@ void SV_WriteClientdataToMessage (edict_t *ent, sizebuf_t *msg) if (ent->v.velocity[i]) bits |= (SU_VELOCITY1<v.weaponframe) bits |= SU_WEAPONFRAME; @@ -674,11 +850,33 @@ void SV_WriteClientdataToMessage (edict_t *ent, sizebuf_t *msg) // if (ent->v.weapon) bits |= SU_WEAPON; + //johnfitz -- PROTOCOL_FITZQUAKE + if (sv.protocol != PROTOCOL_NETQUAKE) + { + if (bits & SU_WEAPON && SV_ModelIndex(PR_GetString(ent->v.weaponmodel)) & 0xFF00) bits |= SU_WEAPON2; + if ((int)ent->v.armorvalue & 0xFF00) bits |= SU_ARMOR2; + if ((int)ent->v.currentammo & 0xFF00) bits |= SU_AMMO2; + if ((int)ent->v.ammo_shells & 0xFF00) bits |= SU_SHELLS2; + if ((int)ent->v.ammo_nails & 0xFF00) bits |= SU_NAILS2; + if ((int)ent->v.ammo_rockets & 0xFF00) bits |= SU_ROCKETS2; + if ((int)ent->v.ammo_cells & 0xFF00) bits |= SU_CELLS2; + if (bits & SU_WEAPONFRAME && (int)ent->v.weaponframe & 0xFF00) bits |= SU_WEAPONFRAME2; + if (bits & SU_WEAPON && ent->alpha != ENTALPHA_DEFAULT) bits |= SU_WEAPONALPHA; //for now, weaponalpha = client entity alpha + if (bits >= 65536) bits |= SU_EXTEND1; + if (bits >= 16777216) bits |= SU_EXTEND2; + } + //johnfitz + // send the data MSG_WriteByte (msg, svc_clientdata); MSG_WriteShort (msg, bits); + //johnfitz -- PROTOCOL_FITZQUAKE + if (bits & SU_EXTEND1) MSG_WriteByte(msg, bits>>16); + if (bits & SU_EXTEND2) MSG_WriteByte(msg, bits>>24); + //johnfitz + if (bits & SU_VIEWHEIGHT) MSG_WriteChar (msg, ent->v.view_ofs[2]); @@ -702,7 +900,7 @@ void SV_WriteClientdataToMessage (edict_t *ent, sizebuf_t *msg) MSG_WriteByte (msg, ent->v.armorvalue); if (bits & SU_WEAPON) MSG_WriteByte (msg, SV_ModelIndex(PR_GetString(ent->v.weaponmodel))); - + MSG_WriteShort (msg, ent->v.health); MSG_WriteByte (msg, ent->v.currentammo); MSG_WriteByte (msg, ent->v.ammo_shells); @@ -725,6 +923,27 @@ void SV_WriteClientdataToMessage (edict_t *ent, sizebuf_t *msg) } } } + + //johnfitz -- PROTOCOL_FITZQUAKE + if (bits & SU_WEAPON2) + MSG_WriteByte (msg, SV_ModelIndex(PR_GetString(ent->v.weaponmodel)) >> 8); + if (bits & SU_ARMOR2) + MSG_WriteByte (msg, (int)ent->v.armorvalue >> 8); + if (bits & SU_AMMO2) + MSG_WriteByte (msg, (int)ent->v.currentammo >> 8); + if (bits & SU_SHELLS2) + MSG_WriteByte (msg, (int)ent->v.ammo_shells >> 8); + if (bits & SU_NAILS2) + MSG_WriteByte (msg, (int)ent->v.ammo_nails >> 8); + if (bits & SU_ROCKETS2) + MSG_WriteByte (msg, (int)ent->v.ammo_rockets >> 8); + if (bits & SU_CELLS2) + MSG_WriteByte (msg, (int)ent->v.ammo_cells >> 8); + if (bits & SU_WEAPONFRAME2) + MSG_WriteByte (msg, (int)ent->v.weaponframe >> 8); + if (bits & SU_WEAPONALPHA) + MSG_WriteByte (msg, ent->alpha); //for now, weaponalpha = client entity alpha + //johnfitz } /* @@ -736,11 +955,16 @@ qboolean SV_SendClientDatagram (client_t *client) { byte buf[MAX_DATAGRAM]; sizebuf_t msg; - + msg.data = buf; msg.maxsize = sizeof(buf); msg.cursize = 0; + //johnfitz -- if client is nonlocal, use smaller max size so packets aren't fragmented + if (Q_strcmp(NET_QSocketGetAddressString(client->netconnection), "LOCAL") != 0) + msg.maxsize = DATAGRAM_MTU; + //johnfitz + MSG_WriteByte (&msg, svc_time); MSG_WriteFloat (&msg, sv.time); @@ -759,7 +983,7 @@ qboolean SV_SendClientDatagram (client_t *client) SV_DropClient (true);// if the message couldn't send, kick off return false; } - + return true; } @@ -790,7 +1014,7 @@ void SV_UpdateToReliableMessages (void) host_client->old_frags = host_client->edict->v.frags; } } - + for (j=0, client = svs.clients ; jactive) @@ -814,7 +1038,7 @@ void SV_SendNop (client_t *client) { sizebuf_t msg; byte buf[4]; - + msg.data = buf; msg.maxsize = sizeof(buf); msg.cursize = 0; @@ -834,7 +1058,7 @@ SV_SendClientMessages void SV_SendClientMessages (void) { int i; - + // update frags, names, etc SV_UpdateToReliableMessages (); @@ -854,7 +1078,7 @@ void SV_SendClientMessages (void) // the player isn't totally in the game yet // send small keepalive messages if too much time has passed // send a full message when the next signon stage has been requested - // some other message data (name changes, etc) may accumulate + // some other message data (name changes, etc) may accumulate // between signon stages if (!host_client->sendsignon) { @@ -873,7 +1097,7 @@ void SV_SendClientMessages (void) host_client->message.overflowed = false; continue; } - + if (host_client->message.cursize || host_client->dropasap) { if (!NET_CanSendMessage (host_client->netconnection)) @@ -895,8 +1119,8 @@ void SV_SendClientMessages (void) } } } - - + + // clear muzzle flashes SV_CleanupEnts (); } @@ -916,10 +1140,10 @@ SV_ModelIndex ================ */ -int SV_ModelIndex (char *name) +int SV_ModelIndex (const char *name) { int i; - + if (!name || !name[0]) return 0; @@ -934,15 +1158,15 @@ int SV_ModelIndex (char *name) /* ================ SV_CreateBaseline - ================ */ void SV_CreateBaseline (void) { int i; - edict_t *svent; - int entnum; - + edict_t *svent; + int entnum; + int bits; //johnfitz -- PROTOCOL_FITZQUAKE + for (entnum = 0; entnum < sv.num_edicts ; entnum++) { // get the current server version @@ -963,29 +1187,75 @@ void SV_CreateBaseline (void) { svent->baseline.colormap = entnum; svent->baseline.modelindex = SV_ModelIndex("progs/player.mdl"); + svent->baseline.alpha = ENTALPHA_DEFAULT; //johnfitz -- alpha support } else { svent->baseline.colormap = 0; - svent->baseline.modelindex = - SV_ModelIndex(PR_GetString(svent->v.model)); + svent->baseline.modelindex = SV_ModelIndex(PR_GetString(svent->v.model)); + svent->baseline.alpha = svent->alpha; //johnfitz -- alpha support + } + + //johnfitz -- PROTOCOL_FITZQUAKE + bits = 0; + if (sv.protocol == PROTOCOL_NETQUAKE) //still want to send baseline in PROTOCOL_NETQUAKE, so reset these values + { + if (svent->baseline.modelindex & 0xFF00) + svent->baseline.modelindex = 0; + if (svent->baseline.frame & 0xFF00) + svent->baseline.frame = 0; + svent->baseline.alpha = ENTALPHA_DEFAULT; } - + else //decide which extra data needs to be sent + { + if (svent->baseline.modelindex & 0xFF00) + bits |= B_LARGEMODEL; + if (svent->baseline.frame & 0xFF00) + bits |= B_LARGEFRAME; + if (svent->baseline.alpha != ENTALPHA_DEFAULT) + bits |= B_ALPHA; + } + //johnfitz + // // add to the message // - MSG_WriteByte (&sv.signon,svc_spawnbaseline); + //johnfitz -- PROTOCOL_FITZQUAKE + if (bits) + MSG_WriteByte (&sv.signon, svc_spawnbaseline2); + else + MSG_WriteByte (&sv.signon, svc_spawnbaseline); + //johnfitz + MSG_WriteShort (&sv.signon,entnum); - MSG_WriteByte (&sv.signon, svent->baseline.modelindex); - MSG_WriteByte (&sv.signon, svent->baseline.frame); + //johnfitz -- PROTOCOL_FITZQUAKE + if (bits) + MSG_WriteByte (&sv.signon, bits); + + if (bits & B_LARGEMODEL) + MSG_WriteShort (&sv.signon, svent->baseline.modelindex); + else + MSG_WriteByte (&sv.signon, svent->baseline.modelindex); + + if (bits & B_LARGEFRAME) + MSG_WriteShort (&sv.signon, svent->baseline.frame); + else + MSG_WriteByte (&sv.signon, svent->baseline.frame); + //johnfitz + MSG_WriteByte (&sv.signon, svent->baseline.colormap); MSG_WriteByte (&sv.signon, svent->baseline.skin); for (i=0 ; i<3 ; i++) { - MSG_WriteCoord(&sv.signon, svent->baseline.origin[i]); - MSG_WriteAngle(&sv.signon, svent->baseline.angles[i]); + MSG_WriteCoord(&sv.signon, svent->baseline.origin[i], sv.protocolflags); + MSG_WriteAngle(&sv.signon, svent->baseline.angles[i], sv.protocolflags); } + + //johnfitz -- PROTOCOL_FITZQUAKE + if (bits & B_ALPHA) + MSG_WriteByte (&sv.signon, svent->baseline.alpha); + //johnfitz } } @@ -999,7 +1269,7 @@ Tell all the clients that the server is changing levels */ void SV_SendReconnect (void) { - char data[128]; + byte data[128]; sizebuf_t msg; msg.data = data; @@ -1008,14 +1278,10 @@ void SV_SendReconnect (void) MSG_WriteChar (&msg, svc_stufftext); MSG_WriteString (&msg, "reconnect\n"); - NET_SendToAll (&msg, 5); - - if (cls.state != ca_dedicated) -#ifdef QUAKE2 - Cbuf_InsertText ("reconnect\n"); -#else + NET_SendToAll (&msg, 5.0); + + if (!isDedicated) Cmd_ExecuteString ("reconnect\n", src_command); -#endif } @@ -1055,12 +1321,7 @@ This is called at the start of each level ================ */ extern float scr_centertime_off; - -#ifdef QUAKE2 -void SV_SpawnServer (char *server, char *startspot) -#else -void SV_SpawnServer (char *server) -#endif +void SV_SpawnServer (const char *server) { static char dummy[8] = { 0,0,0,0,0,0,0,0 }; edict_t *ent; @@ -1086,7 +1347,7 @@ void SV_SpawnServer (char *server) // make cvars consistant // if (coop.value) - Cvar_SetValue ("deathmatch", 0); + Cvar_Set ("deathmatch", "0"); current_skill = (int)(skill.value + 0.5); if (current_skill < 0) current_skill = 0; @@ -1094,55 +1355,61 @@ void SV_SpawnServer (char *server) current_skill = 3; Cvar_SetValue ("skill", (float)current_skill); - + // // set up the new server // + //memset (&sv, 0, sizeof(sv)); Host_ClearMemory (); - memset (&sv, 0, sizeof(sv)); + q_strlcpy (sv.name, server, sizeof(sv.name)); - strcpy (sv.name, server); -#ifdef QUAKE2 - if (startspot) - strcpy(sv.startspot, startspot); -#endif + sv.protocol = sv_protocol; // johnfitz + + if (sv.protocol == PROTOCOL_RMQ) + { + // set up the protocol flags used by this server + // (note - these could be cvar-ised so that server admins could choose the protocol features used by their servers) + sv.protocolflags = PRFL_INT32COORD | PRFL_SHORTANGLE; + } + else sv.protocolflags = 0; // load progs to get entity field count PR_LoadProgs (); // allocate server memory - sv.max_edicts = MAX_EDICTS; - - sv.edicts = Hunk_AllocName (sv.max_edicts*pr_edict_size, "edicts"); + /* Host_ClearMemory() called above already cleared the whole sv structure */ + sv.max_edicts = CLAMP (MIN_EDICTS,(int)max_edicts.value,MAX_EDICTS); //johnfitz -- max_edicts cvar + sv.edicts = (edict_t *) malloc (sv.max_edicts*pr_edict_size); // ericw -- sv.edicts switched to use malloc() sv.datagram.maxsize = sizeof(sv.datagram_buf); sv.datagram.cursize = 0; sv.datagram.data = sv.datagram_buf; - + sv.reliable_datagram.maxsize = sizeof(sv.reliable_datagram_buf); sv.reliable_datagram.cursize = 0; sv.reliable_datagram.data = sv.reliable_datagram_buf; - + sv.signon.maxsize = sizeof(sv.signon_buf); sv.signon.cursize = 0; sv.signon.data = sv.signon_buf; - + // leave slots at start for clients only sv.num_edicts = svs.maxclients+1; + memset(sv.edicts, 0, sv.num_edicts*pr_edict_size); // ericw -- sv.edicts switched to use malloc() for (i=0 ; inumvertexes == -1) - { - Con_Printf ("Couldn't spawn server %s\n", sv.modelname); - sv.active = false; - //total_loading_size = 0; - //loading_stage = 0; - return; - } - // jkrige - bsp version crash - sv.models[1] = sv.worldmodel; - + // // clear world interaction links // SV_ClearWorld (); - + sv.sound_precache[0] = dummy; sv.model_precache[0] = dummy; sv.model_precache[1] = sv.modelname; @@ -1180,7 +1435,7 @@ void SV_SpawnServer (char *server) // // load the rest of the entities -// +// ent = EDICT_NUM(0); memset (&ent->v, 0, progs->entityfields * 4); ent->free = false; @@ -1195,20 +1450,17 @@ void SV_SpawnServer (char *server) pr_global_struct->deathmatch = deathmatch.value; pr_global_struct->mapname = PR_SetEngineString(sv.name); -#ifdef QUAKE2 - pr_global_struct->startspot = sv.startspot - pr_strings; -#endif // serverflags are for cross level information (sigils) pr_global_struct->serverflags = svs.serverflags; - + ED_LoadFromFile (sv.worldmodel->entities); sv.active = true; // all setup is completed, any further precache statements are errors sv.state = ss_active; - + // run two frames to allow everything to settle host_frametime = 0.1; SV_Physics (); @@ -1217,11 +1469,16 @@ void SV_SpawnServer (char *server) // create a baseline for more efficient communications SV_CreateBaseline (); + //johnfitz -- warn if signon buffer larger than standard server can handle + if (sv.signon.cursize > 8000-2) //max size that will fit into 8000-sized client->message buffer with 2 extra bytes on the end + Con_DWarning ("%i byte signon buffer exceeds standard limit of 7998 (max = %d).\n", sv.signon.cursize, sv.signon.maxsize); + //johnfitz + // send serverinfo to all connected clients for (i=0,host_client = svs.clients ; iactive) SV_SendServerinfo (host_client); - + Con_DPrintf ("Server spawned.\n"); } diff --git a/engine/code/sv_move.c b/engine/Quake/sv_move.c similarity index 94% rename from engine/code/sv_move.c rename to engine/Quake/sv_move.c index a0078b9..fd19084 100644 --- a/engine/code/sv_move.c +++ b/engine/Quake/sv_move.c @@ -1,5 +1,7 @@ /* -Copyright (C) 1996-1997 Id Software, Inc. +Copyright (C) 1996-2001 Id Software, Inc. +Copyright (C) 2002-2009 John Fitzgibbons and others +Copyright (C) 2010-2014 QuakeSpasm developers This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -8,7 +10,7 @@ of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. @@ -40,7 +42,7 @@ qboolean SV_CheckBottom (edict_t *ent) trace_t trace; int x, y; float mid, bottom; - + VectorAdd (ent->v.origin, ent->v.mins, mins); VectorAdd (ent->v.origin, ent->v.maxs, maxs); @@ -66,7 +68,7 @@ realcheck: // check it for real... // start[2] = mins[2]; - + // the midpoint must be within 16 of the bottom start[0] = stop[0] = (mins[0] + maxs[0])*0.5; start[1] = stop[1] = (mins[1] + maxs[1])*0.5; @@ -76,16 +78,16 @@ realcheck: if (trace.fraction == 1.0) return false; mid = bottom = trace.endpos[2]; - -// the corners must be within 16 of the midpoint + +// the corners must be within 16 of the midpoint for (x=0 ; x<=1 ; x++) for (y=0 ; y<=1 ; y++) { start[0] = stop[0] = x ? maxs[0] : mins[0]; start[1] = stop[1] = y ? maxs[1] : mins[1]; - + trace = SV_Move (start, vec3_origin, vec3_origin, stop, true, ent); - + if (trace.fraction != 1.0 && trace.endpos[2] > bottom) bottom = trace.endpos[2]; if (trace.fraction == 1.0 || mid - trace.endpos[2] > STEPSIZE) @@ -115,7 +117,7 @@ qboolean SV_movestep (edict_t *ent, vec3_t move, qboolean relink) int i; edict_t *enemy; -// try the move +// try the move VectorCopy (ent->v.origin, oldorg); VectorAdd (ent->v.origin, move, neworg); @@ -136,22 +138,22 @@ qboolean SV_movestep (edict_t *ent, vec3_t move, qboolean relink) neworg[2] += 8; } trace = SV_Move (ent->v.origin, ent->v.mins, ent->v.maxs, neworg, false, ent); - + if (trace.fraction == 1) { if ( ((int)ent->v.flags & FL_SWIM) && SV_PointContents(trace.endpos) == CONTENTS_EMPTY ) return false; // swim monster left water - + VectorCopy (trace.endpos, ent->v.origin); if (relink) SV_LinkEdict (ent, true); return true; } - + if (enemy == sv.edicts) break; } - + return false; } @@ -181,16 +183,16 @@ qboolean SV_movestep (edict_t *ent, vec3_t move, qboolean relink) if (relink) SV_LinkEdict (ent, true); ent->v.flags = (int)ent->v.flags & ~FL_ONGROUND; -// Con_Printf ("fall down\n"); +// Con_Printf ("fall down\n"); return true; } - + return false; // walked off an edge } // check point traces down for dangling corners VectorCopy (trace.endpos, ent->v.origin); - + if (!SV_CheckBottom (ent)) { if ( (int)ent->v.flags & FL_PARTIALGROUND ) @@ -206,7 +208,7 @@ qboolean SV_movestep (edict_t *ent, vec3_t move, qboolean relink) if ( (int)ent->v.flags & FL_PARTIALGROUND ) { -// Con_Printf ("back on ground\n"); +// Con_Printf ("back on ground\n"); ent->v.flags = (int)ent->v.flags & ~FL_PARTIALGROUND; } ent->v.groundentity = EDICT_TO_PROG(trace.ent); @@ -234,10 +236,10 @@ qboolean SV_StepDirection (edict_t *ent, float yaw, float dist) { vec3_t move, oldorigin; float delta; - + ent->v.ideal_yaw = yaw; PF_changeyaw(); - + yaw = yaw*M_PI*2 / 360; move[0] = cos(yaw)*dist; move[1] = sin(yaw)*dist; @@ -255,7 +257,7 @@ qboolean SV_StepDirection (edict_t *ent, float yaw, float dist) return true; } SV_LinkEdict (ent, true); - + return false; } @@ -268,7 +270,7 @@ SV_FixCheckBottom void SV_FixCheckBottom (edict_t *ent) { // Con_Printf ("SV_FixCheckBottom\n"); - + ent->v.flags = (int)ent->v.flags | FL_PARTIALGROUND; } @@ -312,20 +314,20 @@ void SV_NewChaseDir (edict_t *actor, edict_t *enemy, float dist) tdir = d[2] == 90 ? 45 : 315; else tdir = d[2] == 90 ? 135 : 215; - + if (tdir != turnaround && SV_StepDirection(actor, tdir, dist)) return; } // try other directions - if ( ((rand()&3) & 1) || abs(deltay)>abs(deltax)) + if ( ((rand()&3) & 1) || abs((int)deltay)>abs((int)deltax)) // ericw -- explicit int cast to suppress clang suggestion to use fabsf { tdir=d[1]; d[1]=d[2]; d[2]=tdir; } - if (d[1]!=DI_NODIR && d[1]!=turnaround + if (d[1]!=DI_NODIR && d[1]!=turnaround && SV_StepDirection(actor, d[1], dist)) return; @@ -373,7 +375,7 @@ SV_CloseEnough qboolean SV_CloseEnough (edict_t *ent, edict_t *goal, float dist) { int i; - + for (i=0 ; i<3 ; i++) { if (goal->v.absmin[i] > ent->v.absmax[i] + dist) @@ -394,9 +396,6 @@ void SV_MoveToGoal (void) { edict_t *ent, *goal; float dist; -#ifdef QUAKE2 - edict_t *enemy; -#endif ent = PROG_TO_EDICT(pr_global_struct->self); goal = PROG_TO_EDICT(ent->v.goalentity); @@ -409,12 +408,7 @@ void SV_MoveToGoal (void) } // if the next step hits the enemy, return immediately -#ifdef QUAKE2 - enemy = PROG_TO_EDICT(ent->v.enemy); - if (enemy != sv.edicts && SV_CloseEnough (ent, enemy, dist) ) -#else if ( PROG_TO_EDICT(ent->v.enemy) != sv.edicts && SV_CloseEnough (ent, goal, dist) ) -#endif return; // bump around... diff --git a/engine/code/sv_phys.c b/engine/Quake/sv_phys.c similarity index 52% rename from engine/code/sv_phys.c rename to engine/Quake/sv_phys.c index 8f163fa..eb5019a 100644 --- a/engine/code/sv_phys.c +++ b/engine/Quake/sv_phys.c @@ -1,5 +1,7 @@ /* -Copyright (C) 1996-1997 Id Software, Inc. +Copyright (C) 1996-2001 Id Software, Inc. +Copyright (C) 2002-2009 John Fitzgibbons and others +Copyright (C) 2010-2014 QuakeSpasm developers This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -8,7 +10,7 @@ of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. @@ -26,7 +28,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. pushmove objects do not obey gravity, and do not interact with each other or trigger fields, but block normal movement and push normal objects when they move. -onground is set for toss objects when they come to a complete rest. it is set for steping or walking objects +onground is set for toss objects when they come to a complete rest. it is set for steping or walking objects doors, plats, etc are SOLID_BSP, and MOVETYPE_PUSH bonus items are SOLID_TRIGGER touch, and MOVETYPE_TOSS @@ -39,15 +41,13 @@ solid_edge items only clip against bsp models. */ -cvar_t sv_friction = {"sv_friction","4",false,true}; -cvar_t sv_stopspeed = {"sv_stopspeed","100"}; -cvar_t sv_gravity = {"sv_gravity","800",false,true}; -cvar_t sv_maxvelocity = {"sv_maxvelocity","2000"}; -cvar_t sv_nostep = {"sv_nostep","0"}; +cvar_t sv_friction = {"sv_friction","4",CVAR_NOTIFY|CVAR_SERVERINFO}; +cvar_t sv_stopspeed = {"sv_stopspeed","100",CVAR_NONE}; +cvar_t sv_gravity = {"sv_gravity","800",CVAR_NOTIFY|CVAR_SERVERINFO}; +cvar_t sv_maxvelocity = {"sv_maxvelocity","2000",CVAR_NONE}; +cvar_t sv_nostep = {"sv_nostep","0",CVAR_NONE}; +cvar_t sv_freezenonclients = {"sv_freezenonclients","0",CVAR_NONE}; -#ifdef QUAKE2 -static vec3_t vec_origin = {0.0, 0.0, 0.0}; -#endif #define MOVE_EPSILON 0.01 @@ -71,9 +71,6 @@ void SV_CheckAllEnts (void) continue; if (check->v.movetype == MOVETYPE_PUSH || check->v.movetype == MOVETYPE_NONE -#ifdef QUAKE2 - || check->v.movetype == MOVETYPE_FOLLOW -#endif || check->v.movetype == MOVETYPE_NOCLIP) continue; @@ -90,7 +87,6 @@ SV_CheckVelocity void SV_CheckVelocity (edict_t *ent) { int i; - float wishspeed; // jkrige - SV_MAXVELOCITY fix // // bound velocity @@ -102,31 +98,16 @@ void SV_CheckVelocity (edict_t *ent) Con_Printf ("Got a NaN velocity on %s\n", PR_GetString(ent->v.classname)); ent->v.velocity[i] = 0; } - if (IS_NAN(ent->v.origin[i])) { Con_Printf ("Got a NaN origin on %s\n", PR_GetString(ent->v.classname)); ent->v.origin[i] = 0; } - - // jkrige - SV_MAXVELOCITY fix - /* if (ent->v.velocity[i] > sv_maxvelocity.value) ent->v.velocity[i] = sv_maxvelocity.value; else if (ent->v.velocity[i] < -sv_maxvelocity.value) ent->v.velocity[i] = -sv_maxvelocity.value; - */ - // jkrige - SV_MAXVELOCITY fix - } - - // jkrige - SV_MAXVELOCITY fix - wishspeed = Length(ent->v.velocity); - if (wishspeed > sv_maxvelocity.value) - { - VectorScale (ent->v.velocity, sv_maxvelocity.value/wishspeed, ent->v.velocity); - wishspeed = sv_maxvelocity.value; } - // jkrige - SV_MAXVELOCITY fix } /* @@ -142,20 +123,38 @@ Returns false if the entity removed itself. qboolean SV_RunThink (edict_t *ent) { float thinktime; + float oldframe; //johnfitz + int i; //johnfitz thinktime = ent->v.nextthink; if (thinktime <= 0 || thinktime > sv.time + host_frametime) return true; - + if (thinktime < sv.time) thinktime = sv.time; // don't let things stay in the past. // it is possible to start that way // by a trigger with a local time. + + oldframe = ent->v.frame; //johnfitz + ent->v.nextthink = 0; pr_global_struct->time = thinktime; pr_global_struct->self = EDICT_TO_PROG(ent); pr_global_struct->other = EDICT_TO_PROG(sv.edicts); PR_ExecuteProgram (ent->v.think); + +//johnfitz -- PROTOCOL_FITZQUAKE +//capture interval to nextthink here and send it to client for better +//lerp timing, but only if interval is not 0.1 (which client assumes) + ent->sendinterval = false; + if (!ent->free && ent->v.nextthink && (ent->v.movetype == MOVETYPE_STEP || ent->v.frame != oldframe)) + { + i = Q_rint((ent->v.nextthink-thinktime)*255); + if (i >= 0 && i < 256 && i != 25 && i != 26) //25 and 26 are close enough to 0.1 to not send + ent->sendinterval = true; + } +//johnfitz + return !ent->free; } @@ -169,10 +168,10 @@ Two entities have touched, so run their touch functions void SV_Impact (edict_t *e1, edict_t *e2) { int old_self, old_other; - + old_self = pr_global_struct->self; old_other = pr_global_struct->other; - + pr_global_struct->time = sv.time; if (e1->v.touch && e1->v.solid != SOLID_NOT) { @@ -180,7 +179,7 @@ void SV_Impact (edict_t *e1, edict_t *e2) pr_global_struct->other = EDICT_TO_PROG(e2); PR_ExecuteProgram (e1->v.touch); } - + if (e2->v.touch && e2->v.solid != SOLID_NOT) { pr_global_struct->self = EDICT_TO_PROG(e2); @@ -208,13 +207,13 @@ int ClipVelocity (vec3_t in, vec3_t normal, vec3_t out, float overbounce) float backoff; float change; int i, blocked; - + blocked = 0; if (normal[2] > 0) blocked |= 1; // floor if (!normal[2]) blocked |= 2; // step - + backoff = DotProduct (in, normal) * overbounce; for (i=0 ; i<3 ; i++) @@ -224,7 +223,7 @@ int ClipVelocity (vec3_t in, vec3_t normal, vec3_t out, float overbounce) if (out[i] > -STOP_EPSILON && out[i] < STOP_EPSILON) out[i] = 0; } - + return blocked; } @@ -255,14 +254,14 @@ int SV_FlyMove (edict_t *ent, float time, trace_t *steptrace) vec3_t end; float time_left; int blocked; - + numbumps = 4; - + blocked = 0; VectorCopy (ent->v.velocity, original_velocity); VectorCopy (ent->v.velocity, primal_velocity); numplanes = 0; - + time_left = time; for (bumpcount=0 ; bumpcountfree) break; // removed by the impact function - + time_left -= time_left * trace.fraction; - + // cliped to another plane if (numplanes >= MAX_CLIP_PLANES) { // this shouldn't really happen @@ -345,7 +344,7 @@ int SV_FlyMove (edict_t *ent, float time, trace_t *steptrace) if (j == numplanes) break; } - + if (i != numplanes) { // go along this plane VectorCopy (new_velocity, ent->v.velocity); @@ -387,13 +386,6 @@ SV_AddGravity void SV_AddGravity (edict_t *ent) { float ent_gravity; - -#ifdef QUAKE2 - if (ent->v.gravity) - ent_gravity = ent->v.gravity; - else - ent_gravity = 1.0; -#else eval_t *val; val = GetEdictFieldValue(ent, "gravity"); @@ -401,7 +393,7 @@ void SV_AddGravity (edict_t *ent) ent_gravity = val->_float; else ent_gravity = 1.0; -#endif + ent->v.velocity[2] -= ent_gravity * sv_gravity.value * host_frametime; } @@ -425,7 +417,7 @@ trace_t SV_PushEntity (edict_t *ent, vec3_t push) { trace_t trace; vec3_t end; - + VectorAdd (ent->v.origin, push, end); if (ent->v.movetype == MOVETYPE_FLYMISSILE) @@ -434,22 +426,21 @@ trace_t SV_PushEntity (edict_t *ent, vec3_t push) // only clip against bmodels trace = SV_Move (ent->v.origin, ent->v.mins, ent->v.maxs, end, MOVE_NOMONSTERS, ent); else - trace = SV_Move (ent->v.origin, ent->v.mins, ent->v.maxs, end, MOVE_NORMAL, ent); - + trace = SV_Move (ent->v.origin, ent->v.mins, ent->v.maxs, end, MOVE_NORMAL, ent); + VectorCopy (trace.endpos, ent->v.origin); SV_LinkEdict (ent, true); if (trace.ent) - SV_Impact (ent, trace.ent); + SV_Impact (ent, trace.ent); return trace; -} +} /* ============ SV_PushMove - ============ */ void SV_PushMove (edict_t *pusher, float movetime) @@ -459,10 +450,9 @@ void SV_PushMove (edict_t *pusher, float movetime) vec3_t mins, maxs, move; vec3_t entorig, pushorig; int num_moved; - edict_t *moved_edict[MAX_EDICTS]; - vec3_t moved_from[MAX_EDICTS]; - - float solid_backup; // jkrige - MOVETYPE_PUSH fix + edict_t **moved_edict; //johnfitz -- dynamically allocate + vec3_t *moved_from; //johnfitz -- dynamically allocate + int mark; //johnfitz if (!pusher->v.velocity[0] && !pusher->v.velocity[1] && !pusher->v.velocity[2]) { @@ -478,13 +468,18 @@ void SV_PushMove (edict_t *pusher, float movetime) } VectorCopy (pusher->v.origin, pushorig); - + // move the pusher to it's final position VectorAdd (pusher->v.origin, move, pusher->v.origin); pusher->v.ltime += movetime; SV_LinkEdict (pusher, false); + //johnfitz -- dynamically allocate + mark = Hunk_LowMark (); + moved_edict = (edict_t **) Hunk_Alloc (sv.num_edicts*sizeof(edict_t *)); + moved_from = (vec3_t *) Hunk_Alloc (sv.num_edicts*sizeof(vec3_t)); + //johnfitz // see if any solid entities are inside the final position num_moved = 0; @@ -495,9 +490,6 @@ void SV_PushMove (edict_t *pusher, float movetime) continue; if (check->v.movetype == MOVETYPE_PUSH || check->v.movetype == MOVETYPE_NONE -#ifdef QUAKE2 - || check->v.movetype == MOVETYPE_FOLLOW -#endif || check->v.movetype == MOVETYPE_NOCLIP) continue; @@ -518,172 +510,16 @@ void SV_PushMove (edict_t *pusher, float movetime) continue; } - // remove the onground flag for non-players - if (check->v.movetype != MOVETYPE_WALK) - check->v.flags = (int)check->v.flags & ~FL_ONGROUND; - - VectorCopy (check->v.origin, entorig); - VectorCopy (check->v.origin, moved_from[num_moved]); - moved_edict[num_moved] = check; - num_moved++; - - - // jkrige - MOVETYPE_PUSH fix - // try moving the contacted entity - //pusher->v.solid = SOLID_NOT; - //SV_PushEntity (check, move); - //pusher->v.solid = SOLID_BSP; - - // if it is still inside the pusher, block - //block = SV_TestEntityPosition (check); - - solid_backup = pusher->v.solid; - if ( solid_backup == SOLID_BSP // everything that blocks: bsp models = map brushes = doors, plats, etc. - || solid_backup == SOLID_BBOX // normally boxes - || solid_backup == SOLID_SLIDEBOX ) // normally monsters - { - // try moving the contacted entity - pusher->v.solid = SOLID_NOT; - SV_PushEntity (check, move); - pusher->v.solid = solid_backup; - - // if it is still inside the pusher, block - block = SV_TestEntityPosition (check); - } - else - { - block = NULL; - } - // jkrige - MOVETYPE_PUSH fix - - - if (block) - { // fail the move - if (check->v.mins[0] == check->v.maxs[0]) - continue; - if (check->v.solid == SOLID_NOT || check->v.solid == SOLID_TRIGGER) - { // corpse - check->v.mins[0] = check->v.mins[1] = 0; - VectorCopy (check->v.mins, check->v.maxs); - continue; - } - - VectorCopy (entorig, check->v.origin); - SV_LinkEdict (check, true); - - VectorCopy (pushorig, pusher->v.origin); - SV_LinkEdict (pusher, false); - pusher->v.ltime -= movetime; - - // if the pusher has a "blocked" function, call it - // otherwise, just stay in place until the obstacle is gone - if (pusher->v.blocked) - { - pr_global_struct->self = EDICT_TO_PROG(pusher); - pr_global_struct->other = EDICT_TO_PROG(check); - PR_ExecuteProgram (pusher->v.blocked); - } - - // move back any entities we already moved - for (i=0 ; iv.origin); - SV_LinkEdict (moved_edict[i], false); - } - return; - } - } - - -} - -#ifdef QUAKE2 -/* -============ -SV_PushRotate - -============ -*/ -void SV_PushRotate (edict_t *pusher, float movetime) -{ - int i, e; - edict_t *check, *block; - vec3_t move, a, amove; - vec3_t entorig, pushorig; - int num_moved; - edict_t *moved_edict[MAX_EDICTS]; - vec3_t moved_from[MAX_EDICTS]; - vec3_t org, org2; - vec3_t forward, right, up; - - if (!pusher->v.avelocity[0] && !pusher->v.avelocity[1] && !pusher->v.avelocity[2]) - { - pusher->v.ltime += movetime; - return; - } - - for (i=0 ; i<3 ; i++) - amove[i] = pusher->v.avelocity[i] * movetime; - - VectorSubtract (vec3_origin, amove, a); - AngleVectors (a, forward, right, up); - - VectorCopy (pusher->v.angles, pushorig); - -// move the pusher to it's final position - - VectorAdd (pusher->v.angles, amove, pusher->v.angles); - pusher->v.ltime += movetime; - SV_LinkEdict (pusher, false); - - -// see if any solid entities are inside the final position - num_moved = 0; - check = NEXT_EDICT(sv.edicts); - for (e=1 ; efree) - continue; - if (check->v.movetype == MOVETYPE_PUSH - || check->v.movetype == MOVETYPE_NONE - || check->v.movetype == MOVETYPE_FOLLOW - || check->v.movetype == MOVETYPE_NOCLIP) - continue; - - // if the entity is standing on the pusher, it will definately be moved - if ( ! ( ((int)check->v.flags & FL_ONGROUND) - && PROG_TO_EDICT(check->v.groundentity) == pusher) ) - { - if ( check->v.absmin[0] >= pusher->v.absmax[0] - || check->v.absmin[1] >= pusher->v.absmax[1] - || check->v.absmin[2] >= pusher->v.absmax[2] - || check->v.absmax[0] <= pusher->v.absmin[0] - || check->v.absmax[1] <= pusher->v.absmin[1] - || check->v.absmax[2] <= pusher->v.absmin[2] ) - continue; - - // see if the ent's bbox is inside the pusher's final position - if (!SV_TestEntityPosition (check)) - continue; - } - // remove the onground flag for non-players if (check->v.movetype != MOVETYPE_WALK) check->v.flags = (int)check->v.flags & ~FL_ONGROUND; - + VectorCopy (check->v.origin, entorig); VectorCopy (check->v.origin, moved_from[num_moved]); moved_edict[num_moved] = check; num_moved++; - // calculate destination position - VectorSubtract (check->v.origin, pusher->v.origin, org); - org2[0] = DotProduct (org, forward); - org2[1] = -DotProduct (org, right); - org2[2] = DotProduct (org, up); - VectorSubtract (org2, org, move); - - // try moving the contacted entity + // try moving the contacted entity pusher->v.solid = SOLID_NOT; SV_PushEntity (check, move); pusher->v.solid = SOLID_BSP; @@ -700,11 +536,11 @@ void SV_PushRotate (edict_t *pusher, float movetime) VectorCopy (check->v.mins, check->v.maxs); continue; } - + VectorCopy (entorig, check->v.origin); SV_LinkEdict (check, true); - VectorCopy (pushorig, pusher->v.angles); + VectorCopy (pushorig, pusher->v.origin); SV_LinkEdict (pusher, false); pusher->v.ltime -= movetime; @@ -716,394 +552,21 @@ void SV_PushRotate (edict_t *pusher, float movetime) pr_global_struct->other = EDICT_TO_PROG(check); PR_ExecuteProgram (pusher->v.blocked); } - + // move back any entities we already moved for (i=0 ; iv.origin); - VectorSubtract (moved_edict[i]->v.angles, amove, moved_edict[i]->v.angles); SV_LinkEdict (moved_edict[i], false); } + Hunk_FreeToLowMark (mark); //johnfitz return; } - else - { - VectorAdd (check->v.angles, amove, check->v.angles); - } - } - - -} -#endif - -// jkrige - rotating bmodels (ported from Hexen II) -#if 0 -void SV_PushRotate (edict_t *pusher, float movetime) -{ - int i, e, t; - edict_t *check, *block; - vec3_t move, a, amove, mins, maxs, move2, move3, testmove; -// vec3_t amove_norm; - vec3_t entorig, pushorig, pushorigangles; - int num_moved; - edict_t *moved_edict[MAX_EDICTS]; - vec3_t moved_from[MAX_EDICTS]; - vec3_t org, org2, check_center; - vec3_t forward, right, up; - edict_t *ground; - edict_t *master; - edict_t *slave; - int slaves_moved; - qboolean moveit; -// float turn_away, amove_mag; - -#if 0 - Con_DPrintf("SV_PushRotate entity %i (time=%f)\n", NUM_FOR_EDICT(pusher), movetime); - Con_DPrintf("%f %f %f (avelocity)\n", pusher->v.avelocity[0], pusher->v.avelocity[1], pusher->v.avelocity[2]); - Con_DPrintf("%f %f %f\n", pusher->v.angles[0], pusher->v.angles[1], pusher->v.angles[2]); -#endif - - for (i=0 ; i<3 ; i++) - { - amove[i] = pusher->v.avelocity[i] * movetime; - move[i] = pusher->v.velocity[i] * movetime; - mins[i] = pusher->v.absmin[i] + move[i]; - maxs[i] = pusher->v.absmax[i] + move[i]; } - VectorSubtract (vec3_origin, amove, a); - AngleVectors (a, forward, right, up); + Hunk_FreeToLowMark (mark); //johnfitz - VectorCopy (pusher->v.origin, pushorig); - VectorCopy (pusher->v.angles, pushorigangles); - - // move the pusher to it's final position - VectorAdd (pusher->v.origin, move, pusher->v.origin); - VectorAdd (pusher->v.angles, amove, pusher->v.angles); - - pusher->v.ltime += movetime; - SV_LinkEdict (pusher, false); - - master = pusher; - slaves_moved = 0; -/* while (master->v.aiment) - { - slave = PROG_TO_EDICT(master->v.aiment); - - //Con_DPrintf("%f %f %f slave entity %i\n", slave->v.angles[0], slave->v.angles[1], slave->v.angles[2], NUM_FOR_EDICT(slave)); - - slaves_moved++; - VectorCopy (slave->v.angles, moved_from[MAX_EDICTS - slaves_moved]); - moved_edict[MAX_EDICTS - slaves_moved] = slave; - - if (slave->v.movedir[PITCH]) - slave->v.angles[PITCH] = master->v.angles[PITCH]; - else - slave->v.angles[PITCH] += slave->v.avelocity[PITCH] * movetime; - - if (slave->v.movedir[YAW]) - slave->v.angles[YAW] = master->v.angles[YAW]; - else - slave->v.angles[YAW] += slave->v.avelocity[YAW] * movetime; - - if (slave->v.movedir[ROLL]) - slave->v.angles[ROLL] = master->v.angles[ROLL]; - else - slave->v.angles[ROLL] += slave->v.avelocity[ROLL] * movetime; - - slave->v.ltime = master->v.ltime; - SV_LinkEdict (slave, false); - - master = slave; - } -*/ - - // see if any solid entities are inside the final position - num_moved = 0; - check = NEXT_EDICT(sv.edicts); - for (e=1 ; efree) - continue; - if (check->v.movetype == MOVETYPE_PUSH - || check->v.movetype == MOVETYPE_NONE - // || check->v.movetype == MOVETYPE_FOLLOW // jkrige - || check->v.movetype == MOVETYPE_NOCLIP) - continue; - - // if the entity is standing on the pusher, it will definitely be moved - moveit = false; - ground = PROG_TO_EDICT(check->v.groundentity); - if ((int)check->v.flags & FL_ONGROUND) - { - if (ground == pusher) - { - moveit = true; - } - else - { - for (i=0; iv.absmin[0] >= maxs[0] - || check->v.absmin[1] >= maxs[1] - || check->v.absmin[2] >= maxs[2] - || check->v.absmax[0] <= mins[0] - || check->v.absmax[1] <= mins[1] - || check->v.absmax[2] <= mins[2] ) - { - for (i=0; iv.absmin[0] >= slave->v.absmax[0] - || check->v.absmin[1] >= slave->v.absmax[1] - || check->v.absmin[2] >= slave->v.absmax[2] - || check->v.absmax[0] <= slave->v.absmin[0] - || check->v.absmax[1] <= slave->v.absmin[1] - || check->v.absmax[2] <= slave->v.absmin[2] ) - continue; - } - if (i == slaves_moved) - continue; - } - - // see if the ent's bbox is inside the pusher's final position - if (!SV_TestEntityPosition (check)) - continue; - } - - // remove the onground flag for non-players - if (check->v.movetype != MOVETYPE_WALK) - check->v.flags = (int)check->v.flags & ~FL_ONGROUND; - - VectorCopy (check->v.origin, entorig); - VectorCopy (check->v.origin, moved_from[num_moved]); - moved_edict[num_moved] = check; - num_moved++; - - // put check in first move spot - VectorAdd (check->v.origin, move, check->v.origin); - // Use center of model, like in QUAKE!!!! - // Our origins are on the bottom!!! - for (i=0 ; i<3 ; i++) - check_center[i] = (check->v.absmin[i] + check->v.absmax[i])/2; - // calculate destination position - VectorSubtract (check_center, pusher->v.origin, org); - // put check back - VectorSubtract (check->v.origin, move, check->v.origin); - org2[0] = DotProduct (org, forward); - org2[1] = -DotProduct (org, right); - org2[2] = DotProduct (org, up); - VectorSubtract (org2, org, move2); - - //Con_DPrintf("%f %f %f (move2)\n", move2[0], move2[1], move2[2]); - - // VectorAdd (check->v.origin, move2, check->v.origin); - - // Add all moves together - VectorAdd(move,move2,move3); - - // Find the angle of rotation as compared to vector from pusher - // origin to check center - // turn_away = DotProduct(org,a); - - // try moving the contacted entity - for (t = 0; t < 13; t++) - { - switch (t) - { - case 0: - //try x, y and z - VectorCopy(move3,testmove); - break; - case 1: - //Try xy only - VectorSubtract(check->v.origin,testmove,check->v.origin); - testmove[0]=move3[0]; - testmove[1]=move3[1]; - testmove[2]=0; - break; - case 2: - //Try z only - VectorSubtract(check->v.origin,testmove,check->v.origin); - testmove[0]=0; - testmove[1]=0; - testmove[2]=move3[2]; - break; - case 3: - //Try none - VectorSubtract(check->v.origin,testmove,check->v.origin); - testmove[0]=0; - testmove[1]=0; - testmove[2]=0; - break; - case 4: - //Try xy in opposite dir - testmove[0]=move3[0]*-1; - testmove[1]=move3[1]*-1; - testmove[2]=move3[2]; - break; - case 5: - //Try z in opposite dir - VectorSubtract(check->v.origin,testmove,check->v.origin); - testmove[0]=move3[0]; - testmove[1]=move3[1]; - testmove[2]=move3[2]*-1; - break; - case 6: - //Try xyz in opposite dir - VectorSubtract(check->v.origin,testmove,check->v.origin); - testmove[0]=move3[0]*-1; - testmove[1]=move3[1]*-1; - testmove[2]=move3[2]*-1; - break; - case 7: - //Try move3 times 2 - VectorSubtract(check->v.origin,testmove,check->v.origin); - VectorScale(move3,2,testmove); - break; - case 8: - //Try normalized org - VectorSubtract(check->v.origin,testmove,check->v.origin); - - // VectorCopy(amove,amove_norm); - // amove_mag=VectorNormalize(amove_norm); - // //VectorNormalize(org); - // VectorScale(org,amove_mag,org); - - // VectorNormalize(org); - VectorScale(org,movetime,org);//movetime*20? - VectorCopy(org,testmove); - break; - case 9: - //Try normalized org z * 3 only - VectorSubtract(check->v.origin,testmove,check->v.origin); - testmove[0]=0; - testmove[1]=0; - testmove[2]=org[2]*3;//was: +org[2]*(fabs(org[1])+fabs(org[2])); - break; - case 10: - //Try normalized org xy * 2 only - VectorSubtract(check->v.origin,testmove,check->v.origin); - testmove[0]=org[0]*2;//was: +org[0]*fabs(org[2]); - testmove[1]=org[1]*2;//was: +org[1]*fabs(org[2]); - testmove[2]=0; - break; - case 11: - //Try xy in opposite org dir - VectorSubtract(check->v.origin,testmove,check->v.origin); - testmove[0]=org[0]*-2; - testmove[1]=org[1]*-2; - testmove[2]=org[2]; - break; - case 12: - //Try z in opposite dir - VectorSubtract(check->v.origin,testmove,check->v.origin); - testmove[0]=org[0]; - testmove[1]=org[1]; - testmove[2]=org[2]*-3; - break; - } - - if (t != 3) - { - //THIS IS VERY BAD BAD HACK... - pusher->v.solid = SOLID_NOT; - SV_PushEntity (check, move3); - //@@TODO: do we ever want to do anybody's angles? maybe just yaw??? - // if (!((int)check->v.flags & (FL_CLIENT | FL_MONSTER))) - // VectorAdd (check->v.angles, amove, check->v.angles); - check->v.angles[YAW] += amove[YAW]; - pusher->v.solid = SOLID_BSP; - } - // if it is still inside the pusher, block - block = SV_TestEntityPosition (check); - if (!block) - break; - } - - //Con_DPrintf("t: %i\n",t); - - // if (turn_away > 0) - // { - if (block) - { // fail the move - //Con_DPrintf("Check blocked\n"); - if (check->v.mins[0] == check->v.maxs[0]) - continue; - if (check->v.solid == SOLID_NOT || check->v.solid == SOLID_TRIGGER) - { // corpse - check->v.mins[0] = check->v.mins[1] = 0; - VectorCopy (check->v.mins, check->v.maxs); - continue; - } - - VectorCopy (entorig, check->v.origin); - SV_LinkEdict (check, true); - - VectorCopy (pushorig, pusher->v.origin); - VectorCopy (pushorigangles, pusher->v.angles); - SV_LinkEdict (pusher, false); - pusher->v.ltime -= movetime; - - for (i=0; iv.angles); - SV_LinkEdict (slave, false); - slave->v.ltime -= movetime; - } - - // if the pusher has a "blocked" function, call it - // otherwise, just stay in place until the obstacle is gone - if (pusher->v.blocked) - { - pr_global_struct->self = EDICT_TO_PROG(pusher); - pr_global_struct->other = EDICT_TO_PROG(check); - PR_ExecuteProgram (pusher->v.blocked); - } - - // move back any entities we already moved - for (i=0 ; iv.origin); - //@@TODO:: see above - // if (!((int)moved_edict[i]->v.flags & (FL_CLIENT | FL_MONSTER))) - // VectorSubtract (moved_edict[i]->v.angles, amove, moved_edict[i]->v.angles); - moved_edict[i]->v.angles[YAW] -= amove[YAW]; - - SV_LinkEdict (moved_edict[i], false); - } - return; - } - // } - // else if (block) // undo last move - // VectorCopy (entorig, check->v.origin); - } - -#if 0 - Con_DPrintf("result:\n"); - Con_DPrintf("%f %f %f\n", pusher->v.angles[0], pusher->v.angles[1], pusher->v.angles[2]); - for (i=0; iv.angles[0], slave->v.angles[1], slave->v.angles[2], NUM_FOR_EDICT(slave)); - } - Con_DPrintf("\n"); -#endif } -#endif -// jkrige - rotating bmodels (ported from Hexen II) /* ================ @@ -1118,7 +581,7 @@ void SV_Physics_Pusher (edict_t *ent) float movetime; oldltime = ent->v.ltime; - + thinktime = ent->v.nextthink; if (thinktime < ent->v.ltime + host_frametime) { @@ -1131,22 +594,9 @@ void SV_Physics_Pusher (edict_t *ent) if (movetime) { - // jkrige - rotating bmodels - /* -#ifdef QUAKE2 - if (ent->v.avelocity[0] || ent->v.avelocity[1] || ent->v.avelocity[2]) - SV_PushRotate (ent, movetime); - else -#endif - SV_PushMove (ent, movetime); // advances ent->v.ltime if not blocked - */ - //if (ent->v.avelocity[0] || ent->v.avelocity[1] || ent->v.avelocity[2]) - // SV_PushRotate (ent, movetime); - //else - SV_PushMove (ent, movetime); // advances ent->v.ltime if not blocked - // jkrige - rotating bmodels + SV_PushMove (ent, movetime); // advances ent->v.ltime if not blocked } - + if (thinktime > oldltime && thinktime <= ent->v.ltime) { ent->v.nextthink = 0; @@ -1197,7 +647,7 @@ void SV_CheckStuck (edict_t *ent) SV_LinkEdict (ent, true); return; } - + for (z=0 ; z< 18 ; z++) for (i=-1 ; i <= 1 ; i++) for (j=-1 ; j <= 1 ; j++) @@ -1212,7 +662,7 @@ void SV_CheckStuck (edict_t *ent) return; } } - + VectorCopy (org, ent->v.origin); Con_DPrintf ("player is stuck.\n"); } @@ -1227,22 +677,16 @@ qboolean SV_CheckWater (edict_t *ent) { vec3_t point; int cont; -#ifdef QUAKE2 - int truecont; -#endif point[0] = ent->v.origin[0]; point[1] = ent->v.origin[1]; - point[2] = ent->v.origin[2] + ent->v.mins[2] + 1; - + point[2] = ent->v.origin[2] + ent->v.mins[2] + 1; + ent->v.waterlevel = 0; ent->v.watertype = CONTENTS_EMPTY; cont = SV_PointContents (point); if (cont <= CONTENTS_WATER) { -#ifdef QUAKE2 - truecont = SV_TruePointContents (point); -#endif ent->v.watertype = cont; ent->v.waterlevel = 1; point[2] = ent->v.origin[2] + (ent->v.mins[2] + ent->v.maxs[2])*0.5; @@ -1255,24 +699,8 @@ qboolean SV_CheckWater (edict_t *ent) if (cont <= CONTENTS_WATER) ent->v.waterlevel = 3; } -#ifdef QUAKE2 - if (truecont <= CONTENTS_CURRENT_0 && truecont >= CONTENTS_CURRENT_DOWN) - { - static vec3_t current_table[] = - { - {1, 0, 0}, - {0, 1, 0}, - {-1, 0, 0}, - {0, -1, 0}, - {0, 0, 1}, - {0, 0, -1} - }; - - VectorMA (ent->v.basevelocity, 150.0*ent->v.waterlevel/3.0, current_table[CONTENTS_CURRENT_0 - truecont], ent->v.basevelocity); - } -#endif } - + return ent->v.waterlevel > 1; } @@ -1287,19 +715,19 @@ void SV_WallFriction (edict_t *ent, trace_t *trace) vec3_t forward, right, up; float d, i; vec3_t into, side; - + AngleVectors (ent->v.v_angle, forward, right, up); d = DotProduct (trace->plane.normal, forward); - + d += 0.5; if (d >= 0) return; - + // cut the tangential velocity i = DotProduct (trace->plane.normal, ent->v.velocity); VectorScale (trace->plane.normal, i, into); VectorSubtract (ent->v.velocity, into, side); - + ent->v.velocity[0] = side[0] * (1 + d); ent->v.velocity[1] = side[1] * (1 + d); } @@ -1323,7 +751,7 @@ int SV_TryUnstick (edict_t *ent, vec3_t oldvel) vec3_t dir; int clip; trace_t steptrace; - + VectorCopy (ent->v.origin, oldorg); VectorCopy (vec3_origin, dir); @@ -1341,7 +769,7 @@ int SV_TryUnstick (edict_t *ent, vec3_t oldvel) case 6: dir[0] = 2; dir[1] = -2; break; case 7: dir[0] = -2; dir[1] = -2; break; } - + SV_PushEntity (ent, dir); // retry the original move @@ -1356,11 +784,11 @@ int SV_TryUnstick (edict_t *ent, vec3_t oldvel) //Con_DPrintf ("unstuck!\n"); return clip; } - + // go back to the original pos and try again VectorCopy (oldorg, ent->v.origin); } - + VectorCopy (vec3_origin, ent->v.velocity); return 7; // still not moving } @@ -1381,16 +809,16 @@ void SV_WalkMove (edict_t *ent) int clip; int oldonground; trace_t steptrace, downtrace; - + // // do a regular slide move unless it looks like you ran into a step // oldonground = (int)ent->v.flags & FL_ONGROUND; ent->v.flags = (int)ent->v.flags & ~FL_ONGROUND; - + VectorCopy (ent->v.origin, oldorg); VectorCopy (ent->v.velocity, oldvel); - + clip = SV_FlyMove (ent, host_frametime, &steptrace); if ( !(clip & 2) ) @@ -1398,13 +826,13 @@ void SV_WalkMove (edict_t *ent) if (!oldonground && ent->v.waterlevel == 0) return; // don't stair up while jumping - + if (ent->v.movetype != MOVETYPE_WALK) return; // gibbed by a trigger - + if (sv_nostep.value) return; - + if ( (int)sv_player->v.flags & FL_WATERJUMP ) return; @@ -1440,7 +868,7 @@ void SV_WalkMove (edict_t *ent) clip = SV_TryUnstick (ent, oldvel); } } - + // extra friction based on view angle if ( clip & 2 ) SV_WallFriction (ent, &steptrace); @@ -1460,7 +888,7 @@ void SV_WalkMove (edict_t *ent) { // if the push down didn't end up on good ground, use the move without // the step up. This happens near wall / slope combinations, and can -// cause the player to hop up higher on a slope too steep to climb +// cause the player to hop up higher on a slope too steep to climb VectorCopy (nosteporg, ent->v.origin); VectorCopy (nostepvel, ent->v.velocity); } @@ -1481,11 +909,11 @@ void SV_Physics_Client (edict_t *ent, int num) // // call standard client pre-think -// +// pr_global_struct->time = sv.time; pr_global_struct->self = EDICT_TO_PROG(ent); PR_ExecuteProgram (pr_global_struct->PlayerPreThink); - + // // do a move // @@ -1507,16 +935,9 @@ void SV_Physics_Client (edict_t *ent, int num) if (!SV_CheckWater (ent) && ! ((int)ent->v.flags & FL_WATERJUMP) ) SV_AddGravity (ent); SV_CheckStuck (ent); -#ifdef QUAKE2 - VectorAdd (ent->v.velocity, ent->v.basevelocity, ent->v.velocity); -#endif SV_WalkMove (ent); - -#ifdef QUAKE2 - VectorSubtract (ent->v.velocity, ent->v.basevelocity, ent->v.velocity); -#endif break; - + case MOVETYPE_TOSS: case MOVETYPE_BOUNCE: SV_Physics_Toss (ent); @@ -1527,20 +948,20 @@ void SV_Physics_Client (edict_t *ent, int num) return; SV_FlyMove (ent, host_frametime, NULL); break; - + case MOVETYPE_NOCLIP: if (!SV_RunThink (ent)) return; VectorMA (ent->v.origin, host_frametime, ent->v.velocity, ent->v.origin); break; - + default: Sys_Error ("SV_Physics_client: bad movetype %i", (int)ent->v.movetype); } // // call standard player post-think -// +// SV_LinkEdict (ent, true); pr_global_struct->time = sv.time; @@ -1563,23 +984,6 @@ void SV_Physics_None (edict_t *ent) SV_RunThink (ent); } -#ifdef QUAKE2 -/* -============= -SV_Physics_Follow - -Entities that are "stuck" to another entity -============= -*/ -void SV_Physics_Follow (edict_t *ent) -{ -// regular thinking - SV_RunThink (ent); - VectorAdd (PROG_TO_EDICT(ent->v.aiment)->v.origin, ent->v.v_angle, ent->v.origin); - SV_LinkEdict (ent, true); -} -#endif - /* ============= SV_Physics_Noclip @@ -1592,7 +996,7 @@ void SV_Physics_Noclip (edict_t *ent) // regular thinking if (!SV_RunThink (ent)) return; - + VectorMA (ent->v.angles, host_frametime, ent->v.avelocity, ent->v.angles); VectorMA (ent->v.origin, host_frametime, ent->v.velocity, ent->v.origin); @@ -1616,29 +1020,22 @@ SV_CheckWaterTransition void SV_CheckWaterTransition (edict_t *ent) { int cont; -#ifdef QUAKE2 - vec3_t point; - - point[0] = ent->v.origin[0]; - point[1] = ent->v.origin[1]; - point[2] = ent->v.origin[2] + ent->v.mins[2] + 1; - cont = SV_PointContents (point); -#else + cont = SV_PointContents (ent->v.origin); -#endif + if (!ent->v.watertype) { // just spawned here ent->v.watertype = cont; ent->v.waterlevel = 1; return; } - + if (cont <= CONTENTS_WATER) { if (ent->v.watertype == CONTENTS_EMPTY) { // just crossed into water SV_StartSound (ent, 0, "misc/h2ohit1.wav", 255, 1); - } + } ent->v.watertype = cont; ent->v.waterlevel = 1; } @@ -1647,7 +1044,7 @@ void SV_CheckWaterTransition (edict_t *ent) if (ent->v.watertype != CONTENTS_EMPTY) { // just crossed into water SV_StartSound (ent, 0, "misc/h2ohit1.wav", 255, 1); - } + } ent->v.watertype = CONTENTS_EMPTY; ent->v.waterlevel = cont; } @@ -1665,39 +1062,11 @@ void SV_Physics_Toss (edict_t *ent) trace_t trace; vec3_t move; float backoff; -#ifdef QUAKE2 - edict_t *groundentity; - groundentity = PROG_TO_EDICT(ent->v.groundentity); - if ((int)groundentity->v.flags & FL_CONVEYOR) - VectorScale(groundentity->v.movedir, groundentity->v.speed, ent->v.basevelocity); - else - VectorCopy(vec_origin, ent->v.basevelocity); - SV_CheckWater (ent); -#endif // regular thinking if (!SV_RunThink (ent)) return; -#ifdef QUAKE2 - if (ent->v.velocity[2] > 0) - ent->v.flags = (int)ent->v.flags & ~FL_ONGROUND; - - if ( ((int)ent->v.flags & FL_ONGROUND) ) -//@@ - if (VectorCompare(ent->v.basevelocity, vec_origin)) - return; - - SV_CheckVelocity (ent); - -// add gravity - if (! ((int)ent->v.flags & FL_ONGROUND) - && ent->v.movetype != MOVETYPE_FLY - && ent->v.movetype != MOVETYPE_BOUNCEMISSILE - && ent->v.movetype != MOVETYPE_FLYMISSILE) - SV_AddGravity (ent); - -#else // if onground, return without moving if ( ((int)ent->v.flags & FL_ONGROUND) ) return; @@ -1708,31 +1077,20 @@ void SV_Physics_Toss (edict_t *ent) if (ent->v.movetype != MOVETYPE_FLY && ent->v.movetype != MOVETYPE_FLYMISSILE) SV_AddGravity (ent); -#endif // move angles VectorMA (ent->v.angles, host_frametime, ent->v.avelocity, ent->v.angles); // move origin -#ifdef QUAKE2 - VectorAdd (ent->v.velocity, ent->v.basevelocity, ent->v.velocity); -#endif VectorScale (ent->v.velocity, host_frametime, move); trace = SV_PushEntity (ent, move); -#ifdef QUAKE2 - VectorSubtract (ent->v.velocity, ent->v.basevelocity, ent->v.velocity); -#endif if (trace.fraction == 1) return; if (ent->free) return; - + if (ent->v.movetype == MOVETYPE_BOUNCE) backoff = 1.5; -#ifdef QUAKE2 - else if (ent->v.movetype == MOVETYPE_BOUNCEMISSILE) - backoff = 2.0; -#endif else backoff = 1; @@ -1740,12 +1098,8 @@ void SV_Physics_Toss (edict_t *ent) // stop if on ground if (trace.plane.normal[2] > 0.7) - { -#ifdef QUAKE2 - if (ent->v.velocity[2] < 60 || (ent->v.movetype != MOVETYPE_BOUNCE && ent->v.movetype != MOVETYPE_BOUNCEMISSILE)) -#else + { if (ent->v.velocity[2] < 60 || ent->v.movetype != MOVETYPE_BOUNCE) -#endif { ent->v.flags = (int)ent->v.flags | FL_ONGROUND; ent->v.groundentity = EDICT_TO_PROG(trace.ent); @@ -1753,7 +1107,7 @@ void SV_Physics_Toss (edict_t *ent) VectorCopy (vec3_origin, ent->v.avelocity); } } - + // check for in water SV_CheckWaterTransition (ent); } @@ -1777,112 +1131,6 @@ This is also used for objects that have become still on the ground, but will fall if the floor is pulled out from under them. ============= */ -#ifdef QUAKE2 -void SV_Physics_Step (edict_t *ent) -{ - qboolean wasonground; - qboolean inwater; - qboolean hitsound = false; - float *vel; - float speed, newspeed, control; - float friction; - edict_t *groundentity; - - groundentity = PROG_TO_EDICT(ent->v.groundentity); - if ((int)groundentity->v.flags & FL_CONVEYOR) - VectorScale(groundentity->v.movedir, groundentity->v.speed, ent->v.basevelocity); - else - VectorCopy(vec_origin, ent->v.basevelocity); -//@@ - pr_global_struct->time = sv.time; - pr_global_struct->self = EDICT_TO_PROG(ent); - PF_WaterMove(); - - SV_CheckVelocity (ent); - - wasonground = (int)ent->v.flags & FL_ONGROUND; -// ent->v.flags = (int)ent->v.flags & ~FL_ONGROUND; - - // add gravity except: - // flying monsters - // swimming monsters who are in the water - inwater = SV_CheckWater(ent); - if (! wasonground) - if (!((int)ent->v.flags & FL_FLY)) - if (!(((int)ent->v.flags & FL_SWIM) && (ent->v.waterlevel > 0))) - { - if (ent->v.velocity[2] < sv_gravity.value*-0.1) - hitsound = true; - if (!inwater) - SV_AddGravity (ent); - } - - if (!VectorCompare(ent->v.velocity, vec_origin) || !VectorCompare(ent->v.basevelocity, vec_origin)) - { - ent->v.flags = (int)ent->v.flags & ~FL_ONGROUND; - // apply friction - // let dead monsters who aren't completely onground slide - if (wasonground) - if (!(ent->v.health <= 0.0 && !SV_CheckBottom(ent))) - { - vel = ent->v.velocity; - speed = sqrt(vel[0]*vel[0] +vel[1]*vel[1]); - if (speed) - { - friction = sv_friction.value; - - control = speed < sv_stopspeed.value ? sv_stopspeed.value : speed; - newspeed = speed - host_frametime*control*friction; - - if (newspeed < 0) - newspeed = 0; - newspeed /= speed; - - vel[0] = vel[0] * newspeed; - vel[1] = vel[1] * newspeed; - } - } - - VectorAdd (ent->v.velocity, ent->v.basevelocity, ent->v.velocity); - SV_FlyMove (ent, host_frametime, NULL); - VectorSubtract (ent->v.velocity, ent->v.basevelocity, ent->v.velocity); - - // determine if it's on solid ground at all - { - vec3_t mins, maxs, point; - int x, y; - - VectorAdd (ent->v.origin, ent->v.mins, mins); - VectorAdd (ent->v.origin, ent->v.maxs, maxs); - - point[2] = mins[2] - 1; - for (x=0 ; x<=1 ; x++) - for (y=0 ; y<=1 ; y++) - { - point[0] = x ? maxs[0] : mins[0]; - point[1] = y ? maxs[1] : mins[1]; - if (SV_PointContents (point) == CONTENTS_SOLID) - { - ent->v.flags = (int)ent->v.flags | FL_ONGROUND; - break; - } - } - - } - - SV_LinkEdict (ent, true); - - if ((int)ent->v.flags & FL_ONGROUND) - if (!wasonground) - if (hitsound) - SV_StartSound (ent, 0, "demon/dland2.wav", 255, 1); - } - -// regular thinking - SV_RunThink (ent); - SV_CheckWaterTransition (ent); -} -#else void SV_Physics_Step (edict_t *ent) { qboolean hitsound; @@ -1909,10 +1157,10 @@ void SV_Physics_Step (edict_t *ent) // regular thinking SV_RunThink (ent); - + SV_CheckWaterTransition (ent); } -#endif + //============================================================================ @@ -1924,7 +1172,8 @@ SV_Physics */ void SV_Physics (void) { - int i; + int i; + int entity_cap; // For sv_freezenonclients edict_t *ent; // let the progs know that a new frame has started @@ -1939,7 +1188,14 @@ void SV_Physics (void) // treat each object in turn // ent = sv.edicts; - for (i=0 ; ifree) continue; @@ -1955,81 +1211,22 @@ void SV_Physics (void) SV_Physics_Pusher (ent); else if (ent->v.movetype == MOVETYPE_NONE) SV_Physics_None (ent); -#ifdef QUAKE2 - else if (ent->v.movetype == MOVETYPE_FOLLOW) - SV_Physics_Follow (ent); -#endif else if (ent->v.movetype == MOVETYPE_NOCLIP) SV_Physics_Noclip (ent); else if (ent->v.movetype == MOVETYPE_STEP) SV_Physics_Step (ent); - else if (ent->v.movetype == MOVETYPE_TOSS + else if (ent->v.movetype == MOVETYPE_TOSS || ent->v.movetype == MOVETYPE_BOUNCE -#ifdef QUAKE2 - || ent->v.movetype == MOVETYPE_BOUNCEMISSILE -#endif || ent->v.movetype == MOVETYPE_FLY || ent->v.movetype == MOVETYPE_FLYMISSILE) SV_Physics_Toss (ent); else - Sys_Error ("SV_Physics: bad movetype %i", (int)ent->v.movetype); + Sys_Error ("SV_Physics: bad movetype %i", (int)ent->v.movetype); } - - if (pr_global_struct->force_retouch) - pr_global_struct->force_retouch--; - - sv.time += host_frametime; -} - -#ifdef QUAKE2 -trace_t SV_Trace_Toss (edict_t *ent, edict_t *ignore) -{ - edict_t tempent, *tent; - trace_t trace; - vec3_t move; - vec3_t end; - double save_frametime; -// extern particle_t *active_particles, *free_particles; -// particle_t *p; - - - save_frametime = host_frametime; - host_frametime = 0.05; - - memcpy(&tempent, ent, sizeof(edict_t)); - tent = &tempent; + if (pr_global_struct->force_retouch) + pr_global_struct->force_retouch--; - while (1) - { - SV_CheckVelocity (tent); - SV_AddGravity (tent); - VectorMA (tent->v.angles, host_frametime, tent->v.avelocity, tent->v.angles); - VectorScale (tent->v.velocity, host_frametime, move); - VectorAdd (tent->v.origin, move, end); - trace = SV_Move (tent->v.origin, tent->v.mins, tent->v.maxs, end, MOVE_NORMAL, tent); - VectorCopy (trace.endpos, tent->v.origin); - -// p = free_particles; -// if (p) -// { -// free_particles = p->next; -// p->next = active_particles; -// active_particles = p; -// -// p->die = 256; -// p->color = 15; -// p->type = pt_static; -// VectorCopy (vec3_origin, p->vel); -// VectorCopy (tent->v.origin, p->org); -// } - - if (trace.ent) - if (trace.ent != ignore) - break; - } -// p->color = 224; - host_frametime = save_frametime; - return trace; + if (!sv_freezenonclients.value) + sv.time += host_frametime; } -#endif diff --git a/engine/code/sv_user.c b/engine/Quake/sv_user.c similarity index 76% rename from engine/code/sv_user.c rename to engine/Quake/sv_user.c index 203e6bf..c3e4cb5 100644 --- a/engine/code/sv_user.c +++ b/engine/Quake/sv_user.c @@ -1,5 +1,7 @@ /* -Copyright (C) 1996-1997 Id Software, Inc. +Copyright (C) 1996-2001 Id Software, Inc. +Copyright (C) 2002-2009 John Fitzgibbons and others +Copyright (C) 2010-2014 QuakeSpasm developers This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -8,7 +10,7 @@ of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. @@ -24,14 +26,11 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. edict_t *sv_player; extern cvar_t sv_friction; -cvar_t sv_edgefriction = {"edgefriction", "2"}; +cvar_t sv_edgefriction = {"edgefriction", "2", CVAR_NONE}; extern cvar_t sv_stopspeed; static vec3_t forward, right, up; -vec3_t wishdir; -float wishspeed; - // world float *angles; float *origin; @@ -41,8 +40,8 @@ qboolean onground; usercmd_t cmd; -cvar_t sv_idealpitchscale = {"sv_idealpitchscale","0.8"}; - +cvar_t sv_idealpitchscale = {"sv_idealpitchscale","0.8",CVAR_NONE}; +cvar_t sv_altnoclip = {"sv_altnoclip","1",CVAR_ARCHIVE}; //johnfitz /* =============== @@ -61,7 +60,7 @@ void SV_SetIdealPitch (void) if (!((int)sv_player->v.flags & FL_ONGROUND)) return; - + angleval = sv_player->v.angles[YAW] * M_PI*2 / 360; sinval = sin(angleval); cosval = cos(angleval); @@ -71,21 +70,21 @@ void SV_SetIdealPitch (void) top[0] = sv_player->v.origin[0] + cosval*(i+3)*12; top[1] = sv_player->v.origin[1] + sinval*(i+3)*12; top[2] = sv_player->v.origin[2] + sv_player->v.view_ofs[2]; - + bottom[0] = top[0]; bottom[1] = top[1]; bottom[2] = top[2] - 160; - + tr = SV_Move (top, vec3_origin, vec3_origin, bottom, 1, sv_player); if (tr.allsolid) return; // looking at a wall, leave ideal the way is was if (tr.fraction == 1) return; // near a dropoff - + z[i] = top[2] + tr.fraction*(bottom[2]-top[2]); } - + dir = 0; steps = 0; for (j=1 ; j ON_EPSILON || step-dir < -ON_EPSILON ) ) return; // mixed changes - steps++; + steps++; dir = step; } - + if (!dir) { sv_player->v.idealpitch = 0; return; } - - if (steps < 2) - return; - // jkrige - slook cvar - if(!cl_slook.value) + if (steps < 2) return; - // jkrige - slook cvar - sv_player->v.idealpitch = -dir * sv_idealpitchscale.value; } @@ -132,9 +125,9 @@ void SV_UserFriction (void) vec3_t start, stop; float friction; trace_t trace; - + vel = velocity; - + speed = sqrt(vel[0]*vel[0] +vel[1]*vel[1]); if (!speed) return; @@ -152,10 +145,10 @@ void SV_UserFriction (void) else friction = sv_friction.value; -// apply friction +// apply friction control = speed < sv_stopspeed.value ? sv_stopspeed.value : speed; newspeed = speed - host_frametime*control*friction; - + if (newspeed < 0) newspeed = 0; newspeed /= speed; @@ -170,30 +163,9 @@ void SV_UserFriction (void) SV_Accelerate ============== */ -cvar_t sv_maxspeed = {"sv_maxspeed", "320", false, true}; -cvar_t sv_accelerate = {"sv_accelerate", "10"}; -#if 0 -void SV_Accelerate (vec3_t wishvel) -{ - int i; - float addspeed, accelspeed; - vec3_t pushvec; - - if (wishspeed == 0) - return; - - VectorSubtract (wishvel, velocity, pushvec); - addspeed = VectorNormalize (pushvec); - - accelspeed = sv_accelerate.value*host_frametime*addspeed; - if (accelspeed > addspeed) - accelspeed = addspeed; - - for (i=0 ; i<3 ; i++) - velocity[i] += accelspeed*pushvec[i]; -} -#endif -void SV_Accelerate (void) +cvar_t sv_maxspeed = {"sv_maxspeed", "320", CVAR_NOTIFY|CVAR_SERVERINFO}; +cvar_t sv_accelerate = {"sv_accelerate", "10", CVAR_NONE}; +void SV_Accelerate (float wishspeed, const vec3_t wishdir) { int i; float addspeed, accelspeed, currentspeed; @@ -205,16 +177,16 @@ void SV_Accelerate (void) accelspeed = sv_accelerate.value*host_frametime*wishspeed; if (accelspeed > addspeed) accelspeed = addspeed; - + for (i=0 ; i<3 ; i++) - velocity[i] += accelspeed*wishdir[i]; + velocity[i] += accelspeed*wishdir[i]; } -void SV_AirAccelerate (vec3_t wishveloc) +void SV_AirAccelerate (float wishspeed, vec3_t wishveloc) { int i; float addspeed, wishspd, accelspeed, currentspeed; - + wishspd = VectorNormalize (wishveloc); if (wishspd > 30) wishspd = 30; @@ -226,18 +198,18 @@ void SV_AirAccelerate (vec3_t wishveloc) accelspeed = sv_accelerate.value*wishspeed * host_frametime; if (accelspeed > addspeed) accelspeed = addspeed; - + for (i=0 ; i<3 ; i++) - velocity[i] += accelspeed*wishveloc[i]; + velocity[i] += accelspeed*wishveloc[i]; } void DropPunchAngle (void) { float len; - + len = VectorNormalize (sv_player->v.punchangle); - + len -= 10*host_frametime; if (len < 0) len = 0; @@ -269,7 +241,7 @@ void SV_WaterMove (void) else wishvel[2] += cmd.upmove; - wishspeed = Length(wishvel); + wishspeed = VectorLength(wishvel); if (wishspeed > sv_maxspeed.value) { VectorScale (wishvel, sv_maxspeed.value/wishspeed, wishvel); @@ -280,17 +252,17 @@ void SV_WaterMove (void) // // water friction // - speed = Length (velocity); + speed = VectorLength (velocity); if (speed) { newspeed = speed - host_frametime * speed * sv_friction.value; if (newspeed < 0) - newspeed = 0; + newspeed = 0; VectorScale (velocity, newspeed/speed, velocity); } else newspeed = 0; - + // // water acceleration // @@ -322,28 +294,50 @@ void SV_WaterJump (void) sv_player->v.velocity[1] = sv_player->v.movedir[1]; } +/* +=================== +SV_NoclipMove -- johnfitz + +new, alternate noclip. old noclip is still handled in SV_AirMove +=================== +*/ +void SV_NoclipMove (void) +{ + AngleVectors (sv_player->v.v_angle, forward, right, up); + + velocity[0] = forward[0]*cmd.forwardmove + right[0]*cmd.sidemove; + velocity[1] = forward[1]*cmd.forwardmove + right[1]*cmd.sidemove; + velocity[2] = forward[2]*cmd.forwardmove + right[2]*cmd.sidemove; + velocity[2] += cmd.upmove*2; //doubled to match running speed + + if (VectorLength (velocity) > sv_maxspeed.value) + { + VectorNormalize (velocity); + VectorScale (velocity, sv_maxspeed.value, velocity); + } +} /* =================== SV_AirMove - =================== */ void SV_AirMove (void) { int i; - vec3_t wishvel; + vec3_t wishvel, wishdir; + float wishspeed; float fmove, smove; AngleVectors (sv_player->v.angles, forward, right, up); fmove = cmd.forwardmove; smove = cmd.sidemove; - + // hack to not let you back into teleporter if (sv.time < sv_player->v.teleport_time && fmove < 0) fmove = 0; - + for (i=0 ; i<3 ; i++) wishvel[i] = forward[i]*fmove + right[i]*smove; @@ -359,7 +353,7 @@ void SV_AirMove (void) VectorScale (wishvel, sv_maxspeed.value/wishspeed, wishvel); wishspeed = sv_maxspeed.value; } - + if ( sv_player->v.movetype == MOVETYPE_NOCLIP) { // noclip VectorCopy (wishvel, velocity); @@ -367,12 +361,12 @@ void SV_AirMove (void) else if ( onground ) { SV_UserFriction (); - SV_Accelerate (); + SV_Accelerate (wishspeed, wishdir); } else { // not on ground, so little effect on velocity - SV_AirAccelerate (wishvel); - } + SV_AirAccelerate (wishspeed, wishvel); + } } /* @@ -389,14 +383,14 @@ void SV_ClientThink (void) if (sv_player->v.movetype == MOVETYPE_NONE) return; - + onground = (int)sv_player->v.flags & FL_ONGROUND; origin = sv_player->v.origin; velocity = sv_player->v.velocity; DropPunchAngle (); - + // // if dead, behave differently // @@ -408,7 +402,7 @@ void SV_ClientThink (void) // show 1/3 the pitch angle and all the roll angle cmd = host_client->cmd; angles = sv_player->v.angles; - + VectorAdd (sv_player->v.v_angle, sv_player->v.punchangle, v_angle); angles[ROLL] = V_CalcRoll (sv_player->v.angles, sv_player->v.velocity)*4; if (!sv_player->v.fixangle) @@ -425,14 +419,14 @@ void SV_ClientThink (void) // // walk // - if ( (sv_player->v.waterlevel >= 2) - && (sv_player->v.movetype != MOVETYPE_NOCLIP) ) - { + //johnfitz -- alternate noclip + if (sv_player->v.movetype == MOVETYPE_NOCLIP && sv_altnoclip.value) + SV_NoclipMove (); + else if (sv_player->v.waterlevel >= 2 && sv_player->v.movetype != MOVETYPE_NOCLIP) SV_WaterMove (); - return; - } - - SV_AirMove (); + else + SV_AirMove (); + //johnfitz } @@ -446,23 +440,28 @@ void SV_ReadClientMove (usercmd_t *move) int i; vec3_t angle; int bits; - + // read ping time host_client->ping_times[host_client->num_pings%NUM_PING_TIMES] = sv.time - MSG_ReadFloat (); host_client->num_pings++; -// read current angles +// read current angles for (i=0 ; i<3 ; i++) - angle[i] = MSG_ReadAngle (); + //johnfitz -- 16-bit angles for PROTOCOL_FITZQUAKE + if (sv.protocol == PROTOCOL_NETQUAKE) + angle[i] = MSG_ReadAngle (sv.protocolflags); + else + angle[i] = MSG_ReadAngle16 (sv.protocolflags); + //johnfitz VectorCopy (angle, host_client->edict->v.v_angle); - + // read movement move->forwardmove = MSG_ReadShort (); move->sidemove = MSG_ReadShort (); move->upmove = MSG_ReadShort (); - + // read buttons bits = MSG_ReadByte (); host_client->edict->v.button0 = bits & 1; @@ -471,11 +470,6 @@ void SV_ReadClientMove (usercmd_t *move) i = MSG_ReadByte (); if (i) host_client->edict->v.impulse = i; - -#ifdef QUAKE2 -// read light level - host_client->edict->v.light_level = MSG_ReadByte (); -#endif } /* @@ -488,9 +482,9 @@ Returns false if the client should be killed qboolean SV_ReadClientMessage (void) { int ret; - int cmd; - char *s; - + int ccmd; + const char *s; + do { nextmsg: @@ -502,9 +496,9 @@ nextmsg: } if (!ret) return true; - + MSG_BeginReading (); - + while (1) { if (!host_client->active) @@ -514,86 +508,84 @@ nextmsg: { Sys_Printf ("SV_ReadClientMessage: badread\n"); return false; - } - - cmd = MSG_ReadChar (); - - switch (cmd) + } + + ccmd = MSG_ReadChar (); + + switch (ccmd) { case -1: goto nextmsg; // end of message - + default: Sys_Printf ("SV_ReadClientMessage: unknown command char\n"); return false; - + case clc_nop: // Sys_Printf ("clc_nop\n"); break; - - case clc_stringcmd: + + case clc_stringcmd: s = MSG_ReadString (); - if (host_client->privileged) - ret = 2; - else - ret = 0; - if (Q_strncasecmp(s, "status", 6) == 0) + ret = 0; + if (q_strncasecmp(s, "status", 6) == 0) + ret = 1; + else if (q_strncasecmp(s, "god", 3) == 0) ret = 1; - else if (Q_strncasecmp(s, "god", 3) == 0) + else if (q_strncasecmp(s, "notarget", 8) == 0) ret = 1; - else if (Q_strncasecmp(s, "notarget", 8) == 0) + else if (q_strncasecmp(s, "fly", 3) == 0) ret = 1; - else if (Q_strncasecmp(s, "fly", 3) == 0) + else if (q_strncasecmp(s, "name", 4) == 0) ret = 1; - else if (Q_strncasecmp(s, "name", 4) == 0) + else if (q_strncasecmp(s, "noclip", 6) == 0) ret = 1; - else if (Q_strncasecmp(s, "noclip", 6) == 0) + else if (q_strncasecmp(s, "setpos", 6) == 0) ret = 1; - else if (Q_strncasecmp(s, "say", 3) == 0) + else if (q_strncasecmp(s, "say", 3) == 0) ret = 1; - else if (Q_strncasecmp(s, "say_team", 8) == 0) + else if (q_strncasecmp(s, "say_team", 8) == 0) ret = 1; - else if (Q_strncasecmp(s, "tell", 4) == 0) + else if (q_strncasecmp(s, "tell", 4) == 0) ret = 1; - else if (Q_strncasecmp(s, "color", 5) == 0) + else if (q_strncasecmp(s, "color", 5) == 0) ret = 1; - else if (Q_strncasecmp(s, "kill", 4) == 0) + else if (q_strncasecmp(s, "kill", 4) == 0) ret = 1; - else if (Q_strncasecmp(s, "pause", 5) == 0) + else if (q_strncasecmp(s, "pause", 5) == 0) ret = 1; - else if (Q_strncasecmp(s, "spawn", 5) == 0) + else if (q_strncasecmp(s, "spawn", 5) == 0) ret = 1; - else if (Q_strncasecmp(s, "begin", 5) == 0) + else if (q_strncasecmp(s, "begin", 5) == 0) ret = 1; - else if (Q_strncasecmp(s, "prespawn", 8) == 0) + else if (q_strncasecmp(s, "prespawn", 8) == 0) ret = 1; - else if (Q_strncasecmp(s, "kick", 4) == 0) + else if (q_strncasecmp(s, "kick", 4) == 0) ret = 1; - else if (Q_strncasecmp(s, "ping", 4) == 0) + else if (q_strncasecmp(s, "ping", 4) == 0) ret = 1; - else if (Q_strncasecmp(s, "give", 4) == 0) + else if (q_strncasecmp(s, "give", 4) == 0) ret = 1; - else if (Q_strncasecmp(s, "ban", 3) == 0) + else if (q_strncasecmp(s, "ban", 3) == 0) ret = 1; - if (ret == 2) - Cbuf_InsertText (s); - else if (ret == 1) + + if (ret == 1) Cmd_ExecuteString (s, src_client); else Con_DPrintf("%s tried to %s\n", host_client->name, s); break; - + case clc_disconnect: // Sys_Printf ("SV_ReadClientMessage: client disconnected\n"); return false; - + case clc_move: SV_ReadClientMove (&host_client->cmd); break; } } } while (ret == 1); - + return true; } @@ -606,12 +598,12 @@ SV_RunClients void SV_RunClients (void) { int i; - + for (i=0, host_client = svs.clients ; iactive) continue; - + sv_player = host_client->edict; if (!SV_ReadClientMessage ()) diff --git a/engine/Quake/sys.h b/engine/Quake/sys.h new file mode 100644 index 0000000..dd02363 --- /dev/null +++ b/engine/Quake/sys.h @@ -0,0 +1,70 @@ +/* +Copyright (C) 1996-2001 Id Software, Inc. +Copyright (C) 2010-2014 QuakeSpasm developers + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#ifndef _QUAKE_SYS_H +#define _QUAKE_SYS_H + +// sys.h -- non-portable functions + +void Sys_Init (void); + +// +// file IO +// + +// returns the file size or -1 if file is not present. +// the file should be in BINARY mode for stupid OSs that care +int Sys_FileOpenRead (const char *path, int *hndl); + +int Sys_FileOpenWrite (const char *path); +void Sys_FileClose (int handle); +void Sys_FileSeek (int handle, int position); +int Sys_FileRead (int handle, void *dest, int count); +int Sys_FileWrite (int handle,const void *data, int count); +int Sys_FileTime (const char *path); +void Sys_mkdir (const char *path); + +// +// system IO +// +FUNC_NORETURN void Sys_Quit (void); +FUNC_NORETURN void Sys_Error (const char *error, ...) FUNC_PRINTF(1,2); +// an error will cause the entire program to exit +#ifdef __WATCOMC__ +#pragma aux Sys_Error aborts; +#pragma aux Sys_Quit aborts; +#endif + +void Sys_Printf (const char *fmt, ...) FUNC_PRINTF(1,2); +// send text to the console + +double Sys_DoubleTime (void); + +const char *Sys_ConsoleInput (void); + +void Sys_Sleep (unsigned long msecs); +// yield for about 'msecs' milliseconds. + +void Sys_SendKeyEvents (void); +// Perform Key_Event () callbacks until the input que is empty + +#endif /* _QUAKE_SYS_H */ + diff --git a/engine/Quake/sys_sdl_unix.c b/engine/Quake/sys_sdl_unix.c new file mode 100644 index 0000000..d203677 --- /dev/null +++ b/engine/Quake/sys_sdl_unix.c @@ -0,0 +1,475 @@ +/* +Copyright (C) 1996-2001 Id Software, Inc. +Copyright (C) 2002-2005 John Fitzgibbons and others +Copyright (C) 2007-2008 Kristian Duske +Copyright (C) 2010-2014 QuakeSpasm developers + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#include "arch_def.h" +#include "quakedef.h" + +#include +#include +#include +#ifdef PLATFORM_OSX +#include /* dirname() and basename() */ +#endif +#include +#include +#include +#include +#ifdef DO_USERDIRS +#include +#endif + +#if defined(SDL_FRAMEWORK) || defined(NO_SDL_CONFIG) +#if defined(USE_SDL2) +#include +#else +#include +#endif +#else +#include "SDL.h" +#endif + + +qboolean isDedicated; +cvar_t sys_throttle = {"sys_throttle", "0.02", CVAR_ARCHIVE}; + +#define MAX_HANDLES 32 /* johnfitz -- was 10 */ +static FILE *sys_handles[MAX_HANDLES]; + + +static int findhandle (void) +{ + int i; + + for (i = 1; i < MAX_HANDLES; i++) + { + if (!sys_handles[i]) + return i; + } + Sys_Error ("out of handles"); + return -1; +} + +long Sys_filelength (FILE *f) +{ + long pos, end; + + pos = ftell (f); + fseek (f, 0, SEEK_END); + end = ftell (f); + fseek (f, pos, SEEK_SET); + + return end; +} + +int Sys_FileOpenRead (const char *path, int *hndl) +{ + FILE *f; + int i, retval; + + i = findhandle (); + f = fopen(path, "rb"); + + if (!f) + { + *hndl = -1; + retval = -1; + } + else + { + sys_handles[i] = f; + *hndl = i; + retval = Sys_filelength(f); + } + + return retval; +} + +int Sys_FileOpenWrite (const char *path) +{ + FILE *f; + int i; + + i = findhandle (); + f = fopen(path, "wb"); + + if (!f) + Sys_Error ("Error opening %s: %s", path, strerror(errno)); + + sys_handles[i] = f; + return i; +} + +void Sys_FileClose (int handle) +{ + fclose (sys_handles[handle]); + sys_handles[handle] = NULL; +} + +void Sys_FileSeek (int handle, int position) +{ + fseek (sys_handles[handle], position, SEEK_SET); +} + +int Sys_FileRead (int handle, void *dest, int count) +{ + return fread (dest, 1, count, sys_handles[handle]); +} + +int Sys_FileWrite (int handle, const void *data, int count) +{ + return fwrite (data, 1, count, sys_handles[handle]); +} + +int Sys_FileTime (const char *path) +{ + FILE *f; + + f = fopen(path, "rb"); + + if (f) + { + fclose(f); + return 1; + } + + return -1; +} + + +#if defined(__linux__) || defined(__sun) || defined(sun) || defined(_AIX) +static int Sys_NumCPUs (void) +{ + int numcpus = sysconf(_SC_NPROCESSORS_ONLN); + return (numcpus < 1) ? 1 : numcpus; +} + +#elif defined(PLATFORM_OSX) +#include +#if !defined(HW_AVAILCPU) /* using an ancient SDK? */ +#define HW_AVAILCPU 25 /* needs >= 10.2 */ +#endif +static int Sys_NumCPUs (void) +{ + int numcpus; + int mib[2]; + size_t len; + +#if defined(_SC_NPROCESSORS_ONLN) /* needs >= 10.5 */ + numcpus = sysconf(_SC_NPROCESSORS_ONLN); + if (numcpus != -1) + return (numcpus < 1) ? 1 : numcpus; +#endif + len = sizeof(numcpus); + mib[0] = CTL_HW; + mib[1] = HW_AVAILCPU; + sysctl(mib, 2, &numcpus, &len, NULL, 0); + if (sysctl(mib, 2, &numcpus, &len, NULL, 0) == -1) + { + mib[1] = HW_NCPU; + if (sysctl(mib, 2, &numcpus, &len, NULL, 0) == -1) + return 1; + } + return (numcpus < 1) ? 1 : numcpus; +} + +#elif defined(__sgi) || defined(sgi) || defined(__sgi__) /* IRIX */ +static int Sys_NumCPUs (void) +{ + int numcpus = sysconf(_SC_NPROC_ONLN); + if (numcpus < 1) + numcpus = 1; + return numcpus; +} + +#elif defined(PLATFORM_BSD) +#include +static int Sys_NumCPUs (void) +{ + int numcpus; + int mib[2]; + size_t len; + +#if defined(_SC_NPROCESSORS_ONLN) + numcpus = sysconf(_SC_NPROCESSORS_ONLN); + if (numcpus != -1) + return (numcpus < 1) ? 1 : numcpus; +#endif + len = sizeof(numcpus); + mib[0] = CTL_HW; + mib[1] = HW_NCPU; + if (sysctl(mib, 2, &numcpus, &len, NULL, 0) == -1) + return 1; + return (numcpus < 1) ? 1 : numcpus; +} + +#elif defined(__hpux) || defined(__hpux__) || defined(_hpux) +#include +static int Sys_NumCPUs (void) +{ + int numcpus = mpctl(MPC_GETNUMSPUS, NULL, NULL); + return numcpus; +} + +#else /* unknown OS */ +static int Sys_NumCPUs (void) +{ + return -2; +} +#endif + +static char cwd[MAX_OSPATH]; +#ifdef DO_USERDIRS +static char userdir[MAX_OSPATH]; +#ifdef PLATFORM_OSX +#define SYS_USERDIR "Library/Application Support/QuakeSpasm" +#else +#define SYS_USERDIR ".quakespasm" +#endif + +static void Sys_GetUserdir (char *dst, size_t dstsize) +{ + size_t n; + const char *home_dir = NULL; + struct passwd *pwent; + + pwent = getpwuid( getuid() ); + if (pwent == NULL) + perror("getpwuid"); + else + home_dir = pwent->pw_dir; + if (home_dir == NULL) + home_dir = getenv("HOME"); + if (home_dir == NULL) + Sys_Error ("Couldn't determine userspace directory"); + +/* what would be a maximum path for a file in the user's directory... + * $HOME/SYS_USERDIR/game_dir/dirname1/dirname2/dirname3/filename.ext + * still fits in the MAX_OSPATH == 256 definition, but just in case : + */ + n = strlen(home_dir) + strlen(SYS_USERDIR) + 50; + if (n >= dstsize) + Sys_Error ("Insufficient array size for userspace directory"); + + q_snprintf (dst, dstsize, "%s/%s", home_dir, SYS_USERDIR); +} +#endif /* DO_USERDIRS */ + +#ifdef PLATFORM_OSX +static char *OSX_StripAppBundle (char *dir) +{ /* based on the ioquake3 project at icculus.org. */ + static char osx_path[MAX_OSPATH]; + + q_strlcpy (osx_path, dir, sizeof(osx_path)); + if (strcmp(basename(osx_path), "MacOS")) + return dir; + q_strlcpy (osx_path, dirname(osx_path), sizeof(osx_path)); + if (strcmp(basename(osx_path), "Contents")) + return dir; + q_strlcpy (osx_path, dirname(osx_path), sizeof(osx_path)); + if (!strstr(basename(osx_path), ".app")) + return dir; + q_strlcpy (osx_path, dirname(osx_path), sizeof(osx_path)); + return osx_path; +} + +static void Sys_GetBasedir (char *argv0, char *dst, size_t dstsize) +{ + char *tmp; + + if (realpath(argv0, dst) == NULL) + { + perror("realpath"); + if (getcwd(dst, dstsize - 1) == NULL) + _fail: Sys_Error ("Couldn't determine current directory"); + } + else + { + /* strip off the binary name */ + if (! (tmp = strdup (dst))) goto _fail; + q_strlcpy (dst, dirname(tmp), dstsize); + free (tmp); + } + + tmp = OSX_StripAppBundle(dst); + if (tmp != dst) + q_strlcpy (dst, tmp, dstsize); +} +#else +static void Sys_GetBasedir (char *argv0, char *dst, size_t dstsize) +{ + char *tmp; + + if (getcwd(dst, dstsize - 1) == NULL) + Sys_Error ("Couldn't determine current directory"); + + tmp = dst; + while (*tmp != 0) + tmp++; + while (*tmp == 0 && tmp != dst) + { + --tmp; + if (tmp != dst && *tmp == '/') + *tmp = 0; + } +} +#endif + +void Sys_Init (void) +{ + memset (cwd, 0, sizeof(cwd)); + Sys_GetBasedir(host_parms->argv[0], cwd, sizeof(cwd)); + host_parms->basedir = cwd; +#ifndef DO_USERDIRS + host_parms->userdir = host_parms->basedir; /* code elsewhere relies on this ! */ +#else + memset (userdir, 0, sizeof(userdir)); + Sys_GetUserdir(userdir, sizeof(userdir)); + Sys_mkdir (userdir); + host_parms->userdir = userdir; +#endif + host_parms->numcpus = Sys_NumCPUs (); + Sys_Printf("Detected %d CPUs.\n", host_parms->numcpus); +} + +void Sys_mkdir (const char *path) +{ + int rc = mkdir (path, 0777); + if (rc != 0 && errno == EEXIST) + { + struct stat st; + if (stat(path, &st) == 0 && S_ISDIR(st.st_mode)) + rc = 0; + } + if (rc != 0) + { + rc = errno; + Sys_Error("Unable to create directory %s: %s", path, strerror(rc)); + } +} + +static const char errortxt1[] = "\nERROR-OUT BEGIN\n\n"; +static const char errortxt2[] = "\nQUAKE ERROR: "; + +void Sys_Error (const char *error, ...) +{ + va_list argptr; + char text[1024]; + + host_parms->errstate++; + + va_start (argptr, error); + q_vsnprintf (text, sizeof(text), error, argptr); + va_end (argptr); + + fputs (errortxt1, stderr); + Host_Shutdown (); + fputs (errortxt2, stderr); + fputs (text, stderr); + fputs ("\n\n", stderr); + if (!isDedicated) + PL_ErrorDialog(text); + + exit (1); +} + +void Sys_Printf (const char *fmt, ...) +{ + va_list argptr; + + va_start(argptr, fmt); + vprintf(fmt, argptr); + va_end(argptr); +} + +void Sys_Quit (void) +{ + Host_Shutdown(); + + exit (0); +} + +double Sys_DoubleTime (void) +{ + return SDL_GetTicks() / 1000.0; +} + +const char *Sys_ConsoleInput (void) +{ + static char con_text[256]; + static int textlen; + char c; + fd_set set; + struct timeval timeout; + + FD_ZERO (&set); + FD_SET (0, &set); // stdin + timeout.tv_sec = 0; + timeout.tv_usec = 0; + + while (select (1, &set, NULL, NULL, &timeout)) + { + read (0, &c, 1); + if (c == '\n' || c == '\r') + { + con_text[textlen] = '\0'; + textlen = 0; + return con_text; + } + else if (c == 8) + { + if (textlen) + { + textlen--; + con_text[textlen] = '\0'; + } + continue; + } + con_text[textlen] = c; + textlen++; + if (textlen < (int) sizeof(con_text)) + con_text[textlen] = '\0'; + else + { + // buffer is full + textlen = 0; + con_text[0] = '\0'; + Sys_Printf("\nConsole input too long!\n"); + break; + } + } + + return NULL; +} + +void Sys_Sleep (unsigned long msecs) +{ +/* usleep (msecs * 1000);*/ + SDL_Delay (msecs); +} + +void Sys_SendKeyEvents (void) +{ + IN_Commands(); //ericw -- allow joysticks to add keys so they can be used to confirm SCR_ModalMessage + IN_SendKeyEvents(); +} + diff --git a/engine/Quake/sys_sdl_win.c b/engine/Quake/sys_sdl_win.c new file mode 100644 index 0000000..5996577 --- /dev/null +++ b/engine/Quake/sys_sdl_win.c @@ -0,0 +1,443 @@ +/* +Copyright (C) 1996-2001 Id Software, Inc. +Copyright (C) 2002-2005 John Fitzgibbons and others +Copyright (C) 2007-2008 Kristian Duske +Copyright (C) 2010-2014 QuakeSpasm developers + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN +#endif +#include +#include + +#include "quakedef.h" + +#include +#include +#include +#include + +#if defined(SDL_FRAMEWORK) || defined(NO_SDL_CONFIG) +#if defined(USE_SDL2) +#include +#else +#include +#endif +#else +#include "SDL.h" +#endif + + +qboolean isDedicated; +qboolean Win95, Win95old, WinNT, WinVista; +cvar_t sys_throttle = {"sys_throttle", "0.02", CVAR_ARCHIVE}; + +static HANDLE hinput, houtput; + +#define MAX_HANDLES 32 /* johnfitz -- was 10 */ +static FILE *sys_handles[MAX_HANDLES]; + + +static int findhandle (void) +{ + int i; + + for (i = 1; i < MAX_HANDLES; i++) + { + if (!sys_handles[i]) + return i; + } + Sys_Error ("out of handles"); + return -1; +} + +long Sys_filelength (FILE *f) +{ + long pos, end; + + pos = ftell (f); + fseek (f, 0, SEEK_END); + end = ftell (f); + fseek (f, pos, SEEK_SET); + + return end; +} + +int Sys_FileOpenRead_obsolete(const char *path, int *hndl) +{ + FILE *f; + int i, retval; + + i = findhandle (); + f = fopen(path, "rb"); + + if (!f) + { + *hndl = -1; + retval = -1; + } + else + { + sys_handles[i] = f; + *hndl = i; + retval = Sys_filelength(f); + } + + return retval; +} + +int Sys_FileOpenWrite_obsolete(const char *path) +{ + FILE *f; + int i; + + i = findhandle (); + f = fopen(path, "wb"); + + if (!f) + Sys_Error ("Error opening %s: %s", path, strerror(errno)); + + sys_handles[i] = f; + return i; +} + +void Sys_FileClose_obsolete(int handle) +{ + fclose (sys_handles[handle]); + sys_handles[handle] = NULL; +} + +void Sys_FileSeek_obsolete(int handle, int position) +{ + fseek (sys_handles[handle], position, SEEK_SET); +} + +int Sys_FileRead_obsolete(int handle, void *dest, int count) +{ + return fread (dest, 1, count, sys_handles[handle]); +} + +int Sys_FileWrite_obsolete(int handle, const void *data, int count) +{ + return fwrite (data, 1, count, sys_handles[handle]); +} + +int Sys_FileTime_obsolete (const char *path) +{ + FILE *f; + + f = fopen(path, "rb"); + + if (f) + { + fclose(f); + return 1; + } + + return -1; +} + +static char cwd[1024]; + +static void Sys_GetBasedir (char *argv0, char *dst, size_t dstsize) +{ + char *tmp; + size_t rc; + + rc = GetCurrentDirectory(dstsize, dst); + if (rc == 0 || rc > dstsize) + Sys_Error ("Couldn't determine current directory"); + + tmp = dst; + while (*tmp != 0) + tmp++; + while (*tmp == 0 && tmp != dst) + { + --tmp; + if (tmp != dst && (*tmp == '/' || *tmp == '\\')) + *tmp = 0; + } +} + +typedef enum { dpi_unaware = 0, dpi_system_aware = 1, dpi_monitor_aware = 2 } dpi_awareness; +typedef BOOL (WINAPI *SetProcessDPIAwareFunc)(); +typedef HRESULT (WINAPI *SetProcessDPIAwarenessFunc)(dpi_awareness value); + +static void Sys_SetDPIAware (void) +{ + HMODULE hUser32, hShcore; + SetProcessDPIAwarenessFunc setDPIAwareness; + SetProcessDPIAwareFunc setDPIAware; + + /* Neither SDL 1.2 nor SDL 2.0.3 can handle the OS scaling our window. + (e.g. https://bugzilla.libsdl.org/show_bug.cgi?id=2713) + Call SetProcessDpiAwareness/SetProcessDPIAware to opt out of scaling. + */ + + hShcore = LoadLibraryA ("Shcore.dll"); + hUser32 = LoadLibraryA ("user32.dll"); + setDPIAwareness = (SetProcessDPIAwarenessFunc) (hShcore ? GetProcAddress (hShcore, "SetProcessDpiAwareness") : NULL); + setDPIAware = (SetProcessDPIAwareFunc) (hUser32 ? GetProcAddress (hUser32, "SetProcessDPIAware") : NULL); + + if (setDPIAwareness) /* Windows 8.1+ */ + setDPIAwareness (dpi_monitor_aware); + else if (setDPIAware) /* Windows Vista-8.0 */ + setDPIAware (); + + if (hShcore) + FreeLibrary (hShcore); + if (hUser32) + FreeLibrary (hUser32); +} + +static void Sys_SetTimerResolution(void) +{ + /* Set OS timer resolution to 1ms. + Works around buffer underruns with directsound and SDL2, but also + will make Sleep()/SDL_Dleay() accurate to 1ms which should help framerate + stability. + */ + timeBeginPeriod (1); +} + +void Sys_Init (void) +{ + OSVERSIONINFO vinfo; + + Sys_SetTimerResolution (); + Sys_SetDPIAware (); + + memset (cwd, 0, sizeof(cwd)); + Sys_GetBasedir(NULL, cwd, sizeof(cwd)); + host_parms->basedir = cwd; + + /* userdirs not really necessary for windows guys. + * can be done if necessary, though... */ + host_parms->userdir = host_parms->basedir; /* code elsewhere relies on this ! */ + + vinfo.dwOSVersionInfoSize = sizeof(vinfo); + + if (!GetVersionEx (&vinfo)) + Sys_Error ("Couldn't get OS info"); + + if ((vinfo.dwMajorVersion < 4) || + (vinfo.dwPlatformId == VER_PLATFORM_WIN32s)) + { + Sys_Error ("QuakeSpasm requires at least Win95 or NT 4.0"); + } + + if (vinfo.dwPlatformId == VER_PLATFORM_WIN32_NT) + { + SYSTEM_INFO info; + WinNT = true; + if (vinfo.dwMajorVersion >= 6) + WinVista = true; + GetSystemInfo(&info); + host_parms->numcpus = info.dwNumberOfProcessors; + if (host_parms->numcpus < 1) + host_parms->numcpus = 1; + } + else + { + WinNT = false; /* Win9x or WinME */ + host_parms->numcpus = 1; + if ((vinfo.dwMajorVersion == 4) && (vinfo.dwMinorVersion == 0)) + { + Win95 = true; + /* Win95-gold or Win95A can't switch bpp automatically */ + if (vinfo.szCSDVersion[1] != 'C' && vinfo.szCSDVersion[1] != 'B') + Win95old = true; + } + } + Sys_Printf("Detected %d CPUs.\n", host_parms->numcpus); + + if (isDedicated) + { + if (!AllocConsole ()) + { + isDedicated = false; /* so that we have a graphical error dialog */ + Sys_Error ("Couldn't create dedicated server console"); + } + + hinput = GetStdHandle (STD_INPUT_HANDLE); + houtput = GetStdHandle (STD_OUTPUT_HANDLE); + } +} + +void Sys_mkdir_obsolete (const char *path) +{ + if (CreateDirectory(path, NULL) != 0) + return; + if (GetLastError() != ERROR_ALREADY_EXISTS) + Sys_Error("Unable to create directory %s", path); +} + +static const char errortxt1[] = "\nERROR-OUT BEGIN\n\n"; +static const char errortxt2[] = "\nQUAKE ERROR: "; + +void Sys_Error_obsolete(const char *error, ...) +{ + va_list argptr; + char text[1024]; + DWORD dummy; + + host_parms->errstate++; + + va_start (argptr, error); + q_vsnprintf (text, sizeof(text), error, argptr); + va_end (argptr); + + if (isDedicated) + WriteFile (houtput, errortxt1, strlen(errortxt1), &dummy, NULL); + /* SDL will put these into its own stderr log, + so print to stderr even in graphical mode. */ + fputs (errortxt1, stderr); + Host_Shutdown (); + fputs (errortxt2, stderr); + fputs (text, stderr); + fputs ("\n\n", stderr); + if (!isDedicated) + PL_ErrorDialog(text); + else + { + WriteFile (houtput, errortxt2, strlen(errortxt2), &dummy, NULL); + WriteFile (houtput, text, strlen(text), &dummy, NULL); + WriteFile (houtput, "\r\n", 2, &dummy, NULL); + SDL_Delay (3000); /* show the console 3 more seconds */ + } + + exit (1); +} + +void Sys_Printf_obsolete (const char *fmt, ...) +{ + va_list argptr; + char text[1024]; + DWORD dummy; + + va_start (argptr,fmt); + q_vsnprintf (text, sizeof(text), fmt, argptr); + va_end (argptr); + + if (isDedicated) + { + WriteFile(houtput, text, strlen(text), &dummy, NULL); + } + else + { + /* SDL will put these into its own stdout log, + so print to stdout even in graphical mode. */ + fputs (text, stdout); + } +} + +void Sys_Quit_obsolete(void) +{ + Host_Shutdown(); + + if (isDedicated) + FreeConsole (); + + exit (0); +} + +double Sys_DoubleTime_obsolete(void) +{ + return SDL_GetTicks() / 1000.0; +} + +const char *Sys_ConsoleInput_obsolete (void) +{ + static char con_text[256]; + static int textlen; + INPUT_RECORD recs[1024]; + int ch; + DWORD dummy, numread, numevents; + + for ( ;; ) + { + if (GetNumberOfConsoleInputEvents(hinput, &numevents) == 0) + Sys_Error ("Error getting # of console events"); + + if (! numevents) + break; + + if (ReadConsoleInput(hinput, recs, 1, &numread) == 0) + Sys_Error ("Error reading console input"); + + if (numread != 1) + Sys_Error ("Couldn't read console input"); + + if (recs[0].EventType == KEY_EVENT) + { + if (recs[0].Event.KeyEvent.bKeyDown == FALSE) + { + ch = recs[0].Event.KeyEvent.uChar.AsciiChar; + + switch (ch) + { + case '\r': + WriteFile(houtput, "\r\n", 2, &dummy, NULL); + + if (textlen != 0) + { + con_text[textlen] = 0; + textlen = 0; + return con_text; + } + + break; + + case '\b': + WriteFile(houtput, "\b \b", 3, &dummy, NULL); + if (textlen != 0) + textlen--; + + break; + + default: + if (ch >= ' ') + { + WriteFile(houtput, &ch, 1, &dummy, NULL); + con_text[textlen] = ch; + textlen = (textlen + 1) & 0xff; + } + + break; + } + } + } + } + + return NULL; +} + +void Sys_Sleep (unsigned long msecs) +{ +/* Sleep (msecs);*/ + SDL_Delay (msecs); +} + +void Sys_SendKeyEvents (void) +{ + IN_Commands(); //ericw -- allow joysticks to add keys so they can be used to confirm SCR_ModalMessage + IN_SendKeyEvents(); +} + diff --git a/engine/Quake/vid.h b/engine/Quake/vid.h new file mode 100644 index 0000000..46ae8d6 --- /dev/null +++ b/engine/Quake/vid.h @@ -0,0 +1,93 @@ +/* +Copyright (C) 1996-2001 Id Software, Inc. +Copyright (C) 2002-2009 John Fitzgibbons and others +Copyright (C) 2007-2008 Kristian Duske +Copyright (C) 2010-2014 QuakeSpasm developers + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#ifndef __VID_DEFS_H +#define __VID_DEFS_H + +// vid.h -- video driver defs + +#define VID_CBITS 6 +#define VID_GRADES (1 << VID_CBITS) + +#define GAMMA_MAX 3.0 + +// moved here for global use -- kristian +typedef enum { MS_UNINIT, MS_WINDOWED, MS_FULLSCREEN } modestate_t; + +extern modestate_t modestate; + +// a pixel can be one, two, or four bytes +typedef byte pixel_t; + +typedef struct vrect_s +{ + int x, y, width, height; + struct vrect_s *pnext; +} vrect_t; + +typedef struct +{ + pixel_t *buffer; // invisible buffer + pixel_t *colormap; // 256 * VID_GRADES size + unsigned short *colormap16; // 256 * VID_GRADES size + int fullbright; // index of first fullbright color + int rowbytes; // may be > width if displayed in a window + int width; + int height; + float aspect; // width / height -- < 0 is taller than wide + int numpages; + int recalc_refdef; // if true, recalc vid-based stuff + pixel_t *conbuffer; + int conrowbytes; + int conwidth; + int conheight; + int maxwarpwidth; + int maxwarpheight; + pixel_t *direct; // direct drawing to framebuffer, if not NULL +} viddef_t; + +extern viddef_t vid; // global video state + +extern void (*vid_menudrawfn)(void); +extern void (*vid_menukeyfn)(int key); +extern void (*vid_menucmdfn)(void); //johnfitz + +void VID_Init (void); //johnfitz -- removed palette from argument list + +void VID_Shutdown (void); +// Called at shutdown + +void VID_Update (vrect_t *rects); +// flushes the given rectangles from the view buffer to the screen + +void VID_SyncCvars (void); + +void VID_Toggle (void); + +void *VID_GetWindow (void); +qboolean VID_HasMouseOrInputFocus (void); +qboolean VID_IsMinimized (void); +void VID_Lock (void); + +#endif /* __VID_DEFS_H */ + diff --git a/engine/code/view.c b/engine/Quake/view.c similarity index 62% rename from engine/code/view.c rename to engine/Quake/view.c index 147081b..27ed069 100644 --- a/engine/code/view.c +++ b/engine/Quake/view.c @@ -1,5 +1,7 @@ /* -Copyright (C) 1996-1997 Id Software, Inc. +Copyright (C) 1996-2001 Id Software, Inc. +Copyright (C) 2002-2009 John Fitzgibbons and others +Copyright (C) 2010-2014 QuakeSpasm developers This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -8,7 +10,7 @@ of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. @@ -20,7 +22,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // view.c -- player eye positioning #include "quakedef.h" -//#include "r_local.h" // jkrige - removed /* @@ -31,43 +32,46 @@ when crossing a water boudnary. */ -cvar_t lcd_x = {"lcd_x","0"}; -cvar_t lcd_yaw = {"lcd_yaw","0"}; +cvar_t scr_ofsx = {"scr_ofsx","0", CVAR_NONE}; +cvar_t scr_ofsy = {"scr_ofsy","0", CVAR_NONE}; +cvar_t scr_ofsz = {"scr_ofsz","0", CVAR_NONE}; -cvar_t scr_ofsx = {"scr_ofsx","0", false}; -cvar_t scr_ofsy = {"scr_ofsy","0", false}; -cvar_t scr_ofsz = {"scr_ofsz","0", false}; +cvar_t cl_rollspeed = {"cl_rollspeed", "200", CVAR_NONE}; +cvar_t cl_rollangle = {"cl_rollangle", "2.0", CVAR_NONE}; -cvar_t cl_rollspeed = {"cl_rollspeed", "200"}; -cvar_t cl_rollangle = {"cl_rollangle", "2.0"}; +cvar_t cl_bob = {"cl_bob","0.02", CVAR_NONE}; +cvar_t cl_bobcycle = {"cl_bobcycle","0.6", CVAR_NONE}; +cvar_t cl_bobup = {"cl_bobup","0.5", CVAR_NONE}; -cvar_t cl_bob = {"cl_bob","0.02", false}; -cvar_t cl_bobcycle = {"cl_bobcycle","0.6", false}; -cvar_t cl_bobup = {"cl_bobup","0.5", false}; +cvar_t v_kicktime = {"v_kicktime", "0.5", CVAR_NONE}; +cvar_t v_kickroll = {"v_kickroll", "0.6", CVAR_NONE}; +cvar_t v_kickpitch = {"v_kickpitch", "0.6", CVAR_NONE}; +cvar_t v_gunkick = {"v_gunkick", "1", CVAR_NONE}; //johnfitz -cvar_t v_kicktime = {"v_kicktime", "0.5", false}; -cvar_t v_kickroll = {"v_kickroll", "0.6", false}; -cvar_t v_kickpitch = {"v_kickpitch", "0.6", false}; +cvar_t v_iyaw_cycle = {"v_iyaw_cycle", "2", CVAR_NONE}; +cvar_t v_iroll_cycle = {"v_iroll_cycle", "0.5", CVAR_NONE}; +cvar_t v_ipitch_cycle = {"v_ipitch_cycle", "1", CVAR_NONE}; +cvar_t v_iyaw_level = {"v_iyaw_level", "0.3", CVAR_NONE}; +cvar_t v_iroll_level = {"v_iroll_level", "0.1", CVAR_NONE}; +cvar_t v_ipitch_level = {"v_ipitch_level", "0.3", CVAR_NONE}; -cvar_t v_iyaw_cycle = {"v_iyaw_cycle", "2", false}; -cvar_t v_iroll_cycle = {"v_iroll_cycle", "0.5", false}; -cvar_t v_ipitch_cycle = {"v_ipitch_cycle", "1", false}; -cvar_t v_iyaw_level = {"v_iyaw_level", "0.3", false}; -cvar_t v_iroll_level = {"v_iroll_level", "0.1", false}; -cvar_t v_ipitch_level = {"v_ipitch_level", "0.3", false}; +cvar_t v_idlescale = {"v_idlescale", "0", CVAR_NONE}; -cvar_t v_idlescale = {"v_idlescale", "0", false}; +cvar_t crosshair = {"crosshair", "0", CVAR_ARCHIVE}; -cvar_t crosshair = {"crosshair", "0", true}; -cvar_t cl_crossx = {"cl_crossx", "0", false}; -cvar_t cl_crossy = {"cl_crossy", "0", false}; +cvar_t gl_cshiftpercent = {"gl_cshiftpercent", "100", CVAR_NONE}; +cvar_t gl_cshiftpercent_contents = {"gl_cshiftpercent_contents", "100", CVAR_NONE}; // QuakeSpasm +cvar_t gl_cshiftpercent_damage = {"gl_cshiftpercent_damage", "100", CVAR_NONE}; // QuakeSpasm +cvar_t gl_cshiftpercent_bonus = {"gl_cshiftpercent_bonus", "100", CVAR_NONE}; // QuakeSpasm +cvar_t gl_cshiftpercent_powerup = {"gl_cshiftpercent_powerup", "100", CVAR_NONE}; // QuakeSpasm -cvar_t gl_cshiftpercent = {"gl_cshiftpercent", "100", false}; +cvar_t r_viewmodel_quake = {"r_viewmodel_quake", "0", CVAR_ARCHIVE}; float v_dmg_time, v_dmg_roll, v_dmg_pitch; extern int in_forward, in_forward2, in_back; +vec3_t v_punchangles[2]; //johnfitz -- copied from cl.punchangle. 0 is current, 1 is previous value. never the same unless map just loaded /* =============== @@ -76,19 +80,18 @@ V_CalcRoll Used by view and sv_user =============== */ -vec3_t forward, right, up; - float V_CalcRoll (vec3_t angles, vec3_t velocity) { + vec3_t forward, right, up; float sign; float side; float value; - + AngleVectors (angles, forward, right, up); side = DotProduct (velocity, right); sign = side < 0 ? -1 : 1; side = fabs(side); - + value = cl_rollangle.value; // if (cl.inwater) // value *= 6; @@ -97,9 +100,8 @@ float V_CalcRoll (vec3_t angles, vec3_t velocity) side = side * value / cl_rollspeed.value; else side = value; - + return side*sign; - } @@ -113,7 +115,7 @@ float V_CalcBob (void) { float bob; float cycle; - + cycle = cl.time - (int)(cl.time/cl_bobcycle.value)*cl_bobcycle.value; cycle /= cl_bobcycle.value; if (cycle < cl_bobup.value) @@ -125,30 +127,21 @@ float V_CalcBob (void) // (don't count Z, or jumping messes it up) bob = sqrt(cl.velocity[0]*cl.velocity[0] + cl.velocity[1]*cl.velocity[1]) * cl_bob.value; -//Con_Printf ("speed: %5.1f\n", Length(cl.velocity)); +//Con_Printf ("speed: %5.1f\n", VectorLength(cl.velocity)); bob = bob*0.3 + bob*0.7*sin(cycle); - - // jkrige - view weapon bob fix - if (bob > 7) - bob = 7; + if (bob > 4) + bob = 4; else if (bob < -7) bob = -7; - //if (bob > 4) - // bob = 4; - //else if (bob < -7) - // bob = -7; - // jkrige - view weapon bob fix - return bob; - } //============================================================================= -cvar_t v_centermove = {"v_centermove", "0.15", false}; -cvar_t v_centerspeed = {"v_centerspeed","500"}; +cvar_t v_centermove = {"v_centermove", "0.15", CVAR_NONE}; +cvar_t v_centerspeed = {"v_centerspeed","500", CVAR_NONE}; void V_StartPitchDrift (void) @@ -184,7 +177,7 @@ If the user is adjusting pitch manually, either with lookup/lookdown, mlook and mouse, or klook and keyboard, pitch drifting is constantly stopped. Drifting is enabled when the center view key is hit, mlook is released and -lookspring is non 0, or when +lookspring is non 0, or when =============== */ void V_DriftPitch (void) @@ -192,6 +185,7 @@ void V_DriftPitch (void) float delta, move; if (noclip_anglehack || !cl.onground || cls.demoplayback ) + //FIXME: noclip_anglehack is set on the server, so in a nonlocal game this won't work. { cl.driftmove = 0; cl.pitchvel = 0; @@ -205,18 +199,15 @@ void V_DriftPitch (void) cl.driftmove = 0; else cl.driftmove += host_frametime; - + if ( cl.driftmove > v_centermove.value) { - // jkrige - lookspring fix - //V_StartPitchDrift (); - if(lookspring.value) + if (lookspring.value) V_StartPitchDrift (); - // jkrige - lookspring fix } return; } - + delta = cl.idealpitch - cl.viewangles[PITCH]; if (!delta) @@ -227,7 +218,7 @@ void V_DriftPitch (void) move = host_frametime * cl.pitchvel; cl.pitchvel += host_frametime * v_centerspeed.value; - + //Con_Printf ("move: %f (%f)\n", move, host_frametime); if (delta > 0) @@ -250,111 +241,22 @@ void V_DriftPitch (void) } } +/* +============================================================================== + VIEW BLENDING +============================================================================== +*/ - -/* -============================================================================== - - PALETTE FLASHES - -============================================================================== -*/ - - cshift_t cshift_empty = { {130,80,50}, 0 }; cshift_t cshift_water = { {130,80,50}, 128 }; cshift_t cshift_slime = { {0,25,5}, 150 }; cshift_t cshift_lava = { {255,80,0}, 150 }; -// jkrige - gamma -#ifdef GLQUAKE -cvar_t gl_gamma = {"gamma", "2.45", true}; -cvar_t gl_overbrightbits = {"gl_overbrightbits", "0", true}; -#else -cvar_t v_gamma = {"gamma", "1", true}; -#endif -// jkrige - gamma - -byte gammatable[256]; // palette is sent through this - -#ifdef GLQUAKE -byte ramps[3][256]; float v_blend[4]; // rgba 0.0 - 1.0 -#endif // GLQUAKE - -void BuildGammaTable (float g) -{ - int i, inf; - - if (g == 1.0) - { - for (i=0 ; i<256 ; i++) - gammatable[i] = i; - return; - } - - for (i=0 ; i<256 ; i++) - { - inf = 255 * pow ( (i+0.5)/255.5 , g ) + 0.5; - if (inf < 0) - inf = 0; - if (inf > 255) - inf = 255; - gammatable[i] = inf; - } -} - -/* -================= -V_CheckGamma -================= -*/ -// jkrige - gamma -qboolean V_CheckGamma (void) -{ - static float oldgammavalue; - static float oldoverbrightvalue; - - // jkrige - gamma -#ifdef GLQUAKE - if (gl_gamma.value == oldgammavalue && gl_overbrightbits.value == oldoverbrightvalue) - return false; - - oldgammavalue = gl_gamma.value; - oldoverbrightvalue = gl_overbrightbits.value; - - VG_SetColorMappings(); -#else - if (v_gamma.value == oldgammavalue) - return false; - - oldgammavalue = v_gamma.value; - BuildGammaTable (v_gamma.value); -#endif - // jkrige - gamma - - vid.recalc_refdef = 1; // force a surface cache flush - - return true; -} -/*qboolean V_CheckGamma (void) -{ - static float oldgammavalue; - - if (v_gamma.value == oldgammavalue) - return false; - oldgammavalue = v_gamma.value; - - BuildGammaTable (v_gamma.value); - vid.recalc_refdef = 1; // force a surface cache flush - - return true; -}*/ -// jkrige - gamma - +//johnfitz -- deleted BuildGammaTable(), V_CheckGamma(), gammatable[], and ramps[][] /* =============== @@ -370,11 +272,11 @@ void V_ParseDamage (void) entity_t *ent; float side; float count; - + armor = MSG_ReadByte (); blood = MSG_ReadByte (); for (i=0 ; i<3 ; i++) - from[i] = MSG_ReadCoord (); + from[i] = MSG_ReadCoord (cl.protocolflags); count = blood*0.5 + armor*0.5; if (count < 10) @@ -388,7 +290,7 @@ void V_ParseDamage (void) if (cl.cshifts[CSHIFT_DAMAGE].percent > 150) cl.cshifts[CSHIFT_DAMAGE].percent = 150; - if (armor > blood) + if (armor > blood) { cl.cshifts[CSHIFT_DAMAGE].destcolor[0] = 200; cl.cshifts[CSHIFT_DAMAGE].destcolor[1] = 100; @@ -411,15 +313,15 @@ void V_ParseDamage (void) // calculate view angle kicks // ent = &cl_entities[cl.viewentity]; - + VectorSubtract (from, ent->origin, from); VectorNormalize (from); - + AngleVectors (ent->angles, forward, right, up); side = DotProduct (from, right); v_dmg_roll = count*side*v_kickroll.value; - + side = DotProduct (from, forward); v_dmg_pitch = count*side*v_kickpitch.value; @@ -469,6 +371,7 @@ void V_SetContentsColor (int contents) { case CONTENTS_EMPTY: case CONTENTS_SOLID: + case CONTENTS_SKY: //johnfitz -- no blend in sky cl.cshifts[CSHIFT_CONTENTS] = cshift_empty; break; case CONTENTS_LAVA: @@ -526,29 +429,39 @@ void V_CalcPowerupCshift (void) V_CalcBlend ============= */ -#ifdef GLQUAKE void V_CalcBlend (void) { float r, g, b, a, a2; int j; + cvar_t *cshiftpercent_cvars[NUM_CSHIFTS] = { + &gl_cshiftpercent_contents, + &gl_cshiftpercent_damage, + &gl_cshiftpercent_bonus, + &gl_cshiftpercent_powerup + }; r = 0; g = 0; b = 0; a = 0; - for (j=0 ; jvalue / 100.0); + // QuakeSpasm if (!a2) continue; a = a + a2*(1-a); -//Con_Printf ("j:%i a:%f\n", j, a); a2 = a2/a; r = r*(1-a2) + cl.cshifts[j].destcolor[0]*a2; g = g*(1-a2) + cl.cshifts[j].destcolor[1]*a2; @@ -564,43 +477,36 @@ void V_CalcBlend (void) if (v_blend[3] < 0) v_blend[3] = 0; } -#endif /* ============= -V_UpdatePalette +V_UpdateBlend -- johnfitz -- V_UpdatePalette cleaned up and renamed ============= */ -#ifdef GLQUAKE -void V_UpdatePalette (void) +void V_UpdateBlend (void) { int i, j; - qboolean new; - byte *basepal, *newpal; - byte pal[768]; - float r,g,b,a; - int ir, ig, ib; - qboolean force; + qboolean blend_changed; V_CalcPowerupCshift (); - - new = false; - + + blend_changed = false; + for (i=0 ; i 255) - ir = 255; - if (ig > 255) - ig = 255; - if (ib > 255) - ib = 255; - - ramps[0][i] = gammatable[ir]; - ramps[1][i] = gammatable[ig]; - ramps[2][i] = gammatable[ib]; - } + glMatrixMode(GL_PROJECTION); + glLoadIdentity (); + glOrtho (0, 1, 1, 0, -99999, 99999); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity (); - basepal = host_basepal; - newpal = pal; - - for (i=0 ; i<256 ; i++) - { - ir = basepal[0]; - ig = basepal[1]; - ib = basepal[2]; - basepal += 3; - - newpal[0] = ramps[0][ir]; - newpal[1] = ramps[1][ig]; - newpal[2] = ramps[2][ib]; - newpal += 3; - } + glColor4fv (v_blend); - VID_ShiftPalette (pal); -} -#else // !GLQUAKE -void V_UpdatePalette (void) -{ - int i, j; - qboolean new; - byte *basepal, *newpal; - byte pal[768]; - int r,g,b; - qboolean force; + glBegin (GL_QUADS); + glVertex2f (0,0); + glVertex2f (1, 0); + glVertex2f (1, 1); + glVertex2f (0, 1); + glEnd (); - V_CalcPowerupCshift (); - - new = false; - - for (i=0 ; i>8; - g += (cl.cshifts[j].percent*(cl.cshifts[j].destcolor[1]-g))>>8; - b += (cl.cshifts[j].percent*(cl.cshifts[j].destcolor[2]-b))>>8; - } - - newpal[0] = gammatable[r]; - newpal[1] = gammatable[g]; - newpal[2] = gammatable[b]; - newpal += 3; - } - - VID_ShiftPalette (pal); + glDisable (GL_BLEND); + glEnable (GL_DEPTH_TEST); + glEnable (GL_TEXTURE_2D); + glEnable (GL_ALPHA_TEST); } -#endif // !GLQUAKE +/* +============================================================================== + + VIEW RENDERING -/* -============================================================================== - - VIEW RENDERING - -============================================================================== -*/ +============================================================================== +*/ float angledelta (float a) { @@ -751,11 +581,11 @@ CalcGunAngle ================== */ void CalcGunAngle (void) -{ +{ float yaw, pitch, move; static float oldyaw = 0; static float oldpitch = 0; - + yaw = r_refdef.viewangles[YAW]; pitch = -r_refdef.viewangles[PITCH]; @@ -780,7 +610,7 @@ void CalcGunAngle (void) if (oldyaw - move > yaw) yaw = oldyaw - move; } - + if (pitch > oldpitch) { if (oldpitch + move < pitch) @@ -791,7 +621,7 @@ void CalcGunAngle (void) if (oldpitch - move > pitch) pitch = oldpitch - move; } - + oldyaw = yaw; oldpitch = pitch; @@ -811,7 +641,7 @@ V_BoundOffsets void V_BoundOffsets (void) { entity_t *ent; - + ent = &cl_entities[cl.viewentity]; // absolutely bound refresh reletive to entity clipping hull @@ -821,12 +651,10 @@ void V_BoundOffsets (void) r_refdef.vieworg[0] = ent->origin[0] - 14; else if (r_refdef.vieworg[0] > ent->origin[0] + 14) r_refdef.vieworg[0] = ent->origin[0] + 14; - if (r_refdef.vieworg[1] < ent->origin[1] - 14) r_refdef.vieworg[1] = ent->origin[1] - 14; else if (r_refdef.vieworg[1] > ent->origin[1] + 14) r_refdef.vieworg[1] = ent->origin[1] + 14; - if (r_refdef.vieworg[2] < ent->origin[2] - 22) r_refdef.vieworg[2] = ent->origin[2] - 22; else if (r_refdef.vieworg[2] > ent->origin[2] + 30) @@ -858,7 +686,7 @@ Roll is induced by movement and damage void V_CalcViewRoll (void) { float side; - + side = V_CalcRoll (cl_entities[cl.viewentity].angles, cl.velocity); r_refdef.viewangles[ROLL] += side; @@ -874,10 +702,8 @@ void V_CalcViewRoll (void) r_refdef.viewangles[ROLL] = 80; // dead view angle return; } - } - /* ================== V_CalcIntermissionRefdef @@ -908,7 +734,6 @@ void V_CalcIntermissionRefdef (void) /* ================== V_CalcRefdef - ================== */ void V_CalcRefdef (void) @@ -919,11 +744,8 @@ void V_CalcRefdef (void) vec3_t angles; float bob; static float oldz = 0; - - // jkrige - smoothed stair stepping - static float steprate = 1; - static float steprate_accum = 1; - // jkrige - smoothed stair stepping + static vec3_t punch = {0,0,0}; //johnfitz -- v_gunkick + float delta; //johnfitz -- v_gunkick V_DriftPitch (); @@ -931,18 +753,15 @@ void V_CalcRefdef (void) ent = &cl_entities[cl.viewentity]; // view is the weapon model (only visible from inside body) view = &cl.viewent; - + // transform the view offset by the model's matrix to get the offset from // model origin for the view - ent->angles[YAW] = cl.viewangles[YAW]; // the model should face - // the view dir - ent->angles[PITCH] = -cl.viewangles[PITCH]; // the model should face - // the view dir - - + ent->angles[YAW] = cl.viewangles[YAW]; // the model should face the view dir + ent->angles[PITCH] = -cl.viewangles[PITCH]; // the model should face the view dir + bob = V_CalcBob (); - + // refresh position VectorCopy (ent->origin, r_refdef.vieworg); r_refdef.vieworg[2] += cl.viewheight + bob; @@ -959,117 +778,93 @@ void V_CalcRefdef (void) V_AddIdle (); // offsets - angles[PITCH] = -ent->angles[PITCH]; // because entity pitches are - // actually backward + angles[PITCH] = -ent->angles[PITCH]; // because entity pitches are actually backward angles[YAW] = ent->angles[YAW]; angles[ROLL] = ent->angles[ROLL]; AngleVectors (angles, forward, right, up); - for (i=0 ; i<3 ; i++) - { - r_refdef.vieworg[i] += scr_ofsx.value*forward[i] + scr_ofsy.value*right[i] + scr_ofsz.value*up[i]; - } - - + if (cl.maxclients <= 1) //johnfitz -- moved cheat-protection here from V_RenderView + for (i=0 ; i<3 ; i++) + r_refdef.vieworg[i] += scr_ofsx.value*forward[i] + scr_ofsy.value*right[i] + scr_ofsz.value*up[i]; + V_BoundOffsets (); - + // set up gun position VectorCopy (cl.viewangles, view->angles); - + CalcGunAngle (); VectorCopy (ent->origin, view->origin); view->origin[2] += cl.viewheight; for (i=0 ; i<3 ; i++) - { - // jkrige - view weapon bob fix - //view->origin[i] += forward[i]*bob*0.4; - view->origin[i] += forward[i]*bob*0.12; - // jkrige - view weapon bob fix - - //view->origin[i] += right[i]*bob*0.4; - //view->origin[i] += up[i]*bob*0.8; - } + view->origin[i] += forward[i]*bob*0.4; view->origin[2] += bob; - -// fudge position around to keep amount of weapon visible -// roughly equal with different FOV - -#if 0 - if (cl.model_precache[cl.stats[STAT_WEAPON]] && strcmp (cl.model_precache[cl.stats[STAT_WEAPON]]->name, "progs/v_shot2.mdl")) -#endif - - // jkrige - viewsize decreased - /*if (scr_viewsize.value == 110) - view->origin[2] += 1; - else if (scr_viewsize.value == 100) - view->origin[2] += 2; - else if (scr_viewsize.value == 90) - view->origin[2] += 1; - else if (scr_viewsize.value == 80) - view->origin[2] += 0.5;*/ - view->origin[2] += 2.2; - // jkrige - viewsize decreased + //johnfitz -- removed all gun position fudging code (was used to keep gun from getting covered by sbar) + //MarkV -- restored this with r_viewmodel_quake cvar + if (r_viewmodel_quake.value) + { + if (scr_viewsize.value == 110) + view->origin[2] += 1; + else if (scr_viewsize.value == 100) + view->origin[2] += 2; + else if (scr_viewsize.value == 90) + view->origin[2] += 1; + else if (scr_viewsize.value == 80) + view->origin[2] += 0.5; + } view->model = cl.model_precache[cl.stats[STAT_WEAPON]]; view->frame = cl.stats[STAT_WEAPONFRAME]; view->colormap = vid.colormap; -// set up the refresh position - VectorAdd (r_refdef.viewangles, cl.punchangle, r_refdef.viewangles); +//johnfitz -- v_gunkick + if (v_gunkick.value == 1) //original quake kick + VectorAdd (r_refdef.viewangles, cl.punchangle, r_refdef.viewangles); + if (v_gunkick.value == 2) //lerped kick + { + for (i=0; i<3; i++) + if (punch[i] != v_punchangles[0][i]) + { + //speed determined by how far we need to lerp in 1/10th of a second + delta = (v_punchangles[0][i]-v_punchangles[1][i]) * host_frametime * 10; + + if (delta > 0) + punch[i] = q_min(punch[i]+delta, v_punchangles[0][i]); + else if (delta < 0) + punch[i] = q_max(punch[i]+delta, v_punchangles[0][i]); + } - // smooth out stair step ups - if (cl.onground && ent->origin[2] - oldz > 0) + VectorAdd (r_refdef.viewangles, punch, r_refdef.viewangles); + } +//johnfitz + +// smooth out stair step ups + if (!noclip_anglehack && cl.onground && ent->origin[2] - oldz > 0) //johnfitz -- added exception for noclip + //FIXME: noclip_anglehack is set on the server, so in a nonlocal game this won't work. { float steptime; - + steptime = cl.time - cl.oldtime; if (steptime < 0) - steptime = 0; //FIXME I_Error ("steptime < 0"); - - // jkrige - smoothed stair stepping - oldz += steptime * (80*steprate*steprate_accum); - //oldz += steptime * 80; - // jkrige - smoothed stair stepping - + //FIXME I_Error ("steptime < 0"); + steptime = 0; + oldz += steptime * 80; if (oldz > ent->origin[2]) oldz = ent->origin[2]; - - - // jkrige - smoothed stair stepping - steprate_accum += 0.05; - steprate = 0.125*(ent->origin[2] - oldz); - if (steprate < 1) - steprate = 1; - - if (ent->origin[2] - oldz > 56) + if (ent->origin[2] - oldz > 12) oldz = ent->origin[2] - 12; - - //if (ent->origin[2] - oldz > 12) - //oldz = ent->origin[2] - 12; - // jkrige - smoothed stair stepping - r_refdef.vieworg[2] += oldz - ent->origin[2]; view->origin[2] += oldz - ent->origin[2]; } else - { oldz = ent->origin[2]; - // jkrige - smoothed stair stepping - steprate = 1; - steprate_accum = 1; - // jkrige - smoothed stair stepping - } - - // jkrige - removed chase - //if (chase_active.value) - // Chase_Update (); - // jkrige - removed chase + if (chase_active.value) + Chase_UpdateForDrawing (); //johnfitz } /* @@ -1087,70 +882,25 @@ void V_RenderView (void) if (con_forcedup) return; -// don't allow cheats in multiplayer - if (cl.maxclients > 1) - { - Cvar_Set ("scr_ofsx", "0"); - Cvar_Set ("scr_ofsy", "0"); - Cvar_Set ("scr_ofsz", "0"); - } - if (cl.intermission) - { // intermission / finale rendering - V_CalcIntermissionRefdef (); - } - else - { - if (!cl.paused /* && (sv.maxclients > 1 || key_dest == key_game) */ ) - V_CalcRefdef (); - } - - R_PushDlights (); - - if (lcd_x.value) - { - // - // render two interleaved views - // - int i; - - vid.rowbytes <<= 1; - vid.aspect *= 0.5; - - r_refdef.viewangles[YAW] -= lcd_yaw.value; - for (i=0 ; i<3 ; i++) - r_refdef.vieworg[i] -= right[i]*lcd_x.value; - R_RenderView (); - - vid.buffer += vid.rowbytes>>1; - - R_PushDlights (); + V_CalcIntermissionRefdef (); + else if (!cl.paused /* && (cl.maxclients > 1 || key_dest == key_game) */) + V_CalcRefdef (); - r_refdef.viewangles[YAW] += lcd_yaw.value*2; - for (i=0 ; i<3 ; i++) - r_refdef.vieworg[i] += 2*right[i]*lcd_x.value; - R_RenderView (); + //johnfitz -- removed lcd code - vid.buffer -= vid.rowbytes>>1; + R_RenderView (); - r_refdef.vrect.height <<= 1; + V_PolyBlend (); //johnfitz -- moved here from R_Renderview (); +} - vid.rowbytes >>= 1; - vid.aspect *= 2; - } - else - { - R_RenderView (); - } +/* +============================================================================== -#ifndef GLQUAKE - if (crosshair.value) - Draw_Character (scr_vrect.x + scr_vrect.width/2 + cl_crossx.value, scr_vrect.y + scr_vrect.height/2 + cl_crossy.value, '+'); -#endif - -} + INIT -//============================================================================ +============================================================================== +*/ /* ============= @@ -1159,13 +909,10 @@ V_Init */ void V_Init (void) { - Cmd_AddCommand ("v_cshift", V_cshift_f); + Cmd_AddCommand ("v_cshift", V_cshift_f); Cmd_AddCommand ("bf", V_BonusFlash_f); Cmd_AddCommand ("centerview", V_StartPitchDrift); - Cvar_RegisterVariable (&lcd_x); - Cvar_RegisterVariable (&lcd_yaw); - Cvar_RegisterVariable (&v_centermove); Cvar_RegisterVariable (&v_centerspeed); @@ -1178,9 +925,11 @@ void V_Init (void) Cvar_RegisterVariable (&v_idlescale); Cvar_RegisterVariable (&crosshair); - Cvar_RegisterVariable (&cl_crossx); - Cvar_RegisterVariable (&cl_crossy); Cvar_RegisterVariable (&gl_cshiftpercent); + Cvar_RegisterVariable (&gl_cshiftpercent_contents); // QuakeSpasm + Cvar_RegisterVariable (&gl_cshiftpercent_damage); // QuakeSpasm + Cvar_RegisterVariable (&gl_cshiftpercent_bonus); // QuakeSpasm + Cvar_RegisterVariable (&gl_cshiftpercent_powerup); // QuakeSpasm Cvar_RegisterVariable (&scr_ofsx); Cvar_RegisterVariable (&scr_ofsy); @@ -1194,17 +943,8 @@ void V_Init (void) Cvar_RegisterVariable (&v_kicktime); Cvar_RegisterVariable (&v_kickroll); Cvar_RegisterVariable (&v_kickpitch); + Cvar_RegisterVariable (&v_gunkick); //johnfitz - BuildGammaTable (1.0); // no gamma yet - - // jkrige - gamma -#ifdef GLQUAKE - Cvar_RegisterVariable (&gl_gamma); - Cvar_RegisterVariable (&gl_overbrightbits); -#else - Cvar_RegisterVariable (&v_gamma); -#endif - // jkrige - gamma + Cvar_RegisterVariable (&r_viewmodel_quake); //MarkV } - diff --git a/engine/code/view.h b/engine/Quake/view.h similarity index 64% rename from engine/code/view.h rename to engine/Quake/view.h index 66d06ad..af0cdf1 100644 --- a/engine/code/view.h +++ b/engine/Quake/view.h @@ -1,5 +1,7 @@ /* -Copyright (C) 1996-1997 Id Software, Inc. +Copyright (C) 1996-2001 Id Software, Inc. +Copyright (C) 2002-2009 John Fitzgibbons and others +Copyright (C) 2010-2014 QuakeSpasm developers This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -8,7 +10,7 @@ of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. @@ -17,26 +19,21 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -// view.h - -// jkrige - gamma -#ifdef GLQUAKE -extern cvar_t gl_gamma; -extern cvar_t gl_overbrightbits; -#else -extern cvar_t v_gamma; -#endif -// jkrige - gamma - -extern byte gammatable[256]; // palette is sent through this -extern byte ramps[3][256]; -extern float v_blend[4]; -extern cvar_t lcd_x; +#ifndef _QUAKE_VIEW_H +#define _QUAKE_VIEW_H + +extern cvar_t vid_gamma; +extern cvar_t vid_contrast; +extern float v_blend[4]; void V_Init (void); void V_RenderView (void); +void V_CalcBlend (void); +void V_UpdateBlend (void); float V_CalcRoll (vec3_t angles, vec3_t velocity); -void V_UpdatePalette (void); +//void V_UpdatePalette (void); //johnfitz + +#endif /* _QUAKE_VIEW_H */ diff --git a/engine/code/wad.c b/engine/Quake/wad.c similarity index 65% rename from engine/code/wad.c rename to engine/Quake/wad.c index c84f72c..aae5f38 100644 --- a/engine/code/wad.c +++ b/engine/Quake/wad.c @@ -1,5 +1,7 @@ /* -Copyright (C) 1996-1997 Id Software, Inc. +Copyright (C) 1996-2001 Id Software, Inc. +Copyright (C) 2002-2009 John Fitzgibbons and others +Copyright (C) 2010-2014 QuakeSpasm developers This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -8,7 +10,7 @@ of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. @@ -21,9 +23,9 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "quakedef.h" -int wad_numlumps; -lumpinfo_t *wad_lumps; -byte *wad_base; +int wad_numlumps; +lumpinfo_t *wad_lumps; +byte *wad_base = NULL; void SwapPic (qpic_t *pic); @@ -38,61 +40,66 @@ Space padding is so names can be printed nicely in tables. Can safely be performed in place. ================== */ -void W_CleanupName (char *in, char *out) +void W_CleanupName (const char *in, char *out) { int i; int c; - + for (i=0 ; i<16 ; i++ ) { c = in[i]; if (!c) break; - + if (c >= 'A' && c <= 'Z') c += ('a' - 'A'); out[i] = c; } - + for ( ; i< 16 ; i++ ) out[i] = 0; } - - /* ==================== W_LoadWadFile ==================== */ -void W_LoadWadFile (char *filename) +void W_LoadWadFile (void) //johnfitz -- filename is now hard-coded for honesty { lumpinfo_t *lump_p; wadinfo_t *header; - unsigned i; - int infotableofs; - - wad_base = COM_LoadHunkFile (filename); + int i; + int infotableofs; + const char *filename = WADFILENAME; + + //johnfitz -- modified to use malloc + //TODO: use cache_alloc + if (wad_base) + free (wad_base); + wad_base = COM_LoadMallocFile (filename, NULL); if (!wad_base) - Sys_Error ("W_LoadWadFile: couldn't load %s", filename); + Sys_Error ("W_LoadWadFile: couldn't load %s\n\n" + "Basedir is: %s\n\n" + "Check that this has an " GAMENAME " subdirectory containing pak0.pak and pak1.pak, " + "or use the -basedir command-line option to specify another directory.", + filename, com_basedir); header = (wadinfo_t *)wad_base; - - if (header->identification[0] != 'W' - || header->identification[1] != 'A' - || header->identification[2] != 'D' - || header->identification[3] != '2') + + if (header->identification[0] != 'W' || header->identification[1] != 'A' + || header->identification[2] != 'D' || header->identification[3] != '2') Sys_Error ("Wad file %s doesn't have WAD2 id\n",filename); - + wad_numlumps = LittleLong(header->numlumps); infotableofs = LittleLong(header->infotableofs); wad_lumps = (lumpinfo_t *)(wad_base + infotableofs); - + for (i=0, lump_p = wad_lumps ; ifilepos = LittleLong(lump_p->filepos); lump_p->size = LittleLong(lump_p->size); - W_CleanupName (lump_p->name, lump_p->name); + W_CleanupName (lump_p->name, lump_p->name); // CAUTION: in-place editing!!! if (lump_p->type == TYP_QPIC) SwapPic ( (qpic_t *)(wad_base + lump_p->filepos)); } @@ -104,42 +111,44 @@ void W_LoadWadFile (char *filename) W_GetLumpinfo ============= */ -lumpinfo_t *W_GetLumpinfo (char *name) +lumpinfo_t *W_GetLumpinfo (const char *name) { int i; lumpinfo_t *lump_p; char clean[16]; - + W_CleanupName (name, clean); - + for (lump_p=wad_lumps, i=0 ; iname)) return lump_p; } - - Sys_Error ("W_GetLumpinfo: %s not found", name); + + Con_SafePrintf ("W_GetLumpinfo: %s not found\n", name); //johnfitz -- was Sys_Error return NULL; } -void *W_GetLumpName (char *name) +void *W_GetLumpName (const char *name) { lumpinfo_t *lump; - + lump = W_GetLumpinfo (name); - + + if (!lump) return NULL; //johnfitz + return (void *)(wad_base + lump->filepos); } void *W_GetLumpNum (int num) { lumpinfo_t *lump; - + if (num < 0 || num > wad_numlumps) Sys_Error ("W_GetLumpNum: bad number: %i", num); - + lump = wad_lumps + num; - + return (void *)(wad_base + lump->filepos); } @@ -154,5 +163,5 @@ automatic byte swapping void SwapPic (qpic_t *pic) { pic->width = LittleLong(pic->width); - pic->height = LittleLong(pic->height); + pic->height = LittleLong(pic->height); } diff --git a/engine/code/wad.h b/engine/Quake/wad.h similarity index 72% rename from engine/code/wad.h rename to engine/Quake/wad.h index 9a740d9..8838e0e 100644 --- a/engine/code/wad.h +++ b/engine/Quake/wad.h @@ -1,5 +1,7 @@ /* -Copyright (C) 1996-1997 Id Software, Inc. +Copyright (C) 1996-2001 Id Software, Inc. +Copyright (C) 2002-2009 John Fitzgibbons and others +Copyright (C) 2010-2014 QuakeSpasm developers This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -8,7 +10,7 @@ of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. @@ -17,7 +19,9 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -// wad.h + +#ifndef _QUAKE_WAD_H +#define _QUAKE_WAD_H //=============== // TYPES @@ -36,14 +40,14 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #define TYP_SOUND 67 #define TYP_MIPTEX 68 +#define WADFILENAME "gfx.wad" //johnfitz -- filename is now hard-coded for honesty + typedef struct { int width, height; byte data[4]; // variably sized } qpic_t; - - typedef struct { char identification[4]; // should be WAD2 or 2DAW @@ -66,10 +70,13 @@ extern int wad_numlumps; extern lumpinfo_t *wad_lumps; extern byte *wad_base; -void W_LoadWadFile (char *filename); -void W_CleanupName (char *in, char *out); -lumpinfo_t *W_GetLumpinfo (char *name); -void *W_GetLumpName (char *name); +void W_LoadWadFile (void); //johnfitz -- filename is now hard-coded for honesty +void W_CleanupName (const char *in, char *out); +lumpinfo_t *W_GetLumpinfo (const char *name); +void *W_GetLumpName (const char *name); void *W_GetLumpNum (int num); void SwapPic (qpic_t *pic); + +#endif /* _QUAKE_WAD_H */ + diff --git a/engine/code/world.c b/engine/Quake/world.c similarity index 80% rename from engine/code/world.c rename to engine/Quake/world.c index b075323..475cef6 100644 --- a/engine/code/world.c +++ b/engine/Quake/world.c @@ -1,5 +1,8 @@ /* -Copyright (C) 1996-1997 Id Software, Inc. +Copyright (C) 1996-2001 Id Software, Inc. +Copyright (C) 2002-2009 John Fitzgibbons and others +Copyright (C) 2007-2008 Kristian Duske +Copyright (C) 2010-2014 QuakeSpasm developers This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -8,7 +11,7 @@ of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. @@ -54,7 +57,7 @@ HULL BOXES static hull_t box_hull; -static dclipnode_t box_clipnodes[6]; +static mclipnode_t box_clipnodes[6]; //johnfitz -- was dclipnode_t static mplane_t box_planes[6]; /* @@ -78,19 +81,19 @@ void SV_InitBoxHull (void) for (i=0 ; i<6 ; i++) { box_clipnodes[i].planenum = i; - + side = i&1; - + box_clipnodes[i].children[side] = CONTENTS_EMPTY; if (i != 5) box_clipnodes[i].children[side^1] = i + 1; else box_clipnodes[i].children[side^1] = CONTENTS_SOLID; - + box_planes[i].type = i>>1; box_planes[i].normal[i>>1] = 1; } - + } @@ -128,7 +131,7 @@ testing object's origin to get a point to use with the returned hull. */ hull_t *SV_HullForEntity (edict_t *ent, vec3_t mins, vec3_t maxs, vec3_t offset) { - model_t *model; + qmodel_t *model; vec3_t size; vec3_t hullmins, hullmaxs; hull_t *hull; @@ -137,17 +140,14 @@ hull_t *SV_HullForEntity (edict_t *ent, vec3_t mins, vec3_t maxs, vec3_t offset) if (ent->v.solid == SOLID_BSP) { // explicit hulls in the BSP model if (ent->v.movetype != MOVETYPE_PUSH) - Sys_Error ("SOLID_BSP without MOVETYPE_PUSH"); + Host_Error ("SOLID_BSP without MOVETYPE_PUSH (%s at %f %f %f)", + PR_GetString(ent->v.classname), ent->v.origin[0], ent->v.origin[1], ent->v.origin[2]); model = sv.models[ (int)ent->v.modelindex ]; if (!model || model->type != mod_brush) - { - // jkrige - MOVETYPE_PUSH fix - //Sys_Error ("MOVETYPE_PUSH with a non bsp model"); - Sys_Error ("SOLID_BSP with a non bsp model"); - // jkrige - MOVETYPE_PUSH fix - } + Host_Error ("SOLID_BSP with a non bsp model (%s at %f %f %f)", + PR_GetString(ent->v.classname), ent->v.origin[0], ent->v.origin[1], ent->v.origin[2]); VectorSubtract (maxs, mins, size); if (size[0] < 3) @@ -167,7 +167,7 @@ hull_t *SV_HullForEntity (edict_t *ent, vec3_t mins, vec3_t maxs, vec3_t offset) VectorSubtract (ent->v.mins, maxs, hullmins); VectorSubtract (ent->v.maxs, mins, hullmaxs); hull = SV_HullForBox (hullmins, hullmaxs); - + VectorCopy (ent->v.origin, offset); } @@ -215,28 +215,28 @@ areanode_t *SV_CreateAreaNode (int depth, vec3_t mins, vec3_t maxs) ClearLink (&anode->trigger_edicts); ClearLink (&anode->solid_edicts); - + if (depth == AREA_DEPTH) { anode->axis = -1; anode->children[0] = anode->children[1] = NULL; return anode; } - + VectorSubtract (maxs, mins, size); if (size[0] > size[1]) anode->axis = 0; else anode->axis = 1; - + anode->dist = 0.5 * (maxs[anode->axis] + mins[anode->axis]); - VectorCopy (mins, mins1); - VectorCopy (mins, mins2); - VectorCopy (maxs, maxs1); - VectorCopy (maxs, maxs2); - + VectorCopy (mins, mins1); + VectorCopy (mins, mins2); + VectorCopy (maxs, maxs1); + VectorCopy (maxs, maxs2); + maxs1[anode->axis] = mins2[anode->axis] = anode->dist; - + anode->children[0] = SV_CreateAreaNode (depth+1, mins2, maxs2); anode->children[1] = SV_CreateAreaNode (depth+1, mins1, maxs1); @@ -252,7 +252,7 @@ SV_ClearWorld void SV_ClearWorld (void) { SV_InitBoxHull (); - + memset (sv_areanodes, 0, sizeof(sv_areanodes)); sv_numareanodes = 0; SV_CreateAreaNode (0, sv.worldmodel->mins, sv.worldmodel->maxs); @@ -276,20 +276,81 @@ void SV_UnlinkEdict (edict_t *ent) /* ==================== -SV_TouchLinks +SV_AreaTriggerEdicts + +Spike -- just builds a list of entities within the area, rather than walking +them and risking the list getting corrupt. ==================== */ -void SV_TouchLinks ( edict_t *ent, areanode_t *node ) +static void +SV_AreaTriggerEdicts ( edict_t *ent, areanode_t *node, edict_t **list, int *listcount, const int listspace ) { link_t *l, *next; edict_t *touch; - int old_self, old_other; // touch linked edicts for (l = node->trigger_edicts.next ; l != &node->trigger_edicts ; l = next) { next = l->next; touch = EDICT_FROM_AREA(l); + if (touch == ent) + continue; + if (!touch->v.touch || touch->v.solid != SOLID_TRIGGER) + continue; + if (ent->v.absmin[0] > touch->v.absmax[0] + || ent->v.absmin[1] > touch->v.absmax[1] + || ent->v.absmin[2] > touch->v.absmax[2] + || ent->v.absmax[0] < touch->v.absmin[0] + || ent->v.absmax[1] < touch->v.absmin[1] + || ent->v.absmax[2] < touch->v.absmin[2] ) + continue; + + if (*listcount == listspace) + return; // should never happen + + list[*listcount] = touch; + (*listcount)++; + } + +// recurse down both sides + if (node->axis == -1) + return; + + if ( ent->v.absmax[node->axis] > node->dist ) + SV_AreaTriggerEdicts ( ent, node->children[0], list, listcount, listspace ); + if ( ent->v.absmin[node->axis] < node->dist ) + SV_AreaTriggerEdicts ( ent, node->children[1], list, listcount, listspace ); +} + +/* +==================== +SV_TouchLinks + +ericw -- copy the touching edicts to an array (on the hunk) so we can avoid +iteating the trigger_edicts linked list while calling PR_ExecuteProgram +which could potentially corrupt the list while it's being iterated. +Based on code from Spike. +==================== +*/ +void SV_TouchLinks (edict_t *ent) +{ + edict_t **list; + edict_t *touch; + int old_self, old_other; + int i, listcount; + int mark; + + mark = Hunk_LowMark (); + list = (edict_t **) Hunk_Alloc (sv.num_edicts*sizeof(edict_t *)); + + listcount = 0; + SV_AreaTriggerEdicts (ent, sv_areanodes, list, &listcount, sv.num_edicts); + + for (i = 0; i < listcount; i++) + { + touch = list[i]; + // re-validate in case of PR_ExecuteProgram having side effects that make + // edicts later in the list no longer touch if (touch == ent) continue; if (!touch->v.touch || touch->v.solid != SOLID_TRIGGER) @@ -312,15 +373,9 @@ void SV_TouchLinks ( edict_t *ent, areanode_t *node ) pr_global_struct->self = old_self; pr_global_struct->other = old_other; } - -// recurse down both sides - if (node->axis == -1) - return; - - if ( ent->v.absmax[node->axis] > node->dist ) - SV_TouchLinks ( ent, node->children[0] ); - if ( ent->v.absmin[node->axis] < node->dist ) - SV_TouchLinks ( ent, node->children[1] ); + +// free hunk-allocated edicts array + Hunk_FreeToLowMark (mark); } @@ -339,7 +394,7 @@ void SV_FindTouchedLeafs (edict_t *ent, mnode_t *node) if (node->contents == CONTENTS_SOLID) return; - + // add an efrag if the node is a leaf if ( node->contents < 0) @@ -351,19 +406,19 @@ void SV_FindTouchedLeafs (edict_t *ent, mnode_t *node) leafnum = leaf - sv.worldmodel->leafs - 1; ent->leafnums[ent->num_leafs] = leafnum; - ent->num_leafs++; + ent->num_leafs++; return; } - + // NODE_MIXED splitplane = node->plane; sides = BOX_ON_PLANE_SIDE(ent->v.absmin, ent->v.absmax, splitplane); - + // recurse down the contacted sides if (sides & 1) SV_FindTouchedLeafs (ent, node->children[0]); - + if (sides & 2) SV_FindTouchedLeafs (ent, node->children[1]); } @@ -380,7 +435,7 @@ void SV_LinkEdict (edict_t *ent, qboolean touch_triggers) if (ent->area.prev) SV_UnlinkEdict (ent); // unlink from old position - + if (ent == sv.edicts) return; // don't add the world @@ -388,36 +443,8 @@ void SV_LinkEdict (edict_t *ent, qboolean touch_triggers) return; // set the abs box - -#ifdef QUAKE2 - if (ent->v.solid == SOLID_BSP && (ent->v.angles[0] || ent->v.angles[1] || ent->v.angles[2]) ) - { // expand for rotation - float max, v; - int i; - - max = 0; - for (i=0 ; i<3 ; i++) - { - v =fabs( ent->v.mins[i]); - if (v > max) - max = v; - v =fabs( ent->v.maxs[i]); - if (v > max) - max = v; - } - - for (i=0 ; i<3 ; i++) - { - ent->v.absmin[i] = ent->v.origin[i] - max; - ent->v.absmax[i] = ent->v.origin[i] + max; - } - } - else -#endif - { - VectorAdd (ent->v.origin, ent->v.mins, ent->v.absmin); - VectorAdd (ent->v.origin, ent->v.maxs, ent->v.absmax); - } + VectorAdd (ent->v.origin, ent->v.mins, ent->v.absmin); + VectorAdd (ent->v.origin, ent->v.maxs, ent->v.absmax); // // to make items easier to pick up and allow them to be grabbed off @@ -440,7 +467,7 @@ void SV_LinkEdict (edict_t *ent, qboolean touch_triggers) ent->v.absmax[1] += 1; ent->v.absmax[2] += 1; } - + // link to PVS leafs ent->num_leafs = 0; if (ent->v.modelindex) @@ -462,17 +489,17 @@ void SV_LinkEdict (edict_t *ent, qboolean touch_triggers) else break; // crosses the node } - -// link it in + +// link it in if (ent->v.solid == SOLID_TRIGGER) InsertLinkBefore (&ent->area, &node->trigger_edicts); else InsertLinkBefore (&ent->area, &node->solid_edicts); - + // if touch_triggers, touch all entities at this node and decend for more if (touch_triggers) - SV_TouchLinks ( ent, sv_areanodes ); + SV_TouchLinks ( ent ); } @@ -485,8 +512,6 @@ POINT TESTING IN HULLS =============================================================================== */ -#if !id386 - /* ================== SV_HullPointContents @@ -496,32 +521,30 @@ SV_HullPointContents int SV_HullPointContents (hull_t *hull, int num, vec3_t p) { float d; - dclipnode_t *node; + mclipnode_t *node; //johnfitz -- was dclipnode_t mplane_t *plane; while (num >= 0) { if (num < hull->firstclipnode || num > hull->lastclipnode) Sys_Error ("SV_HullPointContents: bad node number"); - + node = hull->clipnodes + num; plane = hull->planes + node->planenum; - + if (plane->type < 3) d = p[plane->type] - plane->dist; else - d = DotProduct (plane->normal, p) - plane->dist; + d = DoublePrecisionDotProduct (plane->normal, p) - plane->dist; if (d < 0) num = node->children[1]; else num = node->children[0]; } - + return num; } -#endif // !id386 - /* ================== @@ -558,10 +581,10 @@ edict_t *SV_TestEntityPosition (edict_t *ent) trace_t trace; trace = SV_Move (ent->v.origin, ent->v.mins, ent->v.maxs, ent->v.origin, 0, ent); - + if (trace.startsolid) return sv.edicts; - + return NULL; } @@ -574,9 +597,6 @@ LINE TESTING IN HULLS =============================================================================== */ -// 1/32 epsilon to keep floating point happy -#define DIST_EPSILON (0.03125) - /* ================== SV_RecursiveHullCheck @@ -585,7 +605,7 @@ SV_RecursiveHullCheck */ qboolean SV_RecursiveHullCheck (hull_t *hull, int num, float p1f, float p2f, vec3_t p1, vec3_t p2, trace_t *trace) { - dclipnode_t *node; + mclipnode_t *node; //johnfitz -- was dclipnode_t mplane_t *plane; float t1, t2; float frac; @@ -626,10 +646,10 @@ qboolean SV_RecursiveHullCheck (hull_t *hull, int num, float p1f, float p2f, vec } else { - t1 = DotProduct (plane->normal, p1) - plane->dist; - t2 = DotProduct (plane->normal, p2) - plane->dist; + t1 = DoublePrecisionDotProduct (plane->normal, p1) - plane->dist; + t2 = DoublePrecisionDotProduct (plane->normal, p2) - plane->dist; } - + #if 1 if (t1 >= 0 && t2 >= 0) return SV_RecursiveHullCheck (hull, node->children[0], p1f, p2f, p1, p2, trace); @@ -651,7 +671,7 @@ qboolean SV_RecursiveHullCheck (hull_t *hull, int num, float p1f, float p2f, vec frac = 0; if (frac > 1) frac = 1; - + midf = p1f + (p2f - p1f)*frac; for (i=0 ; i<3 ; i++) mid[i] = p1[i] + frac*(p2[i] - p1[i]); @@ -670,15 +690,15 @@ qboolean SV_RecursiveHullCheck (hull_t *hull, int num, float p1f, float p2f, vec return false; } #endif - + if (SV_HullPointContents (hull, node->children[side^1], mid) != CONTENTS_SOLID) // go past the node return SV_RecursiveHullCheck (hull, node->children[side^1], midf, p2f, mid, p2, trace); - + if (trace->allsolid) return false; // never got out of the solid area - + //================== // the other side of the node is solid, this is the impact point //================== @@ -743,115 +763,9 @@ trace_t SV_ClipMoveToEntity (edict_t *ent, vec3_t start, vec3_t mins, vec3_t max VectorSubtract (start, offset, start_l); VectorSubtract (end, offset, end_l); - - // jkrige - rotating bmodels -/*#ifdef QUAKE2 - // rotate start and end into the models frame of reference - if (ent->v.solid == SOLID_BSP && - (ent->v.angles[0] || ent->v.angles[1] || ent->v.angles[2]) ) - { - vec3_t a; - vec3_t forward, right, up; - vec3_t temp; - - AngleVectors (ent->v.angles, forward, right, up); - - VectorCopy (start_l, temp); - start_l[0] = DotProduct (temp, forward); - start_l[1] = -DotProduct (temp, right); - start_l[2] = DotProduct (temp, up); - - VectorCopy (end_l, temp); - end_l[0] = DotProduct (temp, forward); - end_l[1] = -DotProduct (temp, right); - end_l[2] = DotProduct (temp, up); - } -#endif*/ - // rotate start and end into the models frame of reference - /* ported from Hexen II - if (ent->v.solid == SOLID_BSP && - (ent->v.angles[0] || ent->v.angles[1] || ent->v.angles[2]) ) - { - vec3_t a; - vec3_t forward, right, up; - vec3_t temp; - - AngleVectors (ent->v.angles, forward, right, up); - - VectorCopy (start_l, temp); - start_l[0] = DotProduct (temp, forward); - start_l[1] = -DotProduct (temp, right); - start_l[2] = DotProduct (temp, up); - - VectorCopy (end_l, temp); - end_l[0] = DotProduct (temp, forward); - end_l[1] = -DotProduct (temp, right); - end_l[2] = DotProduct (temp, up); - } - */ - // jkrige - rotating bmodels - - // trace a line through the apropriate clipping hull SV_RecursiveHullCheck (hull, hull->firstclipnode, 0, 1, start_l, end_l, &trace); - - // jkrige - rotating bmodels -/*#ifdef QUAKE2 - // rotate endpos back to world frame of reference - if (ent->v.solid == SOLID_BSP && - (ent->v.angles[0] || ent->v.angles[1] || ent->v.angles[2]) ) - { - vec3_t a; - vec3_t forward, right, up; - vec3_t temp; - - if (trace.fraction != 1) - { - VectorSubtract (vec3_origin, ent->v.angles, a); - AngleVectors (a, forward, right, up); - - VectorCopy (trace.endpos, temp); - trace.endpos[0] = DotProduct (temp, forward); - trace.endpos[1] = -DotProduct (temp, right); - trace.endpos[2] = DotProduct (temp, up); - - VectorCopy (trace.plane.normal, temp); - trace.plane.normal[0] = DotProduct (temp, forward); - trace.plane.normal[1] = -DotProduct (temp, right); - trace.plane.normal[2] = DotProduct (temp, up); - } - } -#endif*/ - // rotate endpos back to world frame of reference - /* ported from Hexen II - if (ent->v.solid == SOLID_BSP && - (ent->v.angles[0] || ent->v.angles[1] || ent->v.angles[2]) ) - { - vec3_t a; - vec3_t forward, right, up; - vec3_t temp; - - if (trace.fraction != 1) - { - VectorSubtract (vec3_origin, ent->v.angles, a); - AngleVectors (a, forward, right, up); - - VectorCopy (trace.endpos, temp); - trace.endpos[0] = DotProduct (temp, forward); - trace.endpos[1] = -DotProduct (temp, right); - trace.endpos[2] = DotProduct (temp, up); - - VectorCopy (trace.plane.normal, temp); - trace.plane.normal[0] = DotProduct (temp, forward); - trace.plane.normal[1] = -DotProduct (temp, right); - trace.plane.normal[2] = DotProduct (temp, up); - } - } - */ - // jkrige - rotating bmodels - - // fix trace up by the offset if (trace.fraction != 1) VectorAdd (trace.endpos, offset, trace.endpos); @@ -934,7 +848,7 @@ void SV_ClipToLinks ( areanode_t *node, moveclip_t *clip ) else if (trace.startsolid) clip->trace.startsolid = true; } - + // recurse down both sides if (node->axis == -1) return; @@ -959,7 +873,7 @@ boxmins[0] = boxmins[1] = boxmins[2] = -9999; boxmaxs[0] = boxmaxs[1] = boxmaxs[2] = 9999; #else int i; - + for (i=0 ; i<3 ; i++) { if (end[i] > start[i]) @@ -1011,7 +925,7 @@ trace_t SV_Move (vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, int type, e VectorCopy (mins, clip.mins2); VectorCopy (maxs, clip.maxs2); } - + // create the bounding box of the entire move SV_MoveBounds ( start, clip.mins2, clip.maxs2, end, clip.boxmins, clip.boxmaxs ); diff --git a/engine/code/world.h b/engine/Quake/world.h similarity index 86% rename from engine/code/world.h rename to engine/Quake/world.h index cddb94f..fed90b0 100644 --- a/engine/code/world.h +++ b/engine/Quake/world.h @@ -1,5 +1,7 @@ /* -Copyright (C) 1996-1997 Id Software, Inc. +Copyright (C) 1996-2001 Id Software, Inc. +Copyright (C) 2002-2009 John Fitzgibbons and others +Copyright (C) 2010-2014 QuakeSpasm developers This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -8,7 +10,7 @@ of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. @@ -17,7 +19,9 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -// world.h + +#ifndef _QUAKE_WORLD_H +#define _QUAKE_WORLD_H typedef struct { @@ -76,3 +80,8 @@ trace_t SV_Move (vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, int type, e // shouldn't be considered solid objects // passedict is explicitly excluded from clipping checks (normally NULL) + +qboolean SV_RecursiveHullCheck (hull_t *hull, int num, float p1f, float p2f, vec3_t p1, vec3_t p2, trace_t *trace); + +#endif /* _QUAKE_WORLD_H */ + diff --git a/engine/Quake/wsaerror.h b/engine/Quake/wsaerror.h new file mode 100644 index 0000000..b41a98e --- /dev/null +++ b/engine/Quake/wsaerror.h @@ -0,0 +1,91 @@ + +/* strings for winsock error codes. + * from online references, such as + * http://aluigi.org/mytoolz/winerr.h + * http://www.winsock-error.com or + * http://www.sockets.com/err_lst1.htm + */ + +#ifndef __wsaerr_static +#define __wsaerr_static static +#endif /* static */ + +__wsaerr_static const char *__WSAE_StrError (int err) +{ + switch (err) + { + case 0: return "No error"; + case WSAEINTR: return "Interrupted system call"; /* 10004 */ + case WSAEBADF: return "Bad file number"; /* 10009 */ + case WSAEACCES: return "Permission denied"; /* 10013 */ + case WSAEFAULT: return "Bad address"; /* 10014 */ + case WSAEINVAL: return "Invalid argument (not bind)"; /* 10022 */ + case WSAEMFILE: return "Too many open files"; /* 10024 */ + case WSAEWOULDBLOCK: return "Operation would block"; /* 10035 */ + case WSAEINPROGRESS: return "Operation now in progress"; /* 10036 */ + case WSAEALREADY: return "Operation already in progress"; /* 10037 */ + case WSAENOTSOCK: return "Socket operation on non-socket"; /* 10038 */ + case WSAEDESTADDRREQ: return "Destination address required"; /* 10039 */ + case WSAEMSGSIZE: return "Message too long"; /* 10040 */ + case WSAEPROTOTYPE: return "Protocol wrong type for socket"; /* 10041 */ + case WSAENOPROTOOPT: return "Bad protocol option"; /* 10042 */ + case WSAEPROTONOSUPPORT: return "Protocol not supported"; /* 10043 */ + case WSAESOCKTNOSUPPORT: return "Socket type not supported"; /* 10044 */ + case WSAEOPNOTSUPP: return "Operation not supported on socket"; /* 10045 */ + case WSAEPFNOSUPPORT: return "Protocol family not supported"; /* 10046 */ + case WSAEAFNOSUPPORT: return "Address family not supported by protocol family"; /* 10047 */ + case WSAEADDRINUSE: return "Address already in use"; /* 10048 */ + case WSAEADDRNOTAVAIL: return "Can't assign requested address"; /* 10049 */ + case WSAENETDOWN: return "Network is down"; /* 10050 */ + case WSAENETUNREACH: return "Network is unreachable"; /* 10051 */ + case WSAENETRESET: return "Net dropped connection or reset"; /* 10052 */ + case WSAECONNABORTED: return "Software caused connection abort"; /* 10053 */ + case WSAECONNRESET: return "Connection reset by peer"; /* 10054 */ + case WSAENOBUFS: return "No buffer space available"; /* 10055 */ + case WSAEISCONN: return "Socket is already connected"; /* 10056 */ + case WSAENOTCONN: return "Socket is not connected"; /* 10057 */ + case WSAESHUTDOWN: return "Can't send after socket shutdown"; /* 10058 */ + case WSAETOOMANYREFS: return "Too many references, can't splice"; /* 10059 */ + case WSAETIMEDOUT: return "Connection timed out"; /* 10060 */ + case WSAECONNREFUSED: return "Connection refused"; /* 10061 */ + case WSAELOOP: return "Too many levels of symbolic links"; /* 10062 */ + case WSAENAMETOOLONG: return "File name too long"; /* 10063 */ + case WSAEHOSTDOWN: return "Host is down"; /* 10064 */ + case WSAEHOSTUNREACH: return "No Route to Host"; /* 10065 */ + case WSAENOTEMPTY: return "Directory not empty"; /* 10066 */ + case WSAEPROCLIM: return "Too many processes"; /* 10067 */ + case WSAEUSERS: return "Too many users"; /* 10068 */ + case WSAEDQUOT: return "Disc Quota Exceeded"; /* 10069 */ + case WSAESTALE: return "Stale NFS file handle"; /* 10070 */ + case WSAEREMOTE: return "Too many levels of remote in path"; /* 10071 */ + case WSAEDISCON: return "Graceful shutdown in progress"; /* 10101 */ + + case WSASYSNOTREADY: return "Network SubSystem is unavailable"; /* 10091 */ + case WSAVERNOTSUPPORTED: return "WINSOCK DLL Version out of range"; /* 10092 */ + case WSANOTINITIALISED: return "Successful WSASTARTUP not yet performed"; /* 10093 */ + case WSAHOST_NOT_FOUND: return "Authoritative answer: Host not found"; /* 11001 */ + case WSATRY_AGAIN: return "Non-Authoritative: Host not found or SERVERFAIL"; /* 11002 */ + case WSANO_RECOVERY: return "Non-Recoverable errors, FORMERR, REFUSED, NOTIMP"; /* 11003 */ + case WSANO_DATA: return "Valid name, no data record of requested type"; /* 11004 */ + + case WSAENOMORE: return "10102: No more results"; /* 10102 */ + case WSAECANCELLED: return "10103: Call has been canceled"; /* 10103 */ + case WSAEINVALIDPROCTABLE: return "Procedure call table is invalid"; /* 10104 */ + case WSAEINVALIDPROVIDER: return "Service provider is invalid"; /* 10105 */ + case WSAEPROVIDERFAILEDINIT: return "Service provider failed to initialize"; /* 10106 */ + case WSASYSCALLFAILURE: return "System call failure"; /* 10107 */ + case WSASERVICE_NOT_FOUND: return "Service not found"; /* 10108 */ + case WSATYPE_NOT_FOUND: return "Class type not found"; /* 10109 */ + case WSA_E_NO_MORE: return "10110: No more results"; /* 10110 */ + case WSA_E_CANCELLED: return "10111: Call was canceled"; /* 10111 */ + case WSAEREFUSED: return "Database query was refused"; /* 10112 */ + + default: + { + static char _err_unknown[64]; + sprintf(_err_unknown, "Unknown WSAE error (%d)", err); + return _err_unknown; + } + } +} + diff --git a/engine/code/zone.c b/engine/Quake/zone.c similarity index 75% rename from engine/code/zone.c rename to engine/Quake/zone.c index 61b45f9..05936bb 100644 --- a/engine/code/zone.c +++ b/engine/Quake/zone.c @@ -1,5 +1,7 @@ /* -Copyright (C) 1996-1997 Id Software, Inc. +Copyright (C) 1996-2001 Id Software, Inc. +Copyright (C) 2002-2009 John Fitzgibbons and others +Copyright (C) 2010-2014 QuakeSpasm developers This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -8,7 +10,7 @@ of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. @@ -17,28 +19,28 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -// Z_zone.c +// zone.c #include "quakedef.h" -#define DYNAMIC_SIZE (4 * 1024 * 1024) // was 0xc000 (too small for 64-bit) +#define DYNAMIC_SIZE (4 * 1024 * 1024) // ericw -- was 512KB (64-bit) / 384KB (32-bit) #define ZONEID 0x1d4a11 #define MINFRAGMENT 64 typedef struct memblock_s { - int size; // including the header and possibly tiny fragments - int tag; // a tag of 0 is a free block - int id; // should be ZONEID - struct memblock_s *next, *prev; - int pad; // pad to 64 bit boundary + int size; // including the header and possibly tiny fragments + int tag; // a tag of 0 is a free block + int id; // should be ZONEID + int pad; // pad to 64 bit boundary + struct memblock_s *next, *prev; } memblock_t; typedef struct { int size; // total bytes malloced, including header - memblock_t blocklist; // start / end cap for linked list + memblock_t blocklist; // start / end cap for linked list memblock_t *rover; } memzone_t; @@ -61,34 +63,7 @@ all big things are allocated on the hunk. ============================================================================== */ -memzone_t *mainzone; - -void Z_ClearZone (memzone_t *zone, int size); - - -/* -======================== -Z_ClearZone -======================== -*/ -void Z_ClearZone (memzone_t *zone, int size) -{ - memblock_t *block; - -// set the entire zone to one free block - - zone->blocklist.next = zone->blocklist.prev = block = - (memblock_t *)( (byte *)zone + sizeof(memzone_t) ); - zone->blocklist.tag = 1; // in use block - zone->blocklist.id = 0; - zone->blocklist.size = 0; - zone->rover = block; - - block->prev = block->next = &zone->blocklist; - block->tag = 0; // free block - block->id = ZONEID; - block->size = size - sizeof(memzone_t); -} +static memzone_t *mainzone; /* @@ -99,7 +74,7 @@ Z_Free void Z_Free (void *ptr) { memblock_t *block, *other; - + if (!ptr) Sys_Error ("Z_Free: NULL pointer"); @@ -110,7 +85,7 @@ void Z_Free (void *ptr) Sys_Error ("Z_Free: freed a freed pointer"); block->tag = 0; // mark as free - + other = block->prev; if (!other->tag) { // merge with previous free block @@ -121,7 +96,7 @@ void Z_Free (void *ptr) mainzone->rover = other; block = other; } - + other = block->next; if (!other->tag) { // merge the next free block onto the end @@ -134,28 +109,10 @@ void Z_Free (void *ptr) } -/* -======================== -Z_Malloc -======================== -*/ -void *Z_Malloc (int size) -{ - void *buf; - - Z_CheckHeap (); // DEBUG - buf = Z_TagMalloc (size, 1); - if (!buf) - Sys_Error ("Z_Malloc: failed on allocation of %i bytes",size); - Q_memset (buf, 0, size); - - return buf; -} - -void *Z_TagMalloc (int size, int tag) +static void *Z_TagMalloc (int size, int tag) { int extra; - memblock_t *start, *rover, *new, *base; + memblock_t *start, *rover, *newblock, *base; if (!tag) Sys_Error ("Z_TagMalloc: tried to use a 0 tag"); @@ -167,10 +124,10 @@ void *Z_TagMalloc (int size, int tag) size += sizeof(memblock_t); // account for size of block header size += 4; // space for memory trash tester size = (size + 7) & ~7; // align to 8-byte boundary - + base = rover = mainzone->rover; start = base->prev; - + do { if (rover == start) // scaned all the way around the list @@ -180,28 +137,28 @@ void *Z_TagMalloc (int size, int tag) else rover = rover->next; } while (base->tag || base->size < size); - + // // found a block big enough // extra = base->size - size; if (extra > MINFRAGMENT) { // there will be a free fragment after the allocated block - new = (memblock_t *) ((byte *)base + size ); - new->size = extra; - new->tag = 0; // free block - new->prev = base; - new->id = ZONEID; - new->next = base->next; - new->next->prev = new; - base->next = new; + newblock = (memblock_t *) ((byte *)base + size ); + newblock->size = extra; + newblock->tag = 0; // free block + newblock->prev = base; + newblock->id = ZONEID; + newblock->next = base->next; + newblock->next->prev = newblock; + base->next = newblock; base->size = size; } - + base->tag = tag; // no longer a free block - + mainzone->rover = base->next; // next allocation will start looking here - + base->id = ZONEID; // marker for memory trash testing @@ -210,6 +167,47 @@ void *Z_TagMalloc (int size, int tag) return (void *) ((byte *)base + sizeof(memblock_t)); } +/* +======================== +Z_CheckHeap +======================== +*/ +static void Z_CheckHeap (void) +{ + memblock_t *block; + + for (block = mainzone->blocklist.next ; ; block = block->next) + { + if (block->next == &mainzone->blocklist) + break; // all blocks have been hit + if ( (byte *)block + block->size != (byte *)block->next) + Sys_Error ("Z_CheckHeap: block size does not touch the next block\n"); + if ( block->next->prev != block) + Sys_Error ("Z_CheckHeap: next block doesn't have proper back link\n"); + if (!block->tag && !block->next->tag) + Sys_Error ("Z_CheckHeap: two consecutive free blocks\n"); + } +} + + +/* +======================== +Z_Malloc +======================== +*/ +void *Z_Malloc (int size) +{ + void *buf; + + Z_CheckHeap (); // DEBUG + buf = Z_TagMalloc (size, 1); + if (!buf) + Sys_Error ("Z_Malloc: failed on allocation of %i bytes",size); + Q_memset (buf, 0, size); + + return buf; +} + /* ======================== Z_Realloc @@ -222,31 +220,40 @@ void *Z_Realloc(void *ptr, int size) memblock_t *block; if (!ptr) - return Z_Malloc(size); + return Z_Malloc (size); - block = (memblock_t *)((byte *)ptr - sizeof(memblock_t)); + block = (memblock_t *) ((byte *) ptr - sizeof (memblock_t)); if (block->id != ZONEID) - Sys_Error("Z_Realloc: realloced a pointer without ZONEID"); + Sys_Error ("Z_Realloc: realloced a pointer without ZONEID"); if (block->tag == 0) - Sys_Error("Z_Realloc: realloced a freed pointer"); + Sys_Error ("Z_Realloc: realloced a freed pointer"); old_size = block->size; old_size -= (4 + (int)sizeof(memblock_t)); /* see Z_TagMalloc() */ old_ptr = ptr; - Z_Free(ptr); - ptr = Z_TagMalloc(size, 1); + Z_Free (ptr); + ptr = Z_TagMalloc (size, 1); if (!ptr) - Sys_Error("Z_Realloc: failed on allocation of %i bytes", size); + Sys_Error ("Z_Realloc: failed on allocation of %i bytes", size); if (ptr != old_ptr) - memmove(ptr, old_ptr, min(old_size, size)); + memmove (ptr, old_ptr, q_min(old_size, size)); if (old_size < size) - memset((byte *)ptr + old_size, 0, size - old_size); + memset ((byte *)ptr + old_size, 0, size - old_size); + + return ptr; +} +char *Z_Strdup (const char *s) +{ + size_t sz = strlen(s) + 1; + char *ptr = (char *) Z_Malloc (sz); + memcpy (ptr, s, sz); return ptr; } + /* ======================== Z_Print @@ -255,16 +262,16 @@ Z_Print void Z_Print (memzone_t *zone) { memblock_t *block; - + Con_Printf ("zone size: %i location: %p\n",mainzone->size,mainzone); - + for (block = zone->blocklist.next ; ; block = block->next) { Con_Printf ("block:%p size:%7i tag:%3i\n", block, block->size, block->tag); - + if (block->next == &zone->blocklist) - break; // all blocks have been hit + break; // all blocks have been hit if ( (byte *)block + block->size != (byte *)block->next) Con_Printf ("ERROR: block size does not touch the next block\n"); if ( block->next->prev != block) @@ -275,37 +282,16 @@ void Z_Print (memzone_t *zone) } -/* -======================== -Z_CheckHeap -======================== -*/ -void Z_CheckHeap (void) -{ - memblock_t *block; - - for (block = mainzone->blocklist.next ; ; block = block->next) - { - if (block->next == &mainzone->blocklist) - break; // all blocks have been hit - if ( (byte *)block + block->size != (byte *)block->next) - Sys_Error ("Z_CheckHeap: block size does not touch the next block\n"); - if ( block->next->prev != block) - Sys_Error ("Z_CheckHeap: next block doesn't have proper back link\n"); - if (!block->tag && !block->next->tag) - Sys_Error ("Z_CheckHeap: two consecutive free blocks\n"); - } -} - //============================================================================ #define HUNK_SENTINAL 0x1df001ed +#define HUNKNAME_LEN 24 typedef struct { int sentinal; int size; // including sizeof(hunk_t), -1 = not allocated - char name[8]; + char name[HUNKNAME_LEN]; } hunk_t; byte *hunk_base; @@ -317,8 +303,6 @@ int hunk_high_used; qboolean hunk_tempactive; int hunk_tempmark; -void R_FreeTextures (void); - /* ============== Hunk_Check @@ -329,12 +313,12 @@ Run consistancy and sentinal trahing checks void Hunk_Check (void) { hunk_t *h; - + for (h = (hunk_t *)hunk_base ; (byte *)h != hunk_base + hunk_low_used ; ) { if (h->sentinal != HUNK_SENTINAL) Sys_Error ("Hunk_Check: trahsed sentinal"); - if (h->size < 16 || h->size + (byte *)h - hunk_base > hunk_size) + if (h->size < (int) sizeof(hunk_t) || h->size + (byte *)h - hunk_base > hunk_size) Sys_Error ("Hunk_Check: bad size"); h = (hunk_t *)((byte *)h+h->size); } @@ -353,13 +337,12 @@ void Hunk_Print (qboolean all) hunk_t *h, *next, *endlow, *starthigh, *endhigh; int count, sum; int totalblocks; - char name[9]; + char name[HUNKNAME_LEN]; - name[8] = 0; count = 0; sum = 0; totalblocks = 0; - + h = (hunk_t *)hunk_base; endlow = (hunk_t *)(hunk_base + hunk_low_used); starthigh = (hunk_t *)(hunk_base + hunk_size - hunk_high_used); @@ -380,7 +363,7 @@ void Hunk_Print (qboolean all) Con_Printf ("-------------------------\n"); h = starthigh; } - + // // if totally done, break // @@ -392,9 +375,9 @@ void Hunk_Print (qboolean all) // if (h->sentinal != HUNK_SENTINAL) Sys_Error ("Hunk_Check: trahsed sentinal"); - if (h->size < 16 || h->size + (byte *)h - hunk_base > hunk_size) + if (h->size < (int) sizeof(hunk_t) || h->size + (byte *)h - hunk_base > hunk_size) Sys_Error ("Hunk_Check: bad size"); - + next = (hunk_t *)((byte *)h+h->size); count++; totalblocks++; @@ -403,15 +386,15 @@ void Hunk_Print (qboolean all) // // print the single block // - memcpy (name, h->name, 8); + memcpy (name, h->name, HUNKNAME_LEN); if (all) Con_Printf ("%8p :%8i %8s\n",h, h->size, name); - + // // print the total // - if (next == endlow || next == endhigh || - strncmp (h->name, next->name, 8) ) + if (next == endlow || next == endhigh || + strncmp (h->name, next->name, HUNKNAME_LEN - 1)) { if (!all) Con_Printf (" :%8i %8s (TOTAL)\n",sum, name); @@ -424,7 +407,17 @@ void Hunk_Print (qboolean all) Con_Printf ("-------------------------\n"); Con_Printf ("%8i total blocks\n", totalblocks); - + +} + +/* +=================== +Hunk_Print_f -- johnfitz -- console command to call hunk_print +=================== +*/ +void Hunk_Print_f (void) +{ + Hunk_Print (false); } /* @@ -432,33 +425,33 @@ void Hunk_Print (qboolean all) Hunk_AllocName =================== */ -void *Hunk_AllocName (int size, char *name) +void *Hunk_AllocName (int size, const char *name) { hunk_t *h; - + #ifdef PARANOID Hunk_Check (); #endif if (size < 0) Sys_Error ("Hunk_Alloc: bad size: %i", size); - + size = sizeof(hunk_t) + ((size+15)&~15); - + if (hunk_size - hunk_low_used - hunk_high_used < size) Sys_Error ("Hunk_Alloc: failed on %i bytes",size); - + h = (hunk_t *)(hunk_base + hunk_low_used); hunk_low_used += size; Cache_FreeLow (hunk_low_used); memset (h, 0, size); - + h->size = size; h->sentinal = HUNK_SENTINAL; - Q_strncpy (h->name, name, 8); - + q_strlcpy (h->name, name, HUNKNAME_LEN); + return (void *)(h+1); } @@ -515,7 +508,7 @@ void Hunk_FreeToHighMark (int mark) Hunk_HighAllocName =================== */ -void *Hunk_HighAllocName (int size, char *name) +void *Hunk_HighAllocName (int size, const char *name) { hunk_t *h; @@ -548,7 +541,7 @@ void *Hunk_HighAllocName (int size, char *name) memset (h, 0, size); h->size = size; h->sentinal = HUNK_SENTINAL; - Q_strncpy (h->name, name, 8); + q_strlcpy (h->name, name, HUNKNAME_LEN); return (void *)(h+1); } @@ -566,13 +559,13 @@ void *Hunk_TempAlloc (int size) void *buf; size = (size+15)&~15; - + if (hunk_tempactive) { Hunk_FreeToHighMark (hunk_tempmark); hunk_tempactive = false; } - + hunk_tempmark = Hunk_HighMark (); buf = Hunk_HighAllocName (size, "temp"); @@ -582,6 +575,14 @@ void *Hunk_TempAlloc (int size) return buf; } +char *Hunk_Strdup (const char *s, const char *name) +{ + size_t sz = strlen(s) + 1; + char *ptr = (char *) Hunk_AllocName (sz, name); + memcpy (ptr, s, sz); + return ptr; +} + /* =============================================================================== @@ -590,13 +591,14 @@ CACHE MEMORY =============================================================================== */ +#define CACHENAME_LEN 32 typedef struct cache_system_s { - int size; // including this header - cache_user_t *user; - char name[16]; + int size; // including this header + cache_user_t *user; + char name[CACHENAME_LEN]; struct cache_system_s *prev, *next; - struct cache_system_s *lru_prev, *lru_next; // for LRU flushing + struct cache_system_s *lru_prev, *lru_next; // for LRU flushing } cache_system_t; cache_system_t *Cache_TryAlloc (int size, qboolean nobottom); @@ -610,25 +612,25 @@ Cache_Move */ void Cache_Move ( cache_system_t *c) { - cache_system_t *new; + cache_system_t *new_cs; // we are clearing up space at the bottom, so only allocate it late - new = Cache_TryAlloc (c->size, true); - if (new) + new_cs = Cache_TryAlloc (c->size, true); + if (new_cs) { // Con_Printf ("cache_move ok\n"); - Q_memcpy ( new+1, c+1, c->size - sizeof(cache_system_t) ); - new->user = c->user; - Q_memcpy (new->name, c->name, sizeof(new->name)); - Cache_Free (c->user); - new->user->data = (void *)(new+1); + Q_memcpy ( new_cs+1, c+1, c->size - sizeof(cache_system_t) ); + new_cs->user = c->user; + Q_memcpy (new_cs->name, c->name, sizeof(new_cs->name)); + Cache_Free (c->user, false); //johnfitz -- added second argument + new_cs->user->data = (void *)(new_cs+1); } else { // Con_Printf ("cache_move failed\n"); - Cache_Free (c->user); // tough luck... + Cache_Free (c->user, true); // tough luck... //johnfitz -- added second argument } } @@ -642,7 +644,7 @@ Throw things out until the hunk can be expanded to the given point void Cache_FreeLow (int new_low_hunk) { cache_system_t *c; - + while (1) { c = cache_head.next; @@ -664,7 +666,7 @@ Throw things out until the hunk can be expanded to the given point void Cache_FreeHigh (int new_high_hunk) { cache_system_t *c, *prev; - + prev = NULL; while (1) { @@ -674,7 +676,7 @@ void Cache_FreeHigh (int new_high_hunk) if ( (byte *)c + c->size <= hunk_base + hunk_size - new_high_hunk) return; // there is space to grow the hunk if (c == prev) - Cache_Free (c->user); // didn't move out of the way + Cache_Free (c->user, true); // didn't move out of the way //johnfitz -- added second argument else { Cache_Move (c); // try to move it @@ -690,7 +692,7 @@ void Cache_UnlinkLRU (cache_system_t *cs) cs->lru_next->lru_prev = cs->lru_prev; cs->lru_prev->lru_next = cs->lru_next; - + cs->lru_prev = cs->lru_next = NULL; } @@ -715,8 +717,8 @@ Size should already include the header and padding */ cache_system_t *Cache_TryAlloc (int size, qboolean nobottom) { - cache_system_t *cs, *new; - + cache_system_t *cs, *new_cs; + // is the cache completely empty? if (!nobottom && cache_head.prev == &cache_head) @@ -724,64 +726,64 @@ cache_system_t *Cache_TryAlloc (int size, qboolean nobottom) if (hunk_size - hunk_high_used - hunk_low_used < size) Sys_Error ("Cache_TryAlloc: %i is greater then free hunk", size); - new = (cache_system_t *) (hunk_base + hunk_low_used); - memset (new, 0, sizeof(*new)); - new->size = size; + new_cs = (cache_system_t *) (hunk_base + hunk_low_used); + memset (new_cs, 0, sizeof(*new_cs)); + new_cs->size = size; - cache_head.prev = cache_head.next = new; - new->prev = new->next = &cache_head; - - Cache_MakeLRU (new); - return new; + cache_head.prev = cache_head.next = new_cs; + new_cs->prev = new_cs->next = &cache_head; + + Cache_MakeLRU (new_cs); + return new_cs; } - + // search from the bottom up for space - new = (cache_system_t *) (hunk_base + hunk_low_used); + new_cs = (cache_system_t *) (hunk_base + hunk_low_used); cs = cache_head.next; - + do { if (!nobottom || cs != cache_head.next) { - if ( (byte *)cs - (byte *)new >= size) + if ( (byte *)cs - (byte *)new_cs >= size) { // found space - memset (new, 0, sizeof(*new)); - new->size = size; - - new->next = cs; - new->prev = cs->prev; - cs->prev->next = new; - cs->prev = new; - - Cache_MakeLRU (new); - - return new; + memset (new_cs, 0, sizeof(*new_cs)); + new_cs->size = size; + + new_cs->next = cs; + new_cs->prev = cs->prev; + cs->prev->next = new_cs; + cs->prev = new_cs; + + Cache_MakeLRU (new_cs); + + return new_cs; } } - // continue looking - new = (cache_system_t *)((byte *)cs + cs->size); + // continue looking + new_cs = (cache_system_t *)((byte *)cs + cs->size); cs = cs->next; } while (cs != &cache_head); - + // try to allocate one at the very end - if ( hunk_base + hunk_size - hunk_high_used - (byte *)new >= size) + if ( hunk_base + hunk_size - hunk_high_used - (byte *)new_cs >= size) { - memset (new, 0, sizeof(*new)); - new->size = size; - - new->next = &cache_head; - new->prev = cache_head.prev; - cache_head.prev->next = new; - cache_head.prev = new; - - Cache_MakeLRU (new); - - return new; + memset (new_cs, 0, sizeof(*new_cs)); + new_cs->size = size; + + new_cs->next = &cache_head; + new_cs->prev = cache_head.prev; + cache_head.prev->next = new_cs; + cache_head.prev = new_cs; + + Cache_MakeLRU (new_cs); + + return new_cs; } - + return NULL; // couldn't allocate } @@ -795,10 +797,9 @@ Throw everything out, so new data will be demand cached void Cache_Flush (void) { while (cache_head.next != &cache_head) - Cache_Free ( cache_head.next->user ); // reclaim the space + Cache_Free ( cache_head.next->user, true); // reclaim the space //johnfitz -- added second argument } - /* ============ Cache_Print @@ -826,16 +827,6 @@ void Cache_Report (void) Con_DPrintf ("%4.1f megabyte data cache\n", (hunk_size - hunk_high_used - hunk_low_used) / (float)(1024*1024) ); } -/* -============ -Cache_Compact - -============ -*/ -void Cache_Compact (void) -{ -} - /* ============ Cache_Init @@ -857,7 +848,7 @@ Cache_Free Frees the memory and removes it from the LRU list ============== */ -void Cache_Free (cache_user_t *c) +void Cache_Free (cache_user_t *c, qboolean freetextures) //johnfitz -- added second argument { cache_system_t *cs; @@ -873,6 +864,12 @@ void Cache_Free (cache_user_t *c) c->data = NULL; Cache_UnlinkLRU (cs); + + //johnfitz -- if a model becomes uncached, free the gltextures. This only works + //becuase the cache_user_t is the last component of the qmodel_t struct. Should + //fail harmlessly if *c is actually part of an sfx_t struct. I FEEL DIRTY + if (freetextures) + TexMgr_FreeTexturesForOwner ((qmodel_t *)(c + 1) - 1); } @@ -894,7 +891,7 @@ void *Cache_Check (cache_user_t *c) // move to head of LRU Cache_UnlinkLRU (cs); Cache_MakeLRU (cs); - + return c->data; } @@ -904,43 +901,62 @@ void *Cache_Check (cache_user_t *c) Cache_Alloc ============== */ -void *Cache_Alloc (cache_user_t *c, int size, char *name) +void *Cache_Alloc (cache_user_t *c, int size, const char *name) { cache_system_t *cs; if (c->data) Sys_Error ("Cache_Alloc: allready allocated"); - + if (size <= 0) Sys_Error ("Cache_Alloc: size %i", size); size = (size + sizeof(cache_system_t) + 15) & ~15; -// find memory for it +// find memory for it while (1) { cs = Cache_TryAlloc (size, false); if (cs) { - strncpy (cs->name, name, sizeof(cs->name)-1); + q_strlcpy (cs->name, name, CACHENAME_LEN); c->data = (void *)(cs+1); cs->user = c; break; } - + // free the least recently used cahedat if (cache_head.lru_prev == &cache_head) - Sys_Error ("Cache_Alloc: out of memory"); - // not enough memory at all - Cache_Free ( cache_head.lru_prev->user ); - } - + Sys_Error ("Cache_Alloc: out of memory"); // not enough memory at all + + Cache_Free (cache_head.lru_prev->user, true); //johnfitz -- added second argument + } + return Cache_Check (c); } //============================================================================ +static void Memory_InitZone (memzone_t *zone, int size) +{ + memblock_t *block; + +// set the entire zone to one free block + + zone->blocklist.next = zone->blocklist.prev = block = + (memblock_t *)( (byte *)zone + sizeof(memzone_t) ); + zone->blocklist.tag = 1; // in use block + zone->blocklist.id = 0; + zone->blocklist.size = 0; + zone->rover = block; + + block->prev = block->next = &zone->blocklist; + block->tag = 0; // free block + block->id = ZONEID; + block->size = size - sizeof(memzone_t); +} + /* ======================== Memory_Init @@ -951,11 +967,11 @@ void Memory_Init (void *buf, int size) int p; int zonesize = DYNAMIC_SIZE; - hunk_base = buf; + hunk_base = (byte *) buf; hunk_size = size; hunk_low_used = 0; hunk_high_used = 0; - + Cache_Init (); p = COM_CheckParm ("-zone"); if (p) @@ -965,7 +981,9 @@ void Memory_Init (void *buf, int size) else Sys_Error ("Memory_Init: you must specify a size in KB after -zone"); } - mainzone = Hunk_AllocName (zonesize, "zone" ); - Z_ClearZone (mainzone, zonesize); + mainzone = (memzone_t *) Hunk_AllocName (zonesize, "zone" ); + Memory_InitZone (mainzone, zonesize); + + Cmd_AddCommand ("hunk_print", Hunk_Print_f); //johnfitz } diff --git a/engine/code/zone.h b/engine/Quake/zone.h similarity index 82% rename from engine/code/zone.h rename to engine/Quake/zone.h index 0c4dffd..393e322 100644 --- a/engine/code/zone.h +++ b/engine/Quake/zone.h @@ -1,5 +1,7 @@ /* -Copyright (C) 1996-1997 Id Software, Inc. +Copyright (C) 1996-2001 Id Software, Inc. +Copyright (C) 2002-2009 John Fitzgibbons and others +Copyright (C) 2010-2014 QuakeSpasm developers This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -8,7 +10,7 @@ of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. @@ -17,6 +19,10 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +#ifndef __ZZONE_H +#define __ZZONE_H + /* memory allocation @@ -87,17 +93,13 @@ void Memory_Init (void *buf, int size); void Z_Free (void *ptr); void *Z_Malloc (int size); // returns 0 filled memory -void *Z_TagMalloc (int size, int tag); void *Z_Realloc (void *ptr, int size); - -void Z_DumpHeap (void); -void Z_CheckHeap (void); -int Z_FreeMemory (void); +char *Z_Strdup (const char *s); void *Hunk_Alloc (int size); // returns 0 filled memory -void *Hunk_AllocName (int size, char *name); - -void *Hunk_HighAllocName (int size, char *name); +void *Hunk_AllocName (int size, const char *name); +void *Hunk_HighAllocName (int size, const char *name); +char *Hunk_Strdup (const char *s, const char *name); int Hunk_LowMark (void); void Hunk_FreeToLowMark (int mark); @@ -120,13 +122,13 @@ void *Cache_Check (cache_user_t *c); // returns the cached data, and moves to the head of the LRU list // if present, otherwise returns NULL -void Cache_Free (cache_user_t *c); +void Cache_Free (cache_user_t *c, qboolean freetextures); //johnfitz -- added second argument -void *Cache_Alloc (cache_user_t *c, int size, char *name); +void *Cache_Alloc (cache_user_t *c, int size, const char *name); // Returns NULL if all purgable data was tossed and there still // wasn't enough room. void Cache_Report (void); - +#endif /* __ZZONE_H */ diff --git a/engine/Quakespasm-Music.txt b/engine/Quakespasm-Music.txt new file mode 100644 index 0000000..5f4a717 --- /dev/null +++ b/engine/Quakespasm-Music.txt @@ -0,0 +1,90 @@ +QuakeSpasm supports ogg, mp3 and wav external music files to be played +instead of cd music. What you should do is simple: + +1. Use your favorite cd-ripper application and rip your quake cdrom + audio tracks, convert them to ogg or mp3 so they occupy less space, + like track02.ogg, track03.ogg, etc. + + Note #1: There is no such thing as track01: the first tracks of + original Quake and the mission pack cdroms are always data + tracks. + + Note #2: Since the Quake cdrom audio tracks are pre-emphasized, you + should de-emphasize them during or after ripping to make + them sound right. (thanks to Sander van Dijk for this note) + +2. Go into your quake installation directory and create a new directory + id1/music (for windows users id1\music). + +3. If you have the Scourge of Armagon mission pack, then create another + directory hipnotic/music . If you have the Dissolution of Eternity + then create another directory rogue/music . + +4. Take the ripped music files from step1, place them under id1/music. + If you have the mission packs, repeat step1 for the mission packs, + too, and place the ripped music files under hipnotic/music for the + first mission pack or under rogue/music for the second mission pack. + +5. All are ready to go: When a level starts, the engine will first try + playing the necessary cdaudio track and if it doesn't find the cdrom + it will use the ripped music files instead. + + +New console commands: +--------------------- +- music + Start playing the requested music file. + Example: music mymusic1 + + Notice that you don't have to type the file extension: The requested + music will be searched with ogg, mp3, and then with a wav extension, + automatically. + + If you do specify the file extension, like "music mymusic1.wav", then + it will honor your wish and try only the given type: this is good for + testing/comparing the same music in different formats. + +- music_stop + Stops the playing music + +- music_pause + Pauses the playing music + +- music_resume + Resumes playing the music if it was paused + +- music_loop 1 + Makes the background music to loop (default behavior) + +- music_loop 0 + Makes the background music to play once and then stop + +New cvars: +------------------------- +- bgm_extmusic (0 or 1): Disable or enable playback of external music + files instead of cdaudio. default is 1 (enabled). + +New command line options: +------------------------- +- -noextmusic: Disables the playback of external music files instead of + cdaudio. + +Music files in PAK files: +------------------------- +PAK-contained music files are fully supported. + +Music file directories: +------------------------- +- The music files are always searched under the "music" subdirectory of + a game. + +Music file search order: +------------------------- +The engine can handle multiple audio formats. The map-dictated music, +i.e. the ripped cd music, is always searched by the order of searchpath +priority: the file from the searchpath with the highest priority is +chosen, because it is most likely the one from our own game directory +itself. This way, if a mod has track02 as a mp3 or wav, which is below +track02.ogg in the music_handler order, the mp3 or wav will still have +priority over track02.ogg from the id1 game directory. + diff --git a/engine/Quakespasm.html b/engine/Quakespasm.html new file mode 100644 index 0000000..66f0a81 --- /dev/null +++ b/engine/Quakespasm.html @@ -0,0 +1,750 @@ + + + + + QuakeSpasm + + +

QuakeSpasm

+ +

+

+

+
+

+

Page last edited: Sep. 2019

+ +

+

1. About

+ +

+

2. Downloads

+ +

+

3. Hints

+ + +

+

4. Compiling and Installation

+ + +

+

5. Known Bugs

+ +

+

6. Changes

+ + +

+

7. Todo

+ +

+

8. Copyright

+ +

+

9. Contact

+ +

+

10. Links

+ + +
+

1. About

+ + +

+QuakeSpasm +is a modern, cross-platform Quake 1 engine based on +FitzQuake.

+

It includes support for 64 bit CPUs and custom music playback, a new +sound driver, some graphical niceities, and numerous bug-fixes and other improvements.

+

Quakespasm utilizes either the SDL or SDL2 frameworks, so choose which one works best for you. +SDL is probably less buggy, but SDL2 has nicer features and smoother mouse input - though no CD support.

+ +

2. Downloads

+ + +

+

+

+ + +

3. Hints

+ + +

Visit the +FitzQuake homepage for a full run-down of the engine's commands and variables.

+

+

    +
  • To disable some changes, use "quakespasm -fitz" +
  • +
  • Quakespasm's custom data is stored in "quakespasm.pak". Install this file alongside your id1 directory to enable the custom console background and other minor features. +
  • +
  • For different sound backend drivers use "SDL_AUDIODRIVER=DRIVER ./quakespasm" +, where DRIVER may be alsa, dsp, pulse, esd ... +
  • +
  • Shift+Escape draws the Console.
  • +
  • From the console, use UP to browse the command line history and +TAB to autocomplete command and map names.
  • +
  • There is currently no CD Music volume support and SDL2 doesn't support CD audio. cd_sdl.c needs replacing with cd_linux.c, cd_bsd.c etc..
  • +
  • In windows, alternative CD drives are accessible by "quakespasm -cddev F" (for example) +
  • +
  • Quakespasm allows loading new games (mods) on the fly with "game GAMENAME {-quoth/hipnotic/rogue}" +
  • +
  • Use "quakespasm -condebug" to save console log to "qconsole.log". SDL2 builds no longer generate stdout.txt/stderr.txt.
  • +
+

+

3.1 Music Playback +

+ +

Quakespasm can play various external music formats, including MP3, OGG and FLAC. +

    +
  • Tracks should be named like "track02.ogg", "track03.ogg" ... (there is no track01) and placed into "Quake/id1/music".
  • +
  • Unix users may need some extra libraries installed: "libmad" or "libmpg123" for MP3, and "libogg" and "libvorbis" for OGG.
  • +
  • As of 0.90.0, music is played back at 44100 Hz by default with no need to adjust "-sndspeed".
  • +
  • Use the "-noextmusic" option to disable this feature.
  • +
  • See +Quakespasm-Music.txt for more details.
  • +
+

+ +

3.2 Controller Support +

+ +

The SDL2 variant of Quakespasm supports Xbox 360 style game controllers.

+

The default configuration uses the left analog stick for movement and the right for looking.

+

If your controller doesn't work you can try placing +this file in your Quake directory, it is a community-maintained database that adds support for more controllers to SDL2.

+ +

Cvars

+ +

+

    +
  • joy_deadzone - Fraction of the stick travel to be deadzone, between 0 and 1. Default 0.175.
  • +
  • joy_deadzone_trigger - Fraction of trigger range required to register a button press on the analog triggers, between 0 and 1. Default 0.2.
  • +
  • joy_sensitivity_yaw/pitch - Max angular speed in degrees/second when looking. Defaults are 300 for yaw (turning left/right) and 150 for pitch (up/down).
  • +
  • joy_exponent - For the look stick, the stick displacement (between 0 and 1) is raised to this power. Default is 3. A value of 1 would give a linear relationship between stick displacement and fraction of the maximum angular speed.
  • +
  • joy_invert - Set to 1 to invert the vertical axis of the look stick.
  • +
  • joy_swapmovelook - Set to 1 to swap the left and right analog stick functions. Default 0, move on the left stick, look on the right stick.
  • +
  • joy_enable - Set to 0 to disable controller support. Default 1.
  • +
+

+ +

Buttons

+ +

Some of the controller buttons are hardcoded to allow navigating the menu:

+

+

    +
  • Back - alias for TAB
  • +
  • Start - alias for ESC
  • +
  • DPad, analog sticks - mapped to arrow keys
  • +
  • A Button - alias for ENTER in menus
  • +
  • B Button - alias for ESC in menus
  • +
+

+

These buttons can be bound normally:

+

+

    +
  • LTRIGGER - Left trigger
  • +
  • RTRIGGER - Right trigger
  • +
  • LSHOULDER - Left shoulder button
  • +
  • RSHOULDER - Right shoulder button
  • +
  • LTHUMB - Clicking the left thumbstick
  • +
  • RTHUMB - Clicking the right thumbstick
  • +
  • ABUTTON
  • +
  • BBUTTON
  • +
  • XBUTTON
  • +
  • YBUTTON
  • +
+ +quakespasm.pak contains a default.cfg which has been updated to give some default bindings. L/R shoulder buttons are bound to weapon switching, and L/R triggers are jump and attack.

+

The controller support started as Jeremiah Sypult's implementation in Quakespasm-Rift and also uses ideas and code from LordHavoc (DarkPlaces).

+ +

4. Compiling and Installation

+ + +

Quakespasm's (optional) custom data is now stored in the file quakespasm.pak. This file should be placed alongside your quakespasm binary and id1 directory.

+

To checkout the latest version of QuakeSpasm, do: +svn co svn://svn.code.sf.net/p/quakespasm/code/trunk/quakespasm

+

4.1 Linux/Unix +

+ +

After extracting the source tarball, browse the Makefile and edit the music streaming options, then +


+
+make
+cp quakespasm /usr/local/games/quake (for example)
+
+
+
+Compile time options include +
    +
  • make DO_USERDIRS=1 to include user directories support
  • +
  • make DEBUG=1 for debugging
  • +
  • make SDL_CONFIG=/PATH/TO/SDL-CONFIG for unusual SDL installations
  • +
  • make USE_SDL2=1 to compile against SDL2 instead of SDL-1.2
  • +
+

+

Streaming music playback requires "libmad" or "libmpg123" for MP3, and "libogg" and "libvorbis" for OGG files.

+

The project can also be built with Codeblocks (project files included).

+

4.2 Windows +

+ +

The QuakeSpasm developers cross-compile windows binaries using +MinGW and +Mingw-w64.

+

The project can also be built using Visual Studio 2005 (or newer).

+

4.3 Mac OS X +

+ +

A Quakespasm App (including program launcher and update framework) can be made using the Xcode template found in the MacOSX directory.

+

Alternatively, have a look at Makefile.darwin for more instructions on building from a console.

+

5. Known Bugs

+ +

Brightness issues should be fixed with GLSL gamma in 0.90.1, if your system supports OpenGL 2. For reference on older systems:
+ +Some versions of Xorg and SDL have brightness issues.
+Try setting "export SDL_VIDEO_X11_NODIRECTCOLOR=1", or if you have Xorg >= 7.5 and broken brightness, +these patched libSDL binaries may help. +

+

+

6. Changes

+ + + +

6.1 Changes in 0.93.2 +

+ +

+

    +
  • Lightmaps are now dynamically allocated (from QSS), and BLOCK_WIDTH/HEIGHT raised from 128 to 256.
  • +
  • Fixed several uncheked limits that would crash the Slayer's Testaments mod (sf.net bug #33).
  • +
  • Raised MAXALIASTRIS from 2048 to 4096, so that the Slayer's Testaments mod works.
  • +
  • Fixed 'pants' and 'shirt' types so that those textures load correctly on platforms where char is unsigned by default (sf.net bug #28).
  • +
  • Windows audio: WASAPI-enabled SDL2 dlls function properly now.
  • +
  • Update the third-party libraries. Other fixes/cleanups.
  • +
+

+

6.2 Changes in 0.93.1 +

+ +

+

    +
  • Fixed a fog regression which was introduced in 0.93.0.
  • +
  • Fixed a crash (buffer overflow) with invalid vis data.
  • +
  • Fixed buttons crushing players in 64-bit builds.
  • +
  • Change controller movement to use cubic easing by default; added "joy_exponent_move" cvar.
  • +
  • config.cfg is no longer written in case of a Sys_Error.
  • +
  • Fixed Opus encoded cd tracks not being recognized as ripped tracks.
  • +
  • Update the third-party libraries. Other fixes/cleanups.
  • +
+

+

6.3 Changes in 0.93.0 +

+ +

+

    +
  • Raise default "joy_deadzone_trigger" cvar to 0.2.
  • +
  • Raise console buffer size to 1MB.
  • +
  • Raise MAX_STATIC_ENTITIES from 512 to 4096.
  • +
  • Raise MAX_STACK_DEPTH from 32 to 64.
  • +
  • Raise command buffer size from 8K to 256K to support large configs.
  • +
  • Remove MAX_EFRAGS and MAX_MAP_LEAFS limits.
  • +
  • Remove "Loadgame buffer overflow" limit, which could happen when loading DP or QSS saves.
  • +
  • Adjust "exceeds standard limit of" debug warnings to include the actual QS limit.
  • +
  • Change "game" command to now exec quake.rc.
  • +
  • Change "games" / "mods" commands to list all subdirectories.
  • +
  • Restore vid_refreshrate from fitzquake-0.85 for SDL2 builds.
  • +
  • Alpha-masked model support. (MF_HOLEY: 0x4000).
  • +
  • Invalid skin index now draws skin 0 (WinQuake behaviour) instead of blue checkerboard.
  • +
  • Change default screenshot format to png. The 'screenshot' command now supports optional format (tga, png or jpg) and quality (1-100) arguments.
  • +
  • Revert "always run" changes from 0.85.9 and move the QuakeSpasm customizations to a new "cl_alwaysrun" cvar: Set to 1 in order to scale forward/side/up speed by "cl_movespeedkey" (usually 2), and to make "speedkey" act as "slowkey".
  • +
  • Change the "always run" menu option to offer three choices: +
      +
    • off (cl_alwaysrun 0, cl_forwardspeed 200, cl_backspeed 200)
    • +
    • vanilla (cl_alwaysrun 0, cl_forwardspeed 400, cl_backspeed 400)
    • +
    • quakespasm (cl_alwaysrun 1, cl_forwardspeed 200, cl_backspeed 200)
    • +
    +
  • +
  • New "r_scale" cvar. Set to 2, 3, or 4 to render the view at 1/2, 1/3, or 1/4 resolution.
  • +
  • New "r_viewmodel_quake" cvar. Set to 1 for WinQuake gun position (from MarkV).
  • +
  • New "find" / "apropos" command, searches for commands/cvar names for the given substring (from Spike).
  • +
  • New "randmap" command for loading a random map.
  • +
  • New "gl_cshiftpercent_contents", "gl_cshiftpercent_damage", "gl_cshiftpercent_bonus", "gl_cshiftpercent_powerup" cvars for tuning the strength of specic view blends.
  • +
  • GL2 renderer: use a GLSL shader for world faces. Fixes reports of integrated+discrete GPU laptops having inconsistent fog rendering.
  • +
  • Fix macOS startup delay (avoid calling gethostbyname() for ".local" hostnames).
  • +
  • Fix memory corruption in PF_lightstyle with out of bounds lightstyles.
  • +
  • Fix crash in BoundPoly with polygons extending beyond +/-9999.
  • +
  • Fix QS window to stay on the current monitor when changing video modes (SDL2 only).
  • +
  • Fix possible freeze in SV_TouchLinks regardless of what QC does in the touch function.
  • +
  • Fix for maps with empty strings for vector keys (e.g. "origin"); don't read uninitialized memory.
  • +
  • Support for Open Watcom compiler.
  • +
  • Update the third-party libraries.
  • +
+

+

6.4 Changes in 0.92.1 +

+ +

+

    +
  • Fixed large menu scale factors (was broken in 0.92.0).
  • +
  • Fixed PAUSE key (was broken in 0.92.0).
  • +
  • Updated some of the third-party libraries.
  • +
+

+

6.5 Changes in 0.92.0 +

+ +

+

    +
  • SDL2 Game Controller support.
  • +
  • Contrast support with new "contrast" cvar, behaving the same as MarkV. It may be a useful alternative to the existing gamma control for laptops in a bright environment, etc. Raising contrast gives less of a gray/washed out look than raising gamma, but at a disadvantage: colors near white get clipped to white.
  • +
  • RMQ protocol (999) support, adapted from RMQEngine.
  • +
  • New "-protocol x" command line option. Accepted values for 'x' are 15 (NetQuake), 666 (FitzQuake, default), and 999 (RMQ).
  • +
  • New "setpos" console command.
  • +
  • New "vid_borderless" cvar for getting a borderless window.
  • +
  • Increased MAX_MAP_LEAFS from 65535 to 70000 and MAX_LIGHTMAPS from 256 to 512 in order to handle the oms3 map pack.
  • +
  • Server edicts are now allocated using malloc instead of allocating on the hunk.
  • +
  • gl_clear now defaults to 1.
  • +
  • Fix items falling out of the world on oms3.bsp on SSE builds.
  • +
  • Worked around an OSX 10.6 driver bug when using FSAA, which was leading to an unplayable HOM effect on the rest of the screen.
  • +
  • Fix wrong trace endpoint from the tracepos console command.
  • +
  • Updated some of the third-party libraries. Other fixes/clean-ups.
  • +
+

+

6.6 Changes in 0.91.0 +

+ + +

Bugfixes

+ +

+

    +
  • Fix unwanted fog mode change upon video restart.
  • +
  • Work around Intel 855 bug in status bar drawing with "r_oldwater 0" and "scr_sbaralpha 0".
  • +
  • Fix an obscure GLSL bug where changing gamma would result in the screen turning to noise.
  • +
  • Fix GLSL gamma causing the tiled screen border to turn white when "sizedown" is used.
  • +
  • Fix an alias model VBO renderer bug where a model not precached during map start wouldn't be drawn.
  • +
  • Fix the order of OpenGL context creation and window creation in SDL2 video.
  • +
  • Fix a calling convention issue in windows DPI awareness function pointers.
  • +
  • Fix a random texture recoloring after video mode change.
  • +
  • Fix a liquid turning to garbage after several video mode changes and "r_oldwater 0".
  • +
  • Fix a wrong alpha-sorting bug introduced in 0.90.1.
  • +
  • Fix "flush" command not reloading mdl's from disk (bug introduced in 0.90.1).
  • +
  • Prevent a possible buffer overflow in Cbuf_Execute (old Q1/Q2 bug).
  • +
  • Prevent a possible vulnerability in MSG_ReadString (old Q1/Q2 bug).
  • +
+

+ +

Visual improvements

+ +

+

    +
  • New cvars r_lavaalpha, r_slimealpha, r_telealpha for fine-tuning specific liquid opacities (from DirectQ/RMQEngine, non-archived, default to 0), and new worldspawn keys _wateralpha, _lavaalpha, _slimealpha, _telealpha, _skyfog (unique to Quakespasm, similar to the behaviour of the "fog" worldspawn key).
  • +
  • GLSL gamma is now supported on older hardware without NPOT extension.
  • +
+

+ +

Interface improvements

+ +

+

    +
  • New r_pos command to show player position.
  • +
  • NaN detection in traceline with "developer 1" set now warns instead of errors.
  • +
+

+ +

Code cleanup / Other

+ +

+

    +
  • Update third-party libraries.
  • +
+

+ +

Raised limits

+ +

+

    +
  • Default max_edicts 8192 (was 2048) and no longer saved to config.cfg.
  • +
  • Default heapsize 256 MB (was 64 MB).
  • +
  • Default zone 4 MB (was 384 KB).
  • +
  • Raised MAX_SFX to 1024 (was 512).
  • +
+

+

6.7 Changes in 0.90.1 +

+ + +

Bugfixes

+ +

+

    +
  • Fix dynamic light artifact where changing lightmap are rendered one frame late (bug introduced in 0.90.0).
  • +
  • Fix texture memory leak when changing video modes with SDL2.
  • +
  • Fix rare incorrect mdl lighting on 64-bit builds. +(details here.)
  • +
  • Fix fullbrights turning black after "kill" command (bug introduced in 0.90.0).
  • +
  • Clear all fog values on map change to prevent colored fog carrying over to jam3_tronyn.bsp.
  • +
  • Allow loading saves with } character in quoted strings, fixes issue with retrojam1_skacky.bsp.
  • +
  • Fix viewmodel not lerping on extended-limit maps.
  • +
  • Fix crash on out-of-bounds skin number.
  • +
+

+ +

Performance

+ +

+

    +
  • Use multithreaded OpenGL on OS X for better performance.
  • +
  • New, faster mdl renderer using GLSL. Disable with "-noglslalias".
  • +
+

+ +

Visual improvements

+ +

+

    +
  • New gamma correction implementation using GLSL. Fixes all known gamma issues (affecting the full display, persisting after quitting, or darkening the screen on OS X). Disable with "-noglslgamma".
  • +
  • Use high-quality water by default (r_oldwater 0).
  • +
  • Shadows use stencil buffer to avoid overlapping artifacts (from MarkV.)
  • +
  • r_noshadow_list cvar added (from MarkV.)
  • +
+

+ +

Interface improvements

+ +

+

    +
  • Support pausing demo playback with the "pause" command.
  • +
  • Autocompletion for "game", "record", "playdemo".
  • +
  • Experimental windowed fullscreen mode available with vid_desktopfullscreen 1 (only in SDL2 builds, takes effect upon entering fullscreen mode the next time.)
  • +
  • Silence "exceeded standard limit" messages unless developer cvar is >= 1.
  • +
  • Some spam moved from developer 1 to 2: "can't find tga/lit/ent", "trying to load ent", "bad chunk length", "meshing", "PR_AlocStringSlots: realloc'ing"
  • +
+

+ +

Code cleanup

+ +

+

    +
  • Clean up IDE project files to build on fresh systems.
  • +
  • Update 3rd-party libraries.
  • +
+

+

6.8 Changes in 0.90.0 +

+ +

+

    +
  • Fix issues on Windows systems with DPI scaling.
  • +
  • Unix/Mac user directories support. Disabled by default, 'make DO_USERDIRS=1' to enable it.
  • +
  • SDL2 support. Disabled by default, 'make USE_SDL2=1' to enable it.
  • +
  • Revised keyboard input code.
  • +
  • Revised/improved the 'game' command, i.e. on-the-fly mod changing. It now accepts an optional second argument for mission packs or quoth support i.e. -hipnotic, -rogue, or -quoth. For example, for WarpSpasm: "game warp -quoth"
  • +
  • Command line: "-game {quoth/hipnotic/rogue}" is now treated the same as -quoth, -hipnotic, or -rogue.
  • +
  • Console speed now resolution-independent.
  • +
  • Disabled gl_zfix, which caused glitches and is undesirable for new maps. Replacement .ent files to fix z-fighting for several id1 maps added to quakespasm.pak.
  • +
  • PF_VarString buffer bumped to 1024, avoids truncated centerprints from the 'In The Shadows' mod.
  • +
  • Support for opengl non-power-of-two-textures extension (disable with command line: "-notexturenpot".)
  • +
  • Support for OpenGL vertex buffer objects (VBO, OpenGL 1.5 or newer) for world and brush models (disable with command line: "-novbo".)
  • +
  • Antialiasing (FSAA) support (command line: -fsaa x, where x can be 0, 2, 4, 8).
  • +
  • Fence textures support.
  • +
  • Dynamic light speedup. Speedup loading of tga and pcx external images.
  • +
  • Brush model drawing speedup.
  • +
  • Support for BSP2 and 2PSB map formats.
  • +
  • Support for Opus, FLAC, and tracker music (S3M, IT, UMX, etc.), as compile-time options.
  • +
  • Music and sfx now mixed at 44100 Hz to avoid downsampling music. Low-pass filter applied to the sfx if -sndspeed is 11025 (the default), to preserve the same sound quality as 0.85.9. New -mixspeed option sets the rate for mixing sfx and music, and output to the OS (default 44100), setting it to 11025 reverts to 0.85.9 behaviour. New snd_filterquality cvar, value can be between 1 (emulate OS X resampler) and 5 (emulate Windows resampler), controls the sound of the low-pass filter.
  • +
  • Better Hor+ field of view (FOV) scaling behavior.
  • +
  • Better cross-map demo playback support.
  • +
  • Fix screenshots when screen width isn't a multiple of 4.
  • +
  • Fix a lighting glitch due to floating point precision.
  • +
  • Fix a looping sounds glitch.
  • +
  • Fix a vulnerability in file extension handling. Tighten path handling safety.
  • +
  • Initialize opengl with 24-bit depth buffer at 32 bpp.
  • +
  • Reset all models upon gamedir changes. (Fixes failures with mods using custom content.)
  • +
  • Fix broken behavior upon gamedir changes if -basedir is specified on the command line.
  • +
  • NET_MAXMESSAGE and MAX_MSGLEN limits bumped to 64000.
  • +
  • MAX_EFRAGS bumped to 4096, and MAX_CHANNELS to 1024.
  • +
  • MAX_ENT_LEAFS bumped from 16 to 32 to work around disappearing or flickering brush models in some situations. Also, if an entity is visible from MAX_ENT_LEAFS or more leafs, we now always send it to the client.
  • +
  • Fix cvar cycle command not working sometimes.
  • +
  • Host_Error upon missing models. (Prevents segmentation faults.)
  • +
  • Change sv_aim default value to 1 (i.e. turn off autoaim)
  • +
  • Add 'prev' and 'next' keywords to the 'cd' command.
  • +
  • Work around a linux cdrom issue (playback might not start for a while after a stop).
  • +
  • Quakespasm content customization moved from engine-embedded into a new optional quakespasm.pak file.
  • +
  • Version bumped to 0.90.0 (because Quakespasm has a decent life of it's own)
  • +
  • Other fixes and clean-ups.
  • +
+

+

6.9 Changes in 0.85.9 +

+ +

+

    +
  • Fixes for several undefined behaviors in C code (gcc-4.8 support.)
  • +
  • Implemented Hor+ style field of view (FOV) scaling, useful for widescreen resolutions. Configured by new cvar fov_adapt: set it to 1 and your fov will be scaled automatically according to the resolution. Enabled by default.
  • +
  • Adjusted string buffers for PR_ValueString and friends to fix crashes with excessively long global strings seen in some rude mods.
  • +
  • Toned down warning messages from PF_VarString() a bit.
  • +
  • Fixed Fitzquake's map existence check in changelevel (used to leak file handles which would end up in a Sys_Error() due to consuming all free handles if many maps reside not in pak files.)
  • +
  • Fixes/cleanups in chat mode handling. Client no longer gets stuck in chat mode upon disconnect.
  • +
  • Mouse grab/key_dest fixes and key cleanups.
  • +
  • The "speedkey" now acts as "slowkey" when "always run" is on.
  • +
  • Support for demo recording after connection to server. (thanks to Baker for a patch)
  • +
  • Corner case fixes in COM_Parse() for quoted strings and support for C-style /*..*/ comments.
  • +
  • Changed lightmaps to GL_RGBA instead of GL_RGB.
  • +
  • Better parse for opengl extensions list (from quakeforge.)
  • +
  • Vsync saving/loading fixes.
  • +
  • Fixed pointfile loading.
  • +
  • Multiple cleanups in gl_vidsdl.c.
  • +
  • Opus music decoding support (as an optional patch only.)
  • +
  • Several other minor fixes/cleanups.
  • +
+

+

6.10 Changes in 0.85.8 +

+ +

+

    +
  • Made Quake shareware 1.00 and 1.01 versions to be recognized properly.
  • +
  • Fixed control-character handling in unicode mode. Keyboard input tweaks.
  • +
  • Made the keypad keys to send separate key events in game mode.
  • +
  • Text pasting support from OS clipboard to console. (windows and macosx.)
  • +
  • Support for the Apple (Command) key on macosx.
  • +
  • Fixed increased (more than 32) dynamic lights.
  • +
  • Music playback: Made sure that the file's channels count is supported.
  • +
  • Support for Solaris.
  • +
  • Switched to using libmad instead of libmpg123 for MP3 playback on Mac OS X.
  • +
  • Better support for building the Mac OS X version using a makefile, support for cross-compiling on Linux.
  • +
  • Fixed a minor intermissions glitch.
  • +
  • Increased string buffer size from 256 to 384 for PF_VarString to work around broken mods such as UQC.
  • +
  • Restored original behavior for Quake registered version detection.
  • +
  • Minor demo recording/playback tweaks.
  • +
  • Minor tweaks to the scale menu option.
  • +
  • unbindall before loading stored bindings (configurable by new cvar cfg_unbindall, enabled by default.)
  • +
  • New icon.
  • +
  • Miscellaneous source code cleanups.
  • +
+

+

6.11 Changes in 0.85.7 +

+ +

+

    +
  • Added support for cross-level demo playback
  • +
  • gl_texturemode is reimplemented as a cvar with a callback and the setting is automatically saved to the config
  • +
  • Fixed execution of external files without a newline at the end
  • +
  • Reduced memory usage during reloading of textures
  • +
  • Fixed compilation on GNU/kFreeBSD (Debian bug #657793)
  • +
  • Fixed backspace key on Mac OS X
  • +
  • Disable mouse acceleration in Mac OS X
  • +
  • Worked around recursive calling of the anisotropic filter callback
  • +
  • Console word wrap and long input line fixes
  • +
  • Verified correct compilation by clang (using v3.0)
  • +
  • Several other small changes mostly invisible to the end-user
  • +
+

+

6.12 Changes in 0.85.6 +

+ +

+

    +
  • More work for string buffer safety
  • +
  • Reverted v0.85.5 change of not allowing deathmatch and coop cvars to be set at the same time (was reported for possibility of causing compatibility issues with mods)
  • +
  • Several cleanups/changes in the cvar layer
  • +
  • Minor SDL video fixes.
  • +
+

+

6.13 Changes in 0.85.5 +

+ +

+

    +
  • SDL input driver updated adding native keymap and dead key support to the console
  • +
  • Fixed a crash in net play in maps with extended limits
  • +
  • Verified successful compilation using gcc-4.6.x
  • +
  • Added workaround against GL texture flicker (z fighting), controlled by new cvar 'gl_zfix'
  • +
  • Read video variables early so that a vid_restart isn't necessary after init
  • +
  • mlook and lookspring fixes
  • +
  • Added support for loading external entity files, controlled by new cvar 'external_ents'
  • +
  • Made mp3 playback to allocate system memory instead of zone
  • +
  • Some updates to the progs interpreter code
  • +
  • Fixed r_nolerp_list parsing code of fitzquake
  • +
  • Made sure that deathmatch and coop are not set at the same time
  • +
  • Several code updates from uHexen2 project, several code cleanups.
  • +
+

+

6.14 Changes in 0.85.4 +

+ +

+

    +
  • Implement music (OGG, MP3, WAV) playback
  • +
  • A better fix for the infamous SV_TouchLinks problem, no more hard lockups with maps such as "whiteroom"
  • +
  • Add support for mouse buttons 4 and 5
  • +
  • Fix the "unalias" console command
  • +
  • Restore the "screen size" menu item
  • +
  • Fixed an erroneous protocol check in the server code
  • +
  • Raised the default zone memory size to 384 kb
  • +
  • Raised the default max_edicts from 1024 to 2048
  • +
  • Revised lit file loading, the lit file must be from the same game directory as the map itself or from a searchpath with a higher priority
  • +
  • Fixed rest of the compiler warnings
  • +
  • Other minor sound and cdaudio updates
  • +
+

+

6.15 Changes in 0.85.3 +

+ +

+

    +
  • Fix the "-dedicated" option (thanks Oz) and add platform specific networking code (default) rather than SDL_net
  • +
  • Much needed OSX framework stuff from Kristian
  • +
  • Add a persistent history feature (thanks Baker)
  • +
  • Add a slider for scr_sbaralpha, which now defaults to 0.95 (slightly transparent, allowing for a nicer status bar)
  • +
  • Allow player messages longer than 32 characters
  • +
  • Sockaddr fix for FreeBSD/OSX/etc networking
  • +
  • Connect status bar size to the scale slider
  • +
  • Include an ISNAN (is not-a-number) fix to catch the occassional quake C bug giving traceline problems
  • +
  • Enumerate options menus
  • +
  • Add a "prev weapon" menu item (from Sander)
  • +
  • Small fix to Sound Block/Unblock on win32
  • +
  • Lots of code fixes (some from uhexen2)
  • +
  • Sys_Error calls Host_Shutdown
  • +
  • Added MS Visual Studio support
  • +
  • Add a "-cd" option to let the CD Player work in dedicated mode, and some other CD tweaks.
  • +
+

+ +

6.16 Changes in 0.85.2 +

+ +

+

    +
  • Replace the old "Screen size" slider with a "Scale" slider
  • +
  • Don't constantly open and close condebug log
  • +
  • Heap of C clean-ups
  • +
  • Fix mapname sorting
  • +
  • Alias the "mods" command to "games"
  • +
  • Block/Unblock sound upon focus loss/gain
  • +
  • NAT fix (networking protocol fix)
  • +
  • SDLNet_ResolveHost bug-fix allowing connection to ports other than 26000
  • +
  • Bumped array size of sv_main.c::localmodels from 5 to 6 fixing an old fitzquake-0.85 bug which used to cause segfaults depending on the compiler.
  • +
  • Accept commandline options like "+connect ip:port"
  • +
  • Add OSX Makefile (tested?)
  • +
+

+ +

6.17 Changes in 0.85.1 +

+ +

+

    +
  • 64 bit CPU support
  • +
  • Restructured SDL sound driver
  • +
  • Custom conback
  • +
  • Tweaked the command line completion and added a map/changelevel autocompletion function
  • +
  • Alt+Enter toggles fullscreen
  • +
  • Disable Draw_BeginDisc which causes core dumps when called excessively
  • +
  • Show helpful info on start-up
  • +
  • Include real map name (sv.name) and skill in the status bar
  • +
  • Remove confirm quit dialog
  • +
  • Don't spam the console with PackFile seek requests
  • +
  • Default to window mode
  • +
  • Withdraw console when playing demos
  • +
  • Don't play demos on program init
  • +
  • Default Heapsize is 64meg
  • +
  • Changes to default console alpha, speed
  • +
  • Changes to cvar persistence gl_flashblend (default 0), r_shadow, r_wateralpha, r_dynamic, r_novis
  • +
+

+ + +

7. Todo

+ +

+

    +
  • Add uHexen2's first person camera (and menu item)
  • +
  • Native CD audio support (if desired). cd_sdl.c doesn't have proper volume controls and SDL2 doesn't support CD audio
  • +
+

+ +

8. Copyright

+ +

+

+

+ +

9. Contact

+ +

+

+

+ +

10. Links

+ +

+

+

+ + + diff --git a/engine/Quakespasm.txt b/engine/Quakespasm.txt new file mode 100644 index 0000000..38c73f0 --- /dev/null +++ b/engine/Quakespasm.txt @@ -0,0 +1,1047 @@ + QuakeSpasm + + ____________________________________________________________ + + Table of Contents + + 1. About + 2. Downloads + 3. Hints + 3.1 Music Playback + 3.2 Controller Support + 3.2.1 Cvars + 3.2.2 Buttons + + 4. Compiling and Installation + 4.1 Linux/Unix + 4.2 Windows + 4.3 Mac OS X + + 5. Known Bugs + 6. Changes + 6.1 Changes in 0.93.2 + 6.2 Changes in 0.93.1 + 6.3 Changes in 0.93.0 + 6.4 Changes in 0.92.1 + 6.5 Changes in 0.92.0 + 6.6 Changes in 0.91.0 + 6.5.1 Bugfixes + 6.5.2 Visual improvements + 6.5.3 Interface improvements + 6.5.4 Code cleanup / Other + 6.5.5 Raised limits + 6.7 Changes in 0.90.1 + 6.7.1 Bugfixes + 6.7.2 Performance + 6.7.3 Visual improvements + 6.7.4 Interface improvements + 6.7.5 Code cleanup + 6.8 Changes in 0.90.0 + 6.9 Changes in 0.85.9 + 6.10 Changes in 0.85.8 + 6.11 Changes in 0.85.7 + 6.12 Changes in 0.85.6 + 6.13 Changes in 0.85.5 + 6.14 Changes in 0.85.4 + 6.15 Changes in 0.85.3 + 6.16 Changes in 0.85.2 + 6.17 Changes in 0.85.1 + + 7. Todo + 8. Copyright + 9. Contact + 10. Links + + ______________________________________________________________________ + + + Page last edited: Sep. 2019 + + + 1. About + + QuakeSpasm is a modern, cross- + platform Quake 1 engine based on FitzQuake + . + + It includes support for 64 bit CPUs and custom music playback, a new + sound driver, some graphical niceities, and numerous bug-fixes and + other improvements. + + Quakespasm utilizes either the SDL or SDL2 frameworks, so choose + which one works best for you. SDL is probably less buggy, but SDL2 + has nicer features and smoother mouse input - though no CD support. + + + 2. Downloads + + o Project Downloads: http://quakespasm.sourceforge.net/download.htm + + o Automatic Builds: http://quakespasm.ericwa.com/job/quakespasm-sdl2/ + + + 3. Hints + + Visit the FitzQuake homepage for + a full run-down of the engine's commands and variables. + + o To disable some changes, use "quakespasm -fitz" + + o Quakespasm's custom data is stored in "quakespasm.pak". Install + this file alongside your id1 directory to enable the custom console + background and other minor features. + + o For different sound backend drivers use : + "SDL_AUDIODRIVER=DRIVER ./quakespasm" + where DRIVER may be alsa, dsp, pulse, esd ... + + o Shift+Escape draws the Console. + + o From the console, use UP to browse the command line history and TAB + to autocomplete command and map names. + + o There is currently no CD Music volume support and SDL2 doesn't + support CD audio. cd_sdl.c needs replacing with cd_linux.c, + cd_bsd.c etc.. + + o In windows, alternative CD drives are accessible by + "quakespasm -cddev F" (for example) + + o Quakespasm allows loading new games (mods) on the fly with + "game GAMENAME {-quoth/hipnotic/rogue}" + + o Use "quakespasm -condebug" to save console log to "qconsole.log". + SDL2 builds no longer generate stdout.txt/stderr.txt. + + 3.1. Music Playback + + Quakespasm can play various external music formats, including MP3, OGG + and FLAC. + + o Tracks should be named like "track02.ogg", "track03.ogg" ... (there + is no track01) and placed into "Quake/id1/music". + + o Unix users may need some extra libraries installed: "libmad" or + "libmpg123" for MP3, and "libogg" and "libvorbis" for OGG. + + o As of 0.90.0, music is played back at 44100 Hz by default with no + need to adjust "-sndspeed". + + o Use the "-noextmusic" option to disable this feature. + + o See Quakespasm-Music.txt for more details. + + 3.2. Controller Support + + The SDL2 variant of Quakespasm supports Xbox 360 style game + controllers. + + The default configuration uses the left analog stick for movement and + the right for looking. + + If your controller doesn't work you can try placing this file + https://raw.githubusercontent.com/gabomdq/SDL_GameControllerDB/master/gamecontrollerdb.txt + in your Quake directory, it is a community-maintained database that + adds support for more controllers to SDL2. + + 3.2.1. Cvars + + o joy_deadzone - Fraction of the stick travel to be deadzone, between + 0 and 1. Default 0.175. + + o joy_deadzone_trigger - Fraction of trigger range required to + register a button press on the analog triggers, between 0 and 1. + Default 0.2. + + o joy_sensitivity_yaw/pitch - Max angular speed in degrees/second + when looking. Defaults are 300 for yaw (turning left/right) and 150 + for pitch (up/down). + + o joy_exponent - For the look stick, the stick displacement (between + 0 and 1) is raised to this power. Default is 3. A value of 1 would + give a linear relationship between stick displacement and fraction + of the maximum angular speed. + + o joy_invert - Set to 1 to invert the vertical axis of the look + stick. + + o joy_swapmovelook - Set to 1 to swap the left and right analog stick + functions. Default 0, move on the left stick, look on the right + stick. + + o joy_enable - Set to 0 to disable controller support. Default 1. + + 3.2.2. Buttons + + Some of the controller buttons are hardcoded to allow navigating the + menu: + + o Back - alias for TAB + + o Start - alias for ESC + + o DPad, analog sticks - mapped to arrow keys + + o A Button - alias for ENTER in menus + + o B Button - alias for ESC in menus + + These buttons can be bound normally: + + o LTRIGGER - Left trigger + + o RTRIGGER - Right trigger + + o LSHOULDER - Left shoulder button + + o RSHOULDER - Right shoulder button + + o LTHUMB - Clicking the left thumbstick + + o RTHUMB - Clicking the right thumbstick + + o ABUTTON + + o BBUTTON + + o XBUTTON + + o YBUTTON + + quakespasm.pak contains a default.cfg which has been updated to give + some default bindings. L/R shoulder buttons are bound to weapon + switching, and L/R triggers are jump and attack. + + The controller support started as Jeremiah Sypult's implementation in + Quakespasm-Rift and also uses ideas and code from LordHavoc + (DarkPlaces). + + + 4. Compiling and Installation + + Quakespasm's (optional) custom data is now stored in the file + quakespasm.pak. This file should be placed alongside your quakespasm + binary and id1 directory. + + To checkout the latest version of QuakeSpasm, do: + svn co svn://svn.code.sf.net/p/quakespasm/code/trunk/quakespasm + + 4.1. Linux/Unix + + After extracting the source tarball, browse the Makefile and edit the + music streaming options, then + + ______________________________________________________________________ + make + cp quakespasm /usr/local/games/quake (for example) + ______________________________________________________________________ + + + Compile time options include + + o make DO_USERDIRS=1 to include user directories support + + o make DEBUG=1 for debugging + + o make SDL_CONFIG=/PATH/TO/SDL-CONFIG for unusual SDL installations + + o make USE_SDL2=1 to compile against SDL2 instead of SDL-1.2 + + Streaming music playback requires "libmad" or "libmpg123" for MP3, and + "libogg" and "libvorbis" for OGG files. + + The project can also be built with Codeblocks (project files + included). + + 4.2. Windows + + The QuakeSpasm developers cross-compile windows binaries using MinGW + and Mingw-w64 . + + The project can also be built using Visual Studio 2005 (or newer). + + 4.3. Mac OS X + + A Quakespasm App (including program launcher and update framework) can + be made using the Xcode template found in the MacOSX directory. + + Alternatively, have a look at Makefile.darwin for more instructions on + building from a console. + + + 5. Known Bugs + + Brightness issues should be fixed with GLSL gamma in 0.90.1, if your + system supports OpenGL 2. For reference on older systems: + + Some versions of Xorg and SDL have brightness issues. + Try setting "export SDL_VIDEO_X11_NODIRECTCOLOR=1", or if you have + Xorg >= 7.5 and broken brightness, these patched libSDL binaries may + help. + + o Gamma patched libSDL (i686-linux) + http://sf.net/projects/quakespasm/files/Support%20Files/libSDL_gamma_patched.tgz/download + + o Gamma patched libSDL (x86_64-linux) + http://sf.net/projects/quakespasm/files/Support%20Files/libSDL_gamma_patched-AMD64.tgz/download + + + 6. Changes + + + 6.1. Changes in 0.93.2 + + o Lightmaps are now dynamically allocated (from QSS), and + BLOCK_WIDTH/HEIGHT raised from 128 to 256. + + o Fixed several uncheked limits that would crash the Slayer's + Testaments mod (sf.net bug #33). + + o Raised MAXALIASTRIS from 2048 to 4096, so that the Slayer's + Testaments mod works. + + o Fixed 'pants' and 'shirt' types so that those textures load + correctly on platforms where char is unsigned by default + (sf.net bug #28). + + o Windows audio: WASAPI-enabled SDL2 dlls function properly now. + + o Update the third-party libraries. Other fixes/cleanups. + + + 6.2. Changes in 0.93.1 + + o Fixed a fog regression which was introduced in 0.93.0. + + o Fixed a crash (buffer overflow) with invalid vis data. + + o Fixed buttons crushing players in 64-bit builds. + + o Change controller movement to use cubic easing by default; added + "joy_exponent_move" cvar. + + o config.cfg is no longer written in case of a Sys_Error. + + o Fixed Opus encoded cd tracks not being recognized as ripped tracks. + + o Update the third-party libraries. Other fixes/cleanups. + + + 6.3. Changes in 0.93.0 + + o Raise default "joy_deadzone_trigger" cvar to 0.2. + + o Raise console buffer size to 1MB. + + o Raise MAX_STATIC_ENTITIES from 512 to 4096. + + o Raise MAX_STACK_DEPTH from 32 to 64. + + o Raise command buffer size from 8K to 256K to support large configs. + + o Remove MAX_EFRAGS and MAX_MAP_LEAFS limits. + + o Remove "Loadgame buffer overflow" limit, which could happen when + loading DP or QSS saves. + + o Adjust "exceeds standard limit of" debug warnings to include the + actual QS limit. + + o Change "game" command to now exec quake.rc. + + o Change "games" / "mods" commands to list all subdirectories. + + o Restore vid_refreshrate from fitzquake-0.85 for SDL2 builds. + + o Alpha-masked model support. (MF_HOLEY: 0x4000). + + o Invalid skin index now draws skin 0 (WinQuake behaviour) instead of + blue checkerboard. + + o Change default screenshot format to png. The 'screenshot' command + now supports optional format (tga, png or jpg) and quality (1-100) + arguments. + + o Revert "always run" changes from 0.85.9 and move the QuakeSpasm + customizations to a new "cl_alwaysrun" cvar: Set to 1 in order to + scale forward/side/up speed by "cl_movespeedkey" (usually 2), and + to make "speedkey" act as "slowkey". + + o Change "always run" menu option to offer three choices: + - off (cl_alwaysrun 0, cl_forwardspeed 200, cl_backspeed 200) + - vanilla (cl_alwaysrun 0, cl_forwardspeed 400, cl_backspeed 400) + - quakespasm (cl_alwaysrun 1, cl_forwardspeed 200, cl_backspeed 200) + + o New "r_scale" cvar. Set to 2, 3, or 4 to render the view at 1/2, + 1/3, or 1/4 resolution. + + o New "r_viewmodel_quake" cvar. Set to 1 for WinQuake gun position + (from MarkV). + + o New "find" / "apropos" command, searches for commands/cvar names + for the given substring (from Spike). + + o New "randmap" command for loading a random map. + + o New "gl_cshiftpercent_contents", "gl_cshiftpercent_damage", + "gl_cshiftpercent_bonus", "gl_cshiftpercent_powerup" cvars for + tuning the strength of specic view blends. + + o GL2 renderer: use a GLSL shader for world faces. Fixes reports of + integrated+discrete GPU laptops having inconsistent fog rendering. + + o Fix macOS startup delay (avoid calling gethostbyname() for ".local" + hostnames). + + o Fix memory corruption in PF_lightstyle with out of bounds + lightstyles. + + o Fix crash in BoundPoly with polygons extending beyond +/-9999. + + o Fix QS window to stay on the current monitor when changing video + modes (SDL2 only). + + o Fix possible freeze in SV_TouchLinks regardless of what QC does in + the touch function. + + o Fix for maps with empty strings for vector keys (e.g. "origin"); + don't read uninitialized memory. + + o Support for Open Watcom compiler. + + o Update the third-party libraries. + + + 6.4. Changes in 0.92.1 + + o Fixed large menu scale factors (was broken in 0.92.0). + + o Fixed PAUSE key (was broken in 0.92.0). + + o Updated some of the third-party libraries. + + + 6.5. Changes in 0.92.0 + + o SDL2 Game Controller support. + + o Contrast support with new "contrast" cvar, behaving the same as + MarkV. It may be a useful alternative to the existing gamma control + for laptops in a bright environment, etc. Raising contrast gives + less of a gray/washed out look than raising gamma, but at a + disadvantage: colors near white get clipped to white. + + o RMQ protocol (999) support, adapted from RMQEngine. + + o New "-protocol x" command line option. Accepted values for 'x' are + 15 (NetQuake), 666 (FitzQuake, default), and 999 (RMQ). + + o New "setpos" console command. + + o New "vid_borderless" cvar for getting a borderless window. + + o Increased MAX_MAP_LEAFS from 65535 to 70000 and MAX_LIGHTMAPS from + 256 to 512 in order to handle the oms3 map pack. + + o Server edicts are now allocated using malloc instead of allocating + on the hunk. + + o gl_clear now defaults to 1. + + o Fix items falling out of the world on oms3.bsp on SSE builds. + + o Worked around an OSX 10.6 driver bug when using FSAA, which was + leading to an unplayable HOM effect on the rest of the screen. + + o Fix wrong trace endpoint from the tracepos console command. + + o Updated some of the third-party libraries. Other fixes/clean-ups. + + + 6.6. Changes in 0.91.0 + + 6.6.1. Bugfixes + + o Fix unwanted fog mode change upon video restart. + + o Work around Intel 855 bug in status bar drawing with "r_oldwater 0" + and "scr_sbaralpha 0". + + o Fix an obscure GLSL bug where changing gamma would result in the + screen turning to noise. + + o Fix GLSL gamma causing the tiled screen border to turn white when + "sizedown" is used. + + o Fix an alias model VBO renderer bug where a model not precached + during map start wouldn't be drawn. + + o Fix the order of OpenGL context creation and window creation in + SDL2 video. + + o Fix a calling convention issue in windows DPI awareness function + pointers. + + o Fix a random texture recoloring after video mode change. + + o Fix a liquid turning to garbage after several video mode changes + and "r_oldwater 0". + + o Fix a wrong alpha-sorting bug introduced in 0.90.1. + + o Fix "flush" command not reloading mdl's from disk (bug introduced + in 0.90.1). + + o Prevent a possible buffer overflow in Cbuf_Execute (old Q1/Q2 bug). + + o Prevent a possible vulnerability in MSG_ReadString (old Q1/Q2 bug). + + 6.6.2. Visual improvements + + o New cvars r_lavaalpha, r_slimealpha, r_telealpha for fine-tuning + specific liquid opacities (from DirectQ/RMQEngine, non-archived, + default to 0), and new worldspawn keys _wateralpha, _lavaalpha, + _slimealpha, _telealpha, _skyfog (unique to Quakespasm, similar to + the behaviour of the "fog" worldspawn key). + + o GLSL gamma is now supported on older hardware without NPOT + extension. + + 6.6.3. Interface improvements + + o New r_pos command to show player position. + + o NaN detection in traceline with "developer 1" set now warns instead + of errors. + + 6.6.4. Code cleanup / Other + + o Update third-party libraries. + + 6.6.5. Raised limits + + o Default max_edicts 8192 (was 2048) and no longer saved to + config.cfg. + + o Default heapsize 256 MB (was 64 MB). + + o Default zone 4 MB (was 384 KB). + + o Raised MAX_SFX to 1024 (was 512). + + + 6.7. Changes in 0.90.1 + + 6.7.1. Bugfixes + + o Fix dynamic light artifact where changing lightmap are rendered one + frame late (bug introduced in 0.90.0). + + o Fix texture memory leak when changing video modes with SDL2. + + o Fix rare incorrect mdl lighting on 64-bit builds. (details here: + http://forums.insideqc.com/viewtopic.php?f=3&t=5620) + + o Fix fullbrights turning black after "kill" command (bug introduced + in 0.90.0). + + o Clear all fog values on map change to prevent colored fog carrying + over to jam3_tronyn.bsp. + + o Allow loading saves with } character in quoted strings, fixes issue + with retrojam1_skacky.bsp. + + o Fix viewmodel not lerping on extended-limit maps. + + o Fix crash on out-of-bounds skin number. + + 6.7.2. Performance + + o Use multithreaded OpenGL on OS X for better performance. + + o New, faster mdl renderer using GLSL. Disable with "-noglslalias". + + 6.7.3. Visual improvements + + o New gamma correction implementation using GLSL. Fixes all known + gamma issues (affecting the full display, persisting after + quitting, or darkening the screen on OS X). Disable with + "-noglslgamma". + + o Use high-quality water by default (r_oldwater 0). + + o Shadows use stencil buffer to avoid overlapping artifacts (from + MarkV.) + + o r_noshadow_list cvar added (from MarkV.) + + 6.7.4. Interface improvements + + o Support pausing demo playback with the "pause" command. + + o Autocompletion for "game", "record", "playdemo". + + o Experimental windowed fullscreen mode available with + vid_desktopfullscreen 1 (only in SDL2 builds, takes effect upon + entering fullscreen mode the next time.) + + o Silence "exceeded standard limit" messages unless developer cvar is + >= 1. + + o Some spam moved from developer 1 to 2: "can't find tga/lit/ent", + "trying to load ent", "bad chunk length", "meshing", + "PR_AlocStringSlots: realloc'ing" + + 6.7.5. Code cleanup + + o Clean up IDE project files to build on fresh systems. + + o Update 3rd-party libraries. + + + 6.8. Changes in 0.90.0 + + o Fix issues on Windows systems with DPI scaling. + + o Unix/Mac user directories support. Disabled by default, + 'make DO_USERDIRS=1' to enable it. + + o SDL2 support. Disabled by default, 'make USE_SDL2=1' to enable it. + + o Revised keyboard input code. + + o Revised/improved the 'game' command, i.e. on-the-fly mod changing. + It now accepts an optional second argument for mission packs or + quoth support i.e. -hipnotic, -rogue, or -quoth. For example, for + WarpSpasm: "game warp -quoth" + + o Command line: "-game {quoth/hipnotic/rogue}" is now treated the + same as -quoth, -hipnotic, or -rogue. + + o Console speed now resolution-independent. + + o Disabled gl_zfix, which caused glitches and is undesirable for new + maps. Replacement .ent files to fix z-fighting for several id1 maps + added to quakespasm.pak. + + o PF_VarString buffer bumped to 1024, avoids truncated centerprints + from the 'In The Shadows' mod. + + o Support for opengl non-power-of-two-textures extension (disable + with command line: "-notexturenpot".) + + o Support for OpenGL vertex buffer objects (VBO, OpenGL 1.5 or newer) + for world and brush models (disable with command line: "-novbo".) + + o Antialiasing (FSAA) support (command line: -fsaa x, where x can be + 0, 2, 4, 8). + + o Fence textures support. + + o Dynamic light speedup. Speedup loading of tga and pcx external + images. + + o Brush model drawing speedup. + + o Support for BSP2 and 2PSB map formats. + + o Support for Opus, FLAC, and tracker music (S3M, IT, UMX, etc.), as + compile-time options. + + o Music and sfx now mixed at 44100 Hz to avoid downsampling music. + Low-pass filter applied to the sfx if -sndspeed is 11025 (the + default), to preserve the same sound quality as 0.85.9. New + -mixspeed option sets the rate for mixing sfx and music, and output + to the OS (default 44100), setting it to 11025 reverts to 0.85.9 + behaviour. New snd_filterquality cvar, value can be between 1 + (emulate OS X resampler) and 5 (emulate Windows resampler), + controls the sound of the low-pass filter. + + o Better Hor+ field of view (FOV) scaling behavior. + + o Better cross-map demo playback support. + + o Fix screenshots when screen width isn't a multiple of 4. + + o Fix a lighting glitch due to floating point precision. + + o Fix a looping sounds glitch. + + o Fix a vulnerability in file extension handling. Tighten path + handling safety. + + o Initialize opengl with 24-bit depth buffer at 32 bpp. + + o Reset all models upon gamedir changes. (Fixes failures with mods + using custom content.) + + o Fix broken behavior upon gamedir changes if -basedir is specified + on the command line. + + o NET_MAXMESSAGE and MAX_MSGLEN limits bumped to 64000. + + o MAX_EFRAGS bumped to 4096, and MAX_CHANNELS to 1024. + + o MAX_ENT_LEAFS bumped from 16 to 32 to work around disappearing or + flickering brush models in some situations. Also, if an entity is + visible from MAX_ENT_LEAFS or more leafs, we now always send it to + the client. + + o Fix cvar cycle command not working sometimes. + + o Host_Error upon missing models. (Prevents segmentation faults.) + + o Change sv_aim default value to 1 (i.e. turn off autoaim) + + o Add 'prev' and 'next' keywords to the 'cd' command. + + o Work around a linux cdrom issue (playback might not start for a + while after a stop). + + o Quakespasm content customization moved from engine-embedded into a + new optional quakespasm.pak file. + + o Version bumped to 0.90.0 (because Quakespasm has a decent life of + it's own) + + o Other fixes and clean-ups. + + + 6.9. Changes in 0.85.9 + + o Fixes for several undefined behaviors in C code (gcc-4.8 support.) + + o Implemented Hor+ style field of view (FOV) scaling, useful for + widescreen resolutions. Configured by new cvar fov_adapt: set it to + 1 and your fov will be scaled automatically according to the + resolution. Enabled by default. + + o Adjusted string buffers for PR_ValueString and friends to fix + crashes with excessively long global strings seen in some rude + mods. + + o Toned down warning messages from PF_VarString() a bit. + + o Fixed Fitzquake's map existence check in changelevel (used to leak + file handles which would end up in a Sys_Error() due to consuming + all free handles if many maps reside not in pak files.) + + o Fixes/cleanups in chat mode handling. Client no longer gets stuck + in chat mode upon disconnect. + + o Mouse grab/key_dest fixes and key cleanups. + + o The "speedkey" now acts as "slowkey" when "always run" is on. + + o Support for demo recording after connection to server. (thanks to + Baker for a patch) + + o Corner case fixes in COM_Parse() for quoted strings and support for + C-style /*..*/ comments. + + o Changed lightmaps to GL_RGBA instead of GL_RGB. + + o Better parse for opengl extensions list (from quakeforge.) + + o Vsync saving/loading fixes. + + o Fixed pointfile loading. + + o Multiple cleanups in gl_vidsdl.c. + + o Opus music decoding support (as an optional patch only.) + + o Several other minor fixes/cleanups. + + + 6.10. Changes in 0.85.8 + + o Made Quake shareware 1.00 and 1.01 versions to be recognized + properly. + + o Fixed control-character handling in unicode mode. Keyboard input + tweaks. + + o Made the keypad keys to send separate key events in game mode. + + o Text pasting support from OS clipboard to console. (windows and + macosx.) + + o Support for the Apple (Command) key on macosx. + + o Fixed increased (more than 32) dynamic lights. + + o Music playback: Made sure that the file's channels count is + supported. + + o Support for Solaris. + + o Switched to using libmad instead of libmpg123 for MP3 playback on + Mac OS X. + + o Better support for building the Mac OS X version using a makefile, + support for cross-compiling on Linux. + + o Fixed a minor intermissions glitch. + + o Increased string buffer size from 256 to 384 for PF_VarString to + work around broken mods such as UQC. + + o Restored original behavior for Quake registered version detection. + + o Minor demo recording/playback tweaks. + + o Minor tweaks to the scale menu option. + + o unbindall before loading stored bindings (configurable by new cvar + cfg_unbindall, enabled by default.) + + o New icon. + + o Miscellaneous source code cleanups. + + + 6.11. Changes in 0.85.7 + + o Added support for cross-level demo playback + + o gl_texturemode is reimplemented as a cvar with a callback and the + setting is automatically saved to the config + + o Fixed execution of external files without a newline at the end + + o Reduced memory usage during reloading of textures + + o Fixed compilation on GNU/kFreeBSD (Debian bug #657793) + + o Fixed backspace key on Mac OS X + + o Disable mouse acceleration in Mac OS X + + o Worked around recursive calling of the anisotropic filter callback + + o Console word wrap and long input line fixes + + o Verified correct compilation by clang (using v3.0) + + o Several other small changes mostly invisible to the end-user + + + 6.12. Changes in 0.85.6 + + o More work for string buffer safety + + o Reverted v0.85.5 change of not allowing deathmatch and coop cvars + to be set at the same time (was reported for possibility of causing + compatibility issues with mods) + + o Several cleanups/changes in the cvar layer + + o Minor SDL video fixes. + + + 6.13. Changes in 0.85.5 + + o SDL input driver updated adding native keymap and dead key support + to the console + + o Fixed a crash in net play in maps with extended limits + + o Verified successful compilation using gcc-4.6.x + + o Added workaround against GL texture flicker (z fighting), + controlled by new cvar 'gl_zfix' + + o Read video variables early so that a vid_restart isn't necessary + after init + + o mlook and lookspring fixes + + o Added support for loading external entity files, controlled by new + cvar 'external_ents' + + o Made mp3 playback to allocate system memory instead of zone + + o Some updates to the progs interpreter code + + o Fixed r_nolerp_list parsing code of fitzquake + + o Made sure that deathmatch and coop are not set at the same time + + o Several code updates from uHexen2 project, several code cleanups. + + + 6.14. Changes in 0.85.4 + + o Implement music (OGG, MP3, WAV) playback + + o A better fix for the infamous SV_TouchLinks problem, no more hard + lockups with maps such as "whiteroom" + + o Add support for mouse buttons 4 and 5 + + o Fix the "unalias" console command + + o Restore the "screen size" menu item + + o Fixed an erroneous protocol check in the server code + + o Raised the default zone memory size to 384 kb + + o Raised the default max_edicts from 1024 to 2048 + + o Revised lit file loading, the lit file must be from the same game + directory as the map itself or from a searchpath with a higher + priority + + o Fixed rest of the compiler warnings + + o Other minor sound and cdaudio updates + + + 6.15. Changes in 0.85.3 + + o Fix the "-dedicated" option (thanks Oz) and add platform specific + networking code (default) rather than SDL_net + + o Much needed OSX framework stuff from Kristian + + o Add a persistent history feature (thanks Baker) + + o Add a slider for scr_sbaralpha, which now defaults to 0.95 + (slightly transparent, allowing for a nicer status bar) + + o Allow player messages longer than 32 characters + + o Sockaddr fix for FreeBSD/OSX/etc networking + + o Connect status bar size to the scale slider + + o Include an ISNAN (is not-a-number) fix to catch the occassional + quake C bug giving traceline problems + + o Enumerate options menus + + o Add a "prev weapon" menu item (from Sander) + + o Small fix to Sound Block/Unblock on win32 + + o Lots of code fixes (some from uhexen2) + + o Sys_Error calls Host_Shutdown + + o Added MS Visual Studio support + + o Add a "-cd" option to let the CD Player work in dedicated mode, and + some other CD tweaks. + + + 6.16. Changes in 0.85.2 + + o Replace the old "Screen size" slider with a "Scale" slider + + o Don't constantly open and close condebug log + + o Heap of C clean-ups + + o Fix mapname sorting + + o Alias the "mods" command to "games" + + o Block/Unblock sound upon focus loss/gain + + o NAT fix (networking protocol fix) + + o SDLNet_ResolveHost bug-fix allowing connection to ports other than + 26000 + + o Bumped array size of sv_main.c::localmodels from 5 to 6 fixing an + old fitzquake-0.85 bug which used to cause segfaults depending on + the compiler. + + o Accept commandline options like "+connect ip:port" + + o Add OSX Makefile (tested?) + + + 6.17. Changes in 0.85.1 + + o 64 bit CPU support + + o Restructured SDL sound driver + + o Custom conback + + o Tweaked the command line completion and added a map/changelevel + autocompletion function + + o Alt+Enter toggles fullscreen + + o Disable Draw_BeginDisc which causes core dumps when called + excessively + + o Show helpful info on start-up + + o Include real map name (sv.name) and skill in the status bar + + o Remove confirm quit dialog + + o Don't spam the console with PackFile seek requests + + o Default to window mode + + o Withdraw console when playing demos + + o Don't play demos on program init + + o Default Heapsize is 64meg + + o Changes to default console alpha, speed + + o Changes to cvar persistence gl_flashblend (default 0), r_shadow, + r_wateralpha, r_dynamic, r_novis + + + 7. Todo + + o Add uHexen2's first person camera (and menu item) + + o Native CD audio support (if desired). cd_sdl.c doesn't have proper + volume controls and SDL2 doesn't support CD audio + + + 8. Copyright + + o Quake and Quakespasm are released under the GNU GENERAL PUBLIC + LICENSE Version 2: http://www.gnu.org/licenses/gpl-2.0.html + + o Quakespasm console background image by AAS, released under the + CREATIVE COMMONS PUBLIC LICENSE: + http://creativecommons.org/licenses/by/3.0/legalcode + + + 9. Contact + + o QuakeSpasm Project page: + https://sourceforge.net/projects/quakespasm/ + + o Bug reports: + https://sourceforge.net/p/quakespasm/bugs/ + + o Ozkan + Eric + Sander + + + 10. Links + + o QuakeSpasm Homepage: http://quakespasm.sourceforge.net + + o Downloads: http://quakespasm.sourceforge.net/download.htm + + o FitzQuake Homepage: http://www.celephais.net/fitzquake + + o Func Quakespasm forum: + http://www.celephais.net/board/view_thread.php?id=60452 + + o Inside3D forums: http://forums.insideqc.com diff --git a/engine/README.TXT b/engine/README.TXT deleted file mode 100644 index 132bc4d..0000000 --- a/engine/README.TXT +++ /dev/null @@ -1,60 +0,0 @@ - -This is the complete source code for winquake, glquake, quakeworld, and -glquakeworld. - -The projects have been tested with visual C++ 6.0, but masm is also required -to build the assembly language files. It is possible to change a #define and -build with only C code, but the software rendering versions lose almost half -its speed. The OpenGL versions will not be effected very much. The -gas2masm tool was created to allow us to use the same source for the dos, -linux, and windows versions, but I don't really recommend anyone mess -with the asm code. - -The original dos version of Quake should also be buildable from these -sources, but we didn't bother trying. - -The code is all licensed under the terms of the GPL (gnu public license). -You should read the entire license, but the gist of it is that you can do -anything you want with the code, including sell your new version. The catch -is that if you distribute new binary versions, you are required to make the -entire source code available for free to everyone. - -Our previous code releases have been under licenses that preclude -commercial exploitation, but have no clause forcing sharing of source code. -There have been some unfortunate losses to the community as a result of -mod teams keeping their sources closed (and sometimes losing them). If -you are going to publicly release modified versions of this code, you must -also make source code available. I would encourage teams to even go a step -farther and investigate using public CVS servers for development where -possible. - -The primary intent of this release is for entertainment and educational -purposes, but the GPL does allow commercial exploitation if you obey the -full license. If you want to do something commercial and you just can't bear -to have your source changes released, we could still negotiate a separate -license agreement (for $$$), but I would encourage you to just live with the -GPL. - -All of the Quake data files remain copyrighted and licensed under the -original terms, so you cannot redistribute data from the original game, but if -you do a true total conversion, you can create a standalone game based on -this code. - -I will see about having the license changed on the shareware episode of -quake to allow it to be duplicated more freely (for linux distributions, for -example), but I can't give a timeframe for it. You can still download one of -the original quake demos and use that data with the code, but there are -restrictions on the redistribution of the demo data. - -If you never actually bought a complete version of Quake, you might want -to rummage around in a local software bargain bin for one of the originals, -or perhaps find a copy of the "Quake: the offering" boxed set with both -mission packs. - -Thanks to Dave "Zoid" Kirsh and Robert Duffy for doing the grunt work of -building this release. - -John Carmack -Id Software - - diff --git a/engine/projects/uniquake/gl_uniquake.c b/engine/UniQuake/gl_uniquake.c similarity index 56% rename from engine/projects/uniquake/gl_uniquake.c rename to engine/UniQuake/gl_uniquake.c index f249568..4078d1d 100644 --- a/engine/projects/uniquake/gl_uniquake.c +++ b/engine/UniQuake/gl_uniquake.c @@ -1,18 +1,18 @@ #include "uniquake.h" -#include "../../code/quakedef.h" -#include "../../code/gl_model.h" +#include "../Quake/quakedef.h" +#include "../Quake/gl_model.h" typedef struct unity_glcalls_s { void *target; - int(*UploadAliasModel)(void *target, char *name, aliashdr_t *aliashdr, maliasframedesc_t *frames, trivertx_t **poseVerts, mtriangle_t *triangles, stvert_t *stVerts); + int(*UploadAliasModel)(void *target, const char *name, aliashdr_t *aliashdr, maliasframedesc_t *frames, trivertx_t **poseVerts, mtriangle_t *triangles, stvert_t *stVerts); } unity_glcalls_t; const unity_glcalls_t *unity_glcalls; -int UQ_GL_UploadAliasModel(char *name, aliashdr_t *aliashdr, trivertx_t **poseVerts, mtriangle_t *triangles, stvert_t *stVerts) +int UQ_GL_UploadAliasModel(const char *name, aliashdr_t *aliashdr, trivertx_t **poseVerts, mtriangle_t *triangles, stvert_t *stVerts) { // C# doesn't really understand this idea of a variable-length embedded array of structs, // so we pass along the pointer to the first frame struct which allows us to manually marshal the entire array. diff --git a/engine/UniQuake/sys_uniquake.c b/engine/UniQuake/sys_uniquake.c new file mode 100644 index 0000000..7b4b72f --- /dev/null +++ b/engine/UniQuake/sys_uniquake.c @@ -0,0 +1,118 @@ +#include "uniquake.h" + +#include "../Quake/quakedef.h" + +typedef struct unity_syscalls_s +{ + void *target; + + void(*SysPrint)(void *target, const char *msg); + void(*SysError)(void *target, const char *msg); + void(*SysQuit)(void *target); + double(*SysDoubleTime)(void *target); + + int(*SysFileOpenRead)(void *target, const char *path, int *hndl); + int(*SysFileOpenWrite)(void *target, const char *path); + void(*SysFileClose)(void *target, int handle); + void(*SysFileSeek)(void *target, int handle, int position); + int(*SysFileRead)(void *target, int handle, void *dest, int count); + int(*SysFileWrite)(void *target, int handle, const void *data, int count); + int(*SysFileTime)(void *target, const char *path); + void(*SysMkDir)(void *target, const char *path); +} unity_syscalls_t; + +const unity_syscalls_t *unity_syscalls; + +void Sys_Error(const char *error, ...) +{ + va_list argptr; + char text[1024]; + + va_start(argptr, error); + q_vsnprintf(text, sizeof(text), error, argptr); + va_end(argptr); + + unity_syscalls->SysError(unity_syscalls->target, text); +} + +void Sys_Printf(const char *fmt, ...) +{ + va_list argptr; + char text[1024]; + + va_start(argptr, fmt); + q_vsnprintf(text, sizeof(text), fmt, argptr); + va_end(argptr); + + unity_syscalls->SysPrint(unity_syscalls->target, text); +} + +void Sys_Quit(void) +{ + unity_syscalls->SysQuit(unity_syscalls->target); +} + +double Sys_DoubleTime(void) +{ + return unity_syscalls->SysDoubleTime(unity_syscalls->target); +} + +int Sys_FileOpenRead(const char *path, int *hndl) +{ + return unity_syscalls->SysFileOpenRead(unity_syscalls->target, path, hndl); +} + +int Sys_FileOpenWrite(const char *path) +{ + return unity_syscalls->SysFileOpenWrite(unity_syscalls->target, path); +} + +void Sys_FileClose(int handle) +{ + unity_syscalls->SysFileClose(unity_syscalls->target, handle); +} + +void Sys_FileSeek(int handle, int position) +{ + unity_syscalls->SysFileSeek(unity_syscalls->target, handle, position); +} + +int Sys_FileRead(int handle, void *dest, int count) +{ + return unity_syscalls->SysFileRead(unity_syscalls->target, handle, dest, count); +} + +int Sys_FileWrite(int handle, const void *data, int count) +{ + return unity_syscalls->SysFileWrite(unity_syscalls->target, handle, data, count); +} + +int Sys_FileTime(const char *path) +{ + return unity_syscalls->SysFileTime(unity_syscalls->target, path); +} + +void Sys_mkdir(const char *path) +{ + unity_syscalls->SysMkDir(unity_syscalls->target, path); + + // TODO: handle creation errors + /*if (GetLastError() != ERROR_ALREADY_EXISTS) + Sys_Error("Unable to create directory %s", path);*/ +} + +void Sys_Sleep_New(unsigned long msecs) +{ + // TODO: implement +} + +void Sys_SendKeyEvents_New(void) +{ + // TODO: signal Unity to process input & send commands +} + +const char *Sys_ConsoleInput(void) +{ + // Not implemented: we support neither STDIN nor dedicated servers in UniQuake + return NULL; +} diff --git a/engine/projects/uniquake/uniquake.c b/engine/UniQuake/uniquake.c similarity index 67% rename from engine/projects/uniquake/uniquake.c rename to engine/UniQuake/uniquake.c index a2d33dd..d9e1de0 100644 --- a/engine/projects/uniquake/uniquake.c +++ b/engine/UniQuake/uniquake.c @@ -1,32 +1,45 @@ -#include "uniquake.h" - -#include "../../code/quakedef.h" - -UNIQUAKE_API void UniQuake_SetFmodSystem(FMOD_SYSTEM *system) -{ - fmod_system = system; -} - -UNIQUAKE_API void UniQuake_Init(quakeparms_t *parms, const unity_syscalls_t *syscalls, const unity_glcalls_t *glcalls) -{ - unity_syscalls = syscalls; - unity_glcalls = glcalls; - - COM_InitArgv(parms->argc, parms->argv); - parms->argc = com_argc; - parms->argv = com_argv; - - Host_Init(parms); -} - -UNIQUAKE_API void UniQuake_Update(float deltaTime) -{ - // TODO: limit ticrate when running dedicated server - - Host_Frame(deltaTime); -} - -UNIQUAKE_API void UniQuake_Shutdown() -{ - Host_Shutdown(); -} +#include "uniquake.h" + +#include "../Quake/quakedef.h" + +#if USE_FMOD +UNIQUAKE_API void UniQuake_SetFmodSystem(FMOD_SYSTEM *system) +{ + fmod_system = system; +} +#endif + +UNIQUAKE_API void UniQuake_Init(quakeparms_t *parms, const unity_syscalls_t *syscalls, const unity_glcalls_t *glcalls) +{ + host_parms = parms; + + unity_syscalls = syscalls; + unity_glcalls = glcalls; + + COM_InitArgv(parms->argc, parms->argv); + parms->argc = com_argc; + parms->argv = com_argv; + +#ifdef UQ_SDLREF + Sys_InitSDL(); +#endif + + if (!parms->userdir) + parms->userdir = parms->basedir; // Code elsewhere relies on this + + Host_Init(); +} + +UNIQUAKE_API void UniQuake_Update(float deltaTime) +{ + Host_Frame(deltaTime); +} + +UNIQUAKE_API void UniQuake_Shutdown() +{ + Host_Shutdown(); + +#ifdef UQ_SDLREF + Sys_AtExit(); +#endif +} diff --git a/engine/projects/uniquake/uniquake.h b/engine/UniQuake/uniquake.h similarity index 100% rename from engine/projects/uniquake/uniquake.h rename to engine/UniQuake/uniquake.h diff --git a/engine/Windows/SDL2/BUGS.txt b/engine/Windows/SDL2/BUGS.txt new file mode 100644 index 0000000..a8e6b95 --- /dev/null +++ b/engine/Windows/SDL2/BUGS.txt @@ -0,0 +1,16 @@ + +Bugs are now managed in the SDL bug tracker, here: + + https://bugzilla.libsdl.org/ + +You may report bugs there, and search to see if a given issue has already + been reported, discussed, and maybe even fixed. + + +You may also find help at the SDL forums/mailing list: + + https://discourse.libsdl.org/ + +Bug reports are welcome here, but we really appreciate if you use Bugzilla, as + bugs discussed on the mailing list may be forgotten or missed. + diff --git a/engine/Windows/SDL2/COPYING.txt b/engine/Windows/SDL2/COPYING.txt new file mode 100644 index 0000000..9cdb5f8 --- /dev/null +++ b/engine/Windows/SDL2/COPYING.txt @@ -0,0 +1,20 @@ + +Simple DirectMedia Layer +Copyright (C) 1997-2019 Sam Lantinga + +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any damages +arising from the use of this software. + +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it +freely, subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. + diff --git a/engine/Windows/SDL2/README-SDL.txt b/engine/Windows/SDL2/README-SDL.txt new file mode 100644 index 0000000..8d92955 --- /dev/null +++ b/engine/Windows/SDL2/README-SDL.txt @@ -0,0 +1,13 @@ + +Please distribute this file with the SDL runtime environment: + +The Simple DirectMedia Layer (SDL for short) is a cross-platform library +designed to make it easy to write multi-media software, such as games +and emulators. + +The Simple DirectMedia Layer library source code is available from: +https://www.libsdl.org/ + +This library is distributed under the terms of the zlib license: +http://www.zlib.net/zlib_license.html + diff --git a/engine/Windows/SDL2/README.txt b/engine/Windows/SDL2/README.txt new file mode 100644 index 0000000..431ba0e --- /dev/null +++ b/engine/Windows/SDL2/README.txt @@ -0,0 +1,21 @@ + + Simple DirectMedia Layer + + (SDL) + + Version 2.0 + +--- +https://www.libsdl.org/ + +Simple DirectMedia Layer is a cross-platform development library designed +to provide low level access to audio, keyboard, mouse, joystick, and graphics +hardware via OpenGL and Direct3D. It is used by video playback software, +emulators, and popular games including Valve's award winning catalog +and many Humble Bundle games. + +More extensive documentation is available in the docs directory, starting +with README.md + +Enjoy! + Sam Lantinga (slouken@libsdl.org) diff --git a/engine/Windows/SDL2/WhatsNew.txt b/engine/Windows/SDL2/WhatsNew.txt new file mode 100644 index 0000000..b575991 --- /dev/null +++ b/engine/Windows/SDL2/WhatsNew.txt @@ -0,0 +1,473 @@ + +This is a list of major changes in SDL's version history. + +--------------------------------------------------------------------------- +2.0.11/12: +--------------------------------------------------------------------------- + +General: +* Added SDL_LockTextureToSurface(), similar to SDL_LockTexture() but the locked area is exposed as a SDL surface. + +--------------------------------------------------------------------------- +2.0.10: +--------------------------------------------------------------------------- + +General: +* The SDL_RW* macros have been turned into functions that are available only in 2.0.10 and onward +* Added SDL_SIMDGetAlignment(), SDL_SIMDAlloc(), and SDL_SIMDFree(), to allocate memory aligned for SIMD operations for the current CPU +* Added SDL_RenderDrawPointF(), SDL_RenderDrawPointsF(), SDL_RenderDrawLineF(), SDL_RenderDrawLinesF(), SDL_RenderDrawRectF(), SDL_RenderDrawRectsF(), SDL_RenderFillRectF(), SDL_RenderFillRectsF(), SDL_RenderCopyF(), SDL_RenderCopyExF(), to allow floating point precision in the SDL rendering API. +* Added SDL_GetTouchDeviceType() to get the type of a touch device, which can be a touch screen or a trackpad in relative or absolute coordinate mode. +* The SDL rendering API now uses batched rendering by default, for improved performance +* Added SDL_RenderFlush() to force batched render commands to execute, if you're going to mix SDL rendering with native rendering +* Added the hint SDL_HINT_RENDER_BATCHING to control whether batching should be used for the rendering API. This defaults to "1" if you don't specify what rendering driver to use when creating the renderer. +* Added the hint SDL_HINT_EVENT_LOGGING to enable logging of SDL events for debugging purposes +* Added the hint SDL_HINT_GAMECONTROLLERCONFIG_FILE to specify a file that will be loaded at joystick initialization with game controller bindings +* Added the hint SDL_HINT_MOUSE_TOUCH_EVENTS to control whether SDL will synthesize touch events from mouse events +* Improved handling of malformed WAVE and BMP files, fixing potential security exploits + +Linux: +* Removed the Mir video driver in favor of Wayland + +iOS / tvOS: +* Added support for Xbox and PS4 wireless controllers in iOS 13 and tvOS 13 +* Added support for text input using Bluetooth keyboards + +Android: +* Added low latency audio using OpenSL ES +* Removed SDL_HINT_ANDROID_SEPARATE_MOUSE_AND_TOUCH (replaced by SDL_HINT_MOUSE_TOUCH_EVENTS and SDL_HINT_TOUCH_MOUSE_EVENTS) + SDL_HINT_ANDROID_SEPARATE_MOUSE_AND_TOUCH=1, should be replaced by setting both previous hints to 0. + SDL_HINT_ANDROID_SEPARATE_MOUSE_AND_TOUCH=0, should be replaced by setting both previous hints to 1. +* Added the hint SDL_HINT_ANDROID_BLOCK_ON_PAUSE to set whether the event loop will block itself when the app is paused. + + +--------------------------------------------------------------------------- +2.0.9: +--------------------------------------------------------------------------- + +General: +* Added a new sensor API, initialized by passing SDL_INIT_SENSOR to SDL_Init(), and defined in SDL_sensor.h +* Added an event SDL_SENSORUPDATE which is sent when a sensor is updated +* Added SDL_GetDisplayOrientation() to return the current display orientation +* Added an event SDL_DISPLAYEVENT which is sent when the display orientation changes +* Added HIDAPI joystick drivers for more consistent support for Xbox, PS4 and Nintendo Switch Pro controller support across platforms. (Thanks to Valve for contributing the PS4 and Nintendo Switch Pro controller support) +* Added support for many other popular game controllers +* Added SDL_JoystickGetDevicePlayerIndex(), SDL_JoystickGetPlayerIndex(), and SDL_GameControllerGetPlayerIndex() to get the player index for a controller. For XInput controllers this returns the XInput index for the controller. +* Added SDL_GameControllerRumble() and SDL_JoystickRumble() which allow simple rumble without using the haptics API +* Added SDL_GameControllerMappingForDeviceIndex() to get the mapping for a controller before it's opened +* Added the hint SDL_HINT_MOUSE_DOUBLE_CLICK_TIME to control the mouse double-click time +* Added the hint SDL_HINT_MOUSE_DOUBLE_CLICK_RADIUS to control the mouse double-click radius, in pixels +* Added SDL_HasColorKey() to return whether a surface has a colorkey active +* Added SDL_HasAVX512F() to return whether the CPU has AVX-512F features +* Added SDL_IsTablet() to return whether the application is running on a tablet +* Added SDL_THREAD_PRIORITY_TIME_CRITICAL for threads that must run at the highest priority + +Mac OS X: +* Fixed black screen at start on Mac OS X Mojave + +Linux: +* Added SDL_LinuxSetThreadPriority() to allow adjusting the thread priority of native threads using RealtimeKit if available. + +iOS: +* Fixed Asian IME input + +Android: +* Updated required Android SDK to API 26, to match Google's new App Store requirements +* Added support for wired USB Xbox, PS4, and Nintendo Switch Pro controllers +* Added support for relative mouse mode on Android 7.0 and newer (except where it's broken, on Chromebooks and when in DeX mode with Samsung Experience 9.0) +* Added support for custom mouse cursors on Android 7.0 and newer +* Added the hint SDL_HINT_ANDROID_TRAP_BACK_BUTTON to control whether the back button will back out of the app (the default) or be passed to the application as SDL_SCANCODE_AC_BACK +* Added SDL_AndroidBackButton() to trigger the Android system back button behavior when handling the back button in the application +* Added SDL_IsChromebook() to return whether the app is running in the Chromebook Android runtime +* Added SDL_IsDeXMode() to return whether the app is running while docked in the Samsung DeX + + +--------------------------------------------------------------------------- +2.0.8: +--------------------------------------------------------------------------- + +General: +* Added SDL_fmod() and SDL_log10() +* Each of the SDL math functions now has the corresponding float version +* Added SDL_SetYUVConversionMode() and SDL_GetYUVConversionMode() to control the formula used when converting to and from YUV colorspace. The options are JPEG, BT.601, and BT.709 + +Windows: +* Implemented WASAPI support on Windows UWP and removed the deprecated XAudio2 implementation +* Added resampling support on WASAPI on Windows 7 and above + +Windows UWP: +* Added SDL_WinRTGetDeviceFamily() to find out what type of device your application is running on + +Mac OS X: +* Added support for the Vulkan SDK for Mac: + https://www.lunarg.com/lunarg-releases-vulkan-sdk-1-0-69-0-for-mac/ +* Added support for OpenGL ES using ANGLE when it's available + +Mac OS X / iOS / tvOS: +* Added a Metal 2D render implementation +* Added SDL_RenderGetMetalLayer() and SDL_RenderGetMetalCommandEncoder() to insert your own drawing into SDL rendering when using the Metal implementation + +iOS: +* Added the hint SDL_HINT_IOS_HIDE_HOME_INDICATOR to control whether the home indicator bar on iPhone X should be hidden. This defaults to dimming the indicator for fullscreen applications and showing the indicator for windowed applications. + +iOS / Android: +* Added the hint SDL_HINT_RETURN_KEY_HIDES_IME to control whether the return key on the software keyboard should hide the keyboard or send a key event (the default) + +Android: +* SDL now supports building with Android Studio and Gradle by default, and the old Ant project is available in android-project-ant +* SDL now requires the API 19 SDK to build, but can still target devices down to API 14 (Android 4.0.1) +* Added SDL_IsAndroidTV() to tell whether the application is running on Android TV + +Android / tvOS: +* Added the hint SDL_HINT_TV_REMOTE_AS_JOYSTICK to control whether TV remotes should be listed as joystick devices (the default) or send keyboard events. + +Linux: +* Added the hint SDL_HINT_VIDEO_X11_NET_WM_BYPASS_COMPOSITOR to control whether the X server should skip the compositor for the SDL application. This defaults to "1" +* Added the hint SDL_HINT_VIDEO_DOUBLE_BUFFER to control whether the Raspberry Pi and KMSDRM video drivers should use double or triple buffering (the default) + + +--------------------------------------------------------------------------- +2.0.7: +--------------------------------------------------------------------------- + +General: +* Added audio stream conversion functions: + SDL_NewAudioStream + SDL_AudioStreamPut + SDL_AudioStreamGet + SDL_AudioStreamAvailable + SDL_AudioStreamFlush + SDL_AudioStreamClear + SDL_FreeAudioStream +* Added functions to query and set the SDL memory allocation functions: + SDL_GetMemoryFunctions() + SDL_SetMemoryFunctions() + SDL_GetNumAllocations() +* Added locking functions for multi-threaded access to the joystick and game controller APIs: + SDL_LockJoysticks() + SDL_UnlockJoysticks() +* The following functions are now thread-safe: + SDL_SetEventFilter() + SDL_GetEventFilter() + SDL_AddEventWatch() + SDL_DelEventWatch() + + +General: +--------------------------------------------------------------------------- +2.0.6: +--------------------------------------------------------------------------- + +General: +* Added cross-platform Vulkan graphics support in SDL_vulkan.h + SDL_Vulkan_LoadLibrary() + SDL_Vulkan_GetVkGetInstanceProcAddr() + SDL_Vulkan_GetInstanceExtensions() + SDL_Vulkan_CreateSurface() + SDL_Vulkan_GetDrawableSize() + SDL_Vulkan_UnloadLibrary() + This is all the platform-specific code you need to bring up Vulkan on all SDL platforms. You can look at an example in test/testvulkan.c +* Added SDL_ComposeCustomBlendMode() to create custom blend modes for 2D rendering +* Added SDL_HasNEON() which returns whether the CPU has NEON instruction support +* Added support for many game controllers, including the Nintendo Switch Pro Controller +* Added support for inverted axes and separate axis directions in game controller mappings +* Added functions to return information about a joystick before it's opened: + SDL_JoystickGetDeviceVendor() + SDL_JoystickGetDeviceProduct() + SDL_JoystickGetDeviceProductVersion() + SDL_JoystickGetDeviceType() + SDL_JoystickGetDeviceInstanceID() +* Added functions to return information about an open joystick: + SDL_JoystickGetVendor() + SDL_JoystickGetProduct() + SDL_JoystickGetProductVersion() + SDL_JoystickGetType() + SDL_JoystickGetAxisInitialState() +* Added functions to return information about an open game controller: + SDL_GameControllerGetVendor() + SDL_GameControllerGetProduct() + SDL_GameControllerGetProductVersion() +* Added SDL_GameControllerNumMappings() and SDL_GameControllerMappingForIndex() to be able to enumerate the built-in game controller mappings +* Added SDL_LoadFile() and SDL_LoadFile_RW() to load a file into memory +* Added SDL_DuplicateSurface() to make a copy of a surface +* Added an experimental JACK audio driver +* Implemented non-power-of-two audio resampling, optionally using libsamplerate to perform the resampling +* Added the hint SDL_HINT_AUDIO_RESAMPLING_MODE to control the quality of resampling +* Added the hint SDL_HINT_RENDER_LOGICAL_SIZE_MODE to control the scaling policy for SDL_RenderSetLogicalSize(): + "0" or "letterbox" - Uses letterbox/sidebars to fit the entire rendering on screen (the default) + "1" or "overscan" - Will zoom the rendering so it fills the entire screen, allowing edges to be drawn offscreen +* Added the hints SDL_HINT_MOUSE_NORMAL_SPEED_SCALE and SDL_HINT_MOUSE_RELATIVE_SPEED_SCALE to scale the mouse speed when being read from raw mouse input +* Added the hint SDL_HINT_TOUCH_MOUSE_EVENTS to control whether SDL will synthesize mouse events from touch events + +Windows: +* The new default audio driver on Windows is WASAPI and supports hot-plugging devices and changing the default audio device +* The old XAudio2 audio driver is deprecated and will be removed in the next release +* Added hints SDL_HINT_WINDOWS_INTRESOURCE_ICON and SDL_HINT_WINDOWS_INTRESOURCE_ICON_SMALL to specify a custom icon resource ID for SDL windows +* The hint SDL_HINT_WINDOWS_DISABLE_THREAD_NAMING is now on by default for compatibility with .NET languages and various Windows debuggers +* Updated the GUID format for game controller mappings, older mappings will be automatically converted on load +* Implemented the SDL_WINDOW_ALWAYS_ON_TOP flag on Windows + +Linux: +* Added an experimental KMS/DRM video driver for embedded development + +iOS: +* Added a hint SDL_HINT_AUDIO_CATEGORY to control the audio category, determining whether the phone mute switch affects the audio + +--------------------------------------------------------------------------- +2.0.5: +--------------------------------------------------------------------------- + +General: +* Implemented audio capture support for some platforms +* Added SDL_DequeueAudio() to retrieve audio when buffer queuing is turned on for audio capture +* Added events for dragging and dropping text +* Added events for dragging and dropping multiple items +* By default the click raising a window will not be delivered to the SDL application. You can set the hint SDL_HINT_MOUSE_FOCUS_CLICKTHROUGH to "1" to allow that click through to the window. +* Saving a surface with an alpha channel as a BMP will use a newer BMP format that supports alpha information. You can set the hint SDL_HINT_BMP_SAVE_LEGACY_FORMAT to "1" to use the old format. +* Added SDL_GetHintBoolean() to get the boolean value of a hint +* Added SDL_RenderSetIntegerScale() to set whether to smoothly scale or use integral multiples of the viewport size when scaling the rendering output +* Added SDL_CreateRGBSurfaceWithFormat() and SDL_CreateRGBSurfaceWithFormatFrom() to create an SDL surface with a specific pixel format +* Added SDL_GetDisplayUsableBounds() which returns the area usable for windows. For example, on Mac OS X, this subtracts the area occupied by the menu bar and dock. +* Added SDL_GetWindowBordersSize() which returns the size of the window's borders around the client area +* Added a window event SDL_WINDOWEVENT_HIT_TEST when a window had a hit test that wasn't SDL_HITTEST_NORMAL (e.g. in the title bar or window frame) +* Added SDL_SetWindowResizable() to change whether a window is resizable +* Added SDL_SetWindowOpacity() and SDL_GetWindowOpacity() to affect the window transparency +* Added SDL_SetWindowModalFor() to set a window as modal for another window +* Added support for AUDIO_U16LSB and AUDIO_U16MSB to SDL_MixAudioFormat() +* Fixed flipped images when reading back from target textures when using the OpenGL renderer +* Fixed texture color modulation with SDL_BLENDMODE_NONE when using the OpenGL renderer +* Fixed bug where the alpha value of colorkeys was ignored when blitting in some cases + +Windows: +* Added a hint SDL_HINT_WINDOWS_DISABLE_THREAD_NAMING to prevent SDL from raising a debugger exception to name threads. This exception can cause problems with .NET applications when running under a debugger. +* The hint SDL_HINT_THREAD_STACK_SIZE is now supported on Windows +* Fixed XBox controller triggers automatically being pulled at startup +* The first icon from the executable is used as the default window icon at runtime +* Fixed SDL log messages being printed twice if SDL was built with C library support +* Reset dead keys when the SDL window loses focus, so dead keys pressed in SDL applications don't affect text input into other applications. + +Mac OS X: +* Fixed selecting the dummy video driver +* The caps lock key now generates a pressed event when pressed and a released event when released, instead of a press/release event pair when pressed. +* Fixed mouse wheel events on Mac OS X 10.12 +* The audio driver has been updated to use AVFoundation for better compatibility with newer versions of Mac OS X + +Linux: +* Added support for the Fcitx IME +* Added a window event SDL_WINDOWEVENT_TAKE_FOCUS when a window manager asks the SDL window whether it wants to take focus. +* Refresh rates are now rounded instead of truncated, e.g. 59.94 Hz is rounded up to 60 Hz instead of 59. +* Added initial support for touchscreens on Raspberry Pi + +OpenBSD: +* SDL_GetBasePath() is now implemented on OpenBSD + +iOS: +* Added support for dynamically loaded objects on iOS 8 and newer + +tvOS: +* Added support for Apple TV +* Added a hint SDL_HINT_APPLE_TV_REMOTE_ALLOW_ROTATION to control whether he Apple TV remote's joystick axes will automatically match the rotation of the remote. + +Android: +* Fixed SDL not resizing window when Android screen resolution changes +* Corrected the joystick Z axis reporting for the accelerometer + +Emscripten (running in a web browser): +* Many bug fixes and improvements + + +--------------------------------------------------------------------------- +2.0.4: +--------------------------------------------------------------------------- + +General: +* Added support for web applications using Emscripten, see docs/README-emscripten.md for more information +* Added support for web applications using Native Client (NaCl), see docs/README-nacl.md for more information +* Added an API to queue audio instead of using the audio callback: + SDL_QueueAudio(), SDL_GetQueuedAudioSize(), SDL_ClearQueuedAudio() +* Added events for audio device hot plug support: + SDL_AUDIODEVICEADDED, SDL_AUDIODEVICEREMOVED +* Added SDL_PointInRect() +* Added SDL_HasAVX2() to detect CPUs with AVX2 support +* Added SDL_SetWindowHitTest() to let apps treat parts of their SDL window like traditional window decorations (drag areas, resize areas) +* Added SDL_GetGrabbedWindow() to get the window that currently has input grab, if any +* Added SDL_RenderIsClipEnabled() to tell whether clipping is currently enabled in a renderer +* Added SDL_CaptureMouse() to capture the mouse to get events while the mouse is not in your window +* Added SDL_WarpMouseGlobal() to warp the mouse cursor in global screen space +* Added SDL_GetGlobalMouseState() to get the current mouse state outside of an SDL window +* Added a direction field to mouse wheel events to tell whether they are flipped (natural) or not +* Added GL_CONTEXT_RELEASE_BEHAVIOR GL attribute (maps to [WGL|GLX]_ARB_context_flush_control extension) +* Added EGL_KHR_create_context support to allow OpenGL ES version selection on some platforms +* Added NV12 and NV21 YUV texture support for OpenGL and OpenGL ES 2.0 renderers +* Added a Vivante video driver that is used on various SoC platforms +* Added an event SDL_RENDER_DEVICE_RESET that is sent from the D3D renderers when the D3D device is lost, and from Android's event loop when the GLES context had to be recreated +* Added a hint SDL_HINT_NO_SIGNAL_HANDLERS to disable SDL's built in signal handling +* Added a hint SDL_HINT_THREAD_STACK_SIZE to set the stack size of SDL's threads +* Added SDL_sqrtf(), SDL_tan(), and SDL_tanf() to the stdlib routines +* Improved support for WAV and BMP files with unusual chunks in them +* Renamed SDL_assert_data to SDL_AssertData and SDL_assert_state to SDL_AssertState +* Added a hint SDL_HINT_WINDOW_FRAME_USABLE_WHILE_CURSOR_HIDDEN to prevent window interaction while cursor is hidden +* Added SDL_GetDisplayDPI() to get the DPI information for a display +* Added SDL_JoystickCurrentPowerLevel() to get the battery level of a joystick +* Added SDL_JoystickFromInstanceID(), as a helper function, to get the SDL_Joystick* that an event is referring to. +* Added SDL_GameControllerFromInstanceID(), as a helper function, to get the SDL_GameController* that an event is referring to. + +Windows: +* Added support for Windows Phone 8.1 and Windows 10/UWP (Universal Windows Platform) +* Timer resolution is now 1 ms by default, adjustable with the SDL_HINT_TIMER_RESOLUTION hint +* SDLmain no longer depends on the C runtime, so you can use the same .lib in both Debug and Release builds +* Added SDL_SetWindowsMessageHook() to set a function to be called for every windows message before TranslateMessage() +* Added a hint SDL_HINT_WINDOWS_ENABLE_MESSAGELOOP to control whether SDL_PumpEvents() processes the Windows message loop +* You can distinguish between real mouse and touch events by looking for SDL_TOUCH_MOUSEID in the mouse event "which" field +* SDL_SysWMinfo now contains the window HDC +* Added support for Unicode command line options +* Prevent beeping when Alt-key combos are pressed +* SDL_SetTextInputRect() re-positions the OS-rendered IME +* Added a hint SDL_HINT_WINDOWS_NO_CLOSE_ON_ALT_F4 to prevent generating SDL_WINDOWEVENT_CLOSE events when Alt-F4 is pressed +* Added a hint SDL_HINT_XINPUT_USE_OLD_JOYSTICK_MAPPING to use the old axis and button mapping for XInput devices (deprecated) + +Mac OS X: +* Implemented drag-and-drop support +* Improved joystick hot-plug detection +* The SDL_WINDOWEVENT_EXPOSED window event is triggered in the appropriate situations +* Fixed relative mouse mode when the application loses/regains focus +* Fixed bugs related to transitioning to and from Spaces-aware fullscreen-desktop mode +* Fixed the refresh rate of display modes +* SDL_SysWMInfo is now ARC-compatible +* Added a hint SDL_HINT_MAC_BACKGROUND_APP to prevent forcing the application to become a foreground process + +Linux: +* Enabled building with Mir and Wayland support by default. +* Added IBus IME support +* Added a hint SDL_HINT_IME_INTERNAL_EDITING to control whether IBus should handle text editing internally instead of sending SDL_TEXTEDITING events +* Added a hint SDL_HINT_VIDEO_X11_NET_WM_PING to allow disabling _NET_WM_PING protocol handling in SDL_CreateWindow() +* Added support for multiple audio devices when using Pulseaudio +* Fixed duplicate mouse events when using relative mouse motion + +iOS: +* Added support for iOS 8 +* The SDL_WINDOW_ALLOW_HIGHDPI window flag now enables high-dpi support, and SDL_GL_GetDrawableSize() or SDL_GetRendererOutputSize() gets the window resolution in pixels +* SDL_GetWindowSize() and display mode sizes are in the "DPI-independent points" / "screen coordinates" coordinate space rather than pixels (matches OS X behavior) +* Added native resolution support for the iPhone 6 Plus +* Added support for MFi game controllers +* Added support for the hint SDL_HINT_ACCELEROMETER_AS_JOYSTICK +* Added sRGB OpenGL ES context support on iOS 7+ +* Added support for SDL_DisableScreenSaver(), SDL_EnableScreenSaver() and the hint SDL_HINT_VIDEO_ALLOW_SCREENSAVER +* SDL_SysWMinfo now contains the OpenGL ES framebuffer and color renderbuffer objects used by the window's active GLES view +* Fixed various rotation and orientation issues +* Fixed memory leaks + +Android: +* Added a hint SDL_HINT_ANDROID_SEPARATE_MOUSE_AND_TOUCH to prevent mouse events from being registered as touch events +* Added hints SDL_HINT_ANDROID_APK_EXPANSION_MAIN_FILE_VERSION and SDL_HINT_ANDROID_APK_EXPANSION_PATCH_FILE_VERSION +* Added support for SDL_DisableScreenSaver(), SDL_EnableScreenSaver() and the hint SDL_HINT_VIDEO_ALLOW_SCREENSAVER +* Added support for SDL_ShowMessageBox() and SDL_ShowSimpleMessageBox() + +Raspberry Pi: +* Added support for the Raspberry Pi 2 + + +--------------------------------------------------------------------------- +2.0.3: +--------------------------------------------------------------------------- + +Mac OS X: +* Fixed creating an OpenGL context by default on Mac OS X 10.6 + + +--------------------------------------------------------------------------- +2.0.2: +--------------------------------------------------------------------------- +General: +* Added SDL_GL_ResetAttributes() to reset OpenGL attributes to default values +* Added an API to load a database of game controller mappings from a file: + SDL_GameControllerAddMappingsFromFile(), SDL_GameControllerAddMappingsFromRW() +* Added game controller mappings for the PS4 and OUYA controllers +* Added SDL_GetDefaultAssertionHandler() and SDL_GetAssertionHandler() +* Added SDL_DetachThread() +* Added SDL_HasAVX() to determine if the CPU has AVX features +* Added SDL_vsscanf(), SDL_acos(), and SDL_asin() to the stdlib routines +* EGL can now create/manage OpenGL and OpenGL ES 1.x/2.x contexts, and share + them using SDL_GL_SHARE_WITH_CURRENT_CONTEXT +* Added a field "clicks" to the mouse button event which records whether the event is a single click, double click, etc. +* The screensaver is now disabled by default, and there is a hint SDL_HINT_VIDEO_ALLOW_SCREENSAVER that can change that behavior. +* Added a hint SDL_HINT_MOUSE_RELATIVE_MODE_WARP to specify whether mouse relative mode should be emulated using mouse warping. +* testgl2 does not need to link with libGL anymore +* Added testgles2 test program to demonstrate working with OpenGL ES 2.0 +* Added controllermap test program to visually map a game controller + +Windows: +* Support for OpenGL ES 2.x contexts using either WGL or EGL (natively via + the driver or emulated through ANGLE) +* Added a hint SDL_HINT_VIDEO_WIN_D3DCOMPILER to specify which D3D shader compiler to use for OpenGL ES 2 support through ANGLE +* Added a hint SDL_HINT_VIDEO_WINDOW_SHARE_PIXEL_FORMAT that is useful when creating multiple windows that should share the same OpenGL context. +* Added an event SDL_RENDER_TARGETS_RESET that is sent when D3D9 render targets are reset after the device has been restored. + +Mac OS X: +* Added a hint SDL_HINT_MAC_CTRL_CLICK_EMULATE_RIGHT_CLICK to control whether Ctrl+click should be treated as a right click on Mac OS X. This is off by default. + +Linux: +* Fixed fullscreen and focused behavior when receiving NotifyGrab events +* Added experimental Wayland and Mir support, disabled by default + +Android: +* Joystick support (minimum SDK version required to build SDL is now 12, + the required runtime version remains at 10, but on such devices joystick + support won't be available). +* Hotplugging support for joysticks +* Added a hint SDL_HINT_ACCELEROMETER_AS_JOYSTICK to control whether the accelerometer should be listed as a 3 axis joystick, which it will by default. + + +--------------------------------------------------------------------------- +2.0.1: +--------------------------------------------------------------------------- + +General: +* Added an API to get common filesystem paths in SDL_filesystem.h: + SDL_GetBasePath(), SDL_GetPrefPath() +* Added an API to do optimized YV12 and IYUV texture updates: + SDL_UpdateYUVTexture() +* Added an API to get the amount of RAM on the system: + SDL_GetSystemRAM() +* Added a macro to perform timestamp comparisons with SDL_GetTicks(): + SDL_TICKS_PASSED() +* Dramatically improved OpenGL ES 2.0 rendering performance +* Added OpenGL attribute SDL_GL_FRAMEBUFFER_SRGB_CAPABLE + +Windows: +* Created a static library configuration for the Visual Studio 2010 project +* Added a hint to create the Direct3D device with support for multi-threading: + SDL_HINT_RENDER_DIRECT3D_THREADSAFE +* Added a function to get the D3D9 adapter index for a display: + SDL_Direct3D9GetAdapterIndex() +* Added a function to get the D3D9 device for a D3D9 renderer: + SDL_RenderGetD3D9Device() +* Fixed building SDL with the mingw32 toolchain (mingw-w64 is preferred) +* Fixed crash when using two XInput controllers at the same time +* Fixed detecting a mixture of XInput and DirectInput controllers +* Fixed clearing a D3D render target larger than the window +* Improved support for format specifiers in SDL_snprintf() + +Mac OS X: +* Added support for retina displays: + Create your window with the SDL_WINDOW_ALLOW_HIGHDPI flag, and then use SDL_GL_GetDrawableSize() to find the actual drawable size. You are responsible for scaling mouse and drawing coordinates appropriately. +* Fixed mouse warping in fullscreen mode +* Right mouse click is emulated by holding the Ctrl key while left clicking + +Linux: +* Fixed float audio support with the PulseAudio driver +* Fixed missing line endpoints in the OpenGL renderer on some drivers +* X11 symbols are no longer defined to avoid collisions when linking statically + +iOS: +* Fixed status bar visibility on iOS 7 +* Flipped the accelerometer Y axis to match expected values + +Android: +IMPORTANT: You MUST get the updated SDLActivity.java to match C code +* Moved EGL initialization to native code +* Fixed the accelerometer axis rotation relative to the device rotation +* Fixed race conditions when handling the EGL context on pause/resume +* Touch devices are available for enumeration immediately after init + +Raspberry Pi: +* Added support for the Raspberry Pi, see README-raspberrypi.txt for details diff --git a/engine/Windows/SDL2/bin/sdl2-config b/engine/Windows/SDL2/bin/sdl2-config new file mode 100644 index 0000000..737d36f --- /dev/null +++ b/engine/Windows/SDL2/bin/sdl2-config @@ -0,0 +1,57 @@ +#!/bin/sh + +prefix=/opt/cross_sdl2 +exec_prefix=${prefix} +exec_prefix_set=no +lib_suffix= + +usage="\ +Usage: $0 [--prefix[=DIR]] [--exec-prefix[=DIR]] [--version] [--cflags] [--lib-suffix=SUFFIX] [--libs]" + +if test $# -eq 0; then + echo "${usage}" 1>&2 + exit 1 +fi + +while test $# -gt 0; do + case "$1" in + -*=*) optarg=`echo "$1" | sed 's/[-_a-zA-Z0-9]*=//'` ;; + *) optarg= ;; + esac + + case $1 in + --prefix=*) + prefix=$optarg + if test $exec_prefix_set = no ; then + exec_prefix=$optarg + fi + ;; + --prefix) + echo $prefix + ;; + --exec-prefix=*) + exec_prefix=$optarg + exec_prefix_set=yes + ;; + --exec-prefix) + echo $exec_prefix + ;; + --lib-suffix=*) + lib_suffix=$optarg + ;; + --version) + echo 2.0.11 + ;; + --cflags) + echo -I${prefix}/include -Dmain=SDL_main + ;; + --libs) + echo -L${exec_prefix}/lib${lib_suffix} -lmingw32 -lSDL2main -lSDL2 -mwindows + ;; + *) + echo "${usage}" 1>&2 + exit 1 + ;; + esac + shift +done diff --git a/engine/Windows/SDL2/include/SDL.h b/engine/Windows/SDL2/include/SDL.h new file mode 100644 index 0000000..e432939 --- /dev/null +++ b/engine/Windows/SDL2/include/SDL.h @@ -0,0 +1,136 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2019 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL.h + * + * Main include header for the SDL library + */ + + +#ifndef SDL_h_ +#define SDL_h_ + +#include "SDL_main.h" +#include "SDL_stdinc.h" +#include "SDL_assert.h" +#include "SDL_atomic.h" +#include "SDL_audio.h" +#include "SDL_clipboard.h" +#include "SDL_cpuinfo.h" +#include "SDL_endian.h" +#include "SDL_error.h" +#include "SDL_events.h" +#include "SDL_filesystem.h" +#include "SDL_gamecontroller.h" +#include "SDL_haptic.h" +#include "SDL_hints.h" +#include "SDL_joystick.h" +#include "SDL_loadso.h" +#include "SDL_log.h" +#include "SDL_messagebox.h" +#include "SDL_metal.h" +#include "SDL_mutex.h" +#include "SDL_power.h" +#include "SDL_render.h" +#include "SDL_rwops.h" +#include "SDL_sensor.h" +#include "SDL_shape.h" +#include "SDL_system.h" +#include "SDL_thread.h" +#include "SDL_timer.h" +#include "SDL_version.h" +#include "SDL_video.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/* As of version 0.5, SDL is loaded dynamically into the application */ + +/** + * \name SDL_INIT_* + * + * These are the flags which may be passed to SDL_Init(). You should + * specify the subsystems which you will be using in your application. + */ +/* @{ */ +#define SDL_INIT_TIMER 0x00000001u +#define SDL_INIT_AUDIO 0x00000010u +#define SDL_INIT_VIDEO 0x00000020u /**< SDL_INIT_VIDEO implies SDL_INIT_EVENTS */ +#define SDL_INIT_JOYSTICK 0x00000200u /**< SDL_INIT_JOYSTICK implies SDL_INIT_EVENTS */ +#define SDL_INIT_HAPTIC 0x00001000u +#define SDL_INIT_GAMECONTROLLER 0x00002000u /**< SDL_INIT_GAMECONTROLLER implies SDL_INIT_JOYSTICK */ +#define SDL_INIT_EVENTS 0x00004000u +#define SDL_INIT_SENSOR 0x00008000u +#define SDL_INIT_NOPARACHUTE 0x00100000u /**< compatibility; this flag is ignored. */ +#define SDL_INIT_EVERYTHING ( \ + SDL_INIT_TIMER | SDL_INIT_AUDIO | SDL_INIT_VIDEO | SDL_INIT_EVENTS | \ + SDL_INIT_JOYSTICK | SDL_INIT_HAPTIC | SDL_INIT_GAMECONTROLLER | SDL_INIT_SENSOR \ + ) +/* @} */ + +/** + * This function initializes the subsystems specified by \c flags + */ +extern DECLSPEC int SDLCALL SDL_Init(Uint32 flags); + +/** + * This function initializes specific SDL subsystems + * + * Subsystem initialization is ref-counted, you must call + * SDL_QuitSubSystem() for each SDL_InitSubSystem() to correctly + * shutdown a subsystem manually (or call SDL_Quit() to force shutdown). + * If a subsystem is already loaded then this call will + * increase the ref-count and return. + */ +extern DECLSPEC int SDLCALL SDL_InitSubSystem(Uint32 flags); + +/** + * This function cleans up specific SDL subsystems + */ +extern DECLSPEC void SDLCALL SDL_QuitSubSystem(Uint32 flags); + +/** + * This function returns a mask of the specified subsystems which have + * previously been initialized. + * + * If \c flags is 0, it returns a mask of all initialized subsystems. + */ +extern DECLSPEC Uint32 SDLCALL SDL_WasInit(Uint32 flags); + +/** + * This function cleans up all initialized subsystems. You should + * call it upon all exit conditions. + */ +extern DECLSPEC void SDLCALL SDL_Quit(void); + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/engine/Windows/SDL2/include/SDL_assert.h b/engine/Windows/SDL2/include/SDL_assert.h new file mode 100644 index 0000000..8baecb6 --- /dev/null +++ b/engine/Windows/SDL2/include/SDL_assert.h @@ -0,0 +1,291 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2019 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef SDL_assert_h_ +#define SDL_assert_h_ + +#include "SDL_config.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef SDL_ASSERT_LEVEL +#ifdef SDL_DEFAULT_ASSERT_LEVEL +#define SDL_ASSERT_LEVEL SDL_DEFAULT_ASSERT_LEVEL +#elif defined(_DEBUG) || defined(DEBUG) || \ + (defined(__GNUC__) && !defined(__OPTIMIZE__)) +#define SDL_ASSERT_LEVEL 2 +#else +#define SDL_ASSERT_LEVEL 1 +#endif +#endif /* SDL_ASSERT_LEVEL */ + +/* +These are macros and not first class functions so that the debugger breaks +on the assertion line and not in some random guts of SDL, and so each +assert can have unique static variables associated with it. +*/ + +#if defined(_MSC_VER) +/* Don't include intrin.h here because it contains C++ code */ + extern void __cdecl __debugbreak(void); + #define SDL_TriggerBreakpoint() __debugbreak() +#elif ( (!defined(__NACL__)) && ((defined(__GNUC__) || defined(__clang__)) && (defined(__i386__) || defined(__x86_64__))) ) + #define SDL_TriggerBreakpoint() __asm__ __volatile__ ( "int $3\n\t" ) +#elif defined(__386__) && defined(__WATCOMC__) + #define SDL_TriggerBreakpoint() { _asm { int 0x03 } } +#elif defined(HAVE_SIGNAL_H) && !defined(__WATCOMC__) + #include + #define SDL_TriggerBreakpoint() raise(SIGTRAP) +#else + /* How do we trigger breakpoints on this platform? */ + #define SDL_TriggerBreakpoint() +#endif + +#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 supports __func__ as a standard. */ +# define SDL_FUNCTION __func__ +#elif ((__GNUC__ >= 2) || defined(_MSC_VER) || defined (__WATCOMC__)) +# define SDL_FUNCTION __FUNCTION__ +#else +# define SDL_FUNCTION "???" +#endif +#define SDL_FILE __FILE__ +#define SDL_LINE __LINE__ + +/* +sizeof (x) makes the compiler still parse the expression even without +assertions enabled, so the code is always checked at compile time, but +doesn't actually generate code for it, so there are no side effects or +expensive checks at run time, just the constant size of what x WOULD be, +which presumably gets optimized out as unused. +This also solves the problem of... + + int somevalue = blah(); + SDL_assert(somevalue == 1); + +...which would cause compiles to complain that somevalue is unused if we +disable assertions. +*/ + +/* "while (0,0)" fools Microsoft's compiler's /W4 warning level into thinking + this condition isn't constant. And looks like an owl's face! */ +#ifdef _MSC_VER /* stupid /W4 warnings. */ +#define SDL_NULL_WHILE_LOOP_CONDITION (0,0) +#else +#define SDL_NULL_WHILE_LOOP_CONDITION (0) +#endif + +#define SDL_disabled_assert(condition) \ + do { (void) sizeof ((condition)); } while (SDL_NULL_WHILE_LOOP_CONDITION) + +typedef enum +{ + SDL_ASSERTION_RETRY, /**< Retry the assert immediately. */ + SDL_ASSERTION_BREAK, /**< Make the debugger trigger a breakpoint. */ + SDL_ASSERTION_ABORT, /**< Terminate the program. */ + SDL_ASSERTION_IGNORE, /**< Ignore the assert. */ + SDL_ASSERTION_ALWAYS_IGNORE /**< Ignore the assert from now on. */ +} SDL_AssertState; + +typedef struct SDL_AssertData +{ + int always_ignore; + unsigned int trigger_count; + const char *condition; + const char *filename; + int linenum; + const char *function; + const struct SDL_AssertData *next; +} SDL_AssertData; + +#if (SDL_ASSERT_LEVEL > 0) + +/* Never call this directly. Use the SDL_assert* macros. */ +extern DECLSPEC SDL_AssertState SDLCALL SDL_ReportAssertion(SDL_AssertData *, + const char *, + const char *, int) +#if defined(__clang__) +#if __has_feature(attribute_analyzer_noreturn) +/* this tells Clang's static analysis that we're a custom assert function, + and that the analyzer should assume the condition was always true past this + SDL_assert test. */ + __attribute__((analyzer_noreturn)) +#endif +#endif +; + +/* the do {} while(0) avoids dangling else problems: + if (x) SDL_assert(y); else blah(); + ... without the do/while, the "else" could attach to this macro's "if". + We try to handle just the minimum we need here in a macro...the loop, + the static vars, and break points. The heavy lifting is handled in + SDL_ReportAssertion(), in SDL_assert.c. +*/ +#define SDL_enabled_assert(condition) \ + do { \ + while ( !(condition) ) { \ + static struct SDL_AssertData sdl_assert_data = { \ + 0, 0, #condition, 0, 0, 0, 0 \ + }; \ + const SDL_AssertState sdl_assert_state = SDL_ReportAssertion(&sdl_assert_data, SDL_FUNCTION, SDL_FILE, SDL_LINE); \ + if (sdl_assert_state == SDL_ASSERTION_RETRY) { \ + continue; /* go again. */ \ + } else if (sdl_assert_state == SDL_ASSERTION_BREAK) { \ + SDL_TriggerBreakpoint(); \ + } \ + break; /* not retrying. */ \ + } \ + } while (SDL_NULL_WHILE_LOOP_CONDITION) + +#endif /* enabled assertions support code */ + +/* Enable various levels of assertions. */ +#if SDL_ASSERT_LEVEL == 0 /* assertions disabled */ +# define SDL_assert(condition) SDL_disabled_assert(condition) +# define SDL_assert_release(condition) SDL_disabled_assert(condition) +# define SDL_assert_paranoid(condition) SDL_disabled_assert(condition) +#elif SDL_ASSERT_LEVEL == 1 /* release settings. */ +# define SDL_assert(condition) SDL_disabled_assert(condition) +# define SDL_assert_release(condition) SDL_enabled_assert(condition) +# define SDL_assert_paranoid(condition) SDL_disabled_assert(condition) +#elif SDL_ASSERT_LEVEL == 2 /* normal settings. */ +# define SDL_assert(condition) SDL_enabled_assert(condition) +# define SDL_assert_release(condition) SDL_enabled_assert(condition) +# define SDL_assert_paranoid(condition) SDL_disabled_assert(condition) +#elif SDL_ASSERT_LEVEL == 3 /* paranoid settings. */ +# define SDL_assert(condition) SDL_enabled_assert(condition) +# define SDL_assert_release(condition) SDL_enabled_assert(condition) +# define SDL_assert_paranoid(condition) SDL_enabled_assert(condition) +#else +# error Unknown assertion level. +#endif + +/* this assertion is never disabled at any level. */ +#define SDL_assert_always(condition) SDL_enabled_assert(condition) + + +typedef SDL_AssertState (SDLCALL *SDL_AssertionHandler)( + const SDL_AssertData* data, void* userdata); + +/** + * \brief Set an application-defined assertion handler. + * + * This allows an app to show its own assertion UI and/or force the + * response to an assertion failure. If the app doesn't provide this, SDL + * will try to do the right thing, popping up a system-specific GUI dialog, + * and probably minimizing any fullscreen windows. + * + * This callback may fire from any thread, but it runs wrapped in a mutex, so + * it will only fire from one thread at a time. + * + * Setting the callback to NULL restores SDL's original internal handler. + * + * This callback is NOT reset to SDL's internal handler upon SDL_Quit()! + * + * Return SDL_AssertState value of how to handle the assertion failure. + * + * \param handler Callback function, called when an assertion fails. + * \param userdata A pointer passed to the callback as-is. + */ +extern DECLSPEC void SDLCALL SDL_SetAssertionHandler( + SDL_AssertionHandler handler, + void *userdata); + +/** + * \brief Get the default assertion handler. + * + * This returns the function pointer that is called by default when an + * assertion is triggered. This is an internal function provided by SDL, + * that is used for assertions when SDL_SetAssertionHandler() hasn't been + * used to provide a different function. + * + * \return The default SDL_AssertionHandler that is called when an assert triggers. + */ +extern DECLSPEC SDL_AssertionHandler SDLCALL SDL_GetDefaultAssertionHandler(void); + +/** + * \brief Get the current assertion handler. + * + * This returns the function pointer that is called when an assertion is + * triggered. This is either the value last passed to + * SDL_SetAssertionHandler(), or if no application-specified function is + * set, is equivalent to calling SDL_GetDefaultAssertionHandler(). + * + * \param puserdata Pointer to a void*, which will store the "userdata" + * pointer that was passed to SDL_SetAssertionHandler(). + * This value will always be NULL for the default handler. + * If you don't care about this data, it is safe to pass + * a NULL pointer to this function to ignore it. + * \return The SDL_AssertionHandler that is called when an assert triggers. + */ +extern DECLSPEC SDL_AssertionHandler SDLCALL SDL_GetAssertionHandler(void **puserdata); + +/** + * \brief Get a list of all assertion failures. + * + * Get all assertions triggered since last call to SDL_ResetAssertionReport(), + * or the start of the program. + * + * The proper way to examine this data looks something like this: + * + * + * const SDL_AssertData *item = SDL_GetAssertionReport(); + * while (item) { + * printf("'%s', %s (%s:%d), triggered %u times, always ignore: %s.\\n", + * item->condition, item->function, item->filename, + * item->linenum, item->trigger_count, + * item->always_ignore ? "yes" : "no"); + * item = item->next; + * } + * + * + * \return List of all assertions. + * \sa SDL_ResetAssertionReport + */ +extern DECLSPEC const SDL_AssertData * SDLCALL SDL_GetAssertionReport(void); + +/** + * \brief Reset the list of all assertion failures. + * + * Reset list of all assertions triggered. + * + * \sa SDL_GetAssertionReport + */ +extern DECLSPEC void SDLCALL SDL_ResetAssertionReport(void); + + +/* these had wrong naming conventions until 2.0.4. Please update your app! */ +#define SDL_assert_state SDL_AssertState +#define SDL_assert_data SDL_AssertData + + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_assert_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/engine/Windows/SDL2/include/SDL_atomic.h b/engine/Windows/SDL2/include/SDL_atomic.h new file mode 100644 index 0000000..deee35f --- /dev/null +++ b/engine/Windows/SDL2/include/SDL_atomic.h @@ -0,0 +1,295 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2019 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_atomic.h + * + * Atomic operations. + * + * IMPORTANT: + * If you are not an expert in concurrent lockless programming, you should + * only be using the atomic lock and reference counting functions in this + * file. In all other cases you should be protecting your data structures + * with full mutexes. + * + * The list of "safe" functions to use are: + * SDL_AtomicLock() + * SDL_AtomicUnlock() + * SDL_AtomicIncRef() + * SDL_AtomicDecRef() + * + * Seriously, here be dragons! + * ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + * + * You can find out a little more about lockless programming and the + * subtle issues that can arise here: + * http://msdn.microsoft.com/en-us/library/ee418650%28v=vs.85%29.aspx + * + * There's also lots of good information here: + * http://www.1024cores.net/home/lock-free-algorithms + * http://preshing.com/ + * + * These operations may or may not actually be implemented using + * processor specific atomic operations. When possible they are + * implemented as true processor specific atomic operations. When that + * is not possible the are implemented using locks that *do* use the + * available atomic operations. + * + * All of the atomic operations that modify memory are full memory barriers. + */ + +#ifndef SDL_atomic_h_ +#define SDL_atomic_h_ + +#include "SDL_stdinc.h" +#include "SDL_platform.h" + +#include "begin_code.h" + +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \name SDL AtomicLock + * + * The atomic locks are efficient spinlocks using CPU instructions, + * but are vulnerable to starvation and can spin forever if a thread + * holding a lock has been terminated. For this reason you should + * minimize the code executed inside an atomic lock and never do + * expensive things like API or system calls while holding them. + * + * The atomic locks are not safe to lock recursively. + * + * Porting Note: + * The spin lock functions and type are required and can not be + * emulated because they are used in the atomic emulation code. + */ +/* @{ */ + +typedef int SDL_SpinLock; + +/** + * \brief Try to lock a spin lock by setting it to a non-zero value. + * + * \param lock Points to the lock. + * + * \return SDL_TRUE if the lock succeeded, SDL_FALSE if the lock is already held. + */ +extern DECLSPEC SDL_bool SDLCALL SDL_AtomicTryLock(SDL_SpinLock *lock); + +/** + * \brief Lock a spin lock by setting it to a non-zero value. + * + * \param lock Points to the lock. + */ +extern DECLSPEC void SDLCALL SDL_AtomicLock(SDL_SpinLock *lock); + +/** + * \brief Unlock a spin lock by setting it to 0. Always returns immediately + * + * \param lock Points to the lock. + */ +extern DECLSPEC void SDLCALL SDL_AtomicUnlock(SDL_SpinLock *lock); + +/* @} *//* SDL AtomicLock */ + + +/** + * The compiler barrier prevents the compiler from reordering + * reads and writes to globally visible variables across the call. + */ +#if defined(_MSC_VER) && (_MSC_VER > 1200) && !defined(__clang__) +void _ReadWriteBarrier(void); +#pragma intrinsic(_ReadWriteBarrier) +#define SDL_CompilerBarrier() _ReadWriteBarrier() +#elif (defined(__GNUC__) && !defined(__EMSCRIPTEN__)) || (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x5120)) +/* This is correct for all CPUs when using GCC or Solaris Studio 12.1+. */ +#define SDL_CompilerBarrier() __asm__ __volatile__ ("" : : : "memory") +#elif defined(__WATCOMC__) +extern _inline void SDL_CompilerBarrier (void); +#pragma aux SDL_CompilerBarrier = "" parm [] modify exact []; +#else +#define SDL_CompilerBarrier() \ +{ SDL_SpinLock _tmp = 0; SDL_AtomicLock(&_tmp); SDL_AtomicUnlock(&_tmp); } +#endif + +/** + * Memory barriers are designed to prevent reads and writes from being + * reordered by the compiler and being seen out of order on multi-core CPUs. + * + * A typical pattern would be for thread A to write some data and a flag, + * and for thread B to read the flag and get the data. In this case you + * would insert a release barrier between writing the data and the flag, + * guaranteeing that the data write completes no later than the flag is + * written, and you would insert an acquire barrier between reading the + * flag and reading the data, to ensure that all the reads associated + * with the flag have completed. + * + * In this pattern you should always see a release barrier paired with + * an acquire barrier and you should gate the data reads/writes with a + * single flag variable. + * + * For more information on these semantics, take a look at the blog post: + * http://preshing.com/20120913/acquire-and-release-semantics + */ +extern DECLSPEC void SDLCALL SDL_MemoryBarrierReleaseFunction(void); +extern DECLSPEC void SDLCALL SDL_MemoryBarrierAcquireFunction(void); + +#if defined(__GNUC__) && (defined(__powerpc__) || defined(__ppc__)) +#define SDL_MemoryBarrierRelease() __asm__ __volatile__ ("lwsync" : : : "memory") +#define SDL_MemoryBarrierAcquire() __asm__ __volatile__ ("lwsync" : : : "memory") +#elif defined(__GNUC__) && defined(__aarch64__) +#define SDL_MemoryBarrierRelease() __asm__ __volatile__ ("dmb ish" : : : "memory") +#define SDL_MemoryBarrierAcquire() __asm__ __volatile__ ("dmb ish" : : : "memory") +#elif defined(__GNUC__) && defined(__arm__) +#if 0 /* defined(__LINUX__) || defined(__ANDROID__) */ +/* Information from: + https://chromium.googlesource.com/chromium/chromium/+/trunk/base/atomicops_internals_arm_gcc.h#19 + + The Linux kernel provides a helper function which provides the right code for a memory barrier, + hard-coded at address 0xffff0fa0 +*/ +typedef void (*SDL_KernelMemoryBarrierFunc)(); +#define SDL_MemoryBarrierRelease() ((SDL_KernelMemoryBarrierFunc)0xffff0fa0)() +#define SDL_MemoryBarrierAcquire() ((SDL_KernelMemoryBarrierFunc)0xffff0fa0)() +#elif 0 /* defined(__QNXNTO__) */ +#include + +#define SDL_MemoryBarrierRelease() __cpu_membarrier() +#define SDL_MemoryBarrierAcquire() __cpu_membarrier() +#else +#if defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_7EM__) || defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7S__) || defined(__ARM_ARCH_8A__) +#define SDL_MemoryBarrierRelease() __asm__ __volatile__ ("dmb ish" : : : "memory") +#define SDL_MemoryBarrierAcquire() __asm__ __volatile__ ("dmb ish" : : : "memory") +#elif defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) || defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6T2__) || defined(__ARM_ARCH_6Z__) || defined(__ARM_ARCH_6ZK__) || defined(__ARM_ARCH_5TE__) +#ifdef __thumb__ +/* The mcr instruction isn't available in thumb mode, use real functions */ +#define SDL_MEMORY_BARRIER_USES_FUNCTION +#define SDL_MemoryBarrierRelease() SDL_MemoryBarrierReleaseFunction() +#define SDL_MemoryBarrierAcquire() SDL_MemoryBarrierAcquireFunction() +#else +#define SDL_MemoryBarrierRelease() __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 5" : : "r"(0) : "memory") +#define SDL_MemoryBarrierAcquire() __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 5" : : "r"(0) : "memory") +#endif /* __thumb__ */ +#else +#define SDL_MemoryBarrierRelease() __asm__ __volatile__ ("" : : : "memory") +#define SDL_MemoryBarrierAcquire() __asm__ __volatile__ ("" : : : "memory") +#endif /* __LINUX__ || __ANDROID__ */ +#endif /* __GNUC__ && __arm__ */ +#else +#if (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x5120)) +/* This is correct for all CPUs on Solaris when using Solaris Studio 12.1+. */ +#include +#define SDL_MemoryBarrierRelease() __machine_rel_barrier() +#define SDL_MemoryBarrierAcquire() __machine_acq_barrier() +#else +/* This is correct for the x86 and x64 CPUs, and we'll expand this over time. */ +#define SDL_MemoryBarrierRelease() SDL_CompilerBarrier() +#define SDL_MemoryBarrierAcquire() SDL_CompilerBarrier() +#endif +#endif + +/** + * \brief A type representing an atomic integer value. It is a struct + * so people don't accidentally use numeric operations on it. + */ +typedef struct { int value; } SDL_atomic_t; + +/** + * \brief Set an atomic variable to a new value if it is currently an old value. + * + * \return SDL_TRUE if the atomic variable was set, SDL_FALSE otherwise. + * + * \note If you don't know what this function is for, you shouldn't use it! +*/ +extern DECLSPEC SDL_bool SDLCALL SDL_AtomicCAS(SDL_atomic_t *a, int oldval, int newval); + +/** + * \brief Set an atomic variable to a value. + * + * \return The previous value of the atomic variable. + */ +extern DECLSPEC int SDLCALL SDL_AtomicSet(SDL_atomic_t *a, int v); + +/** + * \brief Get the value of an atomic variable + */ +extern DECLSPEC int SDLCALL SDL_AtomicGet(SDL_atomic_t *a); + +/** + * \brief Add to an atomic variable. + * + * \return The previous value of the atomic variable. + * + * \note This same style can be used for any number operation + */ +extern DECLSPEC int SDLCALL SDL_AtomicAdd(SDL_atomic_t *a, int v); + +/** + * \brief Increment an atomic variable used as a reference count. + */ +#ifndef SDL_AtomicIncRef +#define SDL_AtomicIncRef(a) SDL_AtomicAdd(a, 1) +#endif + +/** + * \brief Decrement an atomic variable used as a reference count. + * + * \return SDL_TRUE if the variable reached zero after decrementing, + * SDL_FALSE otherwise + */ +#ifndef SDL_AtomicDecRef +#define SDL_AtomicDecRef(a) (SDL_AtomicAdd(a, -1) == 1) +#endif + +/** + * \brief Set a pointer to a new value if it is currently an old value. + * + * \return SDL_TRUE if the pointer was set, SDL_FALSE otherwise. + * + * \note If you don't know what this function is for, you shouldn't use it! +*/ +extern DECLSPEC SDL_bool SDLCALL SDL_AtomicCASPtr(void **a, void *oldval, void *newval); + +/** + * \brief Set a pointer to a value atomically. + * + * \return The previous value of the pointer. + */ +extern DECLSPEC void* SDLCALL SDL_AtomicSetPtr(void **a, void* v); + +/** + * \brief Get the value of a pointer atomically. + */ +extern DECLSPEC void* SDLCALL SDL_AtomicGetPtr(void **a); + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif + +#include "close_code.h" + +#endif /* SDL_atomic_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/engine/Windows/SDL2/include/SDL_audio.h b/engine/Windows/SDL2/include/SDL_audio.h new file mode 100644 index 0000000..305c01a --- /dev/null +++ b/engine/Windows/SDL2/include/SDL_audio.h @@ -0,0 +1,859 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2019 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_audio.h + * + * Access to the raw audio mixing buffer for the SDL library. + */ + +#ifndef SDL_audio_h_ +#define SDL_audio_h_ + +#include "SDL_stdinc.h" +#include "SDL_error.h" +#include "SDL_endian.h" +#include "SDL_mutex.h" +#include "SDL_thread.h" +#include "SDL_rwops.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief Audio format flags. + * + * These are what the 16 bits in SDL_AudioFormat currently mean... + * (Unspecified bits are always zero). + * + * \verbatim + ++-----------------------sample is signed if set + || + || ++-----------sample is bigendian if set + || || + || || ++---sample is float if set + || || || + || || || +---sample bit size---+ + || || || | | + 15 14 13 12 11 10 09 08 07 06 05 04 03 02 01 00 + \endverbatim + * + * There are macros in SDL 2.0 and later to query these bits. + */ +typedef Uint16 SDL_AudioFormat; + +/** + * \name Audio flags + */ +/* @{ */ + +#define SDL_AUDIO_MASK_BITSIZE (0xFF) +#define SDL_AUDIO_MASK_DATATYPE (1<<8) +#define SDL_AUDIO_MASK_ENDIAN (1<<12) +#define SDL_AUDIO_MASK_SIGNED (1<<15) +#define SDL_AUDIO_BITSIZE(x) (x & SDL_AUDIO_MASK_BITSIZE) +#define SDL_AUDIO_ISFLOAT(x) (x & SDL_AUDIO_MASK_DATATYPE) +#define SDL_AUDIO_ISBIGENDIAN(x) (x & SDL_AUDIO_MASK_ENDIAN) +#define SDL_AUDIO_ISSIGNED(x) (x & SDL_AUDIO_MASK_SIGNED) +#define SDL_AUDIO_ISINT(x) (!SDL_AUDIO_ISFLOAT(x)) +#define SDL_AUDIO_ISLITTLEENDIAN(x) (!SDL_AUDIO_ISBIGENDIAN(x)) +#define SDL_AUDIO_ISUNSIGNED(x) (!SDL_AUDIO_ISSIGNED(x)) + +/** + * \name Audio format flags + * + * Defaults to LSB byte order. + */ +/* @{ */ +#define AUDIO_U8 0x0008 /**< Unsigned 8-bit samples */ +#define AUDIO_S8 0x8008 /**< Signed 8-bit samples */ +#define AUDIO_U16LSB 0x0010 /**< Unsigned 16-bit samples */ +#define AUDIO_S16LSB 0x8010 /**< Signed 16-bit samples */ +#define AUDIO_U16MSB 0x1010 /**< As above, but big-endian byte order */ +#define AUDIO_S16MSB 0x9010 /**< As above, but big-endian byte order */ +#define AUDIO_U16 AUDIO_U16LSB +#define AUDIO_S16 AUDIO_S16LSB +/* @} */ + +/** + * \name int32 support + */ +/* @{ */ +#define AUDIO_S32LSB 0x8020 /**< 32-bit integer samples */ +#define AUDIO_S32MSB 0x9020 /**< As above, but big-endian byte order */ +#define AUDIO_S32 AUDIO_S32LSB +/* @} */ + +/** + * \name float32 support + */ +/* @{ */ +#define AUDIO_F32LSB 0x8120 /**< 32-bit floating point samples */ +#define AUDIO_F32MSB 0x9120 /**< As above, but big-endian byte order */ +#define AUDIO_F32 AUDIO_F32LSB +/* @} */ + +/** + * \name Native audio byte ordering + */ +/* @{ */ +#if SDL_BYTEORDER == SDL_LIL_ENDIAN +#define AUDIO_U16SYS AUDIO_U16LSB +#define AUDIO_S16SYS AUDIO_S16LSB +#define AUDIO_S32SYS AUDIO_S32LSB +#define AUDIO_F32SYS AUDIO_F32LSB +#else +#define AUDIO_U16SYS AUDIO_U16MSB +#define AUDIO_S16SYS AUDIO_S16MSB +#define AUDIO_S32SYS AUDIO_S32MSB +#define AUDIO_F32SYS AUDIO_F32MSB +#endif +/* @} */ + +/** + * \name Allow change flags + * + * Which audio format changes are allowed when opening a device. + */ +/* @{ */ +#define SDL_AUDIO_ALLOW_FREQUENCY_CHANGE 0x00000001 +#define SDL_AUDIO_ALLOW_FORMAT_CHANGE 0x00000002 +#define SDL_AUDIO_ALLOW_CHANNELS_CHANGE 0x00000004 +#define SDL_AUDIO_ALLOW_SAMPLES_CHANGE 0x00000008 +#define SDL_AUDIO_ALLOW_ANY_CHANGE (SDL_AUDIO_ALLOW_FREQUENCY_CHANGE|SDL_AUDIO_ALLOW_FORMAT_CHANGE|SDL_AUDIO_ALLOW_CHANNELS_CHANGE|SDL_AUDIO_ALLOW_SAMPLES_CHANGE) +/* @} */ + +/* @} *//* Audio flags */ + +/** + * This function is called when the audio device needs more data. + * + * \param userdata An application-specific parameter saved in + * the SDL_AudioSpec structure + * \param stream A pointer to the audio data buffer. + * \param len 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. + * + * You can choose to avoid callbacks and use SDL_QueueAudio() instead, if + * you like. Just open your audio device with a NULL callback. + */ +typedef void (SDLCALL * SDL_AudioCallback) (void *userdata, Uint8 * stream, + int len); + +/** + * The calculated values in this structure are calculated by SDL_OpenAudio(). + * + * For multi-channel audio, the default SDL channel mapping is: + * 2: FL FR (stereo) + * 3: FL FR LFE (2.1 surround) + * 4: FL FR BL BR (quad) + * 5: FL FR FC BL BR (quad + center) + * 6: FL FR FC LFE SL SR (5.1 surround - last two can also be BL BR) + * 7: FL FR FC LFE BC SL SR (6.1 surround) + * 8: FL FR FC LFE BL BR SL SR (7.1 surround) + */ +typedef struct SDL_AudioSpec +{ + int freq; /**< DSP frequency -- samples per second */ + SDL_AudioFormat format; /**< Audio data format */ + Uint8 channels; /**< Number of channels: 1 mono, 2 stereo */ + Uint8 silence; /**< Audio buffer silence value (calculated) */ + Uint16 samples; /**< Audio buffer size in sample FRAMES (total samples divided by channel count) */ + Uint16 padding; /**< Necessary for some compile environments */ + Uint32 size; /**< Audio buffer size in bytes (calculated) */ + SDL_AudioCallback callback; /**< Callback that feeds the audio device (NULL to use SDL_QueueAudio()). */ + void *userdata; /**< Userdata passed to callback (ignored for NULL callbacks). */ +} SDL_AudioSpec; + + +struct SDL_AudioCVT; +typedef void (SDLCALL * SDL_AudioFilter) (struct SDL_AudioCVT * cvt, + SDL_AudioFormat format); + +/** + * \brief Upper limit of filters in SDL_AudioCVT + * + * The maximum number of SDL_AudioFilter functions in SDL_AudioCVT is + * currently limited to 9. The SDL_AudioCVT.filters array has 10 pointers, + * one of which is the terminating NULL pointer. + */ +#define SDL_AUDIOCVT_MAX_FILTERS 9 + +/** + * \struct SDL_AudioCVT + * \brief A structure to hold a set of audio conversion filters and buffers. + * + * Note that various parts of the conversion pipeline can take advantage + * of SIMD operations (like SSE2, for example). SDL_AudioCVT doesn't require + * you to pass it aligned data, but can possibly run much faster if you + * set both its (buf) field to a pointer that is aligned to 16 bytes, and its + * (len) field to something that's a multiple of 16, if possible. + */ +#ifdef __GNUC__ +/* This structure is 84 bytes on 32-bit architectures, make sure GCC doesn't + pad it out to 88 bytes to guarantee ABI compatibility between compilers. + vvv + The next time we rev the ABI, make sure to size the ints and add padding. +*/ +#define SDL_AUDIOCVT_PACKED __attribute__((packed)) +#else +#define SDL_AUDIOCVT_PACKED +#endif +/* */ +typedef struct SDL_AudioCVT +{ + int needed; /**< Set to 1 if conversion possible */ + SDL_AudioFormat src_format; /**< Source audio format */ + SDL_AudioFormat dst_format; /**< Target audio format */ + double rate_incr; /**< Rate conversion increment */ + Uint8 *buf; /**< Buffer to hold entire audio data */ + int len; /**< Length of original audio buffer */ + int len_cvt; /**< Length of converted audio buffer */ + int len_mult; /**< buffer must be len*len_mult big */ + double len_ratio; /**< Given len, final size is len*len_ratio */ + SDL_AudioFilter filters[SDL_AUDIOCVT_MAX_FILTERS + 1]; /**< NULL-terminated list of filter functions */ + int filter_index; /**< Current audio conversion function */ +} SDL_AUDIOCVT_PACKED SDL_AudioCVT; + + +/* Function prototypes */ + +/** + * \name Driver discovery functions + * + * These functions return the list of built in audio drivers, in the + * order that they are normally initialized by default. + */ +/* @{ */ +extern DECLSPEC int SDLCALL SDL_GetNumAudioDrivers(void); +extern DECLSPEC const char *SDLCALL SDL_GetAudioDriver(int index); +/* @} */ + +/** + * \name Initialization and cleanup + * + * \internal 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(). + */ +/* @{ */ +extern DECLSPEC int SDLCALL SDL_AudioInit(const char *driver_name); +extern DECLSPEC void SDLCALL SDL_AudioQuit(void); +/* @} */ + +/** + * This function returns the name of the current audio driver, or NULL + * if no driver has been initialized. + */ +extern DECLSPEC const char *SDLCALL SDL_GetCurrentAudioDriver(void); + +/** + * 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 \c obtained. If \c 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, + * - \c desired->freq should be the desired audio frequency in samples-per- + * second. + * - \c desired->format should be the desired audio format. + * - \c 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: \code ms = (samples*1000)/freq \endcode + * - \c desired->size is the size in bytes of the audio buffer, and is + * calculated by SDL_OpenAudio(). + * - \c desired->silence is the value used to set the buffer to silence, + * and is calculated by SDL_OpenAudio(). + * - \c 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. Alternately, you may pass a NULL + * pointer here, and call SDL_QueueAudio() with some frequency, to queue + * more audio samples to be played (or for capture devices, call + * SDL_DequeueAudio() with some frequency, to obtain audio samples). + * - \c desired->userdata is passed as the first parameter to your callback + * function. If you passed a NULL callback, this value is ignored. + * + * The audio device starts out playing silence when it's opened, and should + * be enabled for playing by calling \c 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. + */ +extern DECLSPEC int SDLCALL SDL_OpenAudio(SDL_AudioSpec * desired, + SDL_AudioSpec * obtained); + +/** + * SDL Audio Device IDs. + * + * A successful call to SDL_OpenAudio() is always device id 1, and legacy + * SDL audio APIs assume you want this device ID. SDL_OpenAudioDevice() calls + * always returns devices >= 2 on success. The legacy calls are good both + * for backwards compatibility and when you don't care about multiple, + * specific, or capture devices. + */ +typedef Uint32 SDL_AudioDeviceID; + +/** + * Get the number of available devices exposed by the current driver. + * Only valid after a successfully initializing the audio subsystem. + * Returns -1 if an explicit list of devices can't be determined; this is + * not an error. For example, if SDL is set up to talk to a remote audio + * server, it can't list every one available on the Internet, but it will + * still allow a specific host to be specified to SDL_OpenAudioDevice(). + * + * In many common cases, when this function returns a value <= 0, it can still + * successfully open the default device (NULL for first argument of + * SDL_OpenAudioDevice()). + */ +extern DECLSPEC int SDLCALL SDL_GetNumAudioDevices(int iscapture); + +/** + * Get the human-readable name of a specific audio device. + * Must be a value between 0 and (number of audio devices-1). + * Only valid after a successfully initializing the audio subsystem. + * The values returned by this function reflect the latest call to + * SDL_GetNumAudioDevices(); recall that function to redetect available + * hardware. + * + * The string returned by this function is UTF-8 encoded, read-only, and + * managed internally. You are not to free it. If you need to keep the + * string for any length of time, you should make your own copy of it, as it + * will be invalid next time any of several other SDL functions is called. + */ +extern DECLSPEC const char *SDLCALL SDL_GetAudioDeviceName(int index, + int iscapture); + + +/** + * Open a specific audio device. Passing in a device name of NULL requests + * the most reasonable default (and is equivalent to calling SDL_OpenAudio()). + * + * The device name is a UTF-8 string reported by SDL_GetAudioDeviceName(), but + * some drivers allow arbitrary and driver-specific strings, such as a + * hostname/IP address for a remote audio server, or a filename in the + * diskaudio driver. + * + * \return 0 on error, a valid device ID that is >= 2 on success. + * + * SDL_OpenAudio(), unlike this function, always acts on device ID 1. + */ +extern DECLSPEC SDL_AudioDeviceID SDLCALL SDL_OpenAudioDevice(const char + *device, + int iscapture, + const + SDL_AudioSpec * + desired, + SDL_AudioSpec * + obtained, + int + allowed_changes); + + + +/** + * \name Audio state + * + * Get the current audio state. + */ +/* @{ */ +typedef enum +{ + SDL_AUDIO_STOPPED = 0, + SDL_AUDIO_PLAYING, + SDL_AUDIO_PAUSED +} SDL_AudioStatus; +extern DECLSPEC SDL_AudioStatus SDLCALL SDL_GetAudioStatus(void); + +extern DECLSPEC SDL_AudioStatus SDLCALL +SDL_GetAudioDeviceStatus(SDL_AudioDeviceID dev); +/* @} *//* Audio State */ + +/** + * \name Pause audio functions + * + * These functions pause and unpause the audio callback processing. + * They 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. + */ +/* @{ */ +extern DECLSPEC void SDLCALL SDL_PauseAudio(int pause_on); +extern DECLSPEC void SDLCALL SDL_PauseAudioDevice(SDL_AudioDeviceID dev, + int pause_on); +/* @} *//* Pause audio functions */ + +/** + * \brief Load the audio data of a WAVE file into memory + * + * Loading a WAVE file requires \c src, \c spec, \c audio_buf and \c audio_len + * to be valid pointers. The entire data portion of the file is then loaded + * into memory and decoded if necessary. + * + * If \c freesrc is non-zero, the data source gets automatically closed and + * freed before the function returns. + * + * Supported are RIFF WAVE files with the formats PCM (8, 16, 24, and 32 bits), + * IEEE Float (32 bits), Microsoft ADPCM and IMA ADPCM (4 bits), and A-law and + * µ-law (8 bits). Other formats are currently unsupported and cause an error. + * + * If this function succeeds, the pointer returned by it is equal to \c spec + * and the pointer to the audio data allocated by the function is written to + * \c audio_buf and its length in bytes to \c audio_len. The \ref SDL_AudioSpec + * members \c freq, \c channels, and \c format are set to the values of the + * audio data in the buffer. The \c samples member is set to a sane default and + * all others are set to zero. + * + * It's necessary to use SDL_FreeWAV() to free the audio data returned in + * \c audio_buf when it is no longer used. + * + * Because of the underspecification of the Waveform format, there are many + * problematic files in the wild that cause issues with strict decoders. To + * provide compatibility with these files, this decoder is lenient in regards + * to the truncation of the file, the fact chunk, and the size of the RIFF + * chunk. The hints SDL_HINT_WAVE_RIFF_CHUNK_SIZE, SDL_HINT_WAVE_TRUNCATION, + * and SDL_HINT_WAVE_FACT_CHUNK can be used to tune the behavior of the + * loading process. + * + * Any file that is invalid (due to truncation, corruption, or wrong values in + * the headers), too big, or unsupported causes an error. Additionally, any + * critical I/O error from the data source will terminate the loading process + * with an error. The function returns NULL on error and in all cases (with the + * exception of \c src being NULL), an appropriate error message will be set. + * + * It is required that the data source supports seeking. + * + * Example: + * \code + * SDL_LoadWAV_RW(SDL_RWFromFile("sample.wav", "rb"), 1, ...); + * \endcode + * + * \param src The data source with the WAVE data + * \param freesrc A integer value that makes the function close the data source if non-zero + * \param spec A pointer filled with the audio format of the audio data + * \param audio_buf A pointer filled with the audio data allocated by the function + * \param audio_len A pointer filled with the length of the audio data buffer in bytes + * \return NULL on error, or non-NULL on success. + */ +extern DECLSPEC SDL_AudioSpec *SDLCALL SDL_LoadWAV_RW(SDL_RWops * src, + int freesrc, + SDL_AudioSpec * spec, + Uint8 ** audio_buf, + Uint32 * audio_len); + +/** + * Loads a WAV from a file. + * Compatibility convenience function. + */ +#define SDL_LoadWAV(file, spec, audio_buf, audio_len) \ + SDL_LoadWAV_RW(SDL_RWFromFile(file, "rb"),1, spec,audio_buf,audio_len) + +/** + * This function frees data previously allocated with SDL_LoadWAV_RW() + */ +extern DECLSPEC void SDLCALL SDL_FreeWAV(Uint8 * audio_buf); + +/** + * This function takes a source format and rate and a destination format + * and rate, and initializes the \c cvt structure with information needed + * by SDL_ConvertAudio() to convert a buffer of audio data from one format + * to the other. An unsupported format causes an error and -1 will be returned. + * + * \return 0 if no conversion is needed, 1 if the audio filter is set up, + * or -1 on error. + */ +extern DECLSPEC int SDLCALL SDL_BuildAudioCVT(SDL_AudioCVT * cvt, + SDL_AudioFormat src_format, + Uint8 src_channels, + int src_rate, + SDL_AudioFormat dst_format, + Uint8 dst_channels, + int dst_rate); + +/** + * Once you have initialized the \c cvt structure using SDL_BuildAudioCVT(), + * created an audio buffer \c cvt->buf, and filled it with \c 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 + * \c cvt->buf should be allocated after the \c cvt structure is initialized by + * SDL_BuildAudioCVT(), and should be \c cvt->len*cvt->len_mult bytes long. + * + * \return 0 on success or -1 if \c cvt->buf is NULL. + */ +extern DECLSPEC int SDLCALL SDL_ConvertAudio(SDL_AudioCVT * cvt); + +/* SDL_AudioStream is a new audio conversion interface. + The benefits vs SDL_AudioCVT: + - it can handle resampling data in chunks without generating + artifacts, when it doesn't have the complete buffer available. + - it can handle incoming data in any variable size. + - You push data as you have it, and pull it when you need it + */ +/* this is opaque to the outside world. */ +struct _SDL_AudioStream; +typedef struct _SDL_AudioStream SDL_AudioStream; + +/** + * Create a new audio stream + * + * \param src_format The format of the source audio + * \param src_channels The number of channels of the source audio + * \param src_rate The sampling rate of the source audio + * \param dst_format The format of the desired audio output + * \param dst_channels The number of channels of the desired audio output + * \param dst_rate The sampling rate of the desired audio output + * \return 0 on success, or -1 on error. + * + * \sa SDL_AudioStreamPut + * \sa SDL_AudioStreamGet + * \sa SDL_AudioStreamAvailable + * \sa SDL_AudioStreamFlush + * \sa SDL_AudioStreamClear + * \sa SDL_FreeAudioStream + */ +extern DECLSPEC SDL_AudioStream * SDLCALL SDL_NewAudioStream(const SDL_AudioFormat src_format, + const Uint8 src_channels, + const int src_rate, + const SDL_AudioFormat dst_format, + const Uint8 dst_channels, + const int dst_rate); + +/** + * Add data to be converted/resampled to the stream + * + * \param stream The stream the audio data is being added to + * \param buf A pointer to the audio data to add + * \param len The number of bytes to write to the stream + * \return 0 on success, or -1 on error. + * + * \sa SDL_NewAudioStream + * \sa SDL_AudioStreamGet + * \sa SDL_AudioStreamAvailable + * \sa SDL_AudioStreamFlush + * \sa SDL_AudioStreamClear + * \sa SDL_FreeAudioStream + */ +extern DECLSPEC int SDLCALL SDL_AudioStreamPut(SDL_AudioStream *stream, const void *buf, int len); + +/** + * Get converted/resampled data from the stream + * + * \param stream The stream the audio is being requested from + * \param buf A buffer to fill with audio data + * \param len The maximum number of bytes to fill + * \return The number of bytes read from the stream, or -1 on error + * + * \sa SDL_NewAudioStream + * \sa SDL_AudioStreamPut + * \sa SDL_AudioStreamAvailable + * \sa SDL_AudioStreamFlush + * \sa SDL_AudioStreamClear + * \sa SDL_FreeAudioStream + */ +extern DECLSPEC int SDLCALL SDL_AudioStreamGet(SDL_AudioStream *stream, void *buf, int len); + +/** + * Get the number of converted/resampled bytes available. The stream may be + * buffering data behind the scenes until it has enough to resample + * correctly, so this number might be lower than what you expect, or even + * be zero. Add more data or flush the stream if you need the data now. + * + * \sa SDL_NewAudioStream + * \sa SDL_AudioStreamPut + * \sa SDL_AudioStreamGet + * \sa SDL_AudioStreamFlush + * \sa SDL_AudioStreamClear + * \sa SDL_FreeAudioStream + */ +extern DECLSPEC int SDLCALL SDL_AudioStreamAvailable(SDL_AudioStream *stream); + +/** + * Tell the stream that you're done sending data, and anything being buffered + * should be converted/resampled and made available immediately. + * + * It is legal to add more data to a stream after flushing, but there will + * be audio gaps in the output. Generally this is intended to signal the + * end of input, so the complete output becomes available. + * + * \sa SDL_NewAudioStream + * \sa SDL_AudioStreamPut + * \sa SDL_AudioStreamGet + * \sa SDL_AudioStreamAvailable + * \sa SDL_AudioStreamClear + * \sa SDL_FreeAudioStream + */ +extern DECLSPEC int SDLCALL SDL_AudioStreamFlush(SDL_AudioStream *stream); + +/** + * Clear any pending data in the stream without converting it + * + * \sa SDL_NewAudioStream + * \sa SDL_AudioStreamPut + * \sa SDL_AudioStreamGet + * \sa SDL_AudioStreamAvailable + * \sa SDL_AudioStreamFlush + * \sa SDL_FreeAudioStream + */ +extern DECLSPEC void SDLCALL SDL_AudioStreamClear(SDL_AudioStream *stream); + +/** + * Free an audio stream + * + * \sa SDL_NewAudioStream + * \sa SDL_AudioStreamPut + * \sa SDL_AudioStreamGet + * \sa SDL_AudioStreamAvailable + * \sa SDL_AudioStreamFlush + * \sa SDL_AudioStreamClear + */ +extern DECLSPEC void SDLCALL SDL_FreeAudioStream(SDL_AudioStream *stream); + +#define SDL_MIX_MAXVOLUME 128 +/** + * 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. + */ +extern DECLSPEC void SDLCALL SDL_MixAudio(Uint8 * dst, const Uint8 * src, + Uint32 len, int volume); + +/** + * This works like SDL_MixAudio(), but you specify the audio format instead of + * using the format of audio device 1. Thus it can be used when no audio + * device is open at all. + */ +extern DECLSPEC void SDLCALL SDL_MixAudioFormat(Uint8 * dst, + const Uint8 * src, + SDL_AudioFormat format, + Uint32 len, int volume); + +/** + * Queue more audio on non-callback devices. + * + * (If you are looking to retrieve queued audio from a non-callback capture + * device, you want SDL_DequeueAudio() instead. This will return -1 to + * signify an error if you use it with capture devices.) + * + * SDL offers two ways to feed audio to the device: you can either supply a + * callback that SDL triggers with some frequency to obtain more audio + * (pull method), or you can supply no callback, and then SDL will expect + * you to supply data at regular intervals (push method) with this function. + * + * There are no limits on the amount of data you can queue, short of + * exhaustion of address space. Queued data will drain to the device as + * necessary without further intervention from you. If the device needs + * audio but there is not enough queued, it will play silence to make up + * the difference. This means you will have skips in your audio playback + * if you aren't routinely queueing sufficient data. + * + * This function copies the supplied data, so you are safe to free it when + * the function returns. This function is thread-safe, but queueing to the + * same device from two threads at once does not promise which buffer will + * be queued first. + * + * You may not queue audio on a device that is using an application-supplied + * callback; doing so returns an error. You have to use the audio callback + * or queue audio with this function, but not both. + * + * You should not call SDL_LockAudio() on the device before queueing; SDL + * handles locking internally for this function. + * + * \param dev The device ID to which we will queue audio. + * \param data The data to queue to the device for later playback. + * \param len The number of bytes (not samples!) to which (data) points. + * \return 0 on success, or -1 on error. + * + * \sa SDL_GetQueuedAudioSize + * \sa SDL_ClearQueuedAudio + */ +extern DECLSPEC int SDLCALL SDL_QueueAudio(SDL_AudioDeviceID dev, const void *data, Uint32 len); + +/** + * Dequeue more audio on non-callback devices. + * + * (If you are looking to queue audio for output on a non-callback playback + * device, you want SDL_QueueAudio() instead. This will always return 0 + * if you use it with playback devices.) + * + * SDL offers two ways to retrieve audio from a capture device: you can + * either supply a callback that SDL triggers with some frequency as the + * device records more audio data, (push method), or you can supply no + * callback, and then SDL will expect you to retrieve data at regular + * intervals (pull method) with this function. + * + * There are no limits on the amount of data you can queue, short of + * exhaustion of address space. Data from the device will keep queuing as + * necessary without further intervention from you. This means you will + * eventually run out of memory if you aren't routinely dequeueing data. + * + * Capture devices will not queue data when paused; if you are expecting + * to not need captured audio for some length of time, use + * SDL_PauseAudioDevice() to stop the capture device from queueing more + * data. This can be useful during, say, level loading times. When + * unpaused, capture devices will start queueing data from that point, + * having flushed any capturable data available while paused. + * + * This function is thread-safe, but dequeueing from the same device from + * two threads at once does not promise which thread will dequeued data + * first. + * + * You may not dequeue audio from a device that is using an + * application-supplied callback; doing so returns an error. You have to use + * the audio callback, or dequeue audio with this function, but not both. + * + * You should not call SDL_LockAudio() on the device before queueing; SDL + * handles locking internally for this function. + * + * \param dev The device ID from which we will dequeue audio. + * \param data A pointer into where audio data should be copied. + * \param len The number of bytes (not samples!) to which (data) points. + * \return number of bytes dequeued, which could be less than requested. + * + * \sa SDL_GetQueuedAudioSize + * \sa SDL_ClearQueuedAudio + */ +extern DECLSPEC Uint32 SDLCALL SDL_DequeueAudio(SDL_AudioDeviceID dev, void *data, Uint32 len); + +/** + * Get the number of bytes of still-queued audio. + * + * For playback device: + * + * This is the number of bytes that have been queued for playback with + * SDL_QueueAudio(), but have not yet been sent to the hardware. This + * number may shrink at any time, so this only informs of pending data. + * + * Once we've sent it to the hardware, this function can not decide the + * exact byte boundary of what has been played. It's possible that we just + * gave the hardware several kilobytes right before you called this + * function, but it hasn't played any of it yet, or maybe half of it, etc. + * + * For capture devices: + * + * This is the number of bytes that have been captured by the device and + * are waiting for you to dequeue. This number may grow at any time, so + * this only informs of the lower-bound of available data. + * + * You may not queue audio on a device that is using an application-supplied + * callback; calling this function on such a device always returns 0. + * You have to queue audio with SDL_QueueAudio()/SDL_DequeueAudio(), or use + * the audio callback, but not both. + * + * You should not call SDL_LockAudio() on the device before querying; SDL + * handles locking internally for this function. + * + * \param dev The device ID of which we will query queued audio size. + * \return Number of bytes (not samples!) of queued audio. + * + * \sa SDL_QueueAudio + * \sa SDL_ClearQueuedAudio + */ +extern DECLSPEC Uint32 SDLCALL SDL_GetQueuedAudioSize(SDL_AudioDeviceID dev); + +/** + * Drop any queued audio data. For playback devices, this is any queued data + * still waiting to be submitted to the hardware. For capture devices, this + * is any data that was queued by the device that hasn't yet been dequeued by + * the application. + * + * Immediately after this call, SDL_GetQueuedAudioSize() will return 0. For + * playback devices, the hardware will start playing silence if more audio + * isn't queued. Unpaused capture devices will start filling the queue again + * as soon as they have more data available (which, depending on the state + * of the hardware and the thread, could be before this function call + * returns!). + * + * This will not prevent playback of queued audio that's already been sent + * to the hardware, as we can not undo that, so expect there to be some + * fraction of a second of audio that might still be heard. This can be + * useful if you want to, say, drop any pending music during a level change + * in your game. + * + * You may not queue audio on a device that is using an application-supplied + * callback; calling this function on such a device is always a no-op. + * You have to queue audio with SDL_QueueAudio()/SDL_DequeueAudio(), or use + * the audio callback, but not both. + * + * You should not call SDL_LockAudio() on the device before clearing the + * queue; SDL handles locking internally for this function. + * + * This function always succeeds and thus returns void. + * + * \param dev The device ID of which to clear the audio queue. + * + * \sa SDL_QueueAudio + * \sa SDL_GetQueuedAudioSize + */ +extern DECLSPEC void SDLCALL SDL_ClearQueuedAudio(SDL_AudioDeviceID dev); + + +/** + * \name Audio lock functions + * + * The lock manipulated by these functions protects the callback function. + * During a SDL_LockAudio()/SDL_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. + */ +/* @{ */ +extern DECLSPEC void SDLCALL SDL_LockAudio(void); +extern DECLSPEC void SDLCALL SDL_LockAudioDevice(SDL_AudioDeviceID dev); +extern DECLSPEC void SDLCALL SDL_UnlockAudio(void); +extern DECLSPEC void SDLCALL SDL_UnlockAudioDevice(SDL_AudioDeviceID dev); +/* @} *//* Audio lock functions */ + +/** + * This function shuts down audio processing and closes the audio device. + */ +extern DECLSPEC void SDLCALL SDL_CloseAudio(void); +extern DECLSPEC void SDLCALL SDL_CloseAudioDevice(SDL_AudioDeviceID dev); + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_audio_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/engine/Windows/SDL2/include/SDL_bits.h b/engine/Windows/SDL2/include/SDL_bits.h new file mode 100644 index 0000000..b116cc8 --- /dev/null +++ b/engine/Windows/SDL2/include/SDL_bits.h @@ -0,0 +1,121 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2019 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_bits.h + * + * Functions for fiddling with bits and bitmasks. + */ + +#ifndef SDL_bits_h_ +#define SDL_bits_h_ + +#include "SDL_stdinc.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \file SDL_bits.h + */ + +/** + * Get the index of the most significant bit. Result is undefined when called + * with 0. This operation can also be stated as "count leading zeroes" and + * "log base 2". + * + * \return Index of the most significant bit, or -1 if the value is 0. + */ +#if defined(__WATCOMC__) && defined(__386__) +extern _inline int _SDL_clz_watcom (Uint32); +#pragma aux _SDL_clz_watcom = \ + "bsr eax, eax" \ + "xor eax, 31" \ + parm [eax] nomemory \ + value [eax] \ + modify exact [eax] nomemory; +#endif + +SDL_FORCE_INLINE int +SDL_MostSignificantBitIndex32(Uint32 x) +{ +#if defined(__GNUC__) && (__GNUC__ >= 4 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) + /* Count Leading Zeroes builtin in GCC. + * http://gcc.gnu.org/onlinedocs/gcc-4.3.4/gcc/Other-Builtins.html + */ + if (x == 0) { + return -1; + } + return 31 - __builtin_clz(x); +#elif defined(__WATCOMC__) && defined(__386__) + if (x == 0) { + return -1; + } + return 31 - _SDL_clz_watcom(x); +#else + /* Based off of Bit Twiddling Hacks by Sean Eron Anderson + * , released in the public domain. + * http://graphics.stanford.edu/~seander/bithacks.html#IntegerLog + */ + const Uint32 b[] = {0x2, 0xC, 0xF0, 0xFF00, 0xFFFF0000}; + const int S[] = {1, 2, 4, 8, 16}; + + int msbIndex = 0; + int i; + + if (x == 0) { + return -1; + } + + for (i = 4; i >= 0; i--) + { + if (x & b[i]) + { + x >>= S[i]; + msbIndex |= S[i]; + } + } + + return msbIndex; +#endif +} + +SDL_FORCE_INLINE SDL_bool +SDL_HasExactlyOneBitSet32(Uint32 x) +{ + if (x && !(x & (x - 1))) { + return SDL_TRUE; + } + return SDL_FALSE; +} + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_bits_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/engine/Windows/SDL2/include/SDL_blendmode.h b/engine/Windows/SDL2/include/SDL_blendmode.h new file mode 100644 index 0000000..6f0a22b --- /dev/null +++ b/engine/Windows/SDL2/include/SDL_blendmode.h @@ -0,0 +1,120 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2019 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_blendmode.h + * + * Header file declaring the SDL_BlendMode enumeration + */ + +#ifndef SDL_blendmode_h_ +#define SDL_blendmode_h_ + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief The blend mode used in SDL_RenderCopy() and drawing operations. + */ +typedef enum +{ + SDL_BLENDMODE_NONE = 0x00000000, /**< no blending + dstRGBA = srcRGBA */ + SDL_BLENDMODE_BLEND = 0x00000001, /**< alpha blending + dstRGB = (srcRGB * srcA) + (dstRGB * (1-srcA)) + dstA = srcA + (dstA * (1-srcA)) */ + SDL_BLENDMODE_ADD = 0x00000002, /**< additive blending + dstRGB = (srcRGB * srcA) + dstRGB + dstA = dstA */ + SDL_BLENDMODE_MOD = 0x00000004, /**< color modulate + dstRGB = srcRGB * dstRGB + dstA = dstA */ + SDL_BLENDMODE_INVALID = 0x7FFFFFFF + + /* Additional custom blend modes can be returned by SDL_ComposeCustomBlendMode() */ + +} SDL_BlendMode; + +/** + * \brief The blend operation used when combining source and destination pixel components + */ +typedef enum +{ + SDL_BLENDOPERATION_ADD = 0x1, /**< dst + src: supported by all renderers */ + SDL_BLENDOPERATION_SUBTRACT = 0x2, /**< dst - src : supported by D3D9, D3D11, OpenGL, OpenGLES */ + SDL_BLENDOPERATION_REV_SUBTRACT = 0x3, /**< src - dst : supported by D3D9, D3D11, OpenGL, OpenGLES */ + SDL_BLENDOPERATION_MINIMUM = 0x4, /**< min(dst, src) : supported by D3D11 */ + SDL_BLENDOPERATION_MAXIMUM = 0x5 /**< max(dst, src) : supported by D3D11 */ + +} SDL_BlendOperation; + +/** + * \brief The normalized factor used to multiply pixel components + */ +typedef enum +{ + SDL_BLENDFACTOR_ZERO = 0x1, /**< 0, 0, 0, 0 */ + SDL_BLENDFACTOR_ONE = 0x2, /**< 1, 1, 1, 1 */ + SDL_BLENDFACTOR_SRC_COLOR = 0x3, /**< srcR, srcG, srcB, srcA */ + SDL_BLENDFACTOR_ONE_MINUS_SRC_COLOR = 0x4, /**< 1-srcR, 1-srcG, 1-srcB, 1-srcA */ + SDL_BLENDFACTOR_SRC_ALPHA = 0x5, /**< srcA, srcA, srcA, srcA */ + SDL_BLENDFACTOR_ONE_MINUS_SRC_ALPHA = 0x6, /**< 1-srcA, 1-srcA, 1-srcA, 1-srcA */ + SDL_BLENDFACTOR_DST_COLOR = 0x7, /**< dstR, dstG, dstB, dstA */ + SDL_BLENDFACTOR_ONE_MINUS_DST_COLOR = 0x8, /**< 1-dstR, 1-dstG, 1-dstB, 1-dstA */ + SDL_BLENDFACTOR_DST_ALPHA = 0x9, /**< dstA, dstA, dstA, dstA */ + SDL_BLENDFACTOR_ONE_MINUS_DST_ALPHA = 0xA /**< 1-dstA, 1-dstA, 1-dstA, 1-dstA */ + +} SDL_BlendFactor; + +/** + * \brief Create a custom blend mode, which may or may not be supported by a given renderer + * + * \param srcColorFactor source color factor + * \param dstColorFactor destination color factor + * \param colorOperation color operation + * \param srcAlphaFactor source alpha factor + * \param dstAlphaFactor destination alpha factor + * \param alphaOperation alpha operation + * + * The result of the blend mode operation will be: + * dstRGB = dstRGB * dstColorFactor colorOperation srcRGB * srcColorFactor + * and + * dstA = dstA * dstAlphaFactor alphaOperation srcA * srcAlphaFactor + */ +extern DECLSPEC SDL_BlendMode SDLCALL SDL_ComposeCustomBlendMode(SDL_BlendFactor srcColorFactor, + SDL_BlendFactor dstColorFactor, + SDL_BlendOperation colorOperation, + SDL_BlendFactor srcAlphaFactor, + SDL_BlendFactor dstAlphaFactor, + SDL_BlendOperation alphaOperation); + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_blendmode_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/engine/Windows/SDL2/include/SDL_clipboard.h b/engine/Windows/SDL2/include/SDL_clipboard.h new file mode 100644 index 0000000..c4f8766 --- /dev/null +++ b/engine/Windows/SDL2/include/SDL_clipboard.h @@ -0,0 +1,71 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2019 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_clipboard.h + * + * Include file for SDL clipboard handling + */ + +#ifndef SDL_clipboard_h_ +#define SDL_clipboard_h_ + +#include "SDL_stdinc.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/* Function prototypes */ + +/** + * \brief Put UTF-8 text into the clipboard + * + * \sa SDL_GetClipboardText() + */ +extern DECLSPEC int SDLCALL SDL_SetClipboardText(const char *text); + +/** + * \brief Get UTF-8 text from the clipboard, which must be freed with SDL_free() + * + * \sa SDL_SetClipboardText() + */ +extern DECLSPEC char * SDLCALL SDL_GetClipboardText(void); + +/** + * \brief Returns a flag indicating whether the clipboard exists and contains a text string that is non-empty + * + * \sa SDL_GetClipboardText() + */ +extern DECLSPEC SDL_bool SDLCALL SDL_HasClipboardText(void); + + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_clipboard_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/engine/Windows/SDL2/include/SDL_config.h b/engine/Windows/SDL2/include/SDL_config.h new file mode 100644 index 0000000..7d62d3e --- /dev/null +++ b/engine/Windows/SDL2/include/SDL_config.h @@ -0,0 +1,55 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2019 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef SDL_config_h_ +#define SDL_config_h_ + +#include "SDL_platform.h" + +/** + * \file SDL_config.h + */ + +/* Add any platform that doesn't build using the configure system. */ +#if defined(__WIN32__) +#include "SDL_config_windows.h" +#elif defined(__WINRT__) +#include "SDL_config_winrt.h" +#elif defined(__MACOSX__) +#include "SDL_config_macosx.h" +#elif defined(__IPHONEOS__) +#include "SDL_config_iphoneos.h" +#elif defined(__ANDROID__) +#include "SDL_config_android.h" +#elif defined(__PSP__) +#include "SDL_config_psp.h" +#elif defined(__OS2__) +#include "SDL_config_os2.h" +#else +/* This is a minimal configuration just to get SDL running on new platforms. */ +#include "SDL_config_minimal.h" +#endif /* platform config */ + +#ifdef USING_GENERATED_CONFIG_H +#error Wrong SDL_config.h, check your include path? +#endif + +#endif /* SDL_config_h_ */ diff --git a/engine/Windows/SDL2/include/SDL_config_android.h b/engine/Windows/SDL2/include/SDL_config_android.h new file mode 100644 index 0000000..8f53486 --- /dev/null +++ b/engine/Windows/SDL2/include/SDL_config_android.h @@ -0,0 +1,178 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2019 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef SDL_config_android_h_ +#define SDL_config_android_h_ +#define SDL_config_h_ + +#include "SDL_platform.h" + +/** + * \file SDL_config_android.h + * + * This is a configuration that can be used to build SDL for Android + */ + +#include + +#define HAVE_GCC_ATOMICS 1 + +#define STDC_HEADERS 1 +#define HAVE_ALLOCA_H 1 +#define HAVE_CTYPE_H 1 +#define HAVE_INTTYPES_H 1 +#define HAVE_LIMITS_H 1 +#define HAVE_MATH_H 1 +#define HAVE_SIGNAL_H 1 +#define HAVE_STDINT_H 1 +#define HAVE_STDIO_H 1 +#define HAVE_STRING_H 1 +#define HAVE_SYS_TYPES_H 1 + +/* C library functions */ +#define HAVE_MALLOC 1 +#define HAVE_CALLOC 1 +#define HAVE_REALLOC 1 +#define HAVE_FREE 1 +#define HAVE_ALLOCA 1 +#define HAVE_GETENV 1 +#define HAVE_SETENV 1 +#define HAVE_PUTENV 1 +#define HAVE_SETENV 1 +#define HAVE_UNSETENV 1 +#define HAVE_QSORT 1 +#define HAVE_ABS 1 +#define HAVE_BCOPY 1 +#define HAVE_MEMSET 1 +#define HAVE_MEMCPY 1 +#define HAVE_MEMMOVE 1 +#define HAVE_MEMCMP 1 +#define HAVE_STRLEN 1 +#define HAVE_STRLCPY 1 +#define HAVE_STRLCAT 1 +#define HAVE_STRCHR 1 +#define HAVE_STRRCHR 1 +#define HAVE_STRSTR 1 +#define HAVE_STRTOL 1 +#define HAVE_STRTOUL 1 +#define HAVE_STRTOLL 1 +#define HAVE_STRTOULL 1 +#define HAVE_STRTOD 1 +#define HAVE_ATOI 1 +#define HAVE_ATOF 1 +#define HAVE_STRCMP 1 +#define HAVE_STRNCMP 1 +#define HAVE_STRCASECMP 1 +#define HAVE_STRNCASECMP 1 +#define HAVE_VSSCANF 1 +#define HAVE_VSNPRINTF 1 +#define HAVE_ACOS 1 +#define HAVE_ACOSF 1 +#define HAVE_ASIN 1 +#define HAVE_ASINF 1 +#define HAVE_ATAN 1 +#define HAVE_ATANF 1 +#define HAVE_ATAN2 1 +#define HAVE_ATAN2F 1 +#define HAVE_CEIL 1 +#define HAVE_CEILF 1 +#define HAVE_COPYSIGN 1 +#define HAVE_COPYSIGNF 1 +#define HAVE_COS 1 +#define HAVE_COSF 1 +#define HAVE_EXP 1 +#define HAVE_EXPF 1 +#define HAVE_FABS 1 +#define HAVE_FABSF 1 +#define HAVE_FLOOR 1 +#define HAVE_FLOORF 1 +#define HAVE_FMOD 1 +#define HAVE_FMODF 1 +#define HAVE_LOG 1 +#define HAVE_LOGF 1 +#define HAVE_LOG10 1 +#define HAVE_LOG10F 1 +#define HAVE_POW 1 +#define HAVE_POWF 1 +#define HAVE_SCALBN 1 +#define HAVE_SCALBNF 1 +#define HAVE_SIN 1 +#define HAVE_SINF 1 +#define HAVE_SQRT 1 +#define HAVE_SQRTF 1 +#define HAVE_TAN 1 +#define HAVE_TANF 1 +#define HAVE_SIGACTION 1 +#define HAVE_SETJMP 1 +#define HAVE_NANOSLEEP 1 +#define HAVE_SYSCONF 1 +#define HAVE_CLOCK_GETTIME 1 + +#define SIZEOF_VOIDP 4 + +/* Enable various audio drivers */ +#define SDL_AUDIO_DRIVER_ANDROID 1 +#define SDL_AUDIO_DRIVER_OPENSLES 1 +#define SDL_AUDIO_DRIVER_DUMMY 1 + +/* Enable various input drivers */ +#define SDL_JOYSTICK_ANDROID 1 +#define SDL_JOYSTICK_HIDAPI 1 +#define SDL_HAPTIC_ANDROID 1 + +/* Enable sensor driver */ +#define SDL_SENSOR_ANDROID 1 + +/* Enable various shared object loading systems */ +#define SDL_LOADSO_DLOPEN 1 + +/* Enable various threading systems */ +#define SDL_THREAD_PTHREAD 1 +#define SDL_THREAD_PTHREAD_RECURSIVE_MUTEX 1 + +/* Enable various timer systems */ +#define SDL_TIMER_UNIX 1 + +/* Enable various video drivers */ +#define SDL_VIDEO_DRIVER_ANDROID 1 + +/* Enable OpenGL ES */ +#define SDL_VIDEO_OPENGL_ES 1 +#define SDL_VIDEO_OPENGL_ES2 1 +#define SDL_VIDEO_OPENGL_EGL 1 +#define SDL_VIDEO_RENDER_OGL_ES 1 +#define SDL_VIDEO_RENDER_OGL_ES2 1 + +/* Enable Vulkan support */ +/* Android does not support Vulkan in native code using the "armeabi" ABI. */ +#if defined(__ARM_ARCH) && __ARM_ARCH < 7 +#define SDL_VIDEO_VULKAN 0 +#else +#define SDL_VIDEO_VULKAN 1 +#endif + +/* Enable system power support */ +#define SDL_POWER_ANDROID 1 + +/* Enable the filesystem driver */ +#define SDL_FILESYSTEM_ANDROID 1 + +#endif /* SDL_config_android_h_ */ diff --git a/engine/Windows/SDL2/include/SDL_config_iphoneos.h b/engine/Windows/SDL2/include/SDL_config_iphoneos.h new file mode 100644 index 0000000..8137085 --- /dev/null +++ b/engine/Windows/SDL2/include/SDL_config_iphoneos.h @@ -0,0 +1,205 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2019 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef SDL_config_iphoneos_h_ +#define SDL_config_iphoneos_h_ +#define SDL_config_h_ + +#include "SDL_platform.h" + +#ifdef __LP64__ +#define SIZEOF_VOIDP 8 +#else +#define SIZEOF_VOIDP 4 +#endif + +#define HAVE_GCC_ATOMICS 1 + +#define STDC_HEADERS 1 +#define HAVE_ALLOCA_H 1 +#define HAVE_CTYPE_H 1 +#define HAVE_INTTYPES_H 1 +#define HAVE_LIMITS_H 1 +#define HAVE_MATH_H 1 +#define HAVE_SIGNAL_H 1 +#define HAVE_STDINT_H 1 +#define HAVE_STDIO_H 1 +#define HAVE_STRING_H 1 +#define HAVE_SYS_TYPES_H 1 +/* The libunwind functions are only available on x86 */ +/* #undef HAVE_LIBUNWIND_H */ + +/* C library functions */ +#define HAVE_MALLOC 1 +#define HAVE_CALLOC 1 +#define HAVE_REALLOC 1 +#define HAVE_FREE 1 +#define HAVE_ALLOCA 1 +#define HAVE_GETENV 1 +#define HAVE_SETENV 1 +#define HAVE_PUTENV 1 +#define HAVE_SETENV 1 +#define HAVE_UNSETENV 1 +#define HAVE_QSORT 1 +#define HAVE_ABS 1 +#define HAVE_BCOPY 1 +#define HAVE_MEMSET 1 +#define HAVE_MEMCPY 1 +#define HAVE_MEMMOVE 1 +#define HAVE_MEMCMP 1 +#define HAVE_STRLEN 1 +#define HAVE_STRLCPY 1 +#define HAVE_STRLCAT 1 +#define HAVE_STRCHR 1 +#define HAVE_STRRCHR 1 +#define HAVE_STRSTR 1 +#define HAVE_STRTOL 1 +#define HAVE_STRTOUL 1 +#define HAVE_STRTOLL 1 +#define HAVE_STRTOULL 1 +#define HAVE_STRTOD 1 +#define HAVE_ATOI 1 +#define HAVE_ATOF 1 +#define HAVE_STRCMP 1 +#define HAVE_STRNCMP 1 +#define HAVE_STRCASECMP 1 +#define HAVE_STRNCASECMP 1 +#define HAVE_VSSCANF 1 +#define HAVE_VSNPRINTF 1 +#define HAVE_M_PI 1 +#define HAVE_ACOS 1 +#define HAVE_ACOSF 1 +#define HAVE_ASIN 1 +#define HAVE_ASINF 1 +#define HAVE_ATAN 1 +#define HAVE_ATANF 1 +#define HAVE_ATAN2 1 +#define HAVE_ATAN2F 1 +#define HAVE_CEIL 1 +#define HAVE_CEILF 1 +#define HAVE_COPYSIGN 1 +#define HAVE_COPYSIGNF 1 +#define HAVE_COS 1 +#define HAVE_COSF 1 +#define HAVE_EXP 1 +#define HAVE_EXPF 1 +#define HAVE_FABS 1 +#define HAVE_FABSF 1 +#define HAVE_FLOOR 1 +#define HAVE_FLOORF 1 +#define HAVE_FMOD 1 +#define HAVE_FMODF 1 +#define HAVE_LOG 1 +#define HAVE_LOGF 1 +#define HAVE_LOG10 1 +#define HAVE_LOG10F 1 +#define HAVE_POW 1 +#define HAVE_POWF 1 +#define HAVE_SCALBN 1 +#define HAVE_SCALBNF 1 +#define HAVE_SIN 1 +#define HAVE_SINF 1 +#define HAVE_SQRT 1 +#define HAVE_SQRTF 1 +#define HAVE_TAN 1 +#define HAVE_TANF 1 +#define HAVE_SIGACTION 1 +#define HAVE_SETJMP 1 +#define HAVE_NANOSLEEP 1 +#define HAVE_SYSCONF 1 +#define HAVE_SYSCTLBYNAME 1 + +/* enable iPhone version of Core Audio driver */ +#define SDL_AUDIO_DRIVER_COREAUDIO 1 +/* Enable the dummy audio driver (src/audio/dummy/\*.c) */ +#define SDL_AUDIO_DRIVER_DUMMY 1 + +/* Enable the stub haptic driver (src/haptic/dummy/\*.c) */ +#define SDL_HAPTIC_DUMMY 1 + +/* Enable MFi joystick support */ +#define SDL_JOYSTICK_MFI 1 +/*#define SDL_JOYSTICK_HIDAPI 1*/ + +#ifdef __TVOS__ +#define SDL_SENSOR_DUMMY 1 +#else +/* Enable the CoreMotion sensor driver */ +#define SDL_SENSOR_COREMOTION 1 +#endif + +/* Enable Unix style SO loading */ +#define SDL_LOADSO_DLOPEN 1 + +/* Enable various threading systems */ +#define SDL_THREAD_PTHREAD 1 +#define SDL_THREAD_PTHREAD_RECURSIVE_MUTEX 1 + +/* Enable various timer systems */ +#define SDL_TIMER_UNIX 1 + +/* Supported video drivers */ +#define SDL_VIDEO_DRIVER_UIKIT 1 +#define SDL_VIDEO_DRIVER_DUMMY 1 + +/* Enable OpenGL ES */ +#define SDL_VIDEO_OPENGL_ES2 1 +#define SDL_VIDEO_OPENGL_ES 1 +#define SDL_VIDEO_RENDER_OGL_ES 1 +#define SDL_VIDEO_RENDER_OGL_ES2 1 + +/* Metal supported on 64-bit devices running iOS 8.0 and tvOS 9.0 and newer */ +#if !TARGET_OS_SIMULATOR && !TARGET_CPU_ARM && ((__IPHONE_OS_VERSION_MIN_REQUIRED >= 80000) || (__TV_OS_VERSION_MIN_REQUIRED >= 90000)) +#define SDL_PLATFORM_SUPPORTS_METAL 1 +#else +#define SDL_PLATFORM_SUPPORTS_METAL 0 +#endif + +#if SDL_PLATFORM_SUPPORTS_METAL +#define SDL_VIDEO_RENDER_METAL 1 +#endif + +#if SDL_PLATFORM_SUPPORTS_METAL +#define SDL_VIDEO_VULKAN 1 +#endif + +#if SDL_PLATFORM_SUPPORTS_METAL +#define SDL_VIDEO_METAL 1 +#endif + +/* Enable system power support */ +#define SDL_POWER_UIKIT 1 + +/* enable iPhone keyboard support */ +#define SDL_IPHONE_KEYBOARD 1 + +/* enable iOS extended launch screen */ +#define SDL_IPHONE_LAUNCHSCREEN 1 + +/* Set max recognized G-force from accelerometer + See src/joystick/uikit/SDL_sysjoystick.m for notes on why this is needed + */ +#define SDL_IPHONE_MAX_GFORCE 5.0 + +/* enable filesystem support */ +#define SDL_FILESYSTEM_COCOA 1 + +#endif /* SDL_config_iphoneos_h_ */ diff --git a/engine/Windows/SDL2/include/SDL_config_macosx.h b/engine/Windows/SDL2/include/SDL_config_macosx.h new file mode 100644 index 0000000..2035f2d --- /dev/null +++ b/engine/Windows/SDL2/include/SDL_config_macosx.h @@ -0,0 +1,257 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2019 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef SDL_config_macosx_h_ +#define SDL_config_macosx_h_ +#define SDL_config_h_ + +#include "SDL_platform.h" + +/* This gets us MAC_OS_X_VERSION_MIN_REQUIRED... */ +#include + +/* This is a set of defines to configure the SDL features */ + +#ifdef __LP64__ + #define SIZEOF_VOIDP 8 +#else + #define SIZEOF_VOIDP 4 +#endif + +/* Useful headers */ +#define STDC_HEADERS 1 +#define HAVE_ALLOCA_H 1 +#define HAVE_CTYPE_H 1 +#define HAVE_FLOAT_H 1 +#define HAVE_INTTYPES_H 1 +#define HAVE_LIMITS_H 1 +#define HAVE_MATH_H 1 +#define HAVE_SIGNAL_H 1 +#define HAVE_STDINT_H 1 +#define HAVE_STDIO_H 1 +#define HAVE_STRING_H 1 +#define HAVE_SYS_TYPES_H 1 +#define HAVE_LIBUNWIND_H 1 + +/* C library functions */ +#define HAVE_MALLOC 1 +#define HAVE_CALLOC 1 +#define HAVE_REALLOC 1 +#define HAVE_FREE 1 +#define HAVE_ALLOCA 1 +#define HAVE_GETENV 1 +#define HAVE_SETENV 1 +#define HAVE_PUTENV 1 +#define HAVE_UNSETENV 1 +#define HAVE_QSORT 1 +#define HAVE_ABS 1 +#define HAVE_BCOPY 1 +#define HAVE_MEMSET 1 +#define HAVE_MEMCPY 1 +#define HAVE_MEMMOVE 1 +#define HAVE_MEMCMP 1 +#define HAVE_STRLEN 1 +#define HAVE_STRLCPY 1 +#define HAVE_STRLCAT 1 +#define HAVE_STRCHR 1 +#define HAVE_STRRCHR 1 +#define HAVE_STRSTR 1 +#define HAVE_STRTOL 1 +#define HAVE_STRTOUL 1 +#define HAVE_STRTOLL 1 +#define HAVE_STRTOULL 1 +#define HAVE_STRTOD 1 +#define HAVE_ATOI 1 +#define HAVE_ATOF 1 +#define HAVE_STRCMP 1 +#define HAVE_STRNCMP 1 +#define HAVE_STRCASECMP 1 +#define HAVE_STRNCASECMP 1 +#define HAVE_VSSCANF 1 +#define HAVE_VSNPRINTF 1 +#define HAVE_M_PI 1 +#define HAVE_ACOS 1 +#define HAVE_ACOSF 1 +#define HAVE_ASIN 1 +#define HAVE_ASINF 1 +#define HAVE_ATAN 1 +#define HAVE_ATANF 1 +#define HAVE_ATAN2 1 +#define HAVE_ATAN2F 1 +#define HAVE_CEIL 1 +#define HAVE_CEILF 1 +#define HAVE_COPYSIGN 1 +#define HAVE_COPYSIGNF 1 +#define HAVE_COS 1 +#define HAVE_COSF 1 +#define HAVE_EXP 1 +#define HAVE_EXPF 1 +#define HAVE_FABS 1 +#define HAVE_FABSF 1 +#define HAVE_FLOOR 1 +#define HAVE_FLOORF 1 +#define HAVE_FMOD 1 +#define HAVE_FMODF 1 +#define HAVE_LOG 1 +#define HAVE_LOGF 1 +#define HAVE_LOG10 1 +#define HAVE_LOG10F 1 +#define HAVE_POW 1 +#define HAVE_POWF 1 +#define HAVE_SCALBN 1 +#define HAVE_SCALBNF 1 +#define HAVE_SIN 1 +#define HAVE_SINF 1 +#define HAVE_SQRT 1 +#define HAVE_SQRTF 1 +#define HAVE_TAN 1 +#define HAVE_TANF 1 +#define HAVE_SIGACTION 1 +#define HAVE_SETJMP 1 +#define HAVE_NANOSLEEP 1 +#define HAVE_SYSCONF 1 +#define HAVE_SYSCTLBYNAME 1 + +#define HAVE_GCC_ATOMICS 1 + +/* Enable various audio drivers */ +#define SDL_AUDIO_DRIVER_COREAUDIO 1 +#define SDL_AUDIO_DRIVER_DISK 1 +#define SDL_AUDIO_DRIVER_DUMMY 1 + +/* Enable various input drivers */ +#define SDL_JOYSTICK_IOKIT 1 +#define SDL_JOYSTICK_HIDAPI 1 +#define SDL_HAPTIC_IOKIT 1 + +/* Enable the dummy sensor driver */ +#define SDL_SENSOR_DUMMY 1 + +/* Enable various shared object loading systems */ +#define SDL_LOADSO_DLOPEN 1 + +/* Enable various threading systems */ +#define SDL_THREAD_PTHREAD 1 +#define SDL_THREAD_PTHREAD_RECURSIVE_MUTEX 1 + +/* Enable various timer systems */ +#define SDL_TIMER_UNIX 1 + +/* Enable various video drivers */ +#define SDL_VIDEO_DRIVER_COCOA 1 +#define SDL_VIDEO_DRIVER_DUMMY 1 +#undef SDL_VIDEO_DRIVER_X11 +#define SDL_VIDEO_DRIVER_X11_DYNAMIC "/opt/X11/lib/libX11.6.dylib" +#define SDL_VIDEO_DRIVER_X11_DYNAMIC_XEXT "/opt/X11/lib/libXext.6.dylib" +#define SDL_VIDEO_DRIVER_X11_DYNAMIC_XINERAMA "/opt/X11/lib/libXinerama.1.dylib" +#define SDL_VIDEO_DRIVER_X11_DYNAMIC_XINPUT2 "/opt/X11/lib/libXi.6.dylib" +#define SDL_VIDEO_DRIVER_X11_DYNAMIC_XRANDR "/opt/X11/lib/libXrandr.2.dylib" +#define SDL_VIDEO_DRIVER_X11_DYNAMIC_XSS "/opt/X11/lib/libXss.1.dylib" +#define SDL_VIDEO_DRIVER_X11_DYNAMIC_XVIDMODE "/opt/X11/lib/libXxf86vm.1.dylib" +#define SDL_VIDEO_DRIVER_X11_XDBE 1 +#define SDL_VIDEO_DRIVER_X11_XINERAMA 1 +#define SDL_VIDEO_DRIVER_X11_XRANDR 1 +#define SDL_VIDEO_DRIVER_X11_XSCRNSAVER 1 +#define SDL_VIDEO_DRIVER_X11_XSHAPE 1 +#define SDL_VIDEO_DRIVER_X11_XVIDMODE 1 +#define SDL_VIDEO_DRIVER_X11_HAS_XKBKEYCODETOKEYSYM 1 + +#ifdef MAC_OS_X_VERSION_10_8 +/* + * No matter the versions targeted, this is the 10.8 or later SDK, so you have + * to use the external Xquartz, which is a more modern Xlib. Previous SDKs + * used an older Xlib. + */ +#define SDL_VIDEO_DRIVER_X11_XINPUT2 1 +#define SDL_VIDEO_DRIVER_X11_SUPPORTS_GENERIC_EVENTS 1 +#define SDL_VIDEO_DRIVER_X11_CONST_PARAM_XEXTADDDISPLAY 1 +#endif + +#ifndef SDL_VIDEO_RENDER_OGL +#define SDL_VIDEO_RENDER_OGL 1 +#endif + +#ifndef SDL_VIDEO_RENDER_OGL_ES2 +#define SDL_VIDEO_RENDER_OGL_ES2 1 +#endif + +/* Metal only supported on 64-bit architectures with 10.11+ */ +#if TARGET_CPU_X86_64 && (MAC_OS_X_VERSION_MAX_ALLOWED >= 101100) +#define SDL_PLATFORM_SUPPORTS_METAL 1 +#else +#define SDL_PLATFORM_SUPPORTS_METAL 0 +#endif + +#ifndef SDL_VIDEO_RENDER_METAL +#if SDL_PLATFORM_SUPPORTS_METAL +#define SDL_VIDEO_RENDER_METAL 1 +#else +#define SDL_VIDEO_RENDER_METAL 0 +#endif +#endif + +/* Enable OpenGL support */ +#ifndef SDL_VIDEO_OPENGL +#define SDL_VIDEO_OPENGL 1 +#endif +#ifndef SDL_VIDEO_OPENGL_ES2 +#define SDL_VIDEO_OPENGL_ES2 1 +#endif +#ifndef SDL_VIDEO_OPENGL_EGL +#define SDL_VIDEO_OPENGL_EGL 1 +#endif +#ifndef SDL_VIDEO_OPENGL_CGL +#define SDL_VIDEO_OPENGL_CGL 1 +#endif +#ifndef SDL_VIDEO_OPENGL_GLX +#define SDL_VIDEO_OPENGL_GLX 1 +#endif + +/* Enable Vulkan and Metal support */ +#ifndef SDL_VIDEO_VULKAN +#if SDL_PLATFORM_SUPPORTS_METAL +#define SDL_VIDEO_VULKAN 1 +#else +#define SDL_VIDEO_VULKAN 0 +#endif +#endif + +#ifndef SDL_VIDEO_METAL +#if SDL_PLATFORM_SUPPORTS_METAL +#define SDL_VIDEO_METAL 1 +#else +#define SDL_VIDEO_METAL 0 +#endif +#endif + +/* Enable system power support */ +#define SDL_POWER_MACOSX 1 + +/* enable filesystem support */ +#define SDL_FILESYSTEM_COCOA 1 + +/* Enable assembly routines */ +#define SDL_ASSEMBLY_ROUTINES 1 +#ifdef __ppc__ +#define SDL_ALTIVEC_BLITTERS 1 +#endif + +#endif /* SDL_config_macosx_h_ */ diff --git a/engine/Windows/SDL2/include/SDL_config_minimal.h b/engine/Windows/SDL2/include/SDL_config_minimal.h new file mode 100644 index 0000000..20e45b8 --- /dev/null +++ b/engine/Windows/SDL2/include/SDL_config_minimal.h @@ -0,0 +1,85 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2019 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef SDL_config_minimal_h_ +#define SDL_config_minimal_h_ +#define SDL_config_h_ + +#include "SDL_platform.h" + +/** + * \file SDL_config_minimal.h + * + * This is the minimal configuration that can be used to build SDL. + */ + +#define HAVE_STDARG_H 1 +#define HAVE_STDDEF_H 1 + +/* Most everything except Visual Studio 2008 and earlier has stdint.h now */ +#if defined(_MSC_VER) && (_MSC_VER < 1600) +/* Here are some reasonable defaults */ +typedef unsigned int size_t; +typedef signed char int8_t; +typedef unsigned char uint8_t; +typedef signed short int16_t; +typedef unsigned short uint16_t; +typedef signed int int32_t; +typedef unsigned int uint32_t; +typedef signed long long int64_t; +typedef unsigned long long uint64_t; +typedef unsigned long uintptr_t; +#else +#define HAVE_STDINT_H 1 +#endif /* Visual Studio 2008 */ + +#ifdef __GNUC__ +#define HAVE_GCC_SYNC_LOCK_TEST_AND_SET 1 +#endif + +/* Enable the dummy audio driver (src/audio/dummy/\*.c) */ +#define SDL_AUDIO_DRIVER_DUMMY 1 + +/* Enable the stub joystick driver (src/joystick/dummy/\*.c) */ +#define SDL_JOYSTICK_DISABLED 1 + +/* Enable the stub haptic driver (src/haptic/dummy/\*.c) */ +#define SDL_HAPTIC_DISABLED 1 + +/* Enable the stub sensor driver (src/sensor/dummy/\*.c) */ +#define SDL_SENSOR_DISABLED 1 + +/* Enable the stub shared object loader (src/loadso/dummy/\*.c) */ +#define SDL_LOADSO_DISABLED 1 + +/* Enable the stub thread support (src/thread/generic/\*.c) */ +#define SDL_THREADS_DISABLED 1 + +/* Enable the stub timer support (src/timer/dummy/\*.c) */ +#define SDL_TIMERS_DISABLED 1 + +/* Enable the dummy video driver (src/video/dummy/\*.c) */ +#define SDL_VIDEO_DRIVER_DUMMY 1 + +/* Enable the dummy filesystem driver (src/filesystem/dummy/\*.c) */ +#define SDL_FILESYSTEM_DUMMY 1 + +#endif /* SDL_config_minimal_h_ */ diff --git a/engine/Windows/SDL2/include/SDL_config_os2.h b/engine/Windows/SDL2/include/SDL_config_os2.h new file mode 100644 index 0000000..bc75b3a --- /dev/null +++ b/engine/Windows/SDL2/include/SDL_config_os2.h @@ -0,0 +1,170 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2019 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef SDL_config_os2_h_ +#define SDL_config_os2_h_ +#define SDL_config_h_ + +#include "SDL_platform.h" + +#define SDL_AUDIO_DRIVER_DUMMY 1 +#define SDL_AUDIO_DRIVER_DISK 1 + +#define SDL_POWER_DISABLED 1 +#define SDL_JOYSTICK_DISABLED 1 +#define SDL_HAPTIC_DISABLED 1 +/*#undef SDL_JOYSTICK_HIDAPI */ + +#define SDL_SENSOR_DUMMY 1 +#define SDL_VIDEO_DRIVER_DUMMY 1 + +/* Enable OpenGL support */ +/* #undef SDL_VIDEO_OPENGL */ + +/* Enable Vulkan support */ +/* #undef SDL_VIDEO_VULKAN */ + +#define SDL_LOADSO_DISABLED 1 +#define SDL_THREADS_DISABLED 1 +#define SDL_TIMERS_DISABLED 1 +#define SDL_FILESYSTEM_DUMMY 1 + +/* Enable assembly routines */ +#define SDL_ASSEMBLY_ROUTINES 1 + +/* #undef HAVE_LIBSAMPLERATE_H */ + +/* Enable dynamic libsamplerate support */ +/* #undef SDL_LIBSAMPLERATE_DYNAMIC */ + +#define HAVE_LIBC 1 + +#define HAVE_SYS_TYPES_H 1 +#define HAVE_STDIO_H 1 +#define STDC_HEADERS 1 +#define HAVE_STDLIB_H 1 +#define HAVE_STDARG_H 1 +#define HAVE_STDDEF_H 1 +#define HAVE_MALLOC_H 1 +#define HAVE_MEMORY_H 1 +#define HAVE_STRING_H 1 +#define HAVE_STRINGS_H 1 +#define HAVE_WCHAR_H 1 +#define HAVE_INTTYPES_H 1 +#define HAVE_STDINT_H 1 +#define HAVE_LIMITS_H 1 +#define HAVE_CTYPE_H 1 +#define HAVE_MATH_H 1 +#define HAVE_FLOAT_H 1 +#define HAVE_SIGNAL_H 1 + +#define HAVE_MALLOC 1 +#define HAVE_CALLOC 1 +#define HAVE_REALLOC 1 +#define HAVE_FREE 1 +#if defined(__WATCOMC__) +#define HAVE__FSEEKI64 1 +#define HAVE__FTELLI64 1 +#endif +#define HAVE_ALLOCA 1 +#define HAVE_GETENV 1 +#define HAVE_SETENV 1 +#define HAVE_PUTENV 1 +#define HAVE_QSORT 1 +#define HAVE_ABS 1 +#define HAVE_BCOPY 1 +#define HAVE_MEMSET 1 +#define HAVE_MEMCPY 1 +#define HAVE_MEMMOVE 1 +#define HAVE_MEMCMP 1 +#define HAVE_WCSLEN 1 +#define HAVE_WCSLCPY 1 +#define HAVE_WCSLCAT 1 +#define HAVE_WCSCMP 1 +#define HAVE_STRLEN 1 +#define HAVE_STRLCPY 1 +#define HAVE_STRLCAT 1 +#define HAVE__STRREV 1 +#define HAVE__STRUPR 1 +#define HAVE__STRLWR 1 +#define HAVE_INDEX 1 +#define HAVE_RINDEX 1 +#define HAVE_STRCHR 1 +#define HAVE_STRRCHR 1 +#define HAVE_STRSTR 1 +#define HAVE_ITOA 1 +#define HAVE__LTOA 1 +#define HAVE__ULTOA 1 +#define HAVE_STRTOL 1 +#define HAVE_STRTOUL 1 +#define HAVE__I64TOA 1 +#define HAVE__UI64TOA 1 +#define HAVE_STRTOLL 1 +#define HAVE_STRTOULL 1 +#define HAVE_STRTOD 1 +#define HAVE_ATOI 1 +#define HAVE_ATOF 1 +#define HAVE_STRCMP 1 +#define HAVE_STRNCMP 1 +#define HAVE_STRICMP 1 +#define HAVE_STRCASECMP 1 +#define HAVE_STRNCASECMP 1 +#define HAVE_SSCANF 1 +#define HAVE_SNPRINTF 1 +#define HAVE_VSNPRINTF 1 +#define HAVE_SETJMP 1 +#define HAVE_ACOS 1 +/* #undef HAVE_ACOSF */ +#define HAVE_ASIN 1 +/* #undef HAVE_ASINF */ +#define HAVE_ATAN 1 +#define HAVE_ATAN2 1 +/* #undef HAVE_ATAN2F */ +#define HAVE_CEIL 1 +/* #undef HAVE_CEILF */ +/* #undef HAVE_COPYSIGN */ +/* #undef HAVE_COPYSIGNF */ +#define HAVE_COS 1 +/* #undef HAVE_COSF */ +#define HAVE_EXP 1 +/* #undef HAVE_EXPF */ +#define HAVE_FABS 1 +/* #undef HAVE_FABSF */ +#define HAVE_FLOOR 1 +/* #undef HAVE_FLOORF */ +#define HAVE_FMOD 1 +/* #undef HAVE_FMODF */ +#define HAVE_LOG 1 +/* #undef HAVE_LOGF */ +#define HAVE_LOG10 1 +/* #undef HAVE_LOG10F */ +#define HAVE_POW 1 +/* #undef HAVE_POWF */ +#define HAVE_SIN 1 +/* #undef HAVE_SINF */ +/* #undef HAVE_SCALBN */ +/* #undef HAVE_SCALBNF */ +#define HAVE_SQRT 1 +/* #undef HAVE_SQRTF */ +#define HAVE_TAN 1 +/* #undef HAVE_TANF */ + +#endif /* SDL_config_os2_h_ */ diff --git a/engine/Windows/SDL2/include/SDL_config_pandora.h b/engine/Windows/SDL2/include/SDL_config_pandora.h new file mode 100644 index 0000000..66ccf89 --- /dev/null +++ b/engine/Windows/SDL2/include/SDL_config_pandora.h @@ -0,0 +1,133 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2019 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef SDL_config_pandora_h_ +#define SDL_config_pandora_h_ +#define SDL_config_h_ + +/* This is a set of defines to configure the SDL features */ + +/* General platform specific identifiers */ +#include "SDL_platform.h" + +#ifdef __LP64__ +#define SIZEOF_VOIDP 8 +#else +#define SIZEOF_VOIDP 4 +#endif + +#define SDL_BYTEORDER 1234 + +#define STDC_HEADERS 1 +#define HAVE_ALLOCA_H 1 +#define HAVE_CTYPE_H 1 +#define HAVE_ICONV_H 1 +#define HAVE_INTTYPES_H 1 +#define HAVE_LIMITS_H 1 +#define HAVE_MALLOC_H 1 +#define HAVE_MATH_H 1 +#define HAVE_MEMORY_H 1 +#define HAVE_SIGNAL_H 1 +#define HAVE_STDARG_H 1 +#define HAVE_STDINT_H 1 +#define HAVE_STDIO_H 1 +#define HAVE_STDLIB_H 1 +#define HAVE_STRINGS_H 1 +#define HAVE_STRING_H 1 +#define HAVE_SYS_TYPES_H 1 + +#define HAVE_MALLOC 1 +#define HAVE_CALLOC 1 +#define HAVE_REALLOC 1 +#define HAVE_FREE 1 +#define HAVE_ALLOCA 1 +#define HAVE_GETENV 1 +#define HAVE_SETENV 1 +#define HAVE_PUTENV 1 +#define HAVE_UNSETENV 1 +#define HAVE_QSORT 1 +#define HAVE_ABS 1 +#define HAVE_BCOPY 1 +#define HAVE_MEMSET 1 +#define HAVE_MEMCPY 1 +#define HAVE_MEMMOVE 1 +#define HAVE_STRLEN 1 +#define HAVE_STRCHR 1 +#define HAVE_STRRCHR 1 +#define HAVE_STRSTR 1 +#define HAVE_STRTOL 1 +#define HAVE_STRTOUL 1 +#define HAVE_STRTOLL 1 +#define HAVE_STRTOULL 1 +#define HAVE_ATOI 1 +#define HAVE_ATOF 1 +#define HAVE_STRCMP 1 +#define HAVE_STRNCMP 1 +#define HAVE_STRCASECMP 1 +#define HAVE_STRNCASECMP 1 +#define HAVE_VSSCANF 1 +#define HAVE_VSNPRINTF 1 +#define HAVE_M_PI 1 +#define HAVE_CEIL 1 +#define HAVE_COPYSIGN 1 +#define HAVE_COS 1 +#define HAVE_COSF 1 +#define HAVE_EXP 1 +#define HAVE_FABS 1 +#define HAVE_FLOOR 1 +#define HAVE_LOG 1 +#define HAVE_LOG10 1 +#define HAVE_SCALBN 1 +#define HAVE_SIN 1 +#define HAVE_SINF 1 +#define HAVE_SQRT 1 +#define HAVE_SQRTF 1 +#define HAVE_TAN 1 +#define HAVE_TANF 1 +#define HAVE_SIGACTION 1 +#define HAVE_SETJMP 1 +#define HAVE_NANOSLEEP 1 + +#define SDL_AUDIO_DRIVER_DUMMY 1 +#define SDL_AUDIO_DRIVER_OSS 1 + +#define SDL_INPUT_LINUXEV 1 +#define SDL_INPUT_TSLIB 1 +#define SDL_JOYSTICK_LINUX 1 +#define SDL_HAPTIC_LINUX 1 + +#define SDL_SENSOR_DUMMY 1 + +#define SDL_LOADSO_DLOPEN 1 + +#define SDL_THREAD_PTHREAD 1 +#define SDL_THREAD_PTHREAD_RECURSIVE_MUTEX_NP 1 + +#define SDL_TIMER_UNIX 1 +#define SDL_FILESYSTEM_UNIX 1 + +#define SDL_VIDEO_DRIVER_DUMMY 1 +#define SDL_VIDEO_DRIVER_X11 1 +#define SDL_VIDEO_DRIVER_PANDORA 1 +#define SDL_VIDEO_RENDER_OGL_ES 1 +#define SDL_VIDEO_OPENGL_ES 1 + +#endif /* SDL_config_pandora_h_ */ diff --git a/engine/Windows/SDL2/include/SDL_config_psp.h b/engine/Windows/SDL2/include/SDL_config_psp.h new file mode 100644 index 0000000..dd2d6ec --- /dev/null +++ b/engine/Windows/SDL2/include/SDL_config_psp.h @@ -0,0 +1,164 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2019 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef SDL_config_psp_h_ +#define SDL_config_psp_h_ +#define SDL_config_h_ + +#include "SDL_platform.h" + + + +#ifdef __GNUC__ +#define HAVE_GCC_SYNC_LOCK_TEST_AND_SET 1 +#endif + +#define HAVE_GCC_ATOMICS 1 + +#define STDC_HEADERS 1 +#define HAVE_ALLOCA_H 1 +#define HAVE_CTYPE_H 1 +#define HAVE_INTTYPES_H 1 +#define HAVE_LIMITS_H 1 +#define HAVE_MATH_H 1 +#define HAVE_SIGNAL_H 1 +#define HAVE_STDINT_H 1 +#define HAVE_STDIO_H 1 +#define HAVE_STRING_H 1 +#define HAVE_SYS_TYPES_H 1 + +/* C library functions */ +#define HAVE_MALLOC 1 +#define HAVE_CALLOC 1 +#define HAVE_REALLOC 1 +#define HAVE_FREE 1 +#define HAVE_ALLOCA 1 +#define HAVE_GETENV 1 +#define HAVE_SETENV 1 +#define HAVE_PUTENV 1 +#define HAVE_SETENV 1 +#define HAVE_UNSETENV 1 +#define HAVE_QSORT 1 +#define HAVE_ABS 1 +#define HAVE_BCOPY 1 +#define HAVE_MEMSET 1 +#define HAVE_MEMCPY 1 +#define HAVE_MEMMOVE 1 +#define HAVE_MEMCMP 1 +#define HAVE_STRLEN 1 +#define HAVE_STRLCPY 1 +#define HAVE_STRLCAT 1 +#define HAVE_STRCHR 1 +#define HAVE_STRRCHR 1 +#define HAVE_STRSTR 1 +#define HAVE_STRTOL 1 +#define HAVE_STRTOUL 1 +#define HAVE_STRTOLL 1 +#define HAVE_STRTOULL 1 +#define HAVE_STRTOD 1 +#define HAVE_ATOI 1 +#define HAVE_ATOF 1 +#define HAVE_STRCMP 1 +#define HAVE_STRNCMP 1 +#define HAVE_STRCASECMP 1 +#define HAVE_STRNCASECMP 1 +#define HAVE_VSSCANF 1 +#define HAVE_VSNPRINTF 1 +#define HAVE_M_PI 1 +#define HAVE_ACOS 1 +#define HAVE_ACOSF 1 +#define HAVE_ASIN 1 +#define HAVE_ASINF 1 +#define HAVE_ATAN 1 +#define HAVE_ATANF 1 +#define HAVE_ATAN2 1 +#define HAVE_ATAN2F 1 +#define HAVE_CEIL 1 +#define HAVE_CEILF 1 +#define HAVE_COPYSIGN 1 +#define HAVE_COPYSIGNF 1 +#define HAVE_COS 1 +#define HAVE_COSF 1 +#define HAVE_EXP 1 +#define HAVE_EXPF 1 +#define HAVE_FABS 1 +#define HAVE_FABSF 1 +#define HAVE_FLOOR 1 +#define HAVE_FLOORF 1 +#define HAVE_FMOD 1 +#define HAVE_FMODF 1 +#define HAVE_LOG 1 +#define HAVE_LOGF 1 +#define HAVE_LOG10 1 +#define HAVE_LOG10F 1 +#define HAVE_POW 1 +#define HAVE_POWF 1 +#define HAVE_SCALBN 1 +#define HAVE_SCALBNF 1 +#define HAVE_SIN 1 +#define HAVE_SINF 1 +#define HAVE_SQRT 1 +#define HAVE_SQRTF 1 +#define HAVE_TAN 1 +#define HAVE_TANF 1 +#define HAVE_SETJMP 1 +#define HAVE_NANOSLEEP 1 +/* #define HAVE_SYSCONF 1 */ +/* #define HAVE_SIGACTION 1 */ + + +/* PSP isn't that sophisticated */ +#define LACKS_SYS_MMAN_H 1 + +/* Enable the PSP thread support (src/thread/psp/\*.c) */ +#define SDL_THREAD_PSP 1 + +/* Enable the PSP timer support (src/timer/psp/\*.c) */ +#define SDL_TIMERS_PSP 1 + +/* Enable the PSP joystick driver (src/joystick/psp/\*.c) */ +#define SDL_JOYSTICK_PSP 1 + +/* Enable the dummy sensor driver */ +#define SDL_SENSOR_DUMMY 1 + +/* Enable the PSP audio driver (src/audio/psp/\*.c) */ +#define SDL_AUDIO_DRIVER_PSP 1 + +/* PSP video driver */ +#define SDL_VIDEO_DRIVER_PSP 1 + +/* PSP render driver */ +#define SDL_VIDEO_RENDER_PSP 1 + +#define SDL_POWER_PSP 1 + +/* !!! FIXME: what does PSP do for filesystem stuff? */ +#define SDL_FILESYSTEM_DUMMY 1 + +/* PSP doesn't have haptic device (src/haptic/dummy/\*.c) */ +#define SDL_HAPTIC_DISABLED 1 + +/* PSP can't load shared object (src/loadso/dummy/\*.c) */ +#define SDL_LOADSO_DISABLED 1 + + +#endif /* SDL_config_psp_h_ */ diff --git a/engine/Windows/SDL2/include/SDL_config_windows.h b/engine/Windows/SDL2/include/SDL_config_windows.h new file mode 100644 index 0000000..cae9902 --- /dev/null +++ b/engine/Windows/SDL2/include/SDL_config_windows.h @@ -0,0 +1,256 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2019 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef SDL_config_windows_h_ +#define SDL_config_windows_h_ +#define SDL_config_h_ + +#include "SDL_platform.h" + +/* This is a set of defines to configure the SDL features */ + +#if !defined(_STDINT_H_) && (!defined(HAVE_STDINT_H) || !_HAVE_STDINT_H) +#if defined(__GNUC__) || defined(__DMC__) || defined(__WATCOMC__) +#define HAVE_STDINT_H 1 +#elif defined(_MSC_VER) +typedef signed __int8 int8_t; +typedef unsigned __int8 uint8_t; +typedef signed __int16 int16_t; +typedef unsigned __int16 uint16_t; +typedef signed __int32 int32_t; +typedef unsigned __int32 uint32_t; +typedef signed __int64 int64_t; +typedef unsigned __int64 uint64_t; +#ifndef _UINTPTR_T_DEFINED +#ifdef _WIN64 +typedef unsigned __int64 uintptr_t; +#else +typedef unsigned int uintptr_t; +#endif +#define _UINTPTR_T_DEFINED +#endif +/* Older Visual C++ headers don't have the Win64-compatible typedefs... */ +#if ((_MSC_VER <= 1200) && (!defined(DWORD_PTR))) +#define DWORD_PTR DWORD +#endif +#if ((_MSC_VER <= 1200) && (!defined(LONG_PTR))) +#define LONG_PTR LONG +#endif +#else /* !__GNUC__ && !_MSC_VER */ +typedef signed char int8_t; +typedef unsigned char uint8_t; +typedef signed short int16_t; +typedef unsigned short uint16_t; +typedef signed int int32_t; +typedef unsigned int uint32_t; +typedef signed long long int64_t; +typedef unsigned long long uint64_t; +#ifndef _SIZE_T_DEFINED_ +#define _SIZE_T_DEFINED_ +typedef unsigned int size_t; +#endif +typedef unsigned int uintptr_t; +#endif /* __GNUC__ || _MSC_VER */ +#endif /* !_STDINT_H_ && !HAVE_STDINT_H */ + +#ifdef _WIN64 +# define SIZEOF_VOIDP 8 +#else +# define SIZEOF_VOIDP 4 +#endif + +#define HAVE_DDRAW_H 1 +#define HAVE_DINPUT_H 1 +#define HAVE_DSOUND_H 1 +#define HAVE_DXGI_H 1 +#define HAVE_XINPUT_H 1 +#define HAVE_MMDEVICEAPI_H 1 +#define HAVE_AUDIOCLIENT_H 1 + +/* This is disabled by default to avoid C runtime dependencies and manifest requirements */ +#ifdef HAVE_LIBC +/* Useful headers */ +#define STDC_HEADERS 1 +#define HAVE_CTYPE_H 1 +#define HAVE_FLOAT_H 1 +#define HAVE_LIMITS_H 1 +#define HAVE_MATH_H 1 +#define HAVE_SIGNAL_H 1 +#define HAVE_STDIO_H 1 +#define HAVE_STRING_H 1 + +/* C library functions */ +#define HAVE_MALLOC 1 +#define HAVE_CALLOC 1 +#define HAVE_REALLOC 1 +#define HAVE_FREE 1 +#define HAVE_ALLOCA 1 +#define HAVE_QSORT 1 +#define HAVE_ABS 1 +#define HAVE_MEMSET 1 +#define HAVE_MEMCPY 1 +#define HAVE_MEMMOVE 1 +#define HAVE_MEMCMP 1 +#define HAVE_STRLEN 1 +#define HAVE__STRREV 1 +/* These functions have security warnings, so we won't use them */ +/* #undef HAVE__STRUPR */ +/* #undef HAVE__STRLWR */ +#define HAVE_STRCHR 1 +#define HAVE_STRRCHR 1 +#define HAVE_STRSTR 1 +/* These functions have security warnings, so we won't use them */ +/* #undef HAVE__LTOA */ +/* #undef HAVE__ULTOA */ +#define HAVE_STRTOL 1 +#define HAVE_STRTOUL 1 +#define HAVE_STRTOD 1 +#define HAVE_ATOI 1 +#define HAVE_ATOF 1 +#define HAVE_STRCMP 1 +#define HAVE_STRNCMP 1 +#define HAVE__STRICMP 1 +#define HAVE__STRNICMP 1 +#define HAVE_ACOS 1 +#define HAVE_ACOSF 1 +#define HAVE_ASIN 1 +#define HAVE_ASINF 1 +#define HAVE_ATAN 1 +#define HAVE_ATANF 1 +#define HAVE_ATAN2 1 +#define HAVE_ATAN2F 1 +#define HAVE_CEILF 1 +#define HAVE__COPYSIGN 1 +#define HAVE_COS 1 +#define HAVE_COSF 1 +#define HAVE_EXP 1 +#define HAVE_EXPF 1 +#define HAVE_FABS 1 +#define HAVE_FABSF 1 +#define HAVE_FLOOR 1 +#define HAVE_FLOORF 1 +#define HAVE_FMOD 1 +#define HAVE_FMODF 1 +#define HAVE_LOG 1 +#define HAVE_LOGF 1 +#define HAVE_LOG10 1 +#define HAVE_LOG10F 1 +#define HAVE_POW 1 +#define HAVE_POWF 1 +#define HAVE_SIN 1 +#define HAVE_SINF 1 +#define HAVE_SQRT 1 +#define HAVE_SQRTF 1 +#define HAVE_TAN 1 +#define HAVE_TANF 1 +#if defined(_MSC_VER) +/* These functions were added with the VC++ 2013 C runtime library */ +#if _MSC_VER >= 1800 +#define HAVE_STRTOLL 1 +#define HAVE_VSSCANF 1 +#define HAVE_SCALBN 1 +#define HAVE_SCALBNF 1 +#endif +/* This function is available with at least the VC++ 2008 C runtime library */ +#if _MSC_VER >= 1400 +#define HAVE__FSEEKI64 1 +#endif +#endif +#if !defined(_MSC_VER) || defined(_USE_MATH_DEFINES) +#define HAVE_M_PI 1 +#endif +#else +#define HAVE_STDARG_H 1 +#define HAVE_STDDEF_H 1 +#endif + +/* Enable various audio drivers */ +/* #undef SDL_AUDIO_DRIVER_WASAPI */ +#define SDL_AUDIO_DRIVER_DSOUND 1 +#define SDL_AUDIO_DRIVER_WINMM 1 +#define SDL_AUDIO_DRIVER_DISK 1 +#define SDL_AUDIO_DRIVER_DUMMY 1 + +/* Enable various input drivers */ +#define SDL_JOYSTICK_DINPUT 1 +#define SDL_JOYSTICK_XINPUT 1 +#define SDL_JOYSTICK_HIDAPI 1 +#define SDL_HAPTIC_DINPUT 1 +#define SDL_HAPTIC_XINPUT 1 + +/* Enable the dummy sensor driver */ +#define SDL_SENSOR_DUMMY 1 + +/* Enable various shared object loading systems */ +#define SDL_LOADSO_WINDOWS 1 + +/* Enable various threading systems */ +#define SDL_THREAD_WINDOWS 1 + +/* Enable various timer systems */ +#define SDL_TIMER_WINDOWS 1 + +/* Enable various video drivers */ +#define SDL_VIDEO_DRIVER_DUMMY 1 +#define SDL_VIDEO_DRIVER_WINDOWS 1 + +#ifndef SDL_VIDEO_RENDER_D3D +#define SDL_VIDEO_RENDER_D3D 1 +#endif +#ifndef SDL_VIDEO_RENDER_D3D11 +#define SDL_VIDEO_RENDER_D3D11 0 +#endif + +/* Enable OpenGL support */ +#ifndef SDL_VIDEO_OPENGL +#define SDL_VIDEO_OPENGL 1 +#endif +#ifndef SDL_VIDEO_OPENGL_WGL +#define SDL_VIDEO_OPENGL_WGL 1 +#endif +#ifndef SDL_VIDEO_RENDER_OGL +#define SDL_VIDEO_RENDER_OGL 1 +#endif +#ifndef SDL_VIDEO_RENDER_OGL_ES2 +#define SDL_VIDEO_RENDER_OGL_ES2 1 +#endif +#ifndef SDL_VIDEO_OPENGL_ES2 +#define SDL_VIDEO_OPENGL_ES2 1 +#endif +#ifndef SDL_VIDEO_OPENGL_EGL +#define SDL_VIDEO_OPENGL_EGL 1 +#endif + +/* Enable Vulkan support */ +#define SDL_VIDEO_VULKAN 1 + +/* Enable system power support */ +#define SDL_POWER_WINDOWS 1 + +/* Enable filesystem support */ +#define SDL_FILESYSTEM_WINDOWS 1 + +/* Enable assembly routines (Win64 doesn't have inline asm) */ +#ifndef _WIN64 +#define SDL_ASSEMBLY_ROUTINES 1 +#endif + +#endif /* SDL_config_windows_h_ */ diff --git a/engine/Windows/SDL2/include/SDL_config_winrt.h b/engine/Windows/SDL2/include/SDL_config_winrt.h new file mode 100644 index 0000000..8eeeb51 --- /dev/null +++ b/engine/Windows/SDL2/include/SDL_config_winrt.h @@ -0,0 +1,239 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2019 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef SDL_config_winrt_h_ +#define SDL_config_winrt_h_ +#define SDL_config_h_ + +#include "SDL_platform.h" + +/* Make sure the Windows SDK's NTDDI_VERSION macro gets defined. This is used + by SDL to determine which version of the Windows SDK is being used. +*/ +#include + +/* Define possibly-undefined NTDDI values (used when compiling SDL against + older versions of the Windows SDK. +*/ +#ifndef NTDDI_WINBLUE +#define NTDDI_WINBLUE 0x06030000 +#endif +#ifndef NTDDI_WIN10 +#define NTDDI_WIN10 0x0A000000 +#endif + +/* This is a set of defines to configure the SDL features */ + +#if !defined(_STDINT_H_) && (!defined(HAVE_STDINT_H) || !_HAVE_STDINT_H) +#if defined(__GNUC__) || defined(__DMC__) || defined(__WATCOMC__) +#define HAVE_STDINT_H 1 +#elif defined(_MSC_VER) +typedef signed __int8 int8_t; +typedef unsigned __int8 uint8_t; +typedef signed __int16 int16_t; +typedef unsigned __int16 uint16_t; +typedef signed __int32 int32_t; +typedef unsigned __int32 uint32_t; +typedef signed __int64 int64_t; +typedef unsigned __int64 uint64_t; +#ifndef _UINTPTR_T_DEFINED +#ifdef _WIN64 +typedef unsigned __int64 uintptr_t; +#else +typedef unsigned int uintptr_t; +#endif +#define _UINTPTR_T_DEFINED +#endif +/* Older Visual C++ headers don't have the Win64-compatible typedefs... */ +#if ((_MSC_VER <= 1200) && (!defined(DWORD_PTR))) +#define DWORD_PTR DWORD +#endif +#if ((_MSC_VER <= 1200) && (!defined(LONG_PTR))) +#define LONG_PTR LONG +#endif +#else /* !__GNUC__ && !_MSC_VER */ +typedef signed char int8_t; +typedef unsigned char uint8_t; +typedef signed short int16_t; +typedef unsigned short uint16_t; +typedef signed int int32_t; +typedef unsigned int uint32_t; +typedef signed long long int64_t; +typedef unsigned long long uint64_t; +#ifndef _SIZE_T_DEFINED_ +#define _SIZE_T_DEFINED_ +typedef unsigned int size_t; +#endif +typedef unsigned int uintptr_t; +#endif /* __GNUC__ || _MSC_VER */ +#endif /* !_STDINT_H_ && !HAVE_STDINT_H */ + +#ifdef _WIN64 +# define SIZEOF_VOIDP 8 +#else +# define SIZEOF_VOIDP 4 +#endif + +/* Useful headers */ +#define HAVE_DXGI_H 1 +#if WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP +#define HAVE_XINPUT_H 1 +#endif + +#define HAVE_MMDEVICEAPI_H 1 +#define HAVE_AUDIOCLIENT_H 1 + +#define HAVE_LIBC 1 +#define STDC_HEADERS 1 +#define HAVE_CTYPE_H 1 +#define HAVE_FLOAT_H 1 +#define HAVE_LIMITS_H 1 +#define HAVE_MATH_H 1 +#define HAVE_SIGNAL_H 1 +#define HAVE_STDIO_H 1 +#define HAVE_STRING_H 1 + +/* C library functions */ +#define HAVE_MALLOC 1 +#define HAVE_CALLOC 1 +#define HAVE_REALLOC 1 +#define HAVE_FREE 1 +#define HAVE_ALLOCA 1 +#define HAVE_QSORT 1 +#define HAVE_ABS 1 +#define HAVE_MEMSET 1 +#define HAVE_MEMCPY 1 +#define HAVE_MEMMOVE 1 +#define HAVE_MEMCMP 1 +#define HAVE_STRLEN 1 +#define HAVE__STRREV 1 +#define HAVE__STRUPR 1 +//#define HAVE__STRLWR 1 // TODO, WinRT: consider using _strlwr_s instead +#define HAVE_STRCHR 1 +#define HAVE_STRRCHR 1 +#define HAVE_STRSTR 1 +//#define HAVE_ITOA 1 // TODO, WinRT: consider using _itoa_s instead +//#define HAVE__LTOA 1 // TODO, WinRT: consider using _ltoa_s instead +//#define HAVE__ULTOA 1 // TODO, WinRT: consider using _ultoa_s instead +#define HAVE_STRTOL 1 +#define HAVE_STRTOUL 1 +//#define HAVE_STRTOLL 1 +#define HAVE_STRTOD 1 +#define HAVE_ATOI 1 +#define HAVE_ATOF 1 +#define HAVE_STRCMP 1 +#define HAVE_STRNCMP 1 +#define HAVE__STRICMP 1 +#define HAVE__STRNICMP 1 +#define HAVE_VSNPRINTF 1 +//#define HAVE_SSCANF 1 // TODO, WinRT: consider using sscanf_s instead +#define HAVE_M_PI 1 +#define HAVE_ACOS 1 +#define HAVE_ACOSF 1 +#define HAVE_ASIN 1 +#define HAVE_ASINF 1 +#define HAVE_ATAN 1 +#define HAVE_ATANF 1 +#define HAVE_ATAN2 1 +#define HAVE_ATAN2F 1 +#define HAVE_CEIL 1 +#define HAVE_CEILF 1 +#define HAVE__COPYSIGN 1 +#define HAVE_COS 1 +#define HAVE_COSF 1 +#define HAVE_EXP 1 +#define HAVE_EXPF 1 +#define HAVE_FABS 1 +#define HAVE_FABSF 1 +#define HAVE_FLOOR 1 +#define HAVE_FLOORF 1 +#define HAVE_FMOD 1 +#define HAVE_FMODF 1 +#define HAVE_LOG 1 +#define HAVE_LOGF 1 +#define HAVE_LOG10 1 +#define HAVE_LOG10F 1 +#define HAVE_POW 1 +#define HAVE_POWF 1 +#define HAVE__SCALB 1 +#define HAVE_SIN 1 +#define HAVE_SINF 1 +#define HAVE_SQRT 1 +#define HAVE_SQRTF 1 +#define HAVE_TAN 1 +#define HAVE_TANF 1 +#define HAVE__FSEEKI64 1 + +/* Enable various audio drivers */ +#define SDL_AUDIO_DRIVER_WASAPI 1 +#define SDL_AUDIO_DRIVER_DISK 1 +#define SDL_AUDIO_DRIVER_DUMMY 1 + +/* Enable various input drivers */ +#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP +#define SDL_JOYSTICK_DISABLED 1 +#define SDL_HAPTIC_DISABLED 1 +#else +#define SDL_JOYSTICK_XINPUT 1 +#define SDL_HAPTIC_XINPUT 1 +#endif + +/* Enable the dummy sensor driver */ +#define SDL_SENSOR_DUMMY 1 + +/* Enable various shared object loading systems */ +#define SDL_LOADSO_WINDOWS 1 + +/* Enable various threading systems */ +#if (NTDDI_VERSION >= NTDDI_WINBLUE) +#define SDL_THREAD_WINDOWS 1 +#else +/* WinRT on Windows 8.0 and Windows Phone 8.0 don't support CreateThread() */ +#define SDL_THREAD_STDCPP 1 +#endif + +/* Enable various timer systems */ +#define SDL_TIMER_WINDOWS 1 + +/* Enable various video drivers */ +#define SDL_VIDEO_DRIVER_WINRT 1 +#define SDL_VIDEO_DRIVER_DUMMY 1 + +/* Enable OpenGL ES 2.0 (via a modified ANGLE library) */ +#define SDL_VIDEO_OPENGL_ES2 1 +#define SDL_VIDEO_OPENGL_EGL 1 + +/* Enable appropriate renderer(s) */ +#define SDL_VIDEO_RENDER_D3D11 1 + +#if SDL_VIDEO_OPENGL_ES2 +#define SDL_VIDEO_RENDER_OGL_ES2 1 +#endif + +/* Enable system power support */ +#define SDL_POWER_WINRT 1 + +/* Enable assembly routines (Win64 doesn't have inline asm) */ +#ifndef _WIN64 +#define SDL_ASSEMBLY_ROUTINES 1 +#endif + +#endif /* SDL_config_winrt_h_ */ diff --git a/engine/Windows/SDL2/include/SDL_config_wiz.h b/engine/Windows/SDL2/include/SDL_config_wiz.h new file mode 100644 index 0000000..c5eb9b3 --- /dev/null +++ b/engine/Windows/SDL2/include/SDL_config_wiz.h @@ -0,0 +1,146 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2019 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef SDL_config_wiz_h_ +#define SDL_config_wiz_h_ +#define SDL_config_h_ + +/* This is a set of defines to configure the SDL features */ + +/* General platform specific identifiers */ +#include "SDL_platform.h" + +#define SDL_BYTEORDER 1234 + +#define STDC_HEADERS 1 +#define HAVE_ALLOCA_H 1 +#define HAVE_CTYPE_H 1 +#define HAVE_ICONV_H 1 +#define HAVE_INTTYPES_H 1 +#define HAVE_LIMITS_H 1 +#define HAVE_MALLOC_H 1 +#define HAVE_MATH_H 1 +#define HAVE_MEMORY_H 1 +#define HAVE_SIGNAL_H 1 +#define HAVE_STDARG_H 1 +#define HAVE_STDINT_H 1 +#define HAVE_STDIO_H 1 +#define HAVE_STDLIB_H 1 +#define HAVE_STRINGS_H 1 +#define HAVE_STRING_H 1 +#define HAVE_SYS_TYPES_H 1 + +#define HAVE_MALLOC 1 +#define HAVE_CALLOC 1 +#define HAVE_REALLOC 1 +#define HAVE_FREE 1 +#define HAVE_ALLOCA 1 +#define HAVE_GETENV 1 +#define HAVE_SETENV 1 +#define HAVE_PUTENV 1 +#define HAVE_UNSETENV 1 +#define HAVE_QSORT 1 +#define HAVE_ABS 1 +#define HAVE_BCOPY 1 +#define HAVE_MEMSET 1 +#define HAVE_MEMCPY 1 +#define HAVE_MEMMOVE 1 +#define HAVE_STRLEN 1 +#define HAVE_STRCHR 1 +#define HAVE_STRRCHR 1 +#define HAVE_STRSTR 1 +#define HAVE_STRTOL 1 +#define HAVE_STRTOUL 1 +#define HAVE_STRTOLL 1 +#define HAVE_STRTOULL 1 +#define HAVE_ATOI 1 +#define HAVE_ATOF 1 +#define HAVE_STRCMP 1 +#define HAVE_STRNCMP 1 +#define HAVE_STRCASECMP 1 +#define HAVE_STRNCASECMP 1 +#define HAVE_VSSCANF 1 +#define HAVE_VSNPRINTF 1 +#define HAVE_M_PI 1 +#define HAVE_ACOS 1 +#define HAVE_ACOSF 1 +#define HAVE_ASIN 1 +#define HAVE_ASINF 1 +#define HAVE_ATAN 1 +#define HAVE_ATANF 1 +#define HAVE_ATAN2 1 +#define HAVE_ATAN2F 1 +#define HAVE_CEIL 1 +#define HAVE_CEILF 1 +#define HAVE_COPYSIGN 1 +#define HAVE_COPYSIGNF 1 +#define HAVE_COS 1 +#define HAVE_COSF 1 +#define HAVE_EXP 1 +#define HAVE_EXPF 1 +#define HAVE_FABS 1 +#define HAVE_FABSF 1 +#define HAVE_FLOOR 1 +#define HAVE_FLOORF 1 +#define HAVE_FMOD 1 +#define HAVE_FMODF 1 +#define HAVE_LOG 1 +#define HAVE_LOGF 1 +#define HAVE_LOG10 1 +#define HAVE_LOG10F 1 +#define HAVE_POW 1 +#define HAVE_POWF 1 +#define HAVE_SCALBN 1 +#define HAVE_SCALBNF 1 +#define HAVE_SIN 1 +#define HAVE_SINF 1 +#define HAVE_SQRT 1 +#define HAVE_SQRTF 1 +#define HAVE_TAN 1 +#define HAVE_TANF 1 +#define HAVE_SIGACTION 1 +#define HAVE_SETJMP 1 +#define HAVE_NANOSLEEP 1 +#define HAVE_POW 1 + +#define SDL_AUDIO_DRIVER_DUMMY 1 +#define SDL_AUDIO_DRIVER_OSS 1 + +#define SDL_INPUT_LINUXEV 1 +#define SDL_INPUT_TSLIB 1 +#define SDL_JOYSTICK_LINUX 1 +#define SDL_HAPTIC_LINUX 1 + +#define SDL_SENSOR_DUMMY 1 + +#define SDL_LOADSO_DLOPEN 1 + +#define SDL_THREAD_PTHREAD 1 +#define SDL_THREAD_PTHREAD_RECURSIVE_MUTEX_NP 1 + +#define SDL_TIMER_UNIX 1 + +#define SDL_VIDEO_DRIVER_DUMMY 1 +#define SDL_VIDEO_DRIVER_PANDORA 1 +#define SDL_VIDEO_RENDER_OGL_ES 1 +#define SDL_VIDEO_OPENGL_ES 1 + +#endif /* SDL_config_wiz_h_ */ diff --git a/engine/Windows/SDL2/include/SDL_copying.h b/engine/Windows/SDL2/include/SDL_copying.h new file mode 100644 index 0000000..1ef18cd --- /dev/null +++ b/engine/Windows/SDL2/include/SDL_copying.h @@ -0,0 +1,20 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2019 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ diff --git a/engine/Windows/SDL2/include/SDL_cpuinfo.h b/engine/Windows/SDL2/include/SDL_cpuinfo.h new file mode 100644 index 0000000..2d094e8 --- /dev/null +++ b/engine/Windows/SDL2/include/SDL_cpuinfo.h @@ -0,0 +1,275 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2019 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_cpuinfo.h + * + * CPU feature detection for SDL. + */ + +#ifndef SDL_cpuinfo_h_ +#define SDL_cpuinfo_h_ + +#include "SDL_stdinc.h" + +/* Need to do this here because intrin.h has C++ code in it */ +/* Visual Studio 2005 has a bug where intrin.h conflicts with winnt.h */ +#if defined(_MSC_VER) && (_MSC_VER >= 1500) && (defined(_M_IX86) || defined(_M_X64)) +#ifdef __clang__ +/* Many of the intrinsics SDL uses are not implemented by clang with Visual Studio */ +#undef __MMX__ +#undef __SSE__ +#undef __SSE2__ +#else +#include +#ifndef _WIN64 +#ifndef __MMX__ +#define __MMX__ +#endif +#ifndef __3dNOW__ +#define __3dNOW__ +#endif +#endif +#ifndef __SSE__ +#define __SSE__ +#endif +#ifndef __SSE2__ +#define __SSE2__ +#endif +#endif /* __clang__ */ +#elif defined(__MINGW64_VERSION_MAJOR) +#include +#else +/* altivec.h redefining bool causes a number of problems, see bugs 3993 and 4392, so you need to explicitly define SDL_ENABLE_ALTIVEC_H to have it included. */ +#if defined(HAVE_ALTIVEC_H) && defined(__ALTIVEC__) && !defined(__APPLE_ALTIVEC__) && defined(SDL_ENABLE_ALTIVEC_H) +#include +#endif +#if !defined(SDL_DISABLE_ARM_NEON_H) +# if defined(__ARM_NEON) +# include +# elif defined(__WINDOWS__) || defined(__WINRT__) +/* Visual Studio doesn't define __ARM_ARCH, but _M_ARM (if set, always 7), and _M_ARM64 (if set, always 1). */ +# if defined(_M_ARM) +# include +# include +# define __ARM_NEON 1 /* Set __ARM_NEON so that it can be used elsewhere, at compile time */ +# endif +# if defined (_M_ARM64) +# include +# include +# define __ARM_NEON 1 /* Set __ARM_NEON so that it can be used elsewhere, at compile time */ +# endif +# endif +#endif +#if defined(__3dNOW__) && !defined(SDL_DISABLE_MM3DNOW_H) +#include +#endif +#if defined(HAVE_IMMINTRIN_H) && !defined(SDL_DISABLE_IMMINTRIN_H) +#include +#else +#if defined(__MMX__) && !defined(SDL_DISABLE_MMINTRIN_H) +#include +#endif +#if defined(__SSE__) && !defined(SDL_DISABLE_XMMINTRIN_H) +#include +#endif +#if defined(__SSE2__) && !defined(SDL_DISABLE_EMMINTRIN_H) +#include +#endif +#if defined(__SSE3__) && !defined(SDL_DISABLE_PMMINTRIN_H) +#include +#endif +#endif /* HAVE_IMMINTRIN_H */ +#endif /* compiler version */ + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/* This is a guess for the cacheline size used for padding. + * Most x86 processors have a 64 byte cache line. + * The 64-bit PowerPC processors have a 128 byte cache line. + * We'll use the larger value to be generally safe. + */ +#define SDL_CACHELINE_SIZE 128 + +/** + * This function returns the number of CPU cores available. + */ +extern DECLSPEC int SDLCALL SDL_GetCPUCount(void); + +/** + * This function returns the L1 cache line size of the CPU + * + * This is useful for determining multi-threaded structure padding + * or SIMD prefetch sizes. + */ +extern DECLSPEC int SDLCALL SDL_GetCPUCacheLineSize(void); + +/** + * This function returns true if the CPU has the RDTSC instruction. + */ +extern DECLSPEC SDL_bool SDLCALL SDL_HasRDTSC(void); + +/** + * This function returns true if the CPU has AltiVec features. + */ +extern DECLSPEC SDL_bool SDLCALL SDL_HasAltiVec(void); + +/** + * This function returns true if the CPU has MMX features. + */ +extern DECLSPEC SDL_bool SDLCALL SDL_HasMMX(void); + +/** + * This function returns true if the CPU has 3DNow! features. + */ +extern DECLSPEC SDL_bool SDLCALL SDL_Has3DNow(void); + +/** + * This function returns true if the CPU has SSE features. + */ +extern DECLSPEC SDL_bool SDLCALL SDL_HasSSE(void); + +/** + * This function returns true if the CPU has SSE2 features. + */ +extern DECLSPEC SDL_bool SDLCALL SDL_HasSSE2(void); + +/** + * This function returns true if the CPU has SSE3 features. + */ +extern DECLSPEC SDL_bool SDLCALL SDL_HasSSE3(void); + +/** + * This function returns true if the CPU has SSE4.1 features. + */ +extern DECLSPEC SDL_bool SDLCALL SDL_HasSSE41(void); + +/** + * This function returns true if the CPU has SSE4.2 features. + */ +extern DECLSPEC SDL_bool SDLCALL SDL_HasSSE42(void); + +/** + * This function returns true if the CPU has AVX features. + */ +extern DECLSPEC SDL_bool SDLCALL SDL_HasAVX(void); + +/** + * This function returns true if the CPU has AVX2 features. + */ +extern DECLSPEC SDL_bool SDLCALL SDL_HasAVX2(void); + +/** + * This function returns true if the CPU has AVX-512F (foundation) features. + */ +extern DECLSPEC SDL_bool SDLCALL SDL_HasAVX512F(void); + +/** + * This function returns true if the CPU has ARM SIMD (ARMv6) features. + */ +extern DECLSPEC SDL_bool SDLCALL SDL_HasARMSIMD(void); + +/** + * This function returns true if the CPU has NEON (ARM SIMD) features. + */ +extern DECLSPEC SDL_bool SDLCALL SDL_HasNEON(void); + +/** + * This function returns the amount of RAM configured in the system, in MB. + */ +extern DECLSPEC int SDLCALL SDL_GetSystemRAM(void); + +/** + * \brief Report the alignment this system needs for SIMD allocations. + * + * This will return the minimum number of bytes to which a pointer must be + * aligned to be compatible with SIMD instructions on the current machine. + * For example, if the machine supports SSE only, it will return 16, but if + * it supports AVX-512F, it'll return 64 (etc). This only reports values for + * instruction sets SDL knows about, so if your SDL build doesn't have + * SDL_HasAVX512F(), then it might return 16 for the SSE support it sees and + * not 64 for the AVX-512 instructions that exist but SDL doesn't know about. + * Plan accordingly. + */ +extern DECLSPEC size_t SDLCALL SDL_SIMDGetAlignment(void); + +/** + * \brief Allocate memory in a SIMD-friendly way. + * + * This will allocate a block of memory that is suitable for use with SIMD + * instructions. Specifically, it will be properly aligned and padded for + * the system's supported vector instructions. + * + * The memory returned will be padded such that it is safe to read or write + * an incomplete vector at the end of the memory block. This can be useful + * so you don't have to drop back to a scalar fallback at the end of your + * SIMD processing loop to deal with the final elements without overflowing + * the allocated buffer. + * + * You must free this memory with SDL_FreeSIMD(), not free() or SDL_free() + * or delete[], etc. + * + * Note that SDL will only deal with SIMD instruction sets it is aware of; + * for example, SDL 2.0.8 knows that SSE wants 16-byte vectors + * (SDL_HasSSE()), and AVX2 wants 32 bytes (SDL_HasAVX2()), but doesn't + * know that AVX-512 wants 64. To be clear: if you can't decide to use an + * instruction set with an SDL_Has*() function, don't use that instruction + * set with memory allocated through here. + * + * SDL_AllocSIMD(0) will return a non-NULL pointer, assuming the system isn't + * out of memory. + * + * \param len The length, in bytes, of the block to allocated. The actual + * allocated block might be larger due to padding, etc. + * \return Pointer to newly-allocated block, NULL if out of memory. + * + * \sa SDL_SIMDAlignment + * \sa SDL_SIMDFree + */ +extern DECLSPEC void * SDLCALL SDL_SIMDAlloc(const size_t len); + +/** + * \brief Deallocate memory obtained from SDL_SIMDAlloc + * + * It is not valid to use this function on a pointer from anything but + * SDL_SIMDAlloc(). It can't be used on pointers from malloc, realloc, + * SDL_malloc, memalign, new[], etc. + * + * However, SDL_SIMDFree(NULL) is a legal no-op. + * + * \sa SDL_SIMDAlloc + */ +extern DECLSPEC void SDLCALL SDL_SIMDFree(void *ptr); + +/* vi: set ts=4 sw=4 expandtab: */ +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_cpuinfo_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/engine/Windows/SDL2/include/SDL_egl.h b/engine/Windows/SDL2/include/SDL_egl.h new file mode 100644 index 0000000..f95a906 --- /dev/null +++ b/engine/Windows/SDL2/include/SDL_egl.h @@ -0,0 +1,1676 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2019 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_egl.h + * + * This is a simple file to encapsulate the EGL API headers. + */ +#if !defined(_MSC_VER) && !defined(__ANDROID__) + +#include +#include + +#else /* _MSC_VER */ + +/* EGL headers for Visual Studio */ + +#ifndef __khrplatform_h_ +#define __khrplatform_h_ + +/* +** Copyright (c) 2008-2009 The Khronos Group Inc. +** +** Permission is hereby granted, free of charge, to any person obtaining a +** copy of this software and/or associated documentation files (the +** "Materials"), to deal in the Materials without restriction, including +** without limitation the rights to use, copy, modify, merge, publish, +** distribute, sublicense, and/or sell copies of the Materials, and to +** permit persons to whom the Materials are furnished to do so, subject to +** the following conditions: +** +** The above copyright notice and this permission notice shall be included +** in all copies or substantial portions of the Materials. +** +** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. +*/ + +/* Khronos platform-specific types and definitions. +* +* $Revision: 23298 $ on $Date: 2013-09-30 17:07:13 -0700 (Mon, 30 Sep 2013) $ +* +* Adopters may modify this file to suit their platform. Adopters are +* encouraged to submit platform specific modifications to the Khronos +* group so that they can be included in future versions of this file. +* Please submit changes by sending them to the public Khronos Bugzilla +* (http://khronos.org/bugzilla) by filing a bug against product +* "Khronos (general)" component "Registry". +* +* A predefined template which fills in some of the bug fields can be +* reached using http://tinyurl.com/khrplatform-h-bugreport, but you +* must create a Bugzilla login first. +* +* +* See the Implementer's Guidelines for information about where this file +* should be located on your system and for more details of its use: +* http://www.khronos.org/registry/implementers_guide.pdf +* +* This file should be included as +* #include +* by Khronos client API header files that use its types and defines. +* +* The types in khrplatform.h should only be used to define API-specific types. +* +* Types defined in khrplatform.h: +* khronos_int8_t signed 8 bit +* khronos_uint8_t unsigned 8 bit +* khronos_int16_t signed 16 bit +* khronos_uint16_t unsigned 16 bit +* khronos_int32_t signed 32 bit +* khronos_uint32_t unsigned 32 bit +* khronos_int64_t signed 64 bit +* khronos_uint64_t unsigned 64 bit +* khronos_intptr_t signed same number of bits as a pointer +* khronos_uintptr_t unsigned same number of bits as a pointer +* khronos_ssize_t signed size +* khronos_usize_t unsigned size +* khronos_float_t signed 32 bit floating point +* khronos_time_ns_t unsigned 64 bit time in nanoseconds +* khronos_utime_nanoseconds_t unsigned time interval or absolute time in +* nanoseconds +* khronos_stime_nanoseconds_t signed time interval in nanoseconds +* khronos_boolean_enum_t enumerated boolean type. This should +* only be used as a base type when a client API's boolean type is +* an enum. Client APIs which use an integer or other type for +* booleans cannot use this as the base type for their boolean. +* +* Tokens defined in khrplatform.h: +* +* KHRONOS_FALSE, KHRONOS_TRUE Enumerated boolean false/true values. +* +* KHRONOS_SUPPORT_INT64 is 1 if 64 bit integers are supported; otherwise 0. +* KHRONOS_SUPPORT_FLOAT is 1 if floats are supported; otherwise 0. +* +* Calling convention macros defined in this file: +* KHRONOS_APICALL +* KHRONOS_APIENTRY +* KHRONOS_APIATTRIBUTES +* +* These may be used in function prototypes as: +* +* KHRONOS_APICALL void KHRONOS_APIENTRY funcname( +* int arg1, +* int arg2) KHRONOS_APIATTRIBUTES; +*/ + +/*------------------------------------------------------------------------- +* Definition of KHRONOS_APICALL +*------------------------------------------------------------------------- +* This precedes the return type of the function in the function prototype. +*/ +#if defined(_WIN32) && !defined(__SCITECH_SNAP__) && !defined(SDL_VIDEO_STATIC_ANGLE) +# define KHRONOS_APICALL __declspec(dllimport) +#elif defined (__SYMBIAN32__) +# define KHRONOS_APICALL IMPORT_C +#else +# define KHRONOS_APICALL +#endif + +/*------------------------------------------------------------------------- +* Definition of KHRONOS_APIENTRY +*------------------------------------------------------------------------- +* This follows the return type of the function and precedes the function +* name in the function prototype. +*/ +#if defined(_WIN32) && !defined(_WIN32_WCE) && !defined(__SCITECH_SNAP__) +/* Win32 but not WinCE */ +# define KHRONOS_APIENTRY __stdcall +#else +# define KHRONOS_APIENTRY +#endif + +/*------------------------------------------------------------------------- +* Definition of KHRONOS_APIATTRIBUTES +*------------------------------------------------------------------------- +* This follows the closing parenthesis of the function prototype arguments. +*/ +#if defined (__ARMCC_2__) +#define KHRONOS_APIATTRIBUTES __softfp +#else +#define KHRONOS_APIATTRIBUTES +#endif + +/*------------------------------------------------------------------------- +* basic type definitions +*-----------------------------------------------------------------------*/ +#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || defined(__GNUC__) || defined(__SCO__) || defined(__USLC__) + + +/* +* Using +*/ +#include +typedef int32_t khronos_int32_t; +typedef uint32_t khronos_uint32_t; +typedef int64_t khronos_int64_t; +typedef uint64_t khronos_uint64_t; +#define KHRONOS_SUPPORT_INT64 1 +#define KHRONOS_SUPPORT_FLOAT 1 + +#elif defined(__VMS ) || defined(__sgi) + +/* +* Using +*/ +#include +typedef int32_t khronos_int32_t; +typedef uint32_t khronos_uint32_t; +typedef int64_t khronos_int64_t; +typedef uint64_t khronos_uint64_t; +#define KHRONOS_SUPPORT_INT64 1 +#define KHRONOS_SUPPORT_FLOAT 1 + +#elif defined(_WIN32) && !defined(__SCITECH_SNAP__) + +/* +* Win32 +*/ +typedef __int32 khronos_int32_t; +typedef unsigned __int32 khronos_uint32_t; +typedef __int64 khronos_int64_t; +typedef unsigned __int64 khronos_uint64_t; +#define KHRONOS_SUPPORT_INT64 1 +#define KHRONOS_SUPPORT_FLOAT 1 + +#elif defined(__sun__) || defined(__digital__) + +/* +* Sun or Digital +*/ +typedef int khronos_int32_t; +typedef unsigned int khronos_uint32_t; +#if defined(__arch64__) || defined(_LP64) +typedef long int khronos_int64_t; +typedef unsigned long int khronos_uint64_t; +#else +typedef long long int khronos_int64_t; +typedef unsigned long long int khronos_uint64_t; +#endif /* __arch64__ */ +#define KHRONOS_SUPPORT_INT64 1 +#define KHRONOS_SUPPORT_FLOAT 1 + +#elif 0 + +/* +* Hypothetical platform with no float or int64 support +*/ +typedef int khronos_int32_t; +typedef unsigned int khronos_uint32_t; +#define KHRONOS_SUPPORT_INT64 0 +#define KHRONOS_SUPPORT_FLOAT 0 + +#else + +/* +* Generic fallback +*/ +#include +typedef int32_t khronos_int32_t; +typedef uint32_t khronos_uint32_t; +typedef int64_t khronos_int64_t; +typedef uint64_t khronos_uint64_t; +#define KHRONOS_SUPPORT_INT64 1 +#define KHRONOS_SUPPORT_FLOAT 1 + +#endif + + +/* +* Types that are (so far) the same on all platforms +*/ +typedef signed char khronos_int8_t; +typedef unsigned char khronos_uint8_t; +typedef signed short int khronos_int16_t; +typedef unsigned short int khronos_uint16_t; + +/* +* Types that differ between LLP64 and LP64 architectures - in LLP64, +* pointers are 64 bits, but 'long' is still 32 bits. Win64 appears +* to be the only LLP64 architecture in current use. +*/ +#ifdef _WIN64 +typedef signed long long int khronos_intptr_t; +typedef unsigned long long int khronos_uintptr_t; +typedef signed long long int khronos_ssize_t; +typedef unsigned long long int khronos_usize_t; +#else +typedef signed long int khronos_intptr_t; +typedef unsigned long int khronos_uintptr_t; +typedef signed long int khronos_ssize_t; +typedef unsigned long int khronos_usize_t; +#endif + +#if KHRONOS_SUPPORT_FLOAT +/* +* Float type +*/ +typedef float khronos_float_t; +#endif + +#if KHRONOS_SUPPORT_INT64 +/* Time types +* +* These types can be used to represent a time interval in nanoseconds or +* an absolute Unadjusted System Time. Unadjusted System Time is the number +* of nanoseconds since some arbitrary system event (e.g. since the last +* time the system booted). The Unadjusted System Time is an unsigned +* 64 bit value that wraps back to 0 every 584 years. Time intervals +* may be either signed or unsigned. +*/ +typedef khronos_uint64_t khronos_utime_nanoseconds_t; +typedef khronos_int64_t khronos_stime_nanoseconds_t; +#endif + +/* +* Dummy value used to pad enum types to 32 bits. +*/ +#ifndef KHRONOS_MAX_ENUM +#define KHRONOS_MAX_ENUM 0x7FFFFFFF +#endif + +/* +* Enumerated boolean type +* +* Values other than zero should be considered to be true. Therefore +* comparisons should not be made against KHRONOS_TRUE. +*/ +typedef enum { + KHRONOS_FALSE = 0, + KHRONOS_TRUE = 1, + KHRONOS_BOOLEAN_ENUM_FORCE_SIZE = KHRONOS_MAX_ENUM +} khronos_boolean_enum_t; + +#endif /* __khrplatform_h_ */ + + +#ifndef __eglplatform_h_ +#define __eglplatform_h_ + +/* +** Copyright (c) 2007-2009 The Khronos Group Inc. +** +** Permission is hereby granted, free of charge, to any person obtaining a +** copy of this software and/or associated documentation files (the +** "Materials"), to deal in the Materials without restriction, including +** without limitation the rights to use, copy, modify, merge, publish, +** distribute, sublicense, and/or sell copies of the Materials, and to +** permit persons to whom the Materials are furnished to do so, subject to +** the following conditions: +** +** The above copyright notice and this permission notice shall be included +** in all copies or substantial portions of the Materials. +** +** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. +*/ + +/* Platform-specific types and definitions for egl.h +* $Revision: 12306 $ on $Date: 2010-08-25 09:51:28 -0700 (Wed, 25 Aug 2010) $ +* +* Adopters may modify khrplatform.h and this file to suit their platform. +* You are encouraged to submit all modifications to the Khronos group so that +* they can be included in future versions of this file. Please submit changes +* by sending them to the public Khronos Bugzilla (http://khronos.org/bugzilla) +* by filing a bug against product "EGL" component "Registry". +*/ + +/*#include */ + +/* Macros used in EGL function prototype declarations. +* +* EGL functions should be prototyped as: +* +* EGLAPI return-type EGLAPIENTRY eglFunction(arguments); +* typedef return-type (EXPAPIENTRYP PFNEGLFUNCTIONPROC) (arguments); +* +* KHRONOS_APICALL and KHRONOS_APIENTRY are defined in KHR/khrplatform.h +*/ + +#ifndef EGLAPI +#define EGLAPI KHRONOS_APICALL +#endif + +#ifndef EGLAPIENTRY +#define EGLAPIENTRY KHRONOS_APIENTRY +#endif +#define EGLAPIENTRYP EGLAPIENTRY* + +/* The types NativeDisplayType, NativeWindowType, and NativePixmapType +* are aliases of window-system-dependent types, such as X Display * or +* Windows Device Context. They must be defined in platform-specific +* code below. The EGL-prefixed versions of Native*Type are the same +* types, renamed in EGL 1.3 so all types in the API start with "EGL". +* +* Khronos STRONGLY RECOMMENDS that you use the default definitions +* provided below, since these changes affect both binary and source +* portability of applications using EGL running on different EGL +* implementations. +*/ + +#if defined(_WIN32) || defined(__VC32__) && !defined(__CYGWIN__) && !defined(__SCITECH_SNAP__) /* Win32 and WinCE */ +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN 1 +#endif +#ifndef NOMINMAX /* don't define min() and max(). */ +#define NOMINMAX +#endif +#include + +#if __WINRT__ +#include +typedef IUnknown * EGLNativeWindowType; +typedef IUnknown * EGLNativePixmapType; +typedef IUnknown * EGLNativeDisplayType; +#else +typedef HDC EGLNativeDisplayType; +typedef HBITMAP EGLNativePixmapType; +typedef HWND EGLNativeWindowType; +#endif + +#elif defined(__WINSCW__) || defined(__SYMBIAN32__) /* Symbian */ + +typedef int EGLNativeDisplayType; +typedef void *EGLNativeWindowType; +typedef void *EGLNativePixmapType; + +#elif defined(WL_EGL_PLATFORM) + +typedef struct wl_display *EGLNativeDisplayType; +typedef struct wl_egl_pixmap *EGLNativePixmapType; +typedef struct wl_egl_window *EGLNativeWindowType; + +#elif defined(__GBM__) + +typedef struct gbm_device *EGLNativeDisplayType; +typedef struct gbm_bo *EGLNativePixmapType; +typedef void *EGLNativeWindowType; + +#elif defined(__ANDROID__) /* Android */ + +struct ANativeWindow; +struct egl_native_pixmap_t; + +typedef struct ANativeWindow *EGLNativeWindowType; +typedef struct egl_native_pixmap_t *EGLNativePixmapType; +typedef void *EGLNativeDisplayType; + +#elif defined(MIR_EGL_PLATFORM) + +#include +typedef MirEGLNativeDisplayType EGLNativeDisplayType; +typedef void *EGLNativePixmapType; +typedef MirEGLNativeWindowType EGLNativeWindowType; + +#elif defined(__unix__) + +#ifdef MESA_EGL_NO_X11_HEADERS + +typedef void *EGLNativeDisplayType; +typedef khronos_uintptr_t EGLNativePixmapType; +typedef khronos_uintptr_t EGLNativeWindowType; + +#else + +/* X11 (tentative) */ +#include +#include + +typedef Display *EGLNativeDisplayType; +typedef Pixmap EGLNativePixmapType; +typedef Window EGLNativeWindowType; + +#endif /* MESA_EGL_NO_X11_HEADERS */ + +#else +#error "Platform not recognized" +#endif + +/* EGL 1.2 types, renamed for consistency in EGL 1.3 */ +typedef EGLNativeDisplayType NativeDisplayType; +typedef EGLNativePixmapType NativePixmapType; +typedef EGLNativeWindowType NativeWindowType; + + +/* Define EGLint. This must be a signed integral type large enough to contain +* all legal attribute names and values passed into and out of EGL, whether +* their type is boolean, bitmask, enumerant (symbolic constant), integer, +* handle, or other. While in general a 32-bit integer will suffice, if +* handles are 64 bit types, then EGLint should be defined as a signed 64-bit +* integer type. +*/ +typedef khronos_int32_t EGLint; + +#endif /* __eglplatform_h */ + +#ifndef __egl_h_ +#define __egl_h_ 1 + +#ifdef __cplusplus +extern "C" { +#endif + +/* +** Copyright (c) 2013-2015 The Khronos Group Inc. +** +** Permission is hereby granted, free of charge, to any person obtaining a +** copy of this software and/or associated documentation files (the +** "Materials"), to deal in the Materials without restriction, including +** without limitation the rights to use, copy, modify, merge, publish, +** distribute, sublicense, and/or sell copies of the Materials, and to +** permit persons to whom the Materials are furnished to do so, subject to +** the following conditions: +** +** The above copyright notice and this permission notice shall be included +** in all copies or substantial portions of the Materials. +** +** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. +*/ +/* +** This header is generated from the Khronos OpenGL / OpenGL ES XML +** API Registry. The current version of the Registry, generator scripts +** used to make the header, and the header can be found at +** http://www.opengl.org/registry/ +** +** Khronos $Revision: 31566 $ on $Date: 2015-06-23 08:48:48 -0700 (Tue, 23 Jun 2015) $ +*/ + +/*#include */ + +/* Generated on date 20150623 */ + +/* Generated C header for: + * API: egl + * Versions considered: .* + * Versions emitted: .* + * Default extensions included: None + * Additional extensions included: _nomatch_^ + * Extensions removed: _nomatch_^ + */ + +#ifndef EGL_VERSION_1_0 +#define EGL_VERSION_1_0 1 +typedef unsigned int EGLBoolean; +typedef void *EGLDisplay; +typedef void *EGLConfig; +typedef void *EGLSurface; +typedef void *EGLContext; +typedef void (*__eglMustCastToProperFunctionPointerType)(void); +#define EGL_ALPHA_SIZE 0x3021 +#define EGL_BAD_ACCESS 0x3002 +#define EGL_BAD_ALLOC 0x3003 +#define EGL_BAD_ATTRIBUTE 0x3004 +#define EGL_BAD_CONFIG 0x3005 +#define EGL_BAD_CONTEXT 0x3006 +#define EGL_BAD_CURRENT_SURFACE 0x3007 +#define EGL_BAD_DISPLAY 0x3008 +#define EGL_BAD_MATCH 0x3009 +#define EGL_BAD_NATIVE_PIXMAP 0x300A +#define EGL_BAD_NATIVE_WINDOW 0x300B +#define EGL_BAD_PARAMETER 0x300C +#define EGL_BAD_SURFACE 0x300D +#define EGL_BLUE_SIZE 0x3022 +#define EGL_BUFFER_SIZE 0x3020 +#define EGL_CONFIG_CAVEAT 0x3027 +#define EGL_CONFIG_ID 0x3028 +#define EGL_CORE_NATIVE_ENGINE 0x305B +#define EGL_DEPTH_SIZE 0x3025 +#define EGL_DONT_CARE ((EGLint)-1) +#define EGL_DRAW 0x3059 +#define EGL_EXTENSIONS 0x3055 +#define EGL_FALSE 0 +#define EGL_GREEN_SIZE 0x3023 +#define EGL_HEIGHT 0x3056 +#define EGL_LARGEST_PBUFFER 0x3058 +#define EGL_LEVEL 0x3029 +#define EGL_MAX_PBUFFER_HEIGHT 0x302A +#define EGL_MAX_PBUFFER_PIXELS 0x302B +#define EGL_MAX_PBUFFER_WIDTH 0x302C +#define EGL_NATIVE_RENDERABLE 0x302D +#define EGL_NATIVE_VISUAL_ID 0x302E +#define EGL_NATIVE_VISUAL_TYPE 0x302F +#define EGL_NONE 0x3038 +#define EGL_NON_CONFORMANT_CONFIG 0x3051 +#define EGL_NOT_INITIALIZED 0x3001 +#define EGL_NO_CONTEXT ((EGLContext)0) +#define EGL_NO_DISPLAY ((EGLDisplay)0) +#define EGL_NO_SURFACE ((EGLSurface)0) +#define EGL_PBUFFER_BIT 0x0001 +#define EGL_PIXMAP_BIT 0x0002 +#define EGL_READ 0x305A +#define EGL_RED_SIZE 0x3024 +#define EGL_SAMPLES 0x3031 +#define EGL_SAMPLE_BUFFERS 0x3032 +#define EGL_SLOW_CONFIG 0x3050 +#define EGL_STENCIL_SIZE 0x3026 +#define EGL_SUCCESS 0x3000 +#define EGL_SURFACE_TYPE 0x3033 +#define EGL_TRANSPARENT_BLUE_VALUE 0x3035 +#define EGL_TRANSPARENT_GREEN_VALUE 0x3036 +#define EGL_TRANSPARENT_RED_VALUE 0x3037 +#define EGL_TRANSPARENT_RGB 0x3052 +#define EGL_TRANSPARENT_TYPE 0x3034 +#define EGL_TRUE 1 +#define EGL_VENDOR 0x3053 +#define EGL_VERSION 0x3054 +#define EGL_WIDTH 0x3057 +#define EGL_WINDOW_BIT 0x0004 +EGLAPI EGLBoolean EGLAPIENTRY eglChooseConfig (EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config); +EGLAPI EGLBoolean EGLAPIENTRY eglCopyBuffers (EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target); +EGLAPI EGLContext EGLAPIENTRY eglCreateContext (EGLDisplay dpy, EGLConfig config, EGLContext share_context, const EGLint *attrib_list); +EGLAPI EGLSurface EGLAPIENTRY eglCreatePbufferSurface (EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list); +EGLAPI EGLSurface EGLAPIENTRY eglCreatePixmapSurface (EGLDisplay dpy, EGLConfig config, EGLNativePixmapType pixmap, const EGLint *attrib_list); +EGLAPI EGLSurface EGLAPIENTRY eglCreateWindowSurface (EGLDisplay dpy, EGLConfig config, EGLNativeWindowType win, const EGLint *attrib_list); +EGLAPI EGLBoolean EGLAPIENTRY eglDestroyContext (EGLDisplay dpy, EGLContext ctx); +EGLAPI EGLBoolean EGLAPIENTRY eglDestroySurface (EGLDisplay dpy, EGLSurface surface); +EGLAPI EGLBoolean EGLAPIENTRY eglGetConfigAttrib (EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint *value); +EGLAPI EGLBoolean EGLAPIENTRY eglGetConfigs (EGLDisplay dpy, EGLConfig *configs, EGLint config_size, EGLint *num_config); +EGLAPI EGLDisplay EGLAPIENTRY eglGetCurrentDisplay (void); +EGLAPI EGLSurface EGLAPIENTRY eglGetCurrentSurface (EGLint readdraw); +EGLAPI EGLDisplay EGLAPIENTRY eglGetDisplay (EGLNativeDisplayType display_id); +EGLAPI EGLint EGLAPIENTRY eglGetError (void); +EGLAPI __eglMustCastToProperFunctionPointerType EGLAPIENTRY eglGetProcAddress (const char *procname); +EGLAPI EGLBoolean EGLAPIENTRY eglInitialize (EGLDisplay dpy, EGLint *major, EGLint *minor); +EGLAPI EGLBoolean EGLAPIENTRY eglMakeCurrent (EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx); +EGLAPI EGLBoolean EGLAPIENTRY eglQueryContext (EGLDisplay dpy, EGLContext ctx, EGLint attribute, EGLint *value); +EGLAPI const char *EGLAPIENTRY eglQueryString (EGLDisplay dpy, EGLint name); +EGLAPI EGLBoolean EGLAPIENTRY eglQuerySurface (EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint *value); +EGLAPI EGLBoolean EGLAPIENTRY eglSwapBuffers (EGLDisplay dpy, EGLSurface surface); +EGLAPI EGLBoolean EGLAPIENTRY eglTerminate (EGLDisplay dpy); +EGLAPI EGLBoolean EGLAPIENTRY eglWaitGL (void); +EGLAPI EGLBoolean EGLAPIENTRY eglWaitNative (EGLint engine); +#endif /* EGL_VERSION_1_0 */ + +#ifndef EGL_VERSION_1_1 +#define EGL_VERSION_1_1 1 +#define EGL_BACK_BUFFER 0x3084 +#define EGL_BIND_TO_TEXTURE_RGB 0x3039 +#define EGL_BIND_TO_TEXTURE_RGBA 0x303A +#define EGL_CONTEXT_LOST 0x300E +#define EGL_MIN_SWAP_INTERVAL 0x303B +#define EGL_MAX_SWAP_INTERVAL 0x303C +#define EGL_MIPMAP_TEXTURE 0x3082 +#define EGL_MIPMAP_LEVEL 0x3083 +#define EGL_NO_TEXTURE 0x305C +#define EGL_TEXTURE_2D 0x305F +#define EGL_TEXTURE_FORMAT 0x3080 +#define EGL_TEXTURE_RGB 0x305D +#define EGL_TEXTURE_RGBA 0x305E +#define EGL_TEXTURE_TARGET 0x3081 +EGLAPI EGLBoolean EGLAPIENTRY eglBindTexImage (EGLDisplay dpy, EGLSurface surface, EGLint buffer); +EGLAPI EGLBoolean EGLAPIENTRY eglReleaseTexImage (EGLDisplay dpy, EGLSurface surface, EGLint buffer); +EGLAPI EGLBoolean EGLAPIENTRY eglSurfaceAttrib (EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value); +EGLAPI EGLBoolean EGLAPIENTRY eglSwapInterval (EGLDisplay dpy, EGLint interval); +#endif /* EGL_VERSION_1_1 */ + +#ifndef EGL_VERSION_1_2 +#define EGL_VERSION_1_2 1 +typedef unsigned int EGLenum; +typedef void *EGLClientBuffer; +#define EGL_ALPHA_FORMAT 0x3088 +#define EGL_ALPHA_FORMAT_NONPRE 0x308B +#define EGL_ALPHA_FORMAT_PRE 0x308C +#define EGL_ALPHA_MASK_SIZE 0x303E +#define EGL_BUFFER_PRESERVED 0x3094 +#define EGL_BUFFER_DESTROYED 0x3095 +#define EGL_CLIENT_APIS 0x308D +#define EGL_COLORSPACE 0x3087 +#define EGL_COLORSPACE_sRGB 0x3089 +#define EGL_COLORSPACE_LINEAR 0x308A +#define EGL_COLOR_BUFFER_TYPE 0x303F +#define EGL_CONTEXT_CLIENT_TYPE 0x3097 +#define EGL_DISPLAY_SCALING 10000 +#define EGL_HORIZONTAL_RESOLUTION 0x3090 +#define EGL_LUMINANCE_BUFFER 0x308F +#define EGL_LUMINANCE_SIZE 0x303D +#define EGL_OPENGL_ES_BIT 0x0001 +#define EGL_OPENVG_BIT 0x0002 +#define EGL_OPENGL_ES_API 0x30A0 +#define EGL_OPENVG_API 0x30A1 +#define EGL_OPENVG_IMAGE 0x3096 +#define EGL_PIXEL_ASPECT_RATIO 0x3092 +#define EGL_RENDERABLE_TYPE 0x3040 +#define EGL_RENDER_BUFFER 0x3086 +#define EGL_RGB_BUFFER 0x308E +#define EGL_SINGLE_BUFFER 0x3085 +#define EGL_SWAP_BEHAVIOR 0x3093 +#define EGL_UNKNOWN ((EGLint)-1) +#define EGL_VERTICAL_RESOLUTION 0x3091 +EGLAPI EGLBoolean EGLAPIENTRY eglBindAPI (EGLenum api); +EGLAPI EGLenum EGLAPIENTRY eglQueryAPI (void); +EGLAPI EGLSurface EGLAPIENTRY eglCreatePbufferFromClientBuffer (EGLDisplay dpy, EGLenum buftype, EGLClientBuffer buffer, EGLConfig config, const EGLint *attrib_list); +EGLAPI EGLBoolean EGLAPIENTRY eglReleaseThread (void); +EGLAPI EGLBoolean EGLAPIENTRY eglWaitClient (void); +#endif /* EGL_VERSION_1_2 */ + +#ifndef EGL_VERSION_1_3 +#define EGL_VERSION_1_3 1 +#define EGL_CONFORMANT 0x3042 +#define EGL_CONTEXT_CLIENT_VERSION 0x3098 +#define EGL_MATCH_NATIVE_PIXMAP 0x3041 +#define EGL_OPENGL_ES2_BIT 0x0004 +#define EGL_VG_ALPHA_FORMAT 0x3088 +#define EGL_VG_ALPHA_FORMAT_NONPRE 0x308B +#define EGL_VG_ALPHA_FORMAT_PRE 0x308C +#define EGL_VG_ALPHA_FORMAT_PRE_BIT 0x0040 +#define EGL_VG_COLORSPACE 0x3087 +#define EGL_VG_COLORSPACE_sRGB 0x3089 +#define EGL_VG_COLORSPACE_LINEAR 0x308A +#define EGL_VG_COLORSPACE_LINEAR_BIT 0x0020 +#endif /* EGL_VERSION_1_3 */ + +#ifndef EGL_VERSION_1_4 +#define EGL_VERSION_1_4 1 +#define EGL_DEFAULT_DISPLAY ((EGLNativeDisplayType)0) +#define EGL_MULTISAMPLE_RESOLVE_BOX_BIT 0x0200 +#define EGL_MULTISAMPLE_RESOLVE 0x3099 +#define EGL_MULTISAMPLE_RESOLVE_DEFAULT 0x309A +#define EGL_MULTISAMPLE_RESOLVE_BOX 0x309B +#define EGL_OPENGL_API 0x30A2 +#define EGL_OPENGL_BIT 0x0008 +#define EGL_SWAP_BEHAVIOR_PRESERVED_BIT 0x0400 +EGLAPI EGLContext EGLAPIENTRY eglGetCurrentContext (void); +#endif /* EGL_VERSION_1_4 */ + +#ifndef EGL_VERSION_1_5 +#define EGL_VERSION_1_5 1 +typedef void *EGLSync; +typedef intptr_t EGLAttrib; +typedef khronos_utime_nanoseconds_t EGLTime; +typedef void *EGLImage; +#define EGL_CONTEXT_MAJOR_VERSION 0x3098 +#define EGL_CONTEXT_MINOR_VERSION 0x30FB +#define EGL_CONTEXT_OPENGL_PROFILE_MASK 0x30FD +#define EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY 0x31BD +#define EGL_NO_RESET_NOTIFICATION 0x31BE +#define EGL_LOSE_CONTEXT_ON_RESET 0x31BF +#define EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT 0x00000001 +#define EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT 0x00000002 +#define EGL_CONTEXT_OPENGL_DEBUG 0x31B0 +#define EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE 0x31B1 +#define EGL_CONTEXT_OPENGL_ROBUST_ACCESS 0x31B2 +#define EGL_OPENGL_ES3_BIT 0x00000040 +#define EGL_CL_EVENT_HANDLE 0x309C +#define EGL_SYNC_CL_EVENT 0x30FE +#define EGL_SYNC_CL_EVENT_COMPLETE 0x30FF +#define EGL_SYNC_PRIOR_COMMANDS_COMPLETE 0x30F0 +#define EGL_SYNC_TYPE 0x30F7 +#define EGL_SYNC_STATUS 0x30F1 +#define EGL_SYNC_CONDITION 0x30F8 +#define EGL_SIGNALED 0x30F2 +#define EGL_UNSIGNALED 0x30F3 +#define EGL_SYNC_FLUSH_COMMANDS_BIT 0x0001 +#define EGL_FOREVER 0xFFFFFFFFFFFFFFFFull +#define EGL_TIMEOUT_EXPIRED 0x30F5 +#define EGL_CONDITION_SATISFIED 0x30F6 +#define EGL_NO_SYNC ((EGLSync)0) +#define EGL_SYNC_FENCE 0x30F9 +#define EGL_GL_COLORSPACE 0x309D +#define EGL_GL_COLORSPACE_SRGB 0x3089 +#define EGL_GL_COLORSPACE_LINEAR 0x308A +#define EGL_GL_RENDERBUFFER 0x30B9 +#define EGL_GL_TEXTURE_2D 0x30B1 +#define EGL_GL_TEXTURE_LEVEL 0x30BC +#define EGL_GL_TEXTURE_3D 0x30B2 +#define EGL_GL_TEXTURE_ZOFFSET 0x30BD +#define EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X 0x30B3 +#define EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X 0x30B4 +#define EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y 0x30B5 +#define EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y 0x30B6 +#define EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z 0x30B7 +#define EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z 0x30B8 +#define EGL_IMAGE_PRESERVED 0x30D2 +#define EGL_NO_IMAGE ((EGLImage)0) +EGLAPI EGLSync EGLAPIENTRY eglCreateSync (EGLDisplay dpy, EGLenum type, const EGLAttrib *attrib_list); +EGLAPI EGLBoolean EGLAPIENTRY eglDestroySync (EGLDisplay dpy, EGLSync sync); +EGLAPI EGLint EGLAPIENTRY eglClientWaitSync (EGLDisplay dpy, EGLSync sync, EGLint flags, EGLTime timeout); +EGLAPI EGLBoolean EGLAPIENTRY eglGetSyncAttrib (EGLDisplay dpy, EGLSync sync, EGLint attribute, EGLAttrib *value); +EGLAPI EGLImage EGLAPIENTRY eglCreateImage (EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLAttrib *attrib_list); +EGLAPI EGLBoolean EGLAPIENTRY eglDestroyImage (EGLDisplay dpy, EGLImage image); +EGLAPI EGLDisplay EGLAPIENTRY eglGetPlatformDisplay (EGLenum platform, void *native_display, const EGLAttrib *attrib_list); +EGLAPI EGLSurface EGLAPIENTRY eglCreatePlatformWindowSurface (EGLDisplay dpy, EGLConfig config, void *native_window, const EGLAttrib *attrib_list); +EGLAPI EGLSurface EGLAPIENTRY eglCreatePlatformPixmapSurface (EGLDisplay dpy, EGLConfig config, void *native_pixmap, const EGLAttrib *attrib_list); +EGLAPI EGLBoolean EGLAPIENTRY eglWaitSync (EGLDisplay dpy, EGLSync sync, EGLint flags); +#endif /* EGL_VERSION_1_5 */ + +#ifdef __cplusplus +} +#endif + +#endif /* __egl_h_ */ + + + +#ifndef __eglext_h_ +#define __eglext_h_ 1 + +#ifdef __cplusplus +extern "C" { +#endif + +/* +** Copyright (c) 2013-2015 The Khronos Group Inc. +** +** Permission is hereby granted, free of charge, to any person obtaining a +** copy of this software and/or associated documentation files (the +** "Materials"), to deal in the Materials without restriction, including +** without limitation the rights to use, copy, modify, merge, publish, +** distribute, sublicense, and/or sell copies of the Materials, and to +** permit persons to whom the Materials are furnished to do so, subject to +** the following conditions: +** +** The above copyright notice and this permission notice shall be included +** in all copies or substantial portions of the Materials. +** +** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. +*/ +/* +** This header is generated from the Khronos OpenGL / OpenGL ES XML +** API Registry. The current version of the Registry, generator scripts +** used to make the header, and the header can be found at +** http://www.opengl.org/registry/ +** +** Khronos $Revision: 31566 $ on $Date: 2015-06-23 08:48:48 -0700 (Tue, 23 Jun 2015) $ +*/ + +/*#include */ + +#define EGL_EGLEXT_VERSION 20150623 + +/* Generated C header for: + * API: egl + * Versions considered: .* + * Versions emitted: _nomatch_^ + * Default extensions included: egl + * Additional extensions included: _nomatch_^ + * Extensions removed: _nomatch_^ + */ + +#ifndef EGL_KHR_cl_event +#define EGL_KHR_cl_event 1 +#define EGL_CL_EVENT_HANDLE_KHR 0x309C +#define EGL_SYNC_CL_EVENT_KHR 0x30FE +#define EGL_SYNC_CL_EVENT_COMPLETE_KHR 0x30FF +#endif /* EGL_KHR_cl_event */ + +#ifndef EGL_KHR_cl_event2 +#define EGL_KHR_cl_event2 1 +typedef void *EGLSyncKHR; +typedef intptr_t EGLAttribKHR; +typedef EGLSyncKHR (EGLAPIENTRYP PFNEGLCREATESYNC64KHRPROC) (EGLDisplay dpy, EGLenum type, const EGLAttribKHR *attrib_list); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLSyncKHR EGLAPIENTRY eglCreateSync64KHR (EGLDisplay dpy, EGLenum type, const EGLAttribKHR *attrib_list); +#endif +#endif /* EGL_KHR_cl_event2 */ + +#ifndef EGL_KHR_client_get_all_proc_addresses +#define EGL_KHR_client_get_all_proc_addresses 1 +#endif /* EGL_KHR_client_get_all_proc_addresses */ + +#ifndef EGL_KHR_config_attribs +#define EGL_KHR_config_attribs 1 +#define EGL_CONFORMANT_KHR 0x3042 +#define EGL_VG_COLORSPACE_LINEAR_BIT_KHR 0x0020 +#define EGL_VG_ALPHA_FORMAT_PRE_BIT_KHR 0x0040 +#endif /* EGL_KHR_config_attribs */ + +#ifndef EGL_KHR_create_context +#define EGL_KHR_create_context 1 +#define EGL_CONTEXT_MAJOR_VERSION_KHR 0x3098 +#define EGL_CONTEXT_MINOR_VERSION_KHR 0x30FB +#define EGL_CONTEXT_FLAGS_KHR 0x30FC +#define EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR 0x30FD +#define EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR 0x31BD +#define EGL_NO_RESET_NOTIFICATION_KHR 0x31BE +#define EGL_LOSE_CONTEXT_ON_RESET_KHR 0x31BF +#define EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR 0x00000001 +#define EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR 0x00000002 +#define EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR 0x00000004 +#define EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR 0x00000001 +#define EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT_KHR 0x00000002 +#define EGL_OPENGL_ES3_BIT_KHR 0x00000040 +#endif /* EGL_KHR_create_context */ + +#ifndef EGL_KHR_create_context_no_error +#define EGL_KHR_create_context_no_error 1 +#define EGL_CONTEXT_OPENGL_NO_ERROR_KHR 0x31B3 +#endif /* EGL_KHR_create_context_no_error */ + +#ifndef EGL_KHR_fence_sync +#define EGL_KHR_fence_sync 1 +typedef khronos_utime_nanoseconds_t EGLTimeKHR; +#ifdef KHRONOS_SUPPORT_INT64 +#define EGL_SYNC_PRIOR_COMMANDS_COMPLETE_KHR 0x30F0 +#define EGL_SYNC_CONDITION_KHR 0x30F8 +#define EGL_SYNC_FENCE_KHR 0x30F9 +typedef EGLSyncKHR (EGLAPIENTRYP PFNEGLCREATESYNCKHRPROC) (EGLDisplay dpy, EGLenum type, const EGLint *attrib_list); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLDESTROYSYNCKHRPROC) (EGLDisplay dpy, EGLSyncKHR sync); +typedef EGLint (EGLAPIENTRYP PFNEGLCLIENTWAITSYNCKHRPROC) (EGLDisplay dpy, EGLSyncKHR sync, EGLint flags, EGLTimeKHR timeout); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETSYNCATTRIBKHRPROC) (EGLDisplay dpy, EGLSyncKHR sync, EGLint attribute, EGLint *value); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLSyncKHR EGLAPIENTRY eglCreateSyncKHR (EGLDisplay dpy, EGLenum type, const EGLint *attrib_list); +EGLAPI EGLBoolean EGLAPIENTRY eglDestroySyncKHR (EGLDisplay dpy, EGLSyncKHR sync); +EGLAPI EGLint EGLAPIENTRY eglClientWaitSyncKHR (EGLDisplay dpy, EGLSyncKHR sync, EGLint flags, EGLTimeKHR timeout); +EGLAPI EGLBoolean EGLAPIENTRY eglGetSyncAttribKHR (EGLDisplay dpy, EGLSyncKHR sync, EGLint attribute, EGLint *value); +#endif +#endif /* KHRONOS_SUPPORT_INT64 */ +#endif /* EGL_KHR_fence_sync */ + +#ifndef EGL_KHR_get_all_proc_addresses +#define EGL_KHR_get_all_proc_addresses 1 +#endif /* EGL_KHR_get_all_proc_addresses */ + +#ifndef EGL_KHR_gl_colorspace +#define EGL_KHR_gl_colorspace 1 +#define EGL_GL_COLORSPACE_KHR 0x309D +#define EGL_GL_COLORSPACE_SRGB_KHR 0x3089 +#define EGL_GL_COLORSPACE_LINEAR_KHR 0x308A +#endif /* EGL_KHR_gl_colorspace */ + +#ifndef EGL_KHR_gl_renderbuffer_image +#define EGL_KHR_gl_renderbuffer_image 1 +#define EGL_GL_RENDERBUFFER_KHR 0x30B9 +#endif /* EGL_KHR_gl_renderbuffer_image */ + +#ifndef EGL_KHR_gl_texture_2D_image +#define EGL_KHR_gl_texture_2D_image 1 +#define EGL_GL_TEXTURE_2D_KHR 0x30B1 +#define EGL_GL_TEXTURE_LEVEL_KHR 0x30BC +#endif /* EGL_KHR_gl_texture_2D_image */ + +#ifndef EGL_KHR_gl_texture_3D_image +#define EGL_KHR_gl_texture_3D_image 1 +#define EGL_GL_TEXTURE_3D_KHR 0x30B2 +#define EGL_GL_TEXTURE_ZOFFSET_KHR 0x30BD +#endif /* EGL_KHR_gl_texture_3D_image */ + +#ifndef EGL_KHR_gl_texture_cubemap_image +#define EGL_KHR_gl_texture_cubemap_image 1 +#define EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR 0x30B3 +#define EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X_KHR 0x30B4 +#define EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y_KHR 0x30B5 +#define EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_KHR 0x30B6 +#define EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z_KHR 0x30B7 +#define EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_KHR 0x30B8 +#endif /* EGL_KHR_gl_texture_cubemap_image */ + +#ifndef EGL_KHR_image +#define EGL_KHR_image 1 +typedef void *EGLImageKHR; +#define EGL_NATIVE_PIXMAP_KHR 0x30B0 +#define EGL_NO_IMAGE_KHR ((EGLImageKHR)0) +typedef EGLImageKHR (EGLAPIENTRYP PFNEGLCREATEIMAGEKHRPROC) (EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLint *attrib_list); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLDESTROYIMAGEKHRPROC) (EGLDisplay dpy, EGLImageKHR image); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLImageKHR EGLAPIENTRY eglCreateImageKHR (EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLint *attrib_list); +EGLAPI EGLBoolean EGLAPIENTRY eglDestroyImageKHR (EGLDisplay dpy, EGLImageKHR image); +#endif +#endif /* EGL_KHR_image */ + +#ifndef EGL_KHR_image_base +#define EGL_KHR_image_base 1 +#define EGL_IMAGE_PRESERVED_KHR 0x30D2 +#endif /* EGL_KHR_image_base */ + +#ifndef EGL_KHR_image_pixmap +#define EGL_KHR_image_pixmap 1 +#endif /* EGL_KHR_image_pixmap */ + +#ifndef EGL_KHR_lock_surface +#define EGL_KHR_lock_surface 1 +#define EGL_READ_SURFACE_BIT_KHR 0x0001 +#define EGL_WRITE_SURFACE_BIT_KHR 0x0002 +#define EGL_LOCK_SURFACE_BIT_KHR 0x0080 +#define EGL_OPTIMAL_FORMAT_BIT_KHR 0x0100 +#define EGL_MATCH_FORMAT_KHR 0x3043 +#define EGL_FORMAT_RGB_565_EXACT_KHR 0x30C0 +#define EGL_FORMAT_RGB_565_KHR 0x30C1 +#define EGL_FORMAT_RGBA_8888_EXACT_KHR 0x30C2 +#define EGL_FORMAT_RGBA_8888_KHR 0x30C3 +#define EGL_MAP_PRESERVE_PIXELS_KHR 0x30C4 +#define EGL_LOCK_USAGE_HINT_KHR 0x30C5 +#define EGL_BITMAP_POINTER_KHR 0x30C6 +#define EGL_BITMAP_PITCH_KHR 0x30C7 +#define EGL_BITMAP_ORIGIN_KHR 0x30C8 +#define EGL_BITMAP_PIXEL_RED_OFFSET_KHR 0x30C9 +#define EGL_BITMAP_PIXEL_GREEN_OFFSET_KHR 0x30CA +#define EGL_BITMAP_PIXEL_BLUE_OFFSET_KHR 0x30CB +#define EGL_BITMAP_PIXEL_ALPHA_OFFSET_KHR 0x30CC +#define EGL_BITMAP_PIXEL_LUMINANCE_OFFSET_KHR 0x30CD +#define EGL_LOWER_LEFT_KHR 0x30CE +#define EGL_UPPER_LEFT_KHR 0x30CF +typedef EGLBoolean (EGLAPIENTRYP PFNEGLLOCKSURFACEKHRPROC) (EGLDisplay dpy, EGLSurface surface, const EGLint *attrib_list); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLUNLOCKSURFACEKHRPROC) (EGLDisplay dpy, EGLSurface surface); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLBoolean EGLAPIENTRY eglLockSurfaceKHR (EGLDisplay dpy, EGLSurface surface, const EGLint *attrib_list); +EGLAPI EGLBoolean EGLAPIENTRY eglUnlockSurfaceKHR (EGLDisplay dpy, EGLSurface surface); +#endif +#endif /* EGL_KHR_lock_surface */ + +#ifndef EGL_KHR_lock_surface2 +#define EGL_KHR_lock_surface2 1 +#define EGL_BITMAP_PIXEL_SIZE_KHR 0x3110 +#endif /* EGL_KHR_lock_surface2 */ + +#ifndef EGL_KHR_lock_surface3 +#define EGL_KHR_lock_surface3 1 +typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYSURFACE64KHRPROC) (EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLAttribKHR *value); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLBoolean EGLAPIENTRY eglQuerySurface64KHR (EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLAttribKHR *value); +#endif +#endif /* EGL_KHR_lock_surface3 */ + +#ifndef EGL_KHR_partial_update +#define EGL_KHR_partial_update 1 +#define EGL_BUFFER_AGE_KHR 0x313D +typedef EGLBoolean (EGLAPIENTRYP PFNEGLSETDAMAGEREGIONKHRPROC) (EGLDisplay dpy, EGLSurface surface, EGLint *rects, EGLint n_rects); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLBoolean EGLAPIENTRY eglSetDamageRegionKHR (EGLDisplay dpy, EGLSurface surface, EGLint *rects, EGLint n_rects); +#endif +#endif /* EGL_KHR_partial_update */ + +#ifndef EGL_KHR_platform_android +#define EGL_KHR_platform_android 1 +#define EGL_PLATFORM_ANDROID_KHR 0x3141 +#endif /* EGL_KHR_platform_android */ + +#ifndef EGL_KHR_platform_gbm +#define EGL_KHR_platform_gbm 1 +#define EGL_PLATFORM_GBM_KHR 0x31D7 +#endif /* EGL_KHR_platform_gbm */ + +#ifndef EGL_KHR_platform_wayland +#define EGL_KHR_platform_wayland 1 +#define EGL_PLATFORM_WAYLAND_KHR 0x31D8 +#endif /* EGL_KHR_platform_wayland */ + +#ifndef EGL_KHR_platform_x11 +#define EGL_KHR_platform_x11 1 +#define EGL_PLATFORM_X11_KHR 0x31D5 +#define EGL_PLATFORM_X11_SCREEN_KHR 0x31D6 +#endif /* EGL_KHR_platform_x11 */ + +#ifndef EGL_KHR_reusable_sync +#define EGL_KHR_reusable_sync 1 +#ifdef KHRONOS_SUPPORT_INT64 +#define EGL_SYNC_STATUS_KHR 0x30F1 +#define EGL_SIGNALED_KHR 0x30F2 +#define EGL_UNSIGNALED_KHR 0x30F3 +#define EGL_TIMEOUT_EXPIRED_KHR 0x30F5 +#define EGL_CONDITION_SATISFIED_KHR 0x30F6 +#define EGL_SYNC_TYPE_KHR 0x30F7 +#define EGL_SYNC_REUSABLE_KHR 0x30FA +#define EGL_SYNC_FLUSH_COMMANDS_BIT_KHR 0x0001 +#define EGL_FOREVER_KHR 0xFFFFFFFFFFFFFFFFull +#define EGL_NO_SYNC_KHR ((EGLSyncKHR)0) +typedef EGLBoolean (EGLAPIENTRYP PFNEGLSIGNALSYNCKHRPROC) (EGLDisplay dpy, EGLSyncKHR sync, EGLenum mode); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLBoolean EGLAPIENTRY eglSignalSyncKHR (EGLDisplay dpy, EGLSyncKHR sync, EGLenum mode); +#endif +#endif /* KHRONOS_SUPPORT_INT64 */ +#endif /* EGL_KHR_reusable_sync */ + +#ifndef EGL_KHR_stream +#define EGL_KHR_stream 1 +typedef void *EGLStreamKHR; +typedef khronos_uint64_t EGLuint64KHR; +#ifdef KHRONOS_SUPPORT_INT64 +#define EGL_NO_STREAM_KHR ((EGLStreamKHR)0) +#define EGL_CONSUMER_LATENCY_USEC_KHR 0x3210 +#define EGL_PRODUCER_FRAME_KHR 0x3212 +#define EGL_CONSUMER_FRAME_KHR 0x3213 +#define EGL_STREAM_STATE_KHR 0x3214 +#define EGL_STREAM_STATE_CREATED_KHR 0x3215 +#define EGL_STREAM_STATE_CONNECTING_KHR 0x3216 +#define EGL_STREAM_STATE_EMPTY_KHR 0x3217 +#define EGL_STREAM_STATE_NEW_FRAME_AVAILABLE_KHR 0x3218 +#define EGL_STREAM_STATE_OLD_FRAME_AVAILABLE_KHR 0x3219 +#define EGL_STREAM_STATE_DISCONNECTED_KHR 0x321A +#define EGL_BAD_STREAM_KHR 0x321B +#define EGL_BAD_STATE_KHR 0x321C +typedef EGLStreamKHR (EGLAPIENTRYP PFNEGLCREATESTREAMKHRPROC) (EGLDisplay dpy, const EGLint *attrib_list); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLDESTROYSTREAMKHRPROC) (EGLDisplay dpy, EGLStreamKHR stream); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLSTREAMATTRIBKHRPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLint value); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYSTREAMKHRPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLint *value); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYSTREAMU64KHRPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLuint64KHR *value); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLStreamKHR EGLAPIENTRY eglCreateStreamKHR (EGLDisplay dpy, const EGLint *attrib_list); +EGLAPI EGLBoolean EGLAPIENTRY eglDestroyStreamKHR (EGLDisplay dpy, EGLStreamKHR stream); +EGLAPI EGLBoolean EGLAPIENTRY eglStreamAttribKHR (EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLint value); +EGLAPI EGLBoolean EGLAPIENTRY eglQueryStreamKHR (EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLint *value); +EGLAPI EGLBoolean EGLAPIENTRY eglQueryStreamu64KHR (EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLuint64KHR *value); +#endif +#endif /* KHRONOS_SUPPORT_INT64 */ +#endif /* EGL_KHR_stream */ + +#ifndef EGL_KHR_stream_consumer_gltexture +#define EGL_KHR_stream_consumer_gltexture 1 +#ifdef EGL_KHR_stream +#define EGL_CONSUMER_ACQUIRE_TIMEOUT_USEC_KHR 0x321E +typedef EGLBoolean (EGLAPIENTRYP PFNEGLSTREAMCONSUMERGLTEXTUREEXTERNALKHRPROC) (EGLDisplay dpy, EGLStreamKHR stream); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLSTREAMCONSUMERACQUIREKHRPROC) (EGLDisplay dpy, EGLStreamKHR stream); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLSTREAMCONSUMERRELEASEKHRPROC) (EGLDisplay dpy, EGLStreamKHR stream); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLBoolean EGLAPIENTRY eglStreamConsumerGLTextureExternalKHR (EGLDisplay dpy, EGLStreamKHR stream); +EGLAPI EGLBoolean EGLAPIENTRY eglStreamConsumerAcquireKHR (EGLDisplay dpy, EGLStreamKHR stream); +EGLAPI EGLBoolean EGLAPIENTRY eglStreamConsumerReleaseKHR (EGLDisplay dpy, EGLStreamKHR stream); +#endif +#endif /* EGL_KHR_stream */ +#endif /* EGL_KHR_stream_consumer_gltexture */ + +#ifndef EGL_KHR_stream_cross_process_fd +#define EGL_KHR_stream_cross_process_fd 1 +typedef int EGLNativeFileDescriptorKHR; +#ifdef EGL_KHR_stream +#define EGL_NO_FILE_DESCRIPTOR_KHR ((EGLNativeFileDescriptorKHR)(-1)) +typedef EGLNativeFileDescriptorKHR (EGLAPIENTRYP PFNEGLGETSTREAMFILEDESCRIPTORKHRPROC) (EGLDisplay dpy, EGLStreamKHR stream); +typedef EGLStreamKHR (EGLAPIENTRYP PFNEGLCREATESTREAMFROMFILEDESCRIPTORKHRPROC) (EGLDisplay dpy, EGLNativeFileDescriptorKHR file_descriptor); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLNativeFileDescriptorKHR EGLAPIENTRY eglGetStreamFileDescriptorKHR (EGLDisplay dpy, EGLStreamKHR stream); +EGLAPI EGLStreamKHR EGLAPIENTRY eglCreateStreamFromFileDescriptorKHR (EGLDisplay dpy, EGLNativeFileDescriptorKHR file_descriptor); +#endif +#endif /* EGL_KHR_stream */ +#endif /* EGL_KHR_stream_cross_process_fd */ + +#ifndef EGL_KHR_stream_fifo +#define EGL_KHR_stream_fifo 1 +#ifdef EGL_KHR_stream +#define EGL_STREAM_FIFO_LENGTH_KHR 0x31FC +#define EGL_STREAM_TIME_NOW_KHR 0x31FD +#define EGL_STREAM_TIME_CONSUMER_KHR 0x31FE +#define EGL_STREAM_TIME_PRODUCER_KHR 0x31FF +typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYSTREAMTIMEKHRPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLTimeKHR *value); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLBoolean EGLAPIENTRY eglQueryStreamTimeKHR (EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLTimeKHR *value); +#endif +#endif /* EGL_KHR_stream */ +#endif /* EGL_KHR_stream_fifo */ + +#ifndef EGL_KHR_stream_producer_aldatalocator +#define EGL_KHR_stream_producer_aldatalocator 1 +#ifdef EGL_KHR_stream +#endif /* EGL_KHR_stream */ +#endif /* EGL_KHR_stream_producer_aldatalocator */ + +#ifndef EGL_KHR_stream_producer_eglsurface +#define EGL_KHR_stream_producer_eglsurface 1 +#ifdef EGL_KHR_stream +#define EGL_STREAM_BIT_KHR 0x0800 +typedef EGLSurface (EGLAPIENTRYP PFNEGLCREATESTREAMPRODUCERSURFACEKHRPROC) (EGLDisplay dpy, EGLConfig config, EGLStreamKHR stream, const EGLint *attrib_list); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLSurface EGLAPIENTRY eglCreateStreamProducerSurfaceKHR (EGLDisplay dpy, EGLConfig config, EGLStreamKHR stream, const EGLint *attrib_list); +#endif +#endif /* EGL_KHR_stream */ +#endif /* EGL_KHR_stream_producer_eglsurface */ + +#ifndef EGL_KHR_surfaceless_context +#define EGL_KHR_surfaceless_context 1 +#endif /* EGL_KHR_surfaceless_context */ + +#ifndef EGL_KHR_swap_buffers_with_damage +#define EGL_KHR_swap_buffers_with_damage 1 +typedef EGLBoolean (EGLAPIENTRYP PFNEGLSWAPBUFFERSWITHDAMAGEKHRPROC) (EGLDisplay dpy, EGLSurface surface, EGLint *rects, EGLint n_rects); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLBoolean EGLAPIENTRY eglSwapBuffersWithDamageKHR (EGLDisplay dpy, EGLSurface surface, EGLint *rects, EGLint n_rects); +#endif +#endif /* EGL_KHR_swap_buffers_with_damage */ + +#ifndef EGL_KHR_vg_parent_image +#define EGL_KHR_vg_parent_image 1 +#define EGL_VG_PARENT_IMAGE_KHR 0x30BA +#endif /* EGL_KHR_vg_parent_image */ + +#ifndef EGL_KHR_wait_sync +#define EGL_KHR_wait_sync 1 +typedef EGLint (EGLAPIENTRYP PFNEGLWAITSYNCKHRPROC) (EGLDisplay dpy, EGLSyncKHR sync, EGLint flags); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLint EGLAPIENTRY eglWaitSyncKHR (EGLDisplay dpy, EGLSyncKHR sync, EGLint flags); +#endif +#endif /* EGL_KHR_wait_sync */ + +#ifndef EGL_ANDROID_blob_cache +#define EGL_ANDROID_blob_cache 1 +typedef khronos_ssize_t EGLsizeiANDROID; +typedef void (*EGLSetBlobFuncANDROID) (const void *key, EGLsizeiANDROID keySize, const void *value, EGLsizeiANDROID valueSize); +typedef EGLsizeiANDROID (*EGLGetBlobFuncANDROID) (const void *key, EGLsizeiANDROID keySize, void *value, EGLsizeiANDROID valueSize); +typedef void (EGLAPIENTRYP PFNEGLSETBLOBCACHEFUNCSANDROIDPROC) (EGLDisplay dpy, EGLSetBlobFuncANDROID set, EGLGetBlobFuncANDROID get); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI void EGLAPIENTRY eglSetBlobCacheFuncsANDROID (EGLDisplay dpy, EGLSetBlobFuncANDROID set, EGLGetBlobFuncANDROID get); +#endif +#endif /* EGL_ANDROID_blob_cache */ + +#ifndef EGL_ANDROID_framebuffer_target +#define EGL_ANDROID_framebuffer_target 1 +#define EGL_FRAMEBUFFER_TARGET_ANDROID 0x3147 +#endif /* EGL_ANDROID_framebuffer_target */ + +#ifndef EGL_ANDROID_image_native_buffer +#define EGL_ANDROID_image_native_buffer 1 +#define EGL_NATIVE_BUFFER_ANDROID 0x3140 +#endif /* EGL_ANDROID_image_native_buffer */ + +#ifndef EGL_ANDROID_native_fence_sync +#define EGL_ANDROID_native_fence_sync 1 +#define EGL_SYNC_NATIVE_FENCE_ANDROID 0x3144 +#define EGL_SYNC_NATIVE_FENCE_FD_ANDROID 0x3145 +#define EGL_SYNC_NATIVE_FENCE_SIGNALED_ANDROID 0x3146 +#define EGL_NO_NATIVE_FENCE_FD_ANDROID -1 +typedef EGLint (EGLAPIENTRYP PFNEGLDUPNATIVEFENCEFDANDROIDPROC) (EGLDisplay dpy, EGLSyncKHR sync); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLint EGLAPIENTRY eglDupNativeFenceFDANDROID (EGLDisplay dpy, EGLSyncKHR sync); +#endif +#endif /* EGL_ANDROID_native_fence_sync */ + +#ifndef EGL_ANDROID_recordable +#define EGL_ANDROID_recordable 1 +#define EGL_RECORDABLE_ANDROID 0x3142 +#endif /* EGL_ANDROID_recordable */ + +#ifndef EGL_ANGLE_d3d_share_handle_client_buffer +#define EGL_ANGLE_d3d_share_handle_client_buffer 1 +#define EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE 0x3200 +#endif /* EGL_ANGLE_d3d_share_handle_client_buffer */ + +#ifndef EGL_ANGLE_device_d3d +#define EGL_ANGLE_device_d3d 1 +#define EGL_D3D9_DEVICE_ANGLE 0x33A0 +#define EGL_D3D11_DEVICE_ANGLE 0x33A1 +#endif /* EGL_ANGLE_device_d3d */ + +#ifndef EGL_ANGLE_query_surface_pointer +#define EGL_ANGLE_query_surface_pointer 1 +typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYSURFACEPOINTERANGLEPROC) (EGLDisplay dpy, EGLSurface surface, EGLint attribute, void **value); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLBoolean EGLAPIENTRY eglQuerySurfacePointerANGLE (EGLDisplay dpy, EGLSurface surface, EGLint attribute, void **value); +#endif +#endif /* EGL_ANGLE_query_surface_pointer */ + +#ifndef EGL_ANGLE_surface_d3d_texture_2d_share_handle +#define EGL_ANGLE_surface_d3d_texture_2d_share_handle 1 +#endif /* EGL_ANGLE_surface_d3d_texture_2d_share_handle */ + +#ifndef EGL_ANGLE_window_fixed_size +#define EGL_ANGLE_window_fixed_size 1 +#define EGL_FIXED_SIZE_ANGLE 0x3201 +#endif /* EGL_ANGLE_window_fixed_size */ + +#ifndef EGL_ARM_pixmap_multisample_discard +#define EGL_ARM_pixmap_multisample_discard 1 +#define EGL_DISCARD_SAMPLES_ARM 0x3286 +#endif /* EGL_ARM_pixmap_multisample_discard */ + +#ifndef EGL_EXT_buffer_age +#define EGL_EXT_buffer_age 1 +#define EGL_BUFFER_AGE_EXT 0x313D +#endif /* EGL_EXT_buffer_age */ + +#ifndef EGL_EXT_client_extensions +#define EGL_EXT_client_extensions 1 +#endif /* EGL_EXT_client_extensions */ + +#ifndef EGL_EXT_create_context_robustness +#define EGL_EXT_create_context_robustness 1 +#define EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT 0x30BF +#define EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT 0x3138 +#define EGL_NO_RESET_NOTIFICATION_EXT 0x31BE +#define EGL_LOSE_CONTEXT_ON_RESET_EXT 0x31BF +#endif /* EGL_EXT_create_context_robustness */ + +#ifndef EGL_EXT_device_base +#define EGL_EXT_device_base 1 +typedef void *EGLDeviceEXT; +#define EGL_NO_DEVICE_EXT ((EGLDeviceEXT)(0)) +#define EGL_BAD_DEVICE_EXT 0x322B +#define EGL_DEVICE_EXT 0x322C +typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYDEVICEATTRIBEXTPROC) (EGLDeviceEXT device, EGLint attribute, EGLAttrib *value); +typedef const char *(EGLAPIENTRYP PFNEGLQUERYDEVICESTRINGEXTPROC) (EGLDeviceEXT device, EGLint name); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYDEVICESEXTPROC) (EGLint max_devices, EGLDeviceEXT *devices, EGLint *num_devices); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYDISPLAYATTRIBEXTPROC) (EGLDisplay dpy, EGLint attribute, EGLAttrib *value); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLBoolean EGLAPIENTRY eglQueryDeviceAttribEXT (EGLDeviceEXT device, EGLint attribute, EGLAttrib *value); +EGLAPI const char *EGLAPIENTRY eglQueryDeviceStringEXT (EGLDeviceEXT device, EGLint name); +EGLAPI EGLBoolean EGLAPIENTRY eglQueryDevicesEXT (EGLint max_devices, EGLDeviceEXT *devices, EGLint *num_devices); +EGLAPI EGLBoolean EGLAPIENTRY eglQueryDisplayAttribEXT (EGLDisplay dpy, EGLint attribute, EGLAttrib *value); +#endif +#endif /* EGL_EXT_device_base */ + +#ifndef EGL_EXT_device_drm +#define EGL_EXT_device_drm 1 +#define EGL_DRM_DEVICE_FILE_EXT 0x3233 +#endif /* EGL_EXT_device_drm */ + +#ifndef EGL_EXT_device_enumeration +#define EGL_EXT_device_enumeration 1 +#endif /* EGL_EXT_device_enumeration */ + +#ifndef EGL_EXT_device_openwf +#define EGL_EXT_device_openwf 1 +#define EGL_OPENWF_DEVICE_ID_EXT 0x3237 +#endif /* EGL_EXT_device_openwf */ + +#ifndef EGL_EXT_device_query +#define EGL_EXT_device_query 1 +#endif /* EGL_EXT_device_query */ + +#ifndef EGL_EXT_image_dma_buf_import +#define EGL_EXT_image_dma_buf_import 1 +#define EGL_LINUX_DMA_BUF_EXT 0x3270 +#define EGL_LINUX_DRM_FOURCC_EXT 0x3271 +#define EGL_DMA_BUF_PLANE0_FD_EXT 0x3272 +#define EGL_DMA_BUF_PLANE0_OFFSET_EXT 0x3273 +#define EGL_DMA_BUF_PLANE0_PITCH_EXT 0x3274 +#define EGL_DMA_BUF_PLANE1_FD_EXT 0x3275 +#define EGL_DMA_BUF_PLANE1_OFFSET_EXT 0x3276 +#define EGL_DMA_BUF_PLANE1_PITCH_EXT 0x3277 +#define EGL_DMA_BUF_PLANE2_FD_EXT 0x3278 +#define EGL_DMA_BUF_PLANE2_OFFSET_EXT 0x3279 +#define EGL_DMA_BUF_PLANE2_PITCH_EXT 0x327A +#define EGL_YUV_COLOR_SPACE_HINT_EXT 0x327B +#define EGL_SAMPLE_RANGE_HINT_EXT 0x327C +#define EGL_YUV_CHROMA_HORIZONTAL_SITING_HINT_EXT 0x327D +#define EGL_YUV_CHROMA_VERTICAL_SITING_HINT_EXT 0x327E +#define EGL_ITU_REC601_EXT 0x327F +#define EGL_ITU_REC709_EXT 0x3280 +#define EGL_ITU_REC2020_EXT 0x3281 +#define EGL_YUV_FULL_RANGE_EXT 0x3282 +#define EGL_YUV_NARROW_RANGE_EXT 0x3283 +#define EGL_YUV_CHROMA_SITING_0_EXT 0x3284 +#define EGL_YUV_CHROMA_SITING_0_5_EXT 0x3285 +#endif /* EGL_EXT_image_dma_buf_import */ + +#ifndef EGL_EXT_multiview_window +#define EGL_EXT_multiview_window 1 +#define EGL_MULTIVIEW_VIEW_COUNT_EXT 0x3134 +#endif /* EGL_EXT_multiview_window */ + +#ifndef EGL_EXT_output_base +#define EGL_EXT_output_base 1 +typedef void *EGLOutputLayerEXT; +typedef void *EGLOutputPortEXT; +#define EGL_NO_OUTPUT_LAYER_EXT ((EGLOutputLayerEXT)0) +#define EGL_NO_OUTPUT_PORT_EXT ((EGLOutputPortEXT)0) +#define EGL_BAD_OUTPUT_LAYER_EXT 0x322D +#define EGL_BAD_OUTPUT_PORT_EXT 0x322E +#define EGL_SWAP_INTERVAL_EXT 0x322F +typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETOUTPUTLAYERSEXTPROC) (EGLDisplay dpy, const EGLAttrib *attrib_list, EGLOutputLayerEXT *layers, EGLint max_layers, EGLint *num_layers); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETOUTPUTPORTSEXTPROC) (EGLDisplay dpy, const EGLAttrib *attrib_list, EGLOutputPortEXT *ports, EGLint max_ports, EGLint *num_ports); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLOUTPUTLAYERATTRIBEXTPROC) (EGLDisplay dpy, EGLOutputLayerEXT layer, EGLint attribute, EGLAttrib value); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYOUTPUTLAYERATTRIBEXTPROC) (EGLDisplay dpy, EGLOutputLayerEXT layer, EGLint attribute, EGLAttrib *value); +typedef const char *(EGLAPIENTRYP PFNEGLQUERYOUTPUTLAYERSTRINGEXTPROC) (EGLDisplay dpy, EGLOutputLayerEXT layer, EGLint name); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLOUTPUTPORTATTRIBEXTPROC) (EGLDisplay dpy, EGLOutputPortEXT port, EGLint attribute, EGLAttrib value); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYOUTPUTPORTATTRIBEXTPROC) (EGLDisplay dpy, EGLOutputPortEXT port, EGLint attribute, EGLAttrib *value); +typedef const char *(EGLAPIENTRYP PFNEGLQUERYOUTPUTPORTSTRINGEXTPROC) (EGLDisplay dpy, EGLOutputPortEXT port, EGLint name); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLBoolean EGLAPIENTRY eglGetOutputLayersEXT (EGLDisplay dpy, const EGLAttrib *attrib_list, EGLOutputLayerEXT *layers, EGLint max_layers, EGLint *num_layers); +EGLAPI EGLBoolean EGLAPIENTRY eglGetOutputPortsEXT (EGLDisplay dpy, const EGLAttrib *attrib_list, EGLOutputPortEXT *ports, EGLint max_ports, EGLint *num_ports); +EGLAPI EGLBoolean EGLAPIENTRY eglOutputLayerAttribEXT (EGLDisplay dpy, EGLOutputLayerEXT layer, EGLint attribute, EGLAttrib value); +EGLAPI EGLBoolean EGLAPIENTRY eglQueryOutputLayerAttribEXT (EGLDisplay dpy, EGLOutputLayerEXT layer, EGLint attribute, EGLAttrib *value); +EGLAPI const char *EGLAPIENTRY eglQueryOutputLayerStringEXT (EGLDisplay dpy, EGLOutputLayerEXT layer, EGLint name); +EGLAPI EGLBoolean EGLAPIENTRY eglOutputPortAttribEXT (EGLDisplay dpy, EGLOutputPortEXT port, EGLint attribute, EGLAttrib value); +EGLAPI EGLBoolean EGLAPIENTRY eglQueryOutputPortAttribEXT (EGLDisplay dpy, EGLOutputPortEXT port, EGLint attribute, EGLAttrib *value); +EGLAPI const char *EGLAPIENTRY eglQueryOutputPortStringEXT (EGLDisplay dpy, EGLOutputPortEXT port, EGLint name); +#endif +#endif /* EGL_EXT_output_base */ + +#ifndef EGL_EXT_output_drm +#define EGL_EXT_output_drm 1 +#define EGL_DRM_CRTC_EXT 0x3234 +#define EGL_DRM_PLANE_EXT 0x3235 +#define EGL_DRM_CONNECTOR_EXT 0x3236 +#endif /* EGL_EXT_output_drm */ + +#ifndef EGL_EXT_output_openwf +#define EGL_EXT_output_openwf 1 +#define EGL_OPENWF_PIPELINE_ID_EXT 0x3238 +#define EGL_OPENWF_PORT_ID_EXT 0x3239 +#endif /* EGL_EXT_output_openwf */ + +#ifndef EGL_EXT_platform_base +#define EGL_EXT_platform_base 1 +typedef EGLDisplay (EGLAPIENTRYP PFNEGLGETPLATFORMDISPLAYEXTPROC) (EGLenum platform, void *native_display, const EGLint *attrib_list); +typedef EGLSurface (EGLAPIENTRYP PFNEGLCREATEPLATFORMWINDOWSURFACEEXTPROC) (EGLDisplay dpy, EGLConfig config, void *native_window, const EGLint *attrib_list); +typedef EGLSurface (EGLAPIENTRYP PFNEGLCREATEPLATFORMPIXMAPSURFACEEXTPROC) (EGLDisplay dpy, EGLConfig config, void *native_pixmap, const EGLint *attrib_list); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLDisplay EGLAPIENTRY eglGetPlatformDisplayEXT (EGLenum platform, void *native_display, const EGLint *attrib_list); +EGLAPI EGLSurface EGLAPIENTRY eglCreatePlatformWindowSurfaceEXT (EGLDisplay dpy, EGLConfig config, void *native_window, const EGLint *attrib_list); +EGLAPI EGLSurface EGLAPIENTRY eglCreatePlatformPixmapSurfaceEXT (EGLDisplay dpy, EGLConfig config, void *native_pixmap, const EGLint *attrib_list); +#endif +#endif /* EGL_EXT_platform_base */ + +#ifndef EGL_EXT_platform_device +#define EGL_EXT_platform_device 1 +#define EGL_PLATFORM_DEVICE_EXT 0x313F +#endif /* EGL_EXT_platform_device */ + +#ifndef EGL_EXT_platform_wayland +#define EGL_EXT_platform_wayland 1 +#define EGL_PLATFORM_WAYLAND_EXT 0x31D8 +#endif /* EGL_EXT_platform_wayland */ + +#ifndef EGL_EXT_platform_x11 +#define EGL_EXT_platform_x11 1 +#define EGL_PLATFORM_X11_EXT 0x31D5 +#define EGL_PLATFORM_X11_SCREEN_EXT 0x31D6 +#endif /* EGL_EXT_platform_x11 */ + +#ifndef EGL_EXT_protected_surface +#define EGL_EXT_protected_surface 1 +#define EGL_PROTECTED_CONTENT_EXT 0x32C0 +#endif /* EGL_EXT_protected_surface */ + +#ifndef EGL_EXT_stream_consumer_egloutput +#define EGL_EXT_stream_consumer_egloutput 1 +typedef EGLBoolean (EGLAPIENTRYP PFNEGLSTREAMCONSUMEROUTPUTEXTPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLOutputLayerEXT layer); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLBoolean EGLAPIENTRY eglStreamConsumerOutputEXT (EGLDisplay dpy, EGLStreamKHR stream, EGLOutputLayerEXT layer); +#endif +#endif /* EGL_EXT_stream_consumer_egloutput */ + +#ifndef EGL_EXT_swap_buffers_with_damage +#define EGL_EXT_swap_buffers_with_damage 1 +typedef EGLBoolean (EGLAPIENTRYP PFNEGLSWAPBUFFERSWITHDAMAGEEXTPROC) (EGLDisplay dpy, EGLSurface surface, EGLint *rects, EGLint n_rects); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLBoolean EGLAPIENTRY eglSwapBuffersWithDamageEXT (EGLDisplay dpy, EGLSurface surface, EGLint *rects, EGLint n_rects); +#endif +#endif /* EGL_EXT_swap_buffers_with_damage */ + +#ifndef EGL_EXT_yuv_surface +#define EGL_EXT_yuv_surface 1 +#define EGL_YUV_ORDER_EXT 0x3301 +#define EGL_YUV_NUMBER_OF_PLANES_EXT 0x3311 +#define EGL_YUV_SUBSAMPLE_EXT 0x3312 +#define EGL_YUV_DEPTH_RANGE_EXT 0x3317 +#define EGL_YUV_CSC_STANDARD_EXT 0x330A +#define EGL_YUV_PLANE_BPP_EXT 0x331A +#define EGL_YUV_BUFFER_EXT 0x3300 +#define EGL_YUV_ORDER_YUV_EXT 0x3302 +#define EGL_YUV_ORDER_YVU_EXT 0x3303 +#define EGL_YUV_ORDER_YUYV_EXT 0x3304 +#define EGL_YUV_ORDER_UYVY_EXT 0x3305 +#define EGL_YUV_ORDER_YVYU_EXT 0x3306 +#define EGL_YUV_ORDER_VYUY_EXT 0x3307 +#define EGL_YUV_ORDER_AYUV_EXT 0x3308 +#define EGL_YUV_SUBSAMPLE_4_2_0_EXT 0x3313 +#define EGL_YUV_SUBSAMPLE_4_2_2_EXT 0x3314 +#define EGL_YUV_SUBSAMPLE_4_4_4_EXT 0x3315 +#define EGL_YUV_DEPTH_RANGE_LIMITED_EXT 0x3318 +#define EGL_YUV_DEPTH_RANGE_FULL_EXT 0x3319 +#define EGL_YUV_CSC_STANDARD_601_EXT 0x330B +#define EGL_YUV_CSC_STANDARD_709_EXT 0x330C +#define EGL_YUV_CSC_STANDARD_2020_EXT 0x330D +#define EGL_YUV_PLANE_BPP_0_EXT 0x331B +#define EGL_YUV_PLANE_BPP_8_EXT 0x331C +#define EGL_YUV_PLANE_BPP_10_EXT 0x331D +#endif /* EGL_EXT_yuv_surface */ + +#ifndef EGL_HI_clientpixmap +#define EGL_HI_clientpixmap 1 +struct EGLClientPixmapHI { + void *pData; + EGLint iWidth; + EGLint iHeight; + EGLint iStride; +}; +#define EGL_CLIENT_PIXMAP_POINTER_HI 0x8F74 +typedef EGLSurface (EGLAPIENTRYP PFNEGLCREATEPIXMAPSURFACEHIPROC) (EGLDisplay dpy, EGLConfig config, struct EGLClientPixmapHI *pixmap); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLSurface EGLAPIENTRY eglCreatePixmapSurfaceHI (EGLDisplay dpy, EGLConfig config, struct EGLClientPixmapHI *pixmap); +#endif +#endif /* EGL_HI_clientpixmap */ + +#ifndef EGL_HI_colorformats +#define EGL_HI_colorformats 1 +#define EGL_COLOR_FORMAT_HI 0x8F70 +#define EGL_COLOR_RGB_HI 0x8F71 +#define EGL_COLOR_RGBA_HI 0x8F72 +#define EGL_COLOR_ARGB_HI 0x8F73 +#endif /* EGL_HI_colorformats */ + +#ifndef EGL_IMG_context_priority +#define EGL_IMG_context_priority 1 +#define EGL_CONTEXT_PRIORITY_LEVEL_IMG 0x3100 +#define EGL_CONTEXT_PRIORITY_HIGH_IMG 0x3101 +#define EGL_CONTEXT_PRIORITY_MEDIUM_IMG 0x3102 +#define EGL_CONTEXT_PRIORITY_LOW_IMG 0x3103 +#endif /* EGL_IMG_context_priority */ + +#ifndef EGL_MESA_drm_image +#define EGL_MESA_drm_image 1 +#define EGL_DRM_BUFFER_FORMAT_MESA 0x31D0 +#define EGL_DRM_BUFFER_USE_MESA 0x31D1 +#define EGL_DRM_BUFFER_FORMAT_ARGB32_MESA 0x31D2 +#define EGL_DRM_BUFFER_MESA 0x31D3 +#define EGL_DRM_BUFFER_STRIDE_MESA 0x31D4 +#define EGL_DRM_BUFFER_USE_SCANOUT_MESA 0x00000001 +#define EGL_DRM_BUFFER_USE_SHARE_MESA 0x00000002 +typedef EGLImageKHR (EGLAPIENTRYP PFNEGLCREATEDRMIMAGEMESAPROC) (EGLDisplay dpy, const EGLint *attrib_list); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLEXPORTDRMIMAGEMESAPROC) (EGLDisplay dpy, EGLImageKHR image, EGLint *name, EGLint *handle, EGLint *stride); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLImageKHR EGLAPIENTRY eglCreateDRMImageMESA (EGLDisplay dpy, const EGLint *attrib_list); +EGLAPI EGLBoolean EGLAPIENTRY eglExportDRMImageMESA (EGLDisplay dpy, EGLImageKHR image, EGLint *name, EGLint *handle, EGLint *stride); +#endif +#endif /* EGL_MESA_drm_image */ + +#ifndef EGL_MESA_image_dma_buf_export +#define EGL_MESA_image_dma_buf_export 1 +typedef EGLBoolean (EGLAPIENTRYP PFNEGLEXPORTDMABUFIMAGEQUERYMESAPROC) (EGLDisplay dpy, EGLImageKHR image, int *fourcc, int *num_planes, EGLuint64KHR *modifiers); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLEXPORTDMABUFIMAGEMESAPROC) (EGLDisplay dpy, EGLImageKHR image, int *fds, EGLint *strides, EGLint *offsets); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLBoolean EGLAPIENTRY eglExportDMABUFImageQueryMESA (EGLDisplay dpy, EGLImageKHR image, int *fourcc, int *num_planes, EGLuint64KHR *modifiers); +EGLAPI EGLBoolean EGLAPIENTRY eglExportDMABUFImageMESA (EGLDisplay dpy, EGLImageKHR image, int *fds, EGLint *strides, EGLint *offsets); +#endif +#endif /* EGL_MESA_image_dma_buf_export */ + +#ifndef EGL_MESA_platform_gbm +#define EGL_MESA_platform_gbm 1 +#define EGL_PLATFORM_GBM_MESA 0x31D7 +#endif /* EGL_MESA_platform_gbm */ + +#ifndef EGL_NOK_swap_region +#define EGL_NOK_swap_region 1 +typedef EGLBoolean (EGLAPIENTRYP PFNEGLSWAPBUFFERSREGIONNOKPROC) (EGLDisplay dpy, EGLSurface surface, EGLint numRects, const EGLint *rects); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLBoolean EGLAPIENTRY eglSwapBuffersRegionNOK (EGLDisplay dpy, EGLSurface surface, EGLint numRects, const EGLint *rects); +#endif +#endif /* EGL_NOK_swap_region */ + +#ifndef EGL_NOK_swap_region2 +#define EGL_NOK_swap_region2 1 +typedef EGLBoolean (EGLAPIENTRYP PFNEGLSWAPBUFFERSREGION2NOKPROC) (EGLDisplay dpy, EGLSurface surface, EGLint numRects, const EGLint *rects); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLBoolean EGLAPIENTRY eglSwapBuffersRegion2NOK (EGLDisplay dpy, EGLSurface surface, EGLint numRects, const EGLint *rects); +#endif +#endif /* EGL_NOK_swap_region2 */ + +#ifndef EGL_NOK_texture_from_pixmap +#define EGL_NOK_texture_from_pixmap 1 +#define EGL_Y_INVERTED_NOK 0x307F +#endif /* EGL_NOK_texture_from_pixmap */ + +#ifndef EGL_NV_3dvision_surface +#define EGL_NV_3dvision_surface 1 +#define EGL_AUTO_STEREO_NV 0x3136 +#endif /* EGL_NV_3dvision_surface */ + +#ifndef EGL_NV_coverage_sample +#define EGL_NV_coverage_sample 1 +#define EGL_COVERAGE_BUFFERS_NV 0x30E0 +#define EGL_COVERAGE_SAMPLES_NV 0x30E1 +#endif /* EGL_NV_coverage_sample */ + +#ifndef EGL_NV_coverage_sample_resolve +#define EGL_NV_coverage_sample_resolve 1 +#define EGL_COVERAGE_SAMPLE_RESOLVE_NV 0x3131 +#define EGL_COVERAGE_SAMPLE_RESOLVE_DEFAULT_NV 0x3132 +#define EGL_COVERAGE_SAMPLE_RESOLVE_NONE_NV 0x3133 +#endif /* EGL_NV_coverage_sample_resolve */ + +#ifndef EGL_NV_cuda_event +#define EGL_NV_cuda_event 1 +#define EGL_CUDA_EVENT_HANDLE_NV 0x323B +#define EGL_SYNC_CUDA_EVENT_NV 0x323C +#define EGL_SYNC_CUDA_EVENT_COMPLETE_NV 0x323D +#endif /* EGL_NV_cuda_event */ + +#ifndef EGL_NV_depth_nonlinear +#define EGL_NV_depth_nonlinear 1 +#define EGL_DEPTH_ENCODING_NV 0x30E2 +#define EGL_DEPTH_ENCODING_NONE_NV 0 +#define EGL_DEPTH_ENCODING_NONLINEAR_NV 0x30E3 +#endif /* EGL_NV_depth_nonlinear */ + +#ifndef EGL_NV_device_cuda +#define EGL_NV_device_cuda 1 +#define EGL_CUDA_DEVICE_NV 0x323A +#endif /* EGL_NV_device_cuda */ + +#ifndef EGL_NV_native_query +#define EGL_NV_native_query 1 +typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYNATIVEDISPLAYNVPROC) (EGLDisplay dpy, EGLNativeDisplayType *display_id); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYNATIVEWINDOWNVPROC) (EGLDisplay dpy, EGLSurface surf, EGLNativeWindowType *window); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYNATIVEPIXMAPNVPROC) (EGLDisplay dpy, EGLSurface surf, EGLNativePixmapType *pixmap); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLBoolean EGLAPIENTRY eglQueryNativeDisplayNV (EGLDisplay dpy, EGLNativeDisplayType *display_id); +EGLAPI EGLBoolean EGLAPIENTRY eglQueryNativeWindowNV (EGLDisplay dpy, EGLSurface surf, EGLNativeWindowType *window); +EGLAPI EGLBoolean EGLAPIENTRY eglQueryNativePixmapNV (EGLDisplay dpy, EGLSurface surf, EGLNativePixmapType *pixmap); +#endif +#endif /* EGL_NV_native_query */ + +#ifndef EGL_NV_post_convert_rounding +#define EGL_NV_post_convert_rounding 1 +#endif /* EGL_NV_post_convert_rounding */ + +#ifndef EGL_NV_post_sub_buffer +#define EGL_NV_post_sub_buffer 1 +#define EGL_POST_SUB_BUFFER_SUPPORTED_NV 0x30BE +typedef EGLBoolean (EGLAPIENTRYP PFNEGLPOSTSUBBUFFERNVPROC) (EGLDisplay dpy, EGLSurface surface, EGLint x, EGLint y, EGLint width, EGLint height); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLBoolean EGLAPIENTRY eglPostSubBufferNV (EGLDisplay dpy, EGLSurface surface, EGLint x, EGLint y, EGLint width, EGLint height); +#endif +#endif /* EGL_NV_post_sub_buffer */ + +#ifndef EGL_NV_stream_sync +#define EGL_NV_stream_sync 1 +#define EGL_SYNC_NEW_FRAME_NV 0x321F +typedef EGLSyncKHR (EGLAPIENTRYP PFNEGLCREATESTREAMSYNCNVPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLenum type, const EGLint *attrib_list); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLSyncKHR EGLAPIENTRY eglCreateStreamSyncNV (EGLDisplay dpy, EGLStreamKHR stream, EGLenum type, const EGLint *attrib_list); +#endif +#endif /* EGL_NV_stream_sync */ + +#ifndef EGL_NV_sync +#define EGL_NV_sync 1 +typedef void *EGLSyncNV; +typedef khronos_utime_nanoseconds_t EGLTimeNV; +#ifdef KHRONOS_SUPPORT_INT64 +#define EGL_SYNC_PRIOR_COMMANDS_COMPLETE_NV 0x30E6 +#define EGL_SYNC_STATUS_NV 0x30E7 +#define EGL_SIGNALED_NV 0x30E8 +#define EGL_UNSIGNALED_NV 0x30E9 +#define EGL_SYNC_FLUSH_COMMANDS_BIT_NV 0x0001 +#define EGL_FOREVER_NV 0xFFFFFFFFFFFFFFFFull +#define EGL_ALREADY_SIGNALED_NV 0x30EA +#define EGL_TIMEOUT_EXPIRED_NV 0x30EB +#define EGL_CONDITION_SATISFIED_NV 0x30EC +#define EGL_SYNC_TYPE_NV 0x30ED +#define EGL_SYNC_CONDITION_NV 0x30EE +#define EGL_SYNC_FENCE_NV 0x30EF +#define EGL_NO_SYNC_NV ((EGLSyncNV)0) +typedef EGLSyncNV (EGLAPIENTRYP PFNEGLCREATEFENCESYNCNVPROC) (EGLDisplay dpy, EGLenum condition, const EGLint *attrib_list); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLDESTROYSYNCNVPROC) (EGLSyncNV sync); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLFENCENVPROC) (EGLSyncNV sync); +typedef EGLint (EGLAPIENTRYP PFNEGLCLIENTWAITSYNCNVPROC) (EGLSyncNV sync, EGLint flags, EGLTimeNV timeout); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLSIGNALSYNCNVPROC) (EGLSyncNV sync, EGLenum mode); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETSYNCATTRIBNVPROC) (EGLSyncNV sync, EGLint attribute, EGLint *value); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLSyncNV EGLAPIENTRY eglCreateFenceSyncNV (EGLDisplay dpy, EGLenum condition, const EGLint *attrib_list); +EGLAPI EGLBoolean EGLAPIENTRY eglDestroySyncNV (EGLSyncNV sync); +EGLAPI EGLBoolean EGLAPIENTRY eglFenceNV (EGLSyncNV sync); +EGLAPI EGLint EGLAPIENTRY eglClientWaitSyncNV (EGLSyncNV sync, EGLint flags, EGLTimeNV timeout); +EGLAPI EGLBoolean EGLAPIENTRY eglSignalSyncNV (EGLSyncNV sync, EGLenum mode); +EGLAPI EGLBoolean EGLAPIENTRY eglGetSyncAttribNV (EGLSyncNV sync, EGLint attribute, EGLint *value); +#endif +#endif /* KHRONOS_SUPPORT_INT64 */ +#endif /* EGL_NV_sync */ + +#ifndef EGL_NV_system_time +#define EGL_NV_system_time 1 +typedef khronos_utime_nanoseconds_t EGLuint64NV; +#ifdef KHRONOS_SUPPORT_INT64 +typedef EGLuint64NV (EGLAPIENTRYP PFNEGLGETSYSTEMTIMEFREQUENCYNVPROC) (void); +typedef EGLuint64NV (EGLAPIENTRYP PFNEGLGETSYSTEMTIMENVPROC) (void); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLuint64NV EGLAPIENTRY eglGetSystemTimeFrequencyNV (void); +EGLAPI EGLuint64NV EGLAPIENTRY eglGetSystemTimeNV (void); +#endif +#endif /* KHRONOS_SUPPORT_INT64 */ +#endif /* EGL_NV_system_time */ + +#ifndef EGL_TIZEN_image_native_buffer +#define EGL_TIZEN_image_native_buffer 1 +#define EGL_NATIVE_BUFFER_TIZEN 0x32A0 +#endif /* EGL_TIZEN_image_native_buffer */ + +#ifndef EGL_TIZEN_image_native_surface +#define EGL_TIZEN_image_native_surface 1 +#define EGL_NATIVE_SURFACE_TIZEN 0x32A1 +#endif /* EGL_TIZEN_image_native_surface */ + +#ifdef __cplusplus +} +#endif + +#endif /* __eglext_h_ */ + + +#endif /* _MSC_VER */ diff --git a/engine/Windows/SDL2/include/SDL_endian.h b/engine/Windows/SDL2/include/SDL_endian.h new file mode 100644 index 0000000..1e6daae --- /dev/null +++ b/engine/Windows/SDL2/include/SDL_endian.h @@ -0,0 +1,263 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2019 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_endian.h + * + * Functions for reading and writing endian-specific values + */ + +#ifndef SDL_endian_h_ +#define SDL_endian_h_ + +#include "SDL_stdinc.h" + +/** + * \name The two types of endianness + */ +/* @{ */ +#define SDL_LIL_ENDIAN 1234 +#define SDL_BIG_ENDIAN 4321 +/* @} */ + +#ifndef SDL_BYTEORDER /* Not defined in SDL_config.h? */ +#ifdef __linux__ +#include +#define SDL_BYTEORDER __BYTE_ORDER +#elif defined(__OpenBSD__) +#include +#define SDL_BYTEORDER BYTE_ORDER +#else +#if defined(__hppa__) || \ + defined(__m68k__) || defined(mc68000) || defined(_M_M68K) || \ + (defined(__MIPS__) && defined(__MIPSEB__)) || \ + defined(__ppc__) || defined(__POWERPC__) || defined(_M_PPC) || \ + defined(__sparc__) +#define SDL_BYTEORDER SDL_BIG_ENDIAN +#else +#define SDL_BYTEORDER SDL_LIL_ENDIAN +#endif +#endif /* __linux__ */ +#endif /* !SDL_BYTEORDER */ + + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \file SDL_endian.h + */ +#if defined(__GNUC__) && defined(__i386__) && \ + !(__GNUC__ == 2 && __GNUC_MINOR__ == 95 /* broken gcc version */) +SDL_FORCE_INLINE Uint16 +SDL_Swap16(Uint16 x) +{ + __asm__("xchgb %b0,%h0": "=q"(x):"0"(x)); + return x; +} +#elif defined(__GNUC__) && defined(__x86_64__) +SDL_FORCE_INLINE Uint16 +SDL_Swap16(Uint16 x) +{ + __asm__("xchgb %b0,%h0": "=Q"(x):"0"(x)); + return x; +} +#elif defined(__GNUC__) && (defined(__powerpc__) || defined(__ppc__)) +SDL_FORCE_INLINE Uint16 +SDL_Swap16(Uint16 x) +{ + int result; + + __asm__("rlwimi %0,%2,8,16,23": "=&r"(result):"0"(x >> 8), "r"(x)); + return (Uint16)result; +} +#elif defined(__GNUC__) && (defined(__M68000__) || defined(__M68020__)) && !defined(__mcoldfire__) +SDL_FORCE_INLINE Uint16 +SDL_Swap16(Uint16 x) +{ + __asm__("rorw #8,%0": "=d"(x): "0"(x):"cc"); + return x; +} +#elif defined(__WATCOMC__) && defined(__386__) +extern _inline Uint16 SDL_Swap16(Uint16); +#pragma aux SDL_Swap16 = \ + "xchg al, ah" \ + parm [ax] \ + modify [ax]; +#else +SDL_FORCE_INLINE Uint16 +SDL_Swap16(Uint16 x) +{ + return SDL_static_cast(Uint16, ((x << 8) | (x >> 8))); +} +#endif + +#if defined(__GNUC__) && defined(__i386__) +SDL_FORCE_INLINE Uint32 +SDL_Swap32(Uint32 x) +{ + __asm__("bswap %0": "=r"(x):"0"(x)); + return x; +} +#elif defined(__GNUC__) && defined(__x86_64__) +SDL_FORCE_INLINE Uint32 +SDL_Swap32(Uint32 x) +{ + __asm__("bswapl %0": "=r"(x):"0"(x)); + return x; +} +#elif defined(__GNUC__) && (defined(__powerpc__) || defined(__ppc__)) +SDL_FORCE_INLINE Uint32 +SDL_Swap32(Uint32 x) +{ + Uint32 result; + + __asm__("rlwimi %0,%2,24,16,23": "=&r"(result):"0"(x >> 24), "r"(x)); + __asm__("rlwimi %0,%2,8,8,15": "=&r"(result):"0"(result), "r"(x)); + __asm__("rlwimi %0,%2,24,0,7": "=&r"(result):"0"(result), "r"(x)); + return result; +} +#elif defined(__GNUC__) && (defined(__M68000__) || defined(__M68020__)) && !defined(__mcoldfire__) +SDL_FORCE_INLINE Uint32 +SDL_Swap32(Uint32 x) +{ + __asm__("rorw #8,%0\n\tswap %0\n\trorw #8,%0": "=d"(x): "0"(x):"cc"); + return x; +} +#elif defined(__WATCOMC__) && defined(__386__) +extern _inline Uint32 SDL_Swap32(Uint32); +#ifndef __SW_3 /* 486+ */ +#pragma aux SDL_Swap32 = \ + "bswap eax" \ + parm [eax] \ + modify [eax]; +#else /* 386-only */ +#pragma aux SDL_Swap32 = \ + "xchg al, ah" \ + "ror eax, 16" \ + "xchg al, ah" \ + parm [eax] \ + modify [eax]; +#endif +#else +SDL_FORCE_INLINE Uint32 +SDL_Swap32(Uint32 x) +{ + return SDL_static_cast(Uint32, ((x << 24) | ((x << 8) & 0x00FF0000) | + ((x >> 8) & 0x0000FF00) | (x >> 24))); +} +#endif + +#if defined(__GNUC__) && defined(__i386__) +SDL_FORCE_INLINE Uint64 +SDL_Swap64(Uint64 x) +{ + union + { + struct + { + Uint32 a, b; + } s; + Uint64 u; + } v; + v.u = x; + __asm__("bswapl %0 ; bswapl %1 ; xchgl %0,%1": "=r"(v.s.a), "=r"(v.s.b):"0"(v.s.a), + "1"(v.s. + b)); + return v.u; +} +#elif defined(__GNUC__) && defined(__x86_64__) +SDL_FORCE_INLINE Uint64 +SDL_Swap64(Uint64 x) +{ + __asm__("bswapq %0": "=r"(x):"0"(x)); + return x; +} +#else +SDL_FORCE_INLINE Uint64 +SDL_Swap64(Uint64 x) +{ + Uint32 hi, lo; + + /* Separate into high and low 32-bit values and swap them */ + lo = SDL_static_cast(Uint32, x & 0xFFFFFFFF); + x >>= 32; + hi = SDL_static_cast(Uint32, x & 0xFFFFFFFF); + x = SDL_Swap32(lo); + x <<= 32; + x |= SDL_Swap32(hi); + return (x); +} +#endif + + +SDL_FORCE_INLINE float +SDL_SwapFloat(float x) +{ + union + { + float f; + Uint32 ui32; + } swapper; + swapper.f = x; + swapper.ui32 = SDL_Swap32(swapper.ui32); + return swapper.f; +} + + +/** + * \name Swap to native + * Byteswap item from the specified endianness to the native endianness. + */ +/* @{ */ +#if SDL_BYTEORDER == SDL_LIL_ENDIAN +#define SDL_SwapLE16(X) (X) +#define SDL_SwapLE32(X) (X) +#define SDL_SwapLE64(X) (X) +#define SDL_SwapFloatLE(X) (X) +#define SDL_SwapBE16(X) SDL_Swap16(X) +#define SDL_SwapBE32(X) SDL_Swap32(X) +#define SDL_SwapBE64(X) SDL_Swap64(X) +#define SDL_SwapFloatBE(X) SDL_SwapFloat(X) +#else +#define SDL_SwapLE16(X) SDL_Swap16(X) +#define SDL_SwapLE32(X) SDL_Swap32(X) +#define SDL_SwapLE64(X) SDL_Swap64(X) +#define SDL_SwapFloatLE(X) SDL_SwapFloat(X) +#define SDL_SwapBE16(X) (X) +#define SDL_SwapBE32(X) (X) +#define SDL_SwapBE64(X) (X) +#define SDL_SwapFloatBE(X) (X) +#endif +/* @} *//* Swap to native */ + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_endian_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/engine/Windows/SDL2/include/SDL_error.h b/engine/Windows/SDL2/include/SDL_error.h new file mode 100644 index 0000000..24416e6 --- /dev/null +++ b/engine/Windows/SDL2/include/SDL_error.h @@ -0,0 +1,76 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2019 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_error.h + * + * Simple error message routines for SDL. + */ + +#ifndef SDL_error_h_ +#define SDL_error_h_ + +#include "SDL_stdinc.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/* Public functions */ +/* SDL_SetError() unconditionally returns -1. */ +extern DECLSPEC int SDLCALL SDL_SetError(SDL_PRINTF_FORMAT_STRING const char *fmt, ...) SDL_PRINTF_VARARG_FUNC(1); +extern DECLSPEC const char *SDLCALL SDL_GetError(void); +extern DECLSPEC void SDLCALL SDL_ClearError(void); + +/** + * \name Internal error functions + * + * \internal + * Private error reporting function - used internally. + */ +/* @{ */ +#define SDL_OutOfMemory() SDL_Error(SDL_ENOMEM) +#define SDL_Unsupported() SDL_Error(SDL_UNSUPPORTED) +#define SDL_InvalidParamError(param) SDL_SetError("Parameter '%s' is invalid", (param)) +typedef enum +{ + SDL_ENOMEM, + SDL_EFREAD, + SDL_EFWRITE, + SDL_EFSEEK, + SDL_UNSUPPORTED, + SDL_LASTERROR +} SDL_errorcode; +/* SDL_Error() unconditionally returns -1. */ +extern DECLSPEC int SDLCALL SDL_Error(SDL_errorcode code); +/* @} *//* Internal error functions */ + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_error_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/engine/Windows/SDL2/include/SDL_events.h b/engine/Windows/SDL2/include/SDL_events.h new file mode 100644 index 0000000..eaf5743 --- /dev/null +++ b/engine/Windows/SDL2/include/SDL_events.h @@ -0,0 +1,792 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2019 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_events.h + * + * Include file for SDL event handling. + */ + +#ifndef SDL_events_h_ +#define SDL_events_h_ + +#include "SDL_stdinc.h" +#include "SDL_error.h" +#include "SDL_video.h" +#include "SDL_keyboard.h" +#include "SDL_mouse.h" +#include "SDL_joystick.h" +#include "SDL_gamecontroller.h" +#include "SDL_quit.h" +#include "SDL_gesture.h" +#include "SDL_touch.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/* General keyboard/mouse state definitions */ +#define SDL_RELEASED 0 +#define SDL_PRESSED 1 + +/** + * \brief The types of events that can be delivered. + */ +typedef enum +{ + SDL_FIRSTEVENT = 0, /**< Unused (do not remove) */ + + /* Application events */ + SDL_QUIT = 0x100, /**< User-requested quit */ + + /* These application events have special meaning on iOS, see README-ios.md for details */ + SDL_APP_TERMINATING, /**< The application is being terminated by the OS + Called on iOS in applicationWillTerminate() + Called on Android in onDestroy() + */ + SDL_APP_LOWMEMORY, /**< The application is low on memory, free memory if possible. + Called on iOS in applicationDidReceiveMemoryWarning() + Called on Android in onLowMemory() + */ + SDL_APP_WILLENTERBACKGROUND, /**< The application is about to enter the background + Called on iOS in applicationWillResignActive() + Called on Android in onPause() + */ + SDL_APP_DIDENTERBACKGROUND, /**< The application did enter the background and may not get CPU for some time + Called on iOS in applicationDidEnterBackground() + Called on Android in onPause() + */ + SDL_APP_WILLENTERFOREGROUND, /**< The application is about to enter the foreground + Called on iOS in applicationWillEnterForeground() + Called on Android in onResume() + */ + SDL_APP_DIDENTERFOREGROUND, /**< The application is now interactive + Called on iOS in applicationDidBecomeActive() + Called on Android in onResume() + */ + + /* Display events */ + SDL_DISPLAYEVENT = 0x150, /**< Display state change */ + + /* Window events */ + SDL_WINDOWEVENT = 0x200, /**< Window state change */ + SDL_SYSWMEVENT, /**< System specific event */ + + /* Keyboard events */ + SDL_KEYDOWN = 0x300, /**< Key pressed */ + SDL_KEYUP, /**< Key released */ + SDL_TEXTEDITING, /**< Keyboard text editing (composition) */ + SDL_TEXTINPUT, /**< Keyboard text input */ + SDL_KEYMAPCHANGED, /**< Keymap changed due to a system event such as an + input language or keyboard layout change. + */ + + /* Mouse events */ + SDL_MOUSEMOTION = 0x400, /**< Mouse moved */ + SDL_MOUSEBUTTONDOWN, /**< Mouse button pressed */ + SDL_MOUSEBUTTONUP, /**< Mouse button released */ + SDL_MOUSEWHEEL, /**< Mouse wheel motion */ + + /* Joystick events */ + SDL_JOYAXISMOTION = 0x600, /**< Joystick axis motion */ + SDL_JOYBALLMOTION, /**< Joystick trackball motion */ + SDL_JOYHATMOTION, /**< Joystick hat position change */ + SDL_JOYBUTTONDOWN, /**< Joystick button pressed */ + SDL_JOYBUTTONUP, /**< Joystick button released */ + SDL_JOYDEVICEADDED, /**< A new joystick has been inserted into the system */ + SDL_JOYDEVICEREMOVED, /**< An opened joystick has been removed */ + + /* Game controller events */ + SDL_CONTROLLERAXISMOTION = 0x650, /**< Game controller axis motion */ + SDL_CONTROLLERBUTTONDOWN, /**< Game controller button pressed */ + SDL_CONTROLLERBUTTONUP, /**< Game controller button released */ + SDL_CONTROLLERDEVICEADDED, /**< A new Game controller has been inserted into the system */ + SDL_CONTROLLERDEVICEREMOVED, /**< An opened Game controller has been removed */ + SDL_CONTROLLERDEVICEREMAPPED, /**< The controller mapping was updated */ + + /* Touch events */ + SDL_FINGERDOWN = 0x700, + SDL_FINGERUP, + SDL_FINGERMOTION, + + /* Gesture events */ + SDL_DOLLARGESTURE = 0x800, + SDL_DOLLARRECORD, + SDL_MULTIGESTURE, + + /* Clipboard events */ + SDL_CLIPBOARDUPDATE = 0x900, /**< The clipboard changed */ + + /* Drag and drop events */ + SDL_DROPFILE = 0x1000, /**< The system requests a file open */ + SDL_DROPTEXT, /**< text/plain drag-and-drop event */ + SDL_DROPBEGIN, /**< A new set of drops is beginning (NULL filename) */ + SDL_DROPCOMPLETE, /**< Current set of drops is now complete (NULL filename) */ + + /* Audio hotplug events */ + SDL_AUDIODEVICEADDED = 0x1100, /**< A new audio device is available */ + SDL_AUDIODEVICEREMOVED, /**< An audio device has been removed. */ + + /* Sensor events */ + SDL_SENSORUPDATE = 0x1200, /**< A sensor was updated */ + + /* Render events */ + SDL_RENDER_TARGETS_RESET = 0x2000, /**< The render targets have been reset and their contents need to be updated */ + SDL_RENDER_DEVICE_RESET, /**< The device has been reset and all textures need to be recreated */ + + /** Events ::SDL_USEREVENT through ::SDL_LASTEVENT are for your use, + * and should be allocated with SDL_RegisterEvents() + */ + SDL_USEREVENT = 0x8000, + + /** + * This last event is only for bounding internal arrays + */ + SDL_LASTEVENT = 0xFFFF +} SDL_EventType; + +/** + * \brief Fields shared by every event + */ +typedef struct SDL_CommonEvent +{ + Uint32 type; + Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ +} SDL_CommonEvent; + +/** + * \brief Display state change event data (event.display.*) + */ +typedef struct SDL_DisplayEvent +{ + Uint32 type; /**< ::SDL_DISPLAYEVENT */ + Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ + Uint32 display; /**< The associated display index */ + Uint8 event; /**< ::SDL_DisplayEventID */ + Uint8 padding1; + Uint8 padding2; + Uint8 padding3; + Sint32 data1; /**< event dependent data */ +} SDL_DisplayEvent; + +/** + * \brief Window state change event data (event.window.*) + */ +typedef struct SDL_WindowEvent +{ + Uint32 type; /**< ::SDL_WINDOWEVENT */ + Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ + Uint32 windowID; /**< The associated window */ + Uint8 event; /**< ::SDL_WindowEventID */ + Uint8 padding1; + Uint8 padding2; + Uint8 padding3; + Sint32 data1; /**< event dependent data */ + Sint32 data2; /**< event dependent data */ +} SDL_WindowEvent; + +/** + * \brief Keyboard button event structure (event.key.*) + */ +typedef struct SDL_KeyboardEvent +{ + Uint32 type; /**< ::SDL_KEYDOWN or ::SDL_KEYUP */ + Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ + Uint32 windowID; /**< The window with keyboard focus, if any */ + Uint8 state; /**< ::SDL_PRESSED or ::SDL_RELEASED */ + Uint8 repeat; /**< Non-zero if this is a key repeat */ + Uint8 padding2; + Uint8 padding3; + SDL_Keysym keysym; /**< The key that was pressed or released */ +} SDL_KeyboardEvent; + +#define SDL_TEXTEDITINGEVENT_TEXT_SIZE (32) +/** + * \brief Keyboard text editing event structure (event.edit.*) + */ +typedef struct SDL_TextEditingEvent +{ + Uint32 type; /**< ::SDL_TEXTEDITING */ + Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ + Uint32 windowID; /**< The window with keyboard focus, if any */ + char text[SDL_TEXTEDITINGEVENT_TEXT_SIZE]; /**< The editing text */ + Sint32 start; /**< The start cursor of selected editing text */ + Sint32 length; /**< The length of selected editing text */ +} SDL_TextEditingEvent; + + +#define SDL_TEXTINPUTEVENT_TEXT_SIZE (32) +/** + * \brief Keyboard text input event structure (event.text.*) + */ +typedef struct SDL_TextInputEvent +{ + Uint32 type; /**< ::SDL_TEXTINPUT */ + Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ + Uint32 windowID; /**< The window with keyboard focus, if any */ + char text[SDL_TEXTINPUTEVENT_TEXT_SIZE]; /**< The input text */ +} SDL_TextInputEvent; + +/** + * \brief Mouse motion event structure (event.motion.*) + */ +typedef struct SDL_MouseMotionEvent +{ + Uint32 type; /**< ::SDL_MOUSEMOTION */ + Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ + Uint32 windowID; /**< The window with mouse focus, if any */ + Uint32 which; /**< The mouse instance id, or SDL_TOUCH_MOUSEID */ + Uint32 state; /**< The current button state */ + Sint32 x; /**< X coordinate, relative to window */ + Sint32 y; /**< Y coordinate, relative to window */ + Sint32 xrel; /**< The relative motion in the X direction */ + Sint32 yrel; /**< The relative motion in the Y direction */ +} SDL_MouseMotionEvent; + +/** + * \brief Mouse button event structure (event.button.*) + */ +typedef struct SDL_MouseButtonEvent +{ + Uint32 type; /**< ::SDL_MOUSEBUTTONDOWN or ::SDL_MOUSEBUTTONUP */ + Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ + Uint32 windowID; /**< The window with mouse focus, if any */ + Uint32 which; /**< The mouse instance id, or SDL_TOUCH_MOUSEID */ + Uint8 button; /**< The mouse button index */ + Uint8 state; /**< ::SDL_PRESSED or ::SDL_RELEASED */ + Uint8 clicks; /**< 1 for single-click, 2 for double-click, etc. */ + Uint8 padding1; + Sint32 x; /**< X coordinate, relative to window */ + Sint32 y; /**< Y coordinate, relative to window */ +} SDL_MouseButtonEvent; + +/** + * \brief Mouse wheel event structure (event.wheel.*) + */ +typedef struct SDL_MouseWheelEvent +{ + Uint32 type; /**< ::SDL_MOUSEWHEEL */ + Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ + Uint32 windowID; /**< The window with mouse focus, if any */ + Uint32 which; /**< The mouse instance id, or SDL_TOUCH_MOUSEID */ + Sint32 x; /**< The amount scrolled horizontally, positive to the right and negative to the left */ + Sint32 y; /**< The amount scrolled vertically, positive away from the user and negative toward the user */ + Uint32 direction; /**< Set to one of the SDL_MOUSEWHEEL_* defines. When FLIPPED the values in X and Y will be opposite. Multiply by -1 to change them back */ +} SDL_MouseWheelEvent; + +/** + * \brief Joystick axis motion event structure (event.jaxis.*) + */ +typedef struct SDL_JoyAxisEvent +{ + Uint32 type; /**< ::SDL_JOYAXISMOTION */ + Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ + SDL_JoystickID which; /**< The joystick instance id */ + Uint8 axis; /**< The joystick axis index */ + Uint8 padding1; + Uint8 padding2; + Uint8 padding3; + Sint16 value; /**< The axis value (range: -32768 to 32767) */ + Uint16 padding4; +} SDL_JoyAxisEvent; + +/** + * \brief Joystick trackball motion event structure (event.jball.*) + */ +typedef struct SDL_JoyBallEvent +{ + Uint32 type; /**< ::SDL_JOYBALLMOTION */ + Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ + SDL_JoystickID which; /**< The joystick instance id */ + Uint8 ball; /**< The joystick trackball index */ + Uint8 padding1; + Uint8 padding2; + Uint8 padding3; + Sint16 xrel; /**< The relative motion in the X direction */ + Sint16 yrel; /**< The relative motion in the Y direction */ +} SDL_JoyBallEvent; + +/** + * \brief Joystick hat position change event structure (event.jhat.*) + */ +typedef struct SDL_JoyHatEvent +{ + Uint32 type; /**< ::SDL_JOYHATMOTION */ + Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ + SDL_JoystickID which; /**< The joystick instance id */ + Uint8 hat; /**< The joystick hat index */ + Uint8 value; /**< The hat position value. + * \sa ::SDL_HAT_LEFTUP ::SDL_HAT_UP ::SDL_HAT_RIGHTUP + * \sa ::SDL_HAT_LEFT ::SDL_HAT_CENTERED ::SDL_HAT_RIGHT + * \sa ::SDL_HAT_LEFTDOWN ::SDL_HAT_DOWN ::SDL_HAT_RIGHTDOWN + * + * Note that zero means the POV is centered. + */ + Uint8 padding1; + Uint8 padding2; +} SDL_JoyHatEvent; + +/** + * \brief Joystick button event structure (event.jbutton.*) + */ +typedef struct SDL_JoyButtonEvent +{ + Uint32 type; /**< ::SDL_JOYBUTTONDOWN or ::SDL_JOYBUTTONUP */ + Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ + SDL_JoystickID which; /**< The joystick instance id */ + Uint8 button; /**< The joystick button index */ + Uint8 state; /**< ::SDL_PRESSED or ::SDL_RELEASED */ + Uint8 padding1; + Uint8 padding2; +} SDL_JoyButtonEvent; + +/** + * \brief Joystick device event structure (event.jdevice.*) + */ +typedef struct SDL_JoyDeviceEvent +{ + Uint32 type; /**< ::SDL_JOYDEVICEADDED or ::SDL_JOYDEVICEREMOVED */ + Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ + Sint32 which; /**< The joystick device index for the ADDED event, instance id for the REMOVED event */ +} SDL_JoyDeviceEvent; + + +/** + * \brief Game controller axis motion event structure (event.caxis.*) + */ +typedef struct SDL_ControllerAxisEvent +{ + Uint32 type; /**< ::SDL_CONTROLLERAXISMOTION */ + Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ + SDL_JoystickID which; /**< The joystick instance id */ + Uint8 axis; /**< The controller axis (SDL_GameControllerAxis) */ + Uint8 padding1; + Uint8 padding2; + Uint8 padding3; + Sint16 value; /**< The axis value (range: -32768 to 32767) */ + Uint16 padding4; +} SDL_ControllerAxisEvent; + + +/** + * \brief Game controller button event structure (event.cbutton.*) + */ +typedef struct SDL_ControllerButtonEvent +{ + Uint32 type; /**< ::SDL_CONTROLLERBUTTONDOWN or ::SDL_CONTROLLERBUTTONUP */ + Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ + SDL_JoystickID which; /**< The joystick instance id */ + Uint8 button; /**< The controller button (SDL_GameControllerButton) */ + Uint8 state; /**< ::SDL_PRESSED or ::SDL_RELEASED */ + Uint8 padding1; + Uint8 padding2; +} SDL_ControllerButtonEvent; + + +/** + * \brief Controller device event structure (event.cdevice.*) + */ +typedef struct SDL_ControllerDeviceEvent +{ + Uint32 type; /**< ::SDL_CONTROLLERDEVICEADDED, ::SDL_CONTROLLERDEVICEREMOVED, or ::SDL_CONTROLLERDEVICEREMAPPED */ + Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ + Sint32 which; /**< The joystick device index for the ADDED event, instance id for the REMOVED or REMAPPED event */ +} SDL_ControllerDeviceEvent; + +/** + * \brief Audio device event structure (event.adevice.*) + */ +typedef struct SDL_AudioDeviceEvent +{ + Uint32 type; /**< ::SDL_AUDIODEVICEADDED, or ::SDL_AUDIODEVICEREMOVED */ + Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ + Uint32 which; /**< The audio device index for the ADDED event (valid until next SDL_GetNumAudioDevices() call), SDL_AudioDeviceID for the REMOVED event */ + Uint8 iscapture; /**< zero if an output device, non-zero if a capture device. */ + Uint8 padding1; + Uint8 padding2; + Uint8 padding3; +} SDL_AudioDeviceEvent; + + +/** + * \brief Touch finger event structure (event.tfinger.*) + */ +typedef struct SDL_TouchFingerEvent +{ + Uint32 type; /**< ::SDL_FINGERMOTION or ::SDL_FINGERDOWN or ::SDL_FINGERUP */ + Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ + SDL_TouchID touchId; /**< The touch device id */ + SDL_FingerID fingerId; + float x; /**< Normalized in the range 0...1 */ + float y; /**< Normalized in the range 0...1 */ + float dx; /**< Normalized in the range -1...1 */ + float dy; /**< Normalized in the range -1...1 */ + float pressure; /**< Normalized in the range 0...1 */ + Uint32 windowID; /**< The window underneath the finger, if any */ +} SDL_TouchFingerEvent; + + +/** + * \brief Multiple Finger Gesture Event (event.mgesture.*) + */ +typedef struct SDL_MultiGestureEvent +{ + Uint32 type; /**< ::SDL_MULTIGESTURE */ + Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ + SDL_TouchID touchId; /**< The touch device id */ + float dTheta; + float dDist; + float x; + float y; + Uint16 numFingers; + Uint16 padding; +} SDL_MultiGestureEvent; + + +/** + * \brief Dollar Gesture Event (event.dgesture.*) + */ +typedef struct SDL_DollarGestureEvent +{ + Uint32 type; /**< ::SDL_DOLLARGESTURE or ::SDL_DOLLARRECORD */ + Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ + SDL_TouchID touchId; /**< The touch device id */ + SDL_GestureID gestureId; + Uint32 numFingers; + float error; + float x; /**< Normalized center of gesture */ + float y; /**< Normalized center of gesture */ +} SDL_DollarGestureEvent; + + +/** + * \brief An event used to request a file open by the system (event.drop.*) + * This event is enabled by default, you can disable it with SDL_EventState(). + * \note If this event is enabled, you must free the filename in the event. + */ +typedef struct SDL_DropEvent +{ + Uint32 type; /**< ::SDL_DROPBEGIN or ::SDL_DROPFILE or ::SDL_DROPTEXT or ::SDL_DROPCOMPLETE */ + Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ + char *file; /**< The file name, which should be freed with SDL_free(), is NULL on begin/complete */ + Uint32 windowID; /**< The window that was dropped on, if any */ +} SDL_DropEvent; + + +/** + * \brief Sensor event structure (event.sensor.*) + */ +typedef struct SDL_SensorEvent +{ + Uint32 type; /**< ::SDL_SENSORUPDATE */ + Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ + Sint32 which; /**< The instance ID of the sensor */ + float data[6]; /**< Up to 6 values from the sensor - additional values can be queried using SDL_SensorGetData() */ +} SDL_SensorEvent; + +/** + * \brief The "quit requested" event + */ +typedef struct SDL_QuitEvent +{ + Uint32 type; /**< ::SDL_QUIT */ + Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ +} SDL_QuitEvent; + +/** + * \brief OS Specific event + */ +typedef struct SDL_OSEvent +{ + Uint32 type; /**< ::SDL_QUIT */ + Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ +} SDL_OSEvent; + +/** + * \brief A user-defined event type (event.user.*) + */ +typedef struct SDL_UserEvent +{ + Uint32 type; /**< ::SDL_USEREVENT through ::SDL_LASTEVENT-1 */ + Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ + Uint32 windowID; /**< The associated window if any */ + Sint32 code; /**< User defined event code */ + void *data1; /**< User defined data pointer */ + void *data2; /**< User defined data pointer */ +} SDL_UserEvent; + + +struct SDL_SysWMmsg; +typedef struct SDL_SysWMmsg SDL_SysWMmsg; + +/** + * \brief A video driver dependent system event (event.syswm.*) + * This event is disabled by default, you can enable it with SDL_EventState() + * + * \note If you want to use this event, you should include SDL_syswm.h. + */ +typedef struct SDL_SysWMEvent +{ + Uint32 type; /**< ::SDL_SYSWMEVENT */ + Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ + SDL_SysWMmsg *msg; /**< driver dependent data, defined in SDL_syswm.h */ +} SDL_SysWMEvent; + +/** + * \brief General event structure + */ +typedef union SDL_Event +{ + Uint32 type; /**< Event type, shared with all events */ + SDL_CommonEvent common; /**< Common event data */ + SDL_DisplayEvent display; /**< Display event data */ + SDL_WindowEvent window; /**< Window event data */ + SDL_KeyboardEvent key; /**< Keyboard event data */ + SDL_TextEditingEvent edit; /**< Text editing event data */ + SDL_TextInputEvent text; /**< Text input event data */ + SDL_MouseMotionEvent motion; /**< Mouse motion event data */ + SDL_MouseButtonEvent button; /**< Mouse button event data */ + SDL_MouseWheelEvent wheel; /**< Mouse wheel event data */ + SDL_JoyAxisEvent jaxis; /**< Joystick axis event data */ + SDL_JoyBallEvent jball; /**< Joystick ball event data */ + SDL_JoyHatEvent jhat; /**< Joystick hat event data */ + SDL_JoyButtonEvent jbutton; /**< Joystick button event data */ + SDL_JoyDeviceEvent jdevice; /**< Joystick device change event data */ + SDL_ControllerAxisEvent caxis; /**< Game Controller axis event data */ + SDL_ControllerButtonEvent cbutton; /**< Game Controller button event data */ + SDL_ControllerDeviceEvent cdevice; /**< Game Controller device event data */ + SDL_AudioDeviceEvent adevice; /**< Audio device event data */ + SDL_SensorEvent sensor; /**< Sensor event data */ + SDL_QuitEvent quit; /**< Quit request event data */ + SDL_UserEvent user; /**< Custom event data */ + SDL_SysWMEvent syswm; /**< System dependent window event data */ + SDL_TouchFingerEvent tfinger; /**< Touch finger event data */ + SDL_MultiGestureEvent mgesture; /**< Gesture event data */ + SDL_DollarGestureEvent dgesture; /**< Gesture event data */ + SDL_DropEvent drop; /**< Drag and drop event data */ + + /* This is necessary for ABI compatibility between Visual C++ and GCC + Visual C++ will respect the push pack pragma and use 52 bytes for + this structure, and GCC will use the alignment of the largest datatype + within the union, which is 8 bytes. + + So... we'll add padding to force the size to be 56 bytes for both. + */ + Uint8 padding[56]; +} SDL_Event; + +/* Make sure we haven't broken binary compatibility */ +SDL_COMPILE_TIME_ASSERT(SDL_Event, sizeof(SDL_Event) == 56); + + +/* Function prototypes */ + +/** + * 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. + */ +extern DECLSPEC void SDLCALL SDL_PumpEvents(void); + +/* @{ */ +typedef enum +{ + SDL_ADDEVENT, + SDL_PEEKEVENT, + SDL_GETEVENT +} SDL_eventaction; + +/** + * Checks the event queue for messages and optionally returns them. + * + * If \c action is ::SDL_ADDEVENT, up to \c numevents events will be added to + * the back of the event queue. + * + * If \c action is ::SDL_PEEKEVENT, up to \c numevents events at the front + * of the event queue, within the specified minimum and maximum type, + * will be returned and will not be removed from the queue. + * + * If \c action is ::SDL_GETEVENT, up to \c numevents events at the front + * of the event queue, within the specified minimum and maximum type, + * will be returned and will be removed from the queue. + * + * \return The number of events actually stored, or -1 if there was an error. + * + * This function is thread-safe. + */ +extern DECLSPEC int SDLCALL SDL_PeepEvents(SDL_Event * events, int numevents, + SDL_eventaction action, + Uint32 minType, Uint32 maxType); +/* @} */ + +/** + * Checks to see if certain event types are in the event queue. + */ +extern DECLSPEC SDL_bool SDLCALL SDL_HasEvent(Uint32 type); +extern DECLSPEC SDL_bool SDLCALL SDL_HasEvents(Uint32 minType, Uint32 maxType); + +/** + * This function clears events from the event queue + * This function only affects currently queued events. If you want to make + * sure that all pending OS events are flushed, you can call SDL_PumpEvents() + * on the main thread immediately before the flush call. + */ +extern DECLSPEC void SDLCALL SDL_FlushEvent(Uint32 type); +extern DECLSPEC void SDLCALL SDL_FlushEvents(Uint32 minType, Uint32 maxType); + +/** + * \brief Polls for currently pending events. + * + * \return 1 if there are any pending events, or 0 if there are none available. + * + * \param event If not NULL, the next event is removed from the queue and + * stored in that area. + */ +extern DECLSPEC int SDLCALL SDL_PollEvent(SDL_Event * event); + +/** + * \brief Waits indefinitely for the next available event. + * + * \return 1, or 0 if there was an error while waiting for events. + * + * \param event If not NULL, the next event is removed from the queue and + * stored in that area. + */ +extern DECLSPEC int SDLCALL SDL_WaitEvent(SDL_Event * event); + +/** + * \brief Waits until the specified timeout (in milliseconds) for the next + * available event. + * + * \return 1, or 0 if there was an error while waiting for events. + * + * \param event If not NULL, the next event is removed from the queue and + * stored in that area. + * \param timeout The timeout (in milliseconds) to wait for next event. + */ +extern DECLSPEC int SDLCALL SDL_WaitEventTimeout(SDL_Event * event, + int timeout); + +/** + * \brief Add an event to the event queue. + * + * \return 1 on success, 0 if the event was filtered, or -1 if the event queue + * was full or there was some other error. + */ +extern DECLSPEC int SDLCALL SDL_PushEvent(SDL_Event * event); + +typedef int (SDLCALL * SDL_EventFilter) (void *userdata, SDL_Event * event); + +/** + * Sets up a filter to process all events before they change internal state and + * are posted to the internal event queue. + * + * The filter is prototyped as: + * \code + * int SDL_EventFilter(void *userdata, SDL_Event * event); + * \endcode + * + * 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. + */ +extern DECLSPEC void SDLCALL SDL_SetEventFilter(SDL_EventFilter filter, + void *userdata); + +/** + * Return the current event filter - can be used to "chain" filters. + * If there is no event filter set, this function returns SDL_FALSE. + */ +extern DECLSPEC SDL_bool SDLCALL SDL_GetEventFilter(SDL_EventFilter * filter, + void **userdata); + +/** + * Add a function which is called when an event is added to the queue. + */ +extern DECLSPEC void SDLCALL SDL_AddEventWatch(SDL_EventFilter filter, + void *userdata); + +/** + * Remove an event watch function added with SDL_AddEventWatch() + */ +extern DECLSPEC void SDLCALL SDL_DelEventWatch(SDL_EventFilter filter, + void *userdata); + +/** + * Run the filter function on the current event queue, removing any + * events for which the filter returns 0. + */ +extern DECLSPEC void SDLCALL SDL_FilterEvents(SDL_EventFilter filter, + void *userdata); + +/* @{ */ +#define SDL_QUERY -1 +#define SDL_IGNORE 0 +#define SDL_DISABLE 0 +#define SDL_ENABLE 1 + +/** + * This function allows you to set the state of processing certain events. + * - If \c state is set to ::SDL_IGNORE, that event will be automatically + * dropped from the event queue and will not be filtered. + * - If \c state is set to ::SDL_ENABLE, that event will be processed + * normally. + * - If \c state is set to ::SDL_QUERY, SDL_EventState() will return the + * current processing state of the specified event. + */ +extern DECLSPEC Uint8 SDLCALL SDL_EventState(Uint32 type, int state); +/* @} */ +#define SDL_GetEventState(type) SDL_EventState(type, SDL_QUERY) + +/** + * This function allocates a set of user-defined events, and returns + * the beginning event number for that set of events. + * + * If there aren't enough user-defined events left, this function + * returns (Uint32)-1 + */ +extern DECLSPEC Uint32 SDLCALL SDL_RegisterEvents(int numevents); + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_events_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/engine/Windows/SDL2/include/SDL_filesystem.h b/engine/Windows/SDL2/include/SDL_filesystem.h new file mode 100644 index 0000000..6d97e58 --- /dev/null +++ b/engine/Windows/SDL2/include/SDL_filesystem.h @@ -0,0 +1,136 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2019 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_filesystem.h + * + * \brief Include file for filesystem SDL API functions + */ + +#ifndef SDL_filesystem_h_ +#define SDL_filesystem_h_ + +#include "SDL_stdinc.h" + +#include "begin_code.h" + +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief Get the path where the application resides. + * + * Get the "base path". This is the directory where the application was run + * from, which is probably the installation directory, and may or may not + * be the process's current working directory. + * + * This returns an absolute path in UTF-8 encoding, and is guaranteed to + * end with a path separator ('\\' on Windows, '/' most other places). + * + * The pointer returned by this function is owned by you. Please call + * SDL_free() on the pointer when you are done with it, or it will be a + * memory leak. This is not necessarily a fast call, though, so you should + * call this once near startup and save the string if you need it. + * + * Some platforms can't determine the application's path, and on other + * platforms, this might be meaningless. In such cases, this function will + * return NULL. + * + * \return String of base dir in UTF-8 encoding, or NULL on error. + * + * \sa SDL_GetPrefPath + */ +extern DECLSPEC char *SDLCALL SDL_GetBasePath(void); + +/** + * \brief Get the user-and-app-specific path where files can be written. + * + * Get the "pref dir". This is meant to be where users can write personal + * files (preferences and save games, etc) that are specific to your + * application. This directory is unique per user, per application. + * + * This function will decide the appropriate location in the native filesystem, + * create the directory if necessary, and return a string of the absolute + * path to the directory in UTF-8 encoding. + * + * On Windows, the string might look like: + * "C:\\Users\\bob\\AppData\\Roaming\\My Company\\My Program Name\\" + * + * On Linux, the string might look like: + * "/home/bob/.local/share/My Program Name/" + * + * On Mac OS X, the string might look like: + * "/Users/bob/Library/Application Support/My Program Name/" + * + * (etc.) + * + * You specify the name of your organization (if it's not a real organization, + * your name or an Internet domain you own might do) and the name of your + * application. These should be untranslated proper names. + * + * Both the org and app strings may become part of a directory name, so + * please follow these rules: + * + * - Try to use the same org string (including case-sensitivity) for + * all your applications that use this function. + * - Always use a unique app string for each one, and make sure it never + * changes for an app once you've decided on it. + * - Unicode characters are legal, as long as it's UTF-8 encoded, but... + * - ...only use letters, numbers, and spaces. Avoid punctuation like + * "Game Name 2: Bad Guy's Revenge!" ... "Game Name 2" is sufficient. + * + * This returns an absolute path in UTF-8 encoding, and is guaranteed to + * end with a path separator ('\\' on Windows, '/' most other places). + * + * The pointer returned by this function is owned by you. Please call + * SDL_free() on the pointer when you are done with it, or it will be a + * memory leak. This is not necessarily a fast call, though, so you should + * call this once near startup and save the string if you need it. + * + * You should assume the path returned by this function is the only safe + * place to write files (and that SDL_GetBasePath(), while it might be + * writable, or even the parent of the returned path, aren't where you + * should be writing things). + * + * Some platforms can't determine the pref path, and on other + * platforms, this might be meaningless. In such cases, this function will + * return NULL. + * + * \param org The name of your organization. + * \param app The name of your application. + * \return UTF-8 string of user dir in platform-dependent notation. NULL + * if there's a problem (creating directory failed, etc). + * + * \sa SDL_GetBasePath + */ +extern DECLSPEC char *SDLCALL SDL_GetPrefPath(const char *org, const char *app); + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_filesystem_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/engine/Windows/SDL2/include/SDL_gamecontroller.h b/engine/Windows/SDL2/include/SDL_gamecontroller.h new file mode 100644 index 0000000..ebde387 --- /dev/null +++ b/engine/Windows/SDL2/include/SDL_gamecontroller.h @@ -0,0 +1,390 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2019 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_gamecontroller.h + * + * Include file for SDL game controller event handling + */ + +#ifndef SDL_gamecontroller_h_ +#define SDL_gamecontroller_h_ + +#include "SDL_stdinc.h" +#include "SDL_error.h" +#include "SDL_rwops.h" +#include "SDL_joystick.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \file SDL_gamecontroller.h + * + * In order to use these functions, SDL_Init() must have been called + * with the ::SDL_INIT_GAMECONTROLLER flag. This causes SDL to scan the system + * for game controllers, and load appropriate drivers. + * + * If you would like to receive controller updates while the application + * is in the background, you should set the following hint before calling + * SDL_Init(): SDL_HINT_JOYSTICK_ALLOW_BACKGROUND_EVENTS + */ + +/** + * The gamecontroller structure used to identify an SDL game controller + */ +struct _SDL_GameController; +typedef struct _SDL_GameController SDL_GameController; + + +typedef enum +{ + SDL_CONTROLLER_BINDTYPE_NONE = 0, + SDL_CONTROLLER_BINDTYPE_BUTTON, + SDL_CONTROLLER_BINDTYPE_AXIS, + SDL_CONTROLLER_BINDTYPE_HAT +} SDL_GameControllerBindType; + +/** + * Get the SDL joystick layer binding for this controller button/axis mapping + */ +typedef struct SDL_GameControllerButtonBind +{ + SDL_GameControllerBindType bindType; + union + { + int button; + int axis; + struct { + int hat; + int hat_mask; + } hat; + } value; + +} SDL_GameControllerButtonBind; + + +/** + * To count the number of game controllers in the system for the following: + * int nJoysticks = SDL_NumJoysticks(); + * int nGameControllers = 0; + * for (int i = 0; i < nJoysticks; i++) { + * if (SDL_IsGameController(i)) { + * nGameControllers++; + * } + * } + * + * Using the SDL_HINT_GAMECONTROLLERCONFIG hint or the SDL_GameControllerAddMapping() you can add support for controllers SDL is unaware of or cause an existing controller to have a different binding. The format is: + * guid,name,mappings + * + * Where GUID is the string value from SDL_JoystickGetGUIDString(), name is the human readable string for the device and mappings are controller mappings to joystick ones. + * Under Windows there is a reserved GUID of "xinput" that covers any XInput devices. + * The mapping format for joystick is: + * bX - a joystick button, index X + * hX.Y - hat X with value Y + * aX - axis X of the joystick + * Buttons can be used as a controller axis and vice versa. + * + * This string shows an example of a valid mapping for a controller + * "03000000341a00003608000000000000,PS3 Controller,a:b1,b:b2,y:b3,x:b0,start:b9,guide:b12,back:b8,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftshoulder:b4,rightshoulder:b5,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7", + * + */ + +/** + * Load a set of mappings from a seekable SDL data stream (memory or file), filtered by the current SDL_GetPlatform() + * A community sourced database of controllers is available at https://raw.github.com/gabomdq/SDL_GameControllerDB/master/gamecontrollerdb.txt + * + * If \c freerw is non-zero, the stream will be closed after being read. + * + * \return number of mappings added, -1 on error + */ +extern DECLSPEC int SDLCALL SDL_GameControllerAddMappingsFromRW(SDL_RWops * rw, int freerw); + +/** + * Load a set of mappings from a file, filtered by the current SDL_GetPlatform() + * + * Convenience macro. + */ +#define SDL_GameControllerAddMappingsFromFile(file) SDL_GameControllerAddMappingsFromRW(SDL_RWFromFile(file, "rb"), 1) + +/** + * Add or update an existing mapping configuration + * + * \return 1 if mapping is added, 0 if updated, -1 on error + */ +extern DECLSPEC int SDLCALL SDL_GameControllerAddMapping(const char* mappingString); + +/** + * Get the number of mappings installed + * + * \return the number of mappings + */ +extern DECLSPEC int SDLCALL SDL_GameControllerNumMappings(void); + +/** + * Get the mapping at a particular index. + * + * \return the mapping string. Must be freed with SDL_free(). Returns NULL if the index is out of range. + */ +extern DECLSPEC char * SDLCALL SDL_GameControllerMappingForIndex(int mapping_index); + +/** + * Get a mapping string for a GUID + * + * \return the mapping string. Must be freed with SDL_free(). Returns NULL if no mapping is available + */ +extern DECLSPEC char * SDLCALL SDL_GameControllerMappingForGUID(SDL_JoystickGUID guid); + +/** + * Get a mapping string for an open GameController + * + * \return the mapping string. Must be freed with SDL_free(). Returns NULL if no mapping is available + */ +extern DECLSPEC char * SDLCALL SDL_GameControllerMapping(SDL_GameController * gamecontroller); + +/** + * Is the joystick on this index supported by the game controller interface? + */ +extern DECLSPEC SDL_bool SDLCALL SDL_IsGameController(int joystick_index); + +/** + * Get the implementation dependent name of a game controller. + * This can be called before any controllers are opened. + * If no name can be found, this function returns NULL. + */ +extern DECLSPEC const char *SDLCALL SDL_GameControllerNameForIndex(int joystick_index); + +/** + * Get the mapping of a game controller. + * This can be called before any controllers are opened. + * + * \return the mapping string. Must be freed with SDL_free(). Returns NULL if no mapping is available + */ +extern DECLSPEC char *SDLCALL SDL_GameControllerMappingForDeviceIndex(int joystick_index); + +/** + * Open a game controller for use. + * The index passed as an argument refers to the N'th game controller on the system. + * This index is not the value which will identify this controller in future + * controller events. The joystick's instance id (::SDL_JoystickID) will be + * used there instead. + * + * \return A controller identifier, or NULL if an error occurred. + */ +extern DECLSPEC SDL_GameController *SDLCALL SDL_GameControllerOpen(int joystick_index); + +/** + * Return the SDL_GameController associated with an instance id. + */ +extern DECLSPEC SDL_GameController *SDLCALL SDL_GameControllerFromInstanceID(SDL_JoystickID joyid); + +/** + * Return the name for this currently opened controller + */ +extern DECLSPEC const char *SDLCALL SDL_GameControllerName(SDL_GameController *gamecontroller); + +/** + * Get the player index of an opened game controller, or -1 if it's not available + * + * For XInput controllers this returns the XInput user index. + */ +extern DECLSPEC int SDLCALL SDL_GameControllerGetPlayerIndex(SDL_GameController *gamecontroller); + +/** + * Get the USB vendor ID of an opened controller, if available. + * If the vendor ID isn't available this function returns 0. + */ +extern DECLSPEC Uint16 SDLCALL SDL_GameControllerGetVendor(SDL_GameController * gamecontroller); + +/** + * Get the USB product ID of an opened controller, if available. + * If the product ID isn't available this function returns 0. + */ +extern DECLSPEC Uint16 SDLCALL SDL_GameControllerGetProduct(SDL_GameController * gamecontroller); + +/** + * Get the product version of an opened controller, if available. + * If the product version isn't available this function returns 0. + */ +extern DECLSPEC Uint16 SDLCALL SDL_GameControllerGetProductVersion(SDL_GameController * gamecontroller); + +/** + * Returns SDL_TRUE if the controller has been opened and currently connected, + * or SDL_FALSE if it has not. + */ +extern DECLSPEC SDL_bool SDLCALL SDL_GameControllerGetAttached(SDL_GameController *gamecontroller); + +/** + * Get the underlying joystick object used by a controller + */ +extern DECLSPEC SDL_Joystick *SDLCALL SDL_GameControllerGetJoystick(SDL_GameController *gamecontroller); + +/** + * Enable/disable controller event polling. + * + * If controller events are disabled, you must call SDL_GameControllerUpdate() + * yourself and check the state of the controller when you want controller + * information. + * + * The state can be one of ::SDL_QUERY, ::SDL_ENABLE or ::SDL_IGNORE. + */ +extern DECLSPEC int SDLCALL SDL_GameControllerEventState(int state); + +/** + * Update the current state of the open game controllers. + * + * This is called automatically by the event loop if any game controller + * events are enabled. + */ +extern DECLSPEC void SDLCALL SDL_GameControllerUpdate(void); + + +/** + * The list of axes available from a controller + * + * Thumbstick axis values range from SDL_JOYSTICK_AXIS_MIN to SDL_JOYSTICK_AXIS_MAX, + * and are centered within ~8000 of zero, though advanced UI will allow users to set + * or autodetect the dead zone, which varies between controllers. + * + * Trigger axis values range from 0 to SDL_JOYSTICK_AXIS_MAX. + */ +typedef enum +{ + SDL_CONTROLLER_AXIS_INVALID = -1, + SDL_CONTROLLER_AXIS_LEFTX, + SDL_CONTROLLER_AXIS_LEFTY, + SDL_CONTROLLER_AXIS_RIGHTX, + SDL_CONTROLLER_AXIS_RIGHTY, + SDL_CONTROLLER_AXIS_TRIGGERLEFT, + SDL_CONTROLLER_AXIS_TRIGGERRIGHT, + SDL_CONTROLLER_AXIS_MAX +} SDL_GameControllerAxis; + +/** + * turn this string into a axis mapping + */ +extern DECLSPEC SDL_GameControllerAxis SDLCALL SDL_GameControllerGetAxisFromString(const char *pchString); + +/** + * turn this axis enum into a string mapping + */ +extern DECLSPEC const char* SDLCALL SDL_GameControllerGetStringForAxis(SDL_GameControllerAxis axis); + +/** + * Get the SDL joystick layer binding for this controller button mapping + */ +extern DECLSPEC SDL_GameControllerButtonBind SDLCALL +SDL_GameControllerGetBindForAxis(SDL_GameController *gamecontroller, + SDL_GameControllerAxis axis); + +/** + * Get the current state of an axis control on a game controller. + * + * The state is a value ranging from -32768 to 32767 (except for the triggers, + * which range from 0 to 32767). + * + * The axis indices start at index 0. + */ +extern DECLSPEC Sint16 SDLCALL +SDL_GameControllerGetAxis(SDL_GameController *gamecontroller, + SDL_GameControllerAxis axis); + +/** + * The list of buttons available from a controller + */ +typedef enum +{ + SDL_CONTROLLER_BUTTON_INVALID = -1, + SDL_CONTROLLER_BUTTON_A, + SDL_CONTROLLER_BUTTON_B, + SDL_CONTROLLER_BUTTON_X, + SDL_CONTROLLER_BUTTON_Y, + SDL_CONTROLLER_BUTTON_BACK, + SDL_CONTROLLER_BUTTON_GUIDE, + SDL_CONTROLLER_BUTTON_START, + SDL_CONTROLLER_BUTTON_LEFTSTICK, + SDL_CONTROLLER_BUTTON_RIGHTSTICK, + SDL_CONTROLLER_BUTTON_LEFTSHOULDER, + SDL_CONTROLLER_BUTTON_RIGHTSHOULDER, + SDL_CONTROLLER_BUTTON_DPAD_UP, + SDL_CONTROLLER_BUTTON_DPAD_DOWN, + SDL_CONTROLLER_BUTTON_DPAD_LEFT, + SDL_CONTROLLER_BUTTON_DPAD_RIGHT, + SDL_CONTROLLER_BUTTON_MAX +} SDL_GameControllerButton; + +/** + * turn this string into a button mapping + */ +extern DECLSPEC SDL_GameControllerButton SDLCALL SDL_GameControllerGetButtonFromString(const char *pchString); + +/** + * turn this button enum into a string mapping + */ +extern DECLSPEC const char* SDLCALL SDL_GameControllerGetStringForButton(SDL_GameControllerButton button); + +/** + * Get the SDL joystick layer binding for this controller button mapping + */ +extern DECLSPEC SDL_GameControllerButtonBind SDLCALL +SDL_GameControllerGetBindForButton(SDL_GameController *gamecontroller, + SDL_GameControllerButton button); + + +/** + * Get the current state of a button on a game controller. + * + * The button indices start at index 0. + */ +extern DECLSPEC Uint8 SDLCALL SDL_GameControllerGetButton(SDL_GameController *gamecontroller, + SDL_GameControllerButton button); + +/** + * Trigger a rumble effect + * Each call to this function cancels any previous rumble effect, and calling it with 0 intensity stops any rumbling. + * + * \param gamecontroller The controller to vibrate + * \param low_frequency_rumble The intensity of the low frequency (left) rumble motor, from 0 to 0xFFFF + * \param high_frequency_rumble The intensity of the high frequency (right) rumble motor, from 0 to 0xFFFF + * \param duration_ms The duration of the rumble effect, in milliseconds + * + * \return 0, or -1 if rumble isn't supported on this joystick + */ +extern DECLSPEC int SDLCALL SDL_GameControllerRumble(SDL_GameController *gamecontroller, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble, Uint32 duration_ms); + +/** + * Close a controller previously opened with SDL_GameControllerOpen(). + */ +extern DECLSPEC void SDLCALL SDL_GameControllerClose(SDL_GameController *gamecontroller); + + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_gamecontroller_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/engine/Windows/SDL2/include/SDL_gesture.h b/engine/Windows/SDL2/include/SDL_gesture.h new file mode 100644 index 0000000..9d25e9c --- /dev/null +++ b/engine/Windows/SDL2/include/SDL_gesture.h @@ -0,0 +1,87 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2019 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_gesture.h + * + * Include file for SDL gesture event handling. + */ + +#ifndef SDL_gesture_h_ +#define SDL_gesture_h_ + +#include "SDL_stdinc.h" +#include "SDL_error.h" +#include "SDL_video.h" + +#include "SDL_touch.h" + + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +typedef Sint64 SDL_GestureID; + +/* Function prototypes */ + +/** + * \brief Begin Recording a gesture on the specified touch, or all touches (-1) + * + * + */ +extern DECLSPEC int SDLCALL SDL_RecordGesture(SDL_TouchID touchId); + + +/** + * \brief Save all currently loaded Dollar Gesture templates + * + * + */ +extern DECLSPEC int SDLCALL SDL_SaveAllDollarTemplates(SDL_RWops *dst); + +/** + * \brief Save a currently loaded Dollar Gesture template + * + * + */ +extern DECLSPEC int SDLCALL SDL_SaveDollarTemplate(SDL_GestureID gestureId,SDL_RWops *dst); + + +/** + * \brief Load Dollar Gesture templates from a file + * + * + */ +extern DECLSPEC int SDLCALL SDL_LoadDollarTemplates(SDL_TouchID touchId, SDL_RWops *src); + + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_gesture_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/engine/Windows/SDL2/include/SDL_haptic.h b/engine/Windows/SDL2/include/SDL_haptic.h new file mode 100644 index 0000000..0756276 --- /dev/null +++ b/engine/Windows/SDL2/include/SDL_haptic.h @@ -0,0 +1,1238 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2019 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_haptic.h + * + * \brief The SDL haptic subsystem allows you to control haptic (force feedback) + * devices. + * + * The basic usage is as follows: + * - Initialize the subsystem (::SDL_INIT_HAPTIC). + * - Open a haptic device. + * - SDL_HapticOpen() to open from index. + * - SDL_HapticOpenFromJoystick() to open from an existing joystick. + * - Create an effect (::SDL_HapticEffect). + * - Upload the effect with SDL_HapticNewEffect(). + * - Run the effect with SDL_HapticRunEffect(). + * - (optional) Free the effect with SDL_HapticDestroyEffect(). + * - Close the haptic device with SDL_HapticClose(). + * + * \par Simple rumble example: + * \code + * SDL_Haptic *haptic; + * + * // Open the device + * haptic = SDL_HapticOpen( 0 ); + * if (haptic == NULL) + * return -1; + * + * // Initialize simple rumble + * if (SDL_HapticRumbleInit( haptic ) != 0) + * return -1; + * + * // Play effect at 50% strength for 2 seconds + * if (SDL_HapticRumblePlay( haptic, 0.5, 2000 ) != 0) + * return -1; + * SDL_Delay( 2000 ); + * + * // Clean up + * SDL_HapticClose( haptic ); + * \endcode + * + * \par Complete example: + * \code + * int test_haptic( SDL_Joystick * joystick ) { + * SDL_Haptic *haptic; + * SDL_HapticEffect effect; + * int effect_id; + * + * // Open the device + * haptic = SDL_HapticOpenFromJoystick( joystick ); + * if (haptic == NULL) return -1; // Most likely joystick isn't haptic + * + * // See if it can do sine waves + * if ((SDL_HapticQuery(haptic) & SDL_HAPTIC_SINE)==0) { + * SDL_HapticClose(haptic); // No sine effect + * return -1; + * } + * + * // Create the effect + * memset( &effect, 0, sizeof(SDL_HapticEffect) ); // 0 is safe default + * effect.type = SDL_HAPTIC_SINE; + * effect.periodic.direction.type = SDL_HAPTIC_POLAR; // Polar coordinates + * effect.periodic.direction.dir[0] = 18000; // Force comes from south + * effect.periodic.period = 1000; // 1000 ms + * effect.periodic.magnitude = 20000; // 20000/32767 strength + * effect.periodic.length = 5000; // 5 seconds long + * effect.periodic.attack_length = 1000; // Takes 1 second to get max strength + * effect.periodic.fade_length = 1000; // Takes 1 second to fade away + * + * // Upload the effect + * effect_id = SDL_HapticNewEffect( haptic, &effect ); + * + * // Test the effect + * SDL_HapticRunEffect( haptic, effect_id, 1 ); + * SDL_Delay( 5000); // Wait for the effect to finish + * + * // We destroy the effect, although closing the device also does this + * SDL_HapticDestroyEffect( haptic, effect_id ); + * + * // Close the device + * SDL_HapticClose(haptic); + * + * return 0; // Success + * } + * \endcode + */ + +#ifndef SDL_haptic_h_ +#define SDL_haptic_h_ + +#include "SDL_stdinc.h" +#include "SDL_error.h" +#include "SDL_joystick.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* FIXME: For SDL 2.1, adjust all the magnitude variables to be Uint16 (0xFFFF). + * + * At the moment the magnitude variables are mixed between signed/unsigned, and + * it is also not made clear that ALL of those variables expect a max of 0x7FFF. + * + * Some platforms may have higher precision than that (Linux FF, Windows XInput) + * so we should fix the inconsistency in favor of higher possible precision, + * adjusting for platforms that use different scales. + * -flibit + */ + +/** + * \typedef SDL_Haptic + * + * \brief The haptic structure used to identify an SDL haptic. + * + * \sa SDL_HapticOpen + * \sa SDL_HapticOpenFromJoystick + * \sa SDL_HapticClose + */ +struct _SDL_Haptic; +typedef struct _SDL_Haptic SDL_Haptic; + + +/** + * \name Haptic features + * + * Different haptic features a device can have. + */ +/* @{ */ + +/** + * \name Haptic effects + */ +/* @{ */ + +/** + * \brief Constant effect supported. + * + * Constant haptic effect. + * + * \sa SDL_HapticCondition + */ +#define SDL_HAPTIC_CONSTANT (1u<<0) + +/** + * \brief Sine wave effect supported. + * + * Periodic haptic effect that simulates sine waves. + * + * \sa SDL_HapticPeriodic + */ +#define SDL_HAPTIC_SINE (1u<<1) + +/** + * \brief Left/Right effect supported. + * + * Haptic effect for direct control over high/low frequency motors. + * + * \sa SDL_HapticLeftRight + * \warning this value was SDL_HAPTIC_SQUARE right before 2.0.0 shipped. Sorry, + * we ran out of bits, and this is important for XInput devices. + */ +#define SDL_HAPTIC_LEFTRIGHT (1u<<2) + +/* !!! FIXME: put this back when we have more bits in 2.1 */ +/* #define SDL_HAPTIC_SQUARE (1<<2) */ + +/** + * \brief Triangle wave effect supported. + * + * Periodic haptic effect that simulates triangular waves. + * + * \sa SDL_HapticPeriodic + */ +#define SDL_HAPTIC_TRIANGLE (1u<<3) + +/** + * \brief Sawtoothup wave effect supported. + * + * Periodic haptic effect that simulates saw tooth up waves. + * + * \sa SDL_HapticPeriodic + */ +#define SDL_HAPTIC_SAWTOOTHUP (1u<<4) + +/** + * \brief Sawtoothdown wave effect supported. + * + * Periodic haptic effect that simulates saw tooth down waves. + * + * \sa SDL_HapticPeriodic + */ +#define SDL_HAPTIC_SAWTOOTHDOWN (1u<<5) + +/** + * \brief Ramp effect supported. + * + * Ramp haptic effect. + * + * \sa SDL_HapticRamp + */ +#define SDL_HAPTIC_RAMP (1u<<6) + +/** + * \brief Spring effect supported - uses axes position. + * + * Condition haptic effect that simulates a spring. Effect is based on the + * axes position. + * + * \sa SDL_HapticCondition + */ +#define SDL_HAPTIC_SPRING (1u<<7) + +/** + * \brief Damper effect supported - uses axes velocity. + * + * Condition haptic effect that simulates dampening. Effect is based on the + * axes velocity. + * + * \sa SDL_HapticCondition + */ +#define SDL_HAPTIC_DAMPER (1u<<8) + +/** + * \brief Inertia effect supported - uses axes acceleration. + * + * Condition haptic effect that simulates inertia. Effect is based on the axes + * acceleration. + * + * \sa SDL_HapticCondition + */ +#define SDL_HAPTIC_INERTIA (1u<<9) + +/** + * \brief Friction effect supported - uses axes movement. + * + * Condition haptic effect that simulates friction. Effect is based on the + * axes movement. + * + * \sa SDL_HapticCondition + */ +#define SDL_HAPTIC_FRICTION (1u<<10) + +/** + * \brief Custom effect is supported. + * + * User defined custom haptic effect. + */ +#define SDL_HAPTIC_CUSTOM (1u<<11) + +/* @} *//* Haptic effects */ + +/* These last few are features the device has, not effects */ + +/** + * \brief Device can set global gain. + * + * Device supports setting the global gain. + * + * \sa SDL_HapticSetGain + */ +#define SDL_HAPTIC_GAIN (1u<<12) + +/** + * \brief Device can set autocenter. + * + * Device supports setting autocenter. + * + * \sa SDL_HapticSetAutocenter + */ +#define SDL_HAPTIC_AUTOCENTER (1u<<13) + +/** + * \brief Device can be queried for effect status. + * + * Device supports querying effect status. + * + * \sa SDL_HapticGetEffectStatus + */ +#define SDL_HAPTIC_STATUS (1u<<14) + +/** + * \brief Device can be paused. + * + * Devices supports being paused. + * + * \sa SDL_HapticPause + * \sa SDL_HapticUnpause + */ +#define SDL_HAPTIC_PAUSE (1u<<15) + + +/** + * \name Direction encodings + */ +/* @{ */ + +/** + * \brief Uses polar coordinates for the direction. + * + * \sa SDL_HapticDirection + */ +#define SDL_HAPTIC_POLAR 0 + +/** + * \brief Uses cartesian coordinates for the direction. + * + * \sa SDL_HapticDirection + */ +#define SDL_HAPTIC_CARTESIAN 1 + +/** + * \brief Uses spherical coordinates for the direction. + * + * \sa SDL_HapticDirection + */ +#define SDL_HAPTIC_SPHERICAL 2 + +/* @} *//* Direction encodings */ + +/* @} *//* Haptic features */ + +/* + * Misc defines. + */ + +/** + * \brief Used to play a device an infinite number of times. + * + * \sa SDL_HapticRunEffect + */ +#define SDL_HAPTIC_INFINITY 4294967295U + + +/** + * \brief Structure that represents a haptic direction. + * + * This is the direction where the force comes from, + * instead of the direction in which the force is exerted. + * + * Directions can be specified by: + * - ::SDL_HAPTIC_POLAR : Specified by polar coordinates. + * - ::SDL_HAPTIC_CARTESIAN : Specified by cartesian coordinates. + * - ::SDL_HAPTIC_SPHERICAL : Specified by spherical coordinates. + * + * Cardinal directions of the haptic device are relative to the positioning + * of the device. North is considered to be away from the user. + * + * The following diagram represents the cardinal directions: + * \verbatim + .--. + |__| .-------. + |=.| |.-----.| + |--| || || + | | |'-----'| + |__|~')_____(' + [ COMPUTER ] + + + North (0,-1) + ^ + | + | + (-1,0) West <----[ HAPTIC ]----> East (1,0) + | + | + v + South (0,1) + + + [ USER ] + \|||/ + (o o) + ---ooO-(_)-Ooo--- + \endverbatim + * + * If type is ::SDL_HAPTIC_POLAR, direction is encoded by hundredths of a + * degree starting north and turning clockwise. ::SDL_HAPTIC_POLAR only uses + * the first \c dir parameter. The cardinal directions would be: + * - North: 0 (0 degrees) + * - East: 9000 (90 degrees) + * - South: 18000 (180 degrees) + * - West: 27000 (270 degrees) + * + * If type is ::SDL_HAPTIC_CARTESIAN, direction is encoded by three positions + * (X axis, Y axis and Z axis (with 3 axes)). ::SDL_HAPTIC_CARTESIAN uses + * the first three \c dir parameters. The cardinal directions would be: + * - North: 0,-1, 0 + * - East: 1, 0, 0 + * - South: 0, 1, 0 + * - West: -1, 0, 0 + * + * The Z axis represents the height of the effect if supported, otherwise + * it's unused. In cartesian encoding (1, 2) would be the same as (2, 4), you + * can use any multiple you want, only the direction matters. + * + * If type is ::SDL_HAPTIC_SPHERICAL, direction is encoded by two rotations. + * The first two \c dir parameters are used. The \c dir parameters are as + * follows (all values are in hundredths of degrees): + * - Degrees from (1, 0) rotated towards (0, 1). + * - Degrees towards (0, 0, 1) (device needs at least 3 axes). + * + * + * Example of force coming from the south with all encodings (force coming + * from the south means the user will have to pull the stick to counteract): + * \code + * SDL_HapticDirection direction; + * + * // Cartesian directions + * direction.type = SDL_HAPTIC_CARTESIAN; // Using cartesian direction encoding. + * direction.dir[0] = 0; // X position + * direction.dir[1] = 1; // Y position + * // Assuming the device has 2 axes, we don't need to specify third parameter. + * + * // Polar directions + * direction.type = SDL_HAPTIC_POLAR; // We'll be using polar direction encoding. + * direction.dir[0] = 18000; // Polar only uses first parameter + * + * // Spherical coordinates + * direction.type = SDL_HAPTIC_SPHERICAL; // Spherical encoding + * direction.dir[0] = 9000; // Since we only have two axes we don't need more parameters. + * \endcode + * + * \sa SDL_HAPTIC_POLAR + * \sa SDL_HAPTIC_CARTESIAN + * \sa SDL_HAPTIC_SPHERICAL + * \sa SDL_HapticEffect + * \sa SDL_HapticNumAxes + */ +typedef struct SDL_HapticDirection +{ + Uint8 type; /**< The type of encoding. */ + Sint32 dir[3]; /**< The encoded direction. */ +} SDL_HapticDirection; + + +/** + * \brief A structure containing a template for a Constant effect. + * + * This struct is exclusively for the ::SDL_HAPTIC_CONSTANT effect. + * + * A constant effect applies a constant force in the specified direction + * to the joystick. + * + * \sa SDL_HAPTIC_CONSTANT + * \sa SDL_HapticEffect + */ +typedef struct SDL_HapticConstant +{ + /* Header */ + Uint16 type; /**< ::SDL_HAPTIC_CONSTANT */ + SDL_HapticDirection direction; /**< Direction of the effect. */ + + /* Replay */ + Uint32 length; /**< Duration of the effect. */ + Uint16 delay; /**< Delay before starting the effect. */ + + /* Trigger */ + Uint16 button; /**< Button that triggers the effect. */ + Uint16 interval; /**< How soon it can be triggered again after button. */ + + /* Constant */ + Sint16 level; /**< Strength of the constant effect. */ + + /* Envelope */ + Uint16 attack_length; /**< Duration of the attack. */ + Uint16 attack_level; /**< Level at the start of the attack. */ + Uint16 fade_length; /**< Duration of the fade. */ + Uint16 fade_level; /**< Level at the end of the fade. */ +} SDL_HapticConstant; + +/** + * \brief A structure containing a template for a Periodic effect. + * + * The struct handles the following effects: + * - ::SDL_HAPTIC_SINE + * - ::SDL_HAPTIC_LEFTRIGHT + * - ::SDL_HAPTIC_TRIANGLE + * - ::SDL_HAPTIC_SAWTOOTHUP + * - ::SDL_HAPTIC_SAWTOOTHDOWN + * + * A periodic effect consists in a wave-shaped effect that repeats itself + * over time. The type determines the shape of the wave and the parameters + * determine the dimensions of the wave. + * + * Phase is given by hundredth of a degree meaning that giving the phase a value + * of 9000 will displace it 25% of its period. Here are sample values: + * - 0: No phase displacement. + * - 9000: Displaced 25% of its period. + * - 18000: Displaced 50% of its period. + * - 27000: Displaced 75% of its period. + * - 36000: Displaced 100% of its period, same as 0, but 0 is preferred. + * + * Examples: + * \verbatim + SDL_HAPTIC_SINE + __ __ __ __ + / \ / \ / \ / + / \__/ \__/ \__/ + + SDL_HAPTIC_SQUARE + __ __ __ __ __ + | | | | | | | | | | + | |__| |__| |__| |__| | + + SDL_HAPTIC_TRIANGLE + /\ /\ /\ /\ /\ + / \ / \ / \ / \ / + / \/ \/ \/ \/ + + SDL_HAPTIC_SAWTOOTHUP + /| /| /| /| /| /| /| + / | / | / | / | / | / | / | + / |/ |/ |/ |/ |/ |/ | + + SDL_HAPTIC_SAWTOOTHDOWN + \ |\ |\ |\ |\ |\ |\ | + \ | \ | \ | \ | \ | \ | \ | + \| \| \| \| \| \| \| + \endverbatim + * + * \sa SDL_HAPTIC_SINE + * \sa SDL_HAPTIC_LEFTRIGHT + * \sa SDL_HAPTIC_TRIANGLE + * \sa SDL_HAPTIC_SAWTOOTHUP + * \sa SDL_HAPTIC_SAWTOOTHDOWN + * \sa SDL_HapticEffect + */ +typedef struct SDL_HapticPeriodic +{ + /* Header */ + Uint16 type; /**< ::SDL_HAPTIC_SINE, ::SDL_HAPTIC_LEFTRIGHT, + ::SDL_HAPTIC_TRIANGLE, ::SDL_HAPTIC_SAWTOOTHUP or + ::SDL_HAPTIC_SAWTOOTHDOWN */ + SDL_HapticDirection direction; /**< Direction of the effect. */ + + /* Replay */ + Uint32 length; /**< Duration of the effect. */ + Uint16 delay; /**< Delay before starting the effect. */ + + /* Trigger */ + Uint16 button; /**< Button that triggers the effect. */ + Uint16 interval; /**< How soon it can be triggered again after button. */ + + /* Periodic */ + Uint16 period; /**< Period of the wave. */ + Sint16 magnitude; /**< Peak value; if negative, equivalent to 180 degrees extra phase shift. */ + Sint16 offset; /**< Mean value of the wave. */ + Uint16 phase; /**< Positive phase shift given by hundredth of a degree. */ + + /* Envelope */ + Uint16 attack_length; /**< Duration of the attack. */ + Uint16 attack_level; /**< Level at the start of the attack. */ + Uint16 fade_length; /**< Duration of the fade. */ + Uint16 fade_level; /**< Level at the end of the fade. */ +} SDL_HapticPeriodic; + +/** + * \brief A structure containing a template for a Condition effect. + * + * The struct handles the following effects: + * - ::SDL_HAPTIC_SPRING: Effect based on axes position. + * - ::SDL_HAPTIC_DAMPER: Effect based on axes velocity. + * - ::SDL_HAPTIC_INERTIA: Effect based on axes acceleration. + * - ::SDL_HAPTIC_FRICTION: Effect based on axes movement. + * + * Direction is handled by condition internals instead of a direction member. + * The condition effect specific members have three parameters. The first + * refers to the X axis, the second refers to the Y axis and the third + * refers to the Z axis. The right terms refer to the positive side of the + * axis and the left terms refer to the negative side of the axis. Please + * refer to the ::SDL_HapticDirection diagram for which side is positive and + * which is negative. + * + * \sa SDL_HapticDirection + * \sa SDL_HAPTIC_SPRING + * \sa SDL_HAPTIC_DAMPER + * \sa SDL_HAPTIC_INERTIA + * \sa SDL_HAPTIC_FRICTION + * \sa SDL_HapticEffect + */ +typedef struct SDL_HapticCondition +{ + /* Header */ + Uint16 type; /**< ::SDL_HAPTIC_SPRING, ::SDL_HAPTIC_DAMPER, + ::SDL_HAPTIC_INERTIA or ::SDL_HAPTIC_FRICTION */ + SDL_HapticDirection direction; /**< Direction of the effect - Not used ATM. */ + + /* Replay */ + Uint32 length; /**< Duration of the effect. */ + Uint16 delay; /**< Delay before starting the effect. */ + + /* Trigger */ + Uint16 button; /**< Button that triggers the effect. */ + Uint16 interval; /**< How soon it can be triggered again after button. */ + + /* Condition */ + Uint16 right_sat[3]; /**< Level when joystick is to the positive side; max 0xFFFF. */ + Uint16 left_sat[3]; /**< Level when joystick is to the negative side; max 0xFFFF. */ + Sint16 right_coeff[3]; /**< How fast to increase the force towards the positive side. */ + Sint16 left_coeff[3]; /**< How fast to increase the force towards the negative side. */ + Uint16 deadband[3]; /**< Size of the dead zone; max 0xFFFF: whole axis-range when 0-centered. */ + Sint16 center[3]; /**< Position of the dead zone. */ +} SDL_HapticCondition; + +/** + * \brief A structure containing a template for a Ramp effect. + * + * This struct is exclusively for the ::SDL_HAPTIC_RAMP effect. + * + * The ramp effect starts at start strength and ends at end strength. + * It augments in linear fashion. If you use attack and fade with a ramp + * the effects get added to the ramp effect making the effect become + * quadratic instead of linear. + * + * \sa SDL_HAPTIC_RAMP + * \sa SDL_HapticEffect + */ +typedef struct SDL_HapticRamp +{ + /* Header */ + Uint16 type; /**< ::SDL_HAPTIC_RAMP */ + SDL_HapticDirection direction; /**< Direction of the effect. */ + + /* Replay */ + Uint32 length; /**< Duration of the effect. */ + Uint16 delay; /**< Delay before starting the effect. */ + + /* Trigger */ + Uint16 button; /**< Button that triggers the effect. */ + Uint16 interval; /**< How soon it can be triggered again after button. */ + + /* Ramp */ + Sint16 start; /**< Beginning strength level. */ + Sint16 end; /**< Ending strength level. */ + + /* Envelope */ + Uint16 attack_length; /**< Duration of the attack. */ + Uint16 attack_level; /**< Level at the start of the attack. */ + Uint16 fade_length; /**< Duration of the fade. */ + Uint16 fade_level; /**< Level at the end of the fade. */ +} SDL_HapticRamp; + +/** + * \brief A structure containing a template for a Left/Right effect. + * + * This struct is exclusively for the ::SDL_HAPTIC_LEFTRIGHT effect. + * + * The Left/Right effect is used to explicitly control the large and small + * motors, commonly found in modern game controllers. The small (right) motor + * is high frequency, and the large (left) motor is low frequency. + * + * \sa SDL_HAPTIC_LEFTRIGHT + * \sa SDL_HapticEffect + */ +typedef struct SDL_HapticLeftRight +{ + /* Header */ + Uint16 type; /**< ::SDL_HAPTIC_LEFTRIGHT */ + + /* Replay */ + Uint32 length; /**< Duration of the effect in milliseconds. */ + + /* Rumble */ + Uint16 large_magnitude; /**< Control of the large controller motor. */ + Uint16 small_magnitude; /**< Control of the small controller motor. */ +} SDL_HapticLeftRight; + +/** + * \brief A structure containing a template for the ::SDL_HAPTIC_CUSTOM effect. + * + * This struct is exclusively for the ::SDL_HAPTIC_CUSTOM effect. + * + * A custom force feedback effect is much like a periodic effect, where the + * application can define its exact shape. You will have to allocate the + * data yourself. Data should consist of channels * samples Uint16 samples. + * + * If channels is one, the effect is rotated using the defined direction. + * Otherwise it uses the samples in data for the different axes. + * + * \sa SDL_HAPTIC_CUSTOM + * \sa SDL_HapticEffect + */ +typedef struct SDL_HapticCustom +{ + /* Header */ + Uint16 type; /**< ::SDL_HAPTIC_CUSTOM */ + SDL_HapticDirection direction; /**< Direction of the effect. */ + + /* Replay */ + Uint32 length; /**< Duration of the effect. */ + Uint16 delay; /**< Delay before starting the effect. */ + + /* Trigger */ + Uint16 button; /**< Button that triggers the effect. */ + Uint16 interval; /**< How soon it can be triggered again after button. */ + + /* Custom */ + Uint8 channels; /**< Axes to use, minimum of one. */ + Uint16 period; /**< Sample periods. */ + Uint16 samples; /**< Amount of samples. */ + Uint16 *data; /**< Should contain channels*samples items. */ + + /* Envelope */ + Uint16 attack_length; /**< Duration of the attack. */ + Uint16 attack_level; /**< Level at the start of the attack. */ + Uint16 fade_length; /**< Duration of the fade. */ + Uint16 fade_level; /**< Level at the end of the fade. */ +} SDL_HapticCustom; + +/** + * \brief The generic template for any haptic effect. + * + * All values max at 32767 (0x7FFF). Signed values also can be negative. + * Time values unless specified otherwise are in milliseconds. + * + * You can also pass ::SDL_HAPTIC_INFINITY to length instead of a 0-32767 + * value. Neither delay, interval, attack_length nor fade_length support + * ::SDL_HAPTIC_INFINITY. Fade will also not be used since effect never ends. + * + * Additionally, the ::SDL_HAPTIC_RAMP effect does not support a duration of + * ::SDL_HAPTIC_INFINITY. + * + * Button triggers may not be supported on all devices, it is advised to not + * use them if possible. Buttons start at index 1 instead of index 0 like + * the joystick. + * + * If both attack_length and fade_level are 0, the envelope is not used, + * otherwise both values are used. + * + * Common parts: + * \code + * // Replay - All effects have this + * Uint32 length; // Duration of effect (ms). + * Uint16 delay; // Delay before starting effect. + * + * // Trigger - All effects have this + * Uint16 button; // Button that triggers effect. + * Uint16 interval; // How soon before effect can be triggered again. + * + * // Envelope - All effects except condition effects have this + * Uint16 attack_length; // Duration of the attack (ms). + * Uint16 attack_level; // Level at the start of the attack. + * Uint16 fade_length; // Duration of the fade out (ms). + * Uint16 fade_level; // Level at the end of the fade. + * \endcode + * + * + * Here we have an example of a constant effect evolution in time: + * \verbatim + Strength + ^ + | + | effect level --> _________________ + | / \ + | / \ + | / \ + | / \ + | attack_level --> | \ + | | | <--- fade_level + | + +--------------------------------------------------> Time + [--] [---] + attack_length fade_length + + [------------------][-----------------------] + delay length + \endverbatim + * + * Note either the attack_level or the fade_level may be above the actual + * effect level. + * + * \sa SDL_HapticConstant + * \sa SDL_HapticPeriodic + * \sa SDL_HapticCondition + * \sa SDL_HapticRamp + * \sa SDL_HapticLeftRight + * \sa SDL_HapticCustom + */ +typedef union SDL_HapticEffect +{ + /* Common for all force feedback effects */ + Uint16 type; /**< Effect type. */ + SDL_HapticConstant constant; /**< Constant effect. */ + SDL_HapticPeriodic periodic; /**< Periodic effect. */ + SDL_HapticCondition condition; /**< Condition effect. */ + SDL_HapticRamp ramp; /**< Ramp effect. */ + SDL_HapticLeftRight leftright; /**< Left/Right effect. */ + SDL_HapticCustom custom; /**< Custom effect. */ +} SDL_HapticEffect; + + +/* Function prototypes */ +/** + * \brief Count the number of haptic devices attached to the system. + * + * \return Number of haptic devices detected on the system. + */ +extern DECLSPEC int SDLCALL SDL_NumHaptics(void); + +/** + * \brief Get the implementation dependent name of a haptic device. + * + * This can be called before any joysticks are opened. + * If no name can be found, this function returns NULL. + * + * \param device_index Index of the device to get its name. + * \return Name of the device or NULL on error. + * + * \sa SDL_NumHaptics + */ +extern DECLSPEC const char *SDLCALL SDL_HapticName(int device_index); + +/** + * \brief Opens a haptic device for use. + * + * The index passed as an argument refers to the N'th haptic device on this + * system. + * + * When opening a haptic device, its gain will be set to maximum and + * autocenter will be disabled. To modify these values use + * SDL_HapticSetGain() and SDL_HapticSetAutocenter(). + * + * \param device_index Index of the device to open. + * \return Device identifier or NULL on error. + * + * \sa SDL_HapticIndex + * \sa SDL_HapticOpenFromMouse + * \sa SDL_HapticOpenFromJoystick + * \sa SDL_HapticClose + * \sa SDL_HapticSetGain + * \sa SDL_HapticSetAutocenter + * \sa SDL_HapticPause + * \sa SDL_HapticStopAll + */ +extern DECLSPEC SDL_Haptic *SDLCALL SDL_HapticOpen(int device_index); + +/** + * \brief Checks if the haptic device at index has been opened. + * + * \param device_index Index to check to see if it has been opened. + * \return 1 if it has been opened or 0 if it hasn't. + * + * \sa SDL_HapticOpen + * \sa SDL_HapticIndex + */ +extern DECLSPEC int SDLCALL SDL_HapticOpened(int device_index); + +/** + * \brief Gets the index of a haptic device. + * + * \param haptic Haptic device to get the index of. + * \return The index of the haptic device or -1 on error. + * + * \sa SDL_HapticOpen + * \sa SDL_HapticOpened + */ +extern DECLSPEC int SDLCALL SDL_HapticIndex(SDL_Haptic * haptic); + +/** + * \brief Gets whether or not the current mouse has haptic capabilities. + * + * \return SDL_TRUE if the mouse is haptic, SDL_FALSE if it isn't. + * + * \sa SDL_HapticOpenFromMouse + */ +extern DECLSPEC int SDLCALL SDL_MouseIsHaptic(void); + +/** + * \brief Tries to open a haptic device from the current mouse. + * + * \return The haptic device identifier or NULL on error. + * + * \sa SDL_MouseIsHaptic + * \sa SDL_HapticOpen + */ +extern DECLSPEC SDL_Haptic *SDLCALL SDL_HapticOpenFromMouse(void); + +/** + * \brief Checks to see if a joystick has haptic features. + * + * \param joystick Joystick to test for haptic capabilities. + * \return SDL_TRUE if the joystick is haptic, SDL_FALSE if it isn't + * or -1 if an error occurred. + * + * \sa SDL_HapticOpenFromJoystick + */ +extern DECLSPEC int SDLCALL SDL_JoystickIsHaptic(SDL_Joystick * joystick); + +/** + * \brief Opens a haptic device for use from a joystick device. + * + * You must still close the haptic device separately. It will not be closed + * with the joystick. + * + * When opening from a joystick you should first close the haptic device before + * closing the joystick device. If not, on some implementations the haptic + * device will also get unallocated and you'll be unable to use force feedback + * on that device. + * + * \param joystick Joystick to create a haptic device from. + * \return A valid haptic device identifier on success or NULL on error. + * + * \sa SDL_HapticOpen + * \sa SDL_HapticClose + */ +extern DECLSPEC SDL_Haptic *SDLCALL SDL_HapticOpenFromJoystick(SDL_Joystick * + joystick); + +/** + * \brief Closes a haptic device previously opened with SDL_HapticOpen(). + * + * \param haptic Haptic device to close. + */ +extern DECLSPEC void SDLCALL SDL_HapticClose(SDL_Haptic * haptic); + +/** + * \brief Returns the number of effects a haptic device can store. + * + * On some platforms this isn't fully supported, and therefore is an + * approximation. Always check to see if your created effect was actually + * created and do not rely solely on SDL_HapticNumEffects(). + * + * \param haptic The haptic device to query effect max. + * \return The number of effects the haptic device can store or + * -1 on error. + * + * \sa SDL_HapticNumEffectsPlaying + * \sa SDL_HapticQuery + */ +extern DECLSPEC int SDLCALL SDL_HapticNumEffects(SDL_Haptic * haptic); + +/** + * \brief Returns the number of effects a haptic device can play at the same + * time. + * + * This is not supported on all platforms, but will always return a value. + * Added here for the sake of completeness. + * + * \param haptic The haptic device to query maximum playing effects. + * \return The number of effects the haptic device can play at the same time + * or -1 on error. + * + * \sa SDL_HapticNumEffects + * \sa SDL_HapticQuery + */ +extern DECLSPEC int SDLCALL SDL_HapticNumEffectsPlaying(SDL_Haptic * haptic); + +/** + * \brief Gets the haptic device's supported features in bitwise manner. + * + * Example: + * \code + * if (SDL_HapticQuery(haptic) & SDL_HAPTIC_CONSTANT) { + * printf("We have constant haptic effect!\n"); + * } + * \endcode + * + * \param haptic The haptic device to query. + * \return Haptic features in bitwise manner (OR'd). + * + * \sa SDL_HapticNumEffects + * \sa SDL_HapticEffectSupported + */ +extern DECLSPEC unsigned int SDLCALL SDL_HapticQuery(SDL_Haptic * haptic); + + +/** + * \brief Gets the number of haptic axes the device has. + * + * \sa SDL_HapticDirection + */ +extern DECLSPEC int SDLCALL SDL_HapticNumAxes(SDL_Haptic * haptic); + +/** + * \brief Checks to see if effect is supported by haptic. + * + * \param haptic Haptic device to check on. + * \param effect Effect to check to see if it is supported. + * \return SDL_TRUE if effect is supported, SDL_FALSE if it isn't or -1 on error. + * + * \sa SDL_HapticQuery + * \sa SDL_HapticNewEffect + */ +extern DECLSPEC int SDLCALL SDL_HapticEffectSupported(SDL_Haptic * haptic, + SDL_HapticEffect * + effect); + +/** + * \brief Creates a new haptic effect on the device. + * + * \param haptic Haptic device to create the effect on. + * \param effect Properties of the effect to create. + * \return The identifier of the effect on success or -1 on error. + * + * \sa SDL_HapticUpdateEffect + * \sa SDL_HapticRunEffect + * \sa SDL_HapticDestroyEffect + */ +extern DECLSPEC int SDLCALL SDL_HapticNewEffect(SDL_Haptic * haptic, + SDL_HapticEffect * effect); + +/** + * \brief Updates the properties of an effect. + * + * Can be used dynamically, although behavior when dynamically changing + * direction may be strange. Specifically the effect may reupload itself + * and start playing from the start. You cannot change the type either when + * running SDL_HapticUpdateEffect(). + * + * \param haptic Haptic device that has the effect. + * \param effect Identifier of the effect to update. + * \param data New effect properties to use. + * \return 0 on success or -1 on error. + * + * \sa SDL_HapticNewEffect + * \sa SDL_HapticRunEffect + * \sa SDL_HapticDestroyEffect + */ +extern DECLSPEC int SDLCALL SDL_HapticUpdateEffect(SDL_Haptic * haptic, + int effect, + SDL_HapticEffect * data); + +/** + * \brief Runs the haptic effect on its associated haptic device. + * + * If iterations are ::SDL_HAPTIC_INFINITY, it'll run the effect over and over + * repeating the envelope (attack and fade) every time. If you only want the + * effect to last forever, set ::SDL_HAPTIC_INFINITY in the effect's length + * parameter. + * + * \param haptic Haptic device to run the effect on. + * \param effect Identifier of the haptic effect to run. + * \param iterations Number of iterations to run the effect. Use + * ::SDL_HAPTIC_INFINITY for infinity. + * \return 0 on success or -1 on error. + * + * \sa SDL_HapticStopEffect + * \sa SDL_HapticDestroyEffect + * \sa SDL_HapticGetEffectStatus + */ +extern DECLSPEC int SDLCALL SDL_HapticRunEffect(SDL_Haptic * haptic, + int effect, + Uint32 iterations); + +/** + * \brief Stops the haptic effect on its associated haptic device. + * + * \param haptic Haptic device to stop the effect on. + * \param effect Identifier of the effect to stop. + * \return 0 on success or -1 on error. + * + * \sa SDL_HapticRunEffect + * \sa SDL_HapticDestroyEffect + */ +extern DECLSPEC int SDLCALL SDL_HapticStopEffect(SDL_Haptic * haptic, + int effect); + +/** + * \brief Destroys a haptic effect on the device. + * + * This will stop the effect if it's running. Effects are automatically + * destroyed when the device is closed. + * + * \param haptic Device to destroy the effect on. + * \param effect Identifier of the effect to destroy. + * + * \sa SDL_HapticNewEffect + */ +extern DECLSPEC void SDLCALL SDL_HapticDestroyEffect(SDL_Haptic * haptic, + int effect); + +/** + * \brief Gets the status of the current effect on the haptic device. + * + * Device must support the ::SDL_HAPTIC_STATUS feature. + * + * \param haptic Haptic device to query the effect status on. + * \param effect Identifier of the effect to query its status. + * \return 0 if it isn't playing, 1 if it is playing or -1 on error. + * + * \sa SDL_HapticRunEffect + * \sa SDL_HapticStopEffect + */ +extern DECLSPEC int SDLCALL SDL_HapticGetEffectStatus(SDL_Haptic * haptic, + int effect); + +/** + * \brief Sets the global gain of the device. + * + * Device must support the ::SDL_HAPTIC_GAIN feature. + * + * The user may specify the maximum gain by setting the environment variable + * SDL_HAPTIC_GAIN_MAX which should be between 0 and 100. All calls to + * SDL_HapticSetGain() will scale linearly using SDL_HAPTIC_GAIN_MAX as the + * maximum. + * + * \param haptic Haptic device to set the gain on. + * \param gain Value to set the gain to, should be between 0 and 100. + * \return 0 on success or -1 on error. + * + * \sa SDL_HapticQuery + */ +extern DECLSPEC int SDLCALL SDL_HapticSetGain(SDL_Haptic * haptic, int gain); + +/** + * \brief Sets the global autocenter of the device. + * + * Autocenter should be between 0 and 100. Setting it to 0 will disable + * autocentering. + * + * Device must support the ::SDL_HAPTIC_AUTOCENTER feature. + * + * \param haptic Haptic device to set autocentering on. + * \param autocenter Value to set autocenter to, 0 disables autocentering. + * \return 0 on success or -1 on error. + * + * \sa SDL_HapticQuery + */ +extern DECLSPEC int SDLCALL SDL_HapticSetAutocenter(SDL_Haptic * haptic, + int autocenter); + +/** + * \brief Pauses a haptic device. + * + * Device must support the ::SDL_HAPTIC_PAUSE feature. Call + * SDL_HapticUnpause() to resume playback. + * + * Do not modify the effects nor add new ones while the device is paused. + * That can cause all sorts of weird errors. + * + * \param haptic Haptic device to pause. + * \return 0 on success or -1 on error. + * + * \sa SDL_HapticUnpause + */ +extern DECLSPEC int SDLCALL SDL_HapticPause(SDL_Haptic * haptic); + +/** + * \brief Unpauses a haptic device. + * + * Call to unpause after SDL_HapticPause(). + * + * \param haptic Haptic device to unpause. + * \return 0 on success or -1 on error. + * + * \sa SDL_HapticPause + */ +extern DECLSPEC int SDLCALL SDL_HapticUnpause(SDL_Haptic * haptic); + +/** + * \brief Stops all the currently playing effects on a haptic device. + * + * \param haptic Haptic device to stop. + * \return 0 on success or -1 on error. + */ +extern DECLSPEC int SDLCALL SDL_HapticStopAll(SDL_Haptic * haptic); + +/** + * \brief Checks to see if rumble is supported on a haptic device. + * + * \param haptic Haptic device to check to see if it supports rumble. + * \return SDL_TRUE if effect is supported, SDL_FALSE if it isn't or -1 on error. + * + * \sa SDL_HapticRumbleInit + * \sa SDL_HapticRumblePlay + * \sa SDL_HapticRumbleStop + */ +extern DECLSPEC int SDLCALL SDL_HapticRumbleSupported(SDL_Haptic * haptic); + +/** + * \brief Initializes the haptic device for simple rumble playback. + * + * \param haptic Haptic device to initialize for simple rumble playback. + * \return 0 on success or -1 on error. + * + * \sa SDL_HapticOpen + * \sa SDL_HapticRumbleSupported + * \sa SDL_HapticRumblePlay + * \sa SDL_HapticRumbleStop + */ +extern DECLSPEC int SDLCALL SDL_HapticRumbleInit(SDL_Haptic * haptic); + +/** + * \brief Runs simple rumble on a haptic device + * + * \param haptic Haptic device to play rumble effect on. + * \param strength Strength of the rumble to play as a 0-1 float value. + * \param length Length of the rumble to play in milliseconds. + * \return 0 on success or -1 on error. + * + * \sa SDL_HapticRumbleSupported + * \sa SDL_HapticRumbleInit + * \sa SDL_HapticRumbleStop + */ +extern DECLSPEC int SDLCALL SDL_HapticRumblePlay(SDL_Haptic * haptic, float strength, Uint32 length ); + +/** + * \brief Stops the simple rumble on a haptic device. + * + * \param haptic Haptic to stop the rumble on. + * \return 0 on success or -1 on error. + * + * \sa SDL_HapticRumbleSupported + * \sa SDL_HapticRumbleInit + * \sa SDL_HapticRumblePlay + */ +extern DECLSPEC int SDLCALL SDL_HapticRumbleStop(SDL_Haptic * haptic); + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_haptic_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/engine/Windows/SDL2/include/SDL_hints.h b/engine/Windows/SDL2/include/SDL_hints.h new file mode 100644 index 0000000..7703095 --- /dev/null +++ b/engine/Windows/SDL2/include/SDL_hints.h @@ -0,0 +1,1295 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2019 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_hints.h + * + * Official documentation for SDL configuration variables + * + * This file contains functions to set and get configuration hints, + * as well as listing each of them alphabetically. + * + * The convention for naming hints is SDL_HINT_X, where "SDL_X" is + * the environment variable that can be used to override the default. + * + * In general these hints are just that - they may or may not be + * supported or applicable on any given platform, but they provide + * a way for an application or user to give the library a hint as + * to how they would like the library to work. + */ + +#ifndef SDL_hints_h_ +#define SDL_hints_h_ + +#include "SDL_stdinc.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief A variable controlling how 3D acceleration is used to accelerate the SDL screen surface. + * + * SDL can try to accelerate the SDL screen surface by using streaming + * textures with a 3D rendering engine. This variable controls whether and + * how this is done. + * + * This variable can be set to the following values: + * "0" - Disable 3D acceleration + * "1" - Enable 3D acceleration, using the default renderer. + * "X" - Enable 3D acceleration, using X where X is one of the valid rendering drivers. (e.g. "direct3d", "opengl", etc.) + * + * By default SDL tries to make a best guess for each platform whether + * to use acceleration or not. + */ +#define SDL_HINT_FRAMEBUFFER_ACCELERATION "SDL_FRAMEBUFFER_ACCELERATION" + +/** + * \brief A variable specifying which render driver to use. + * + * If the application doesn't pick a specific renderer to use, this variable + * specifies the name of the preferred renderer. If the preferred renderer + * can't be initialized, the normal default renderer is used. + * + * This variable is case insensitive and can be set to the following values: + * "direct3d" + * "opengl" + * "opengles2" + * "opengles" + * "metal" + * "software" + * + * The default varies by platform, but it's the first one in the list that + * is available on the current platform. + */ +#define SDL_HINT_RENDER_DRIVER "SDL_RENDER_DRIVER" + +/** + * \brief A variable controlling whether the OpenGL render driver uses shaders if they are available. + * + * This variable can be set to the following values: + * "0" - Disable shaders + * "1" - Enable shaders + * + * By default shaders are used if OpenGL supports them. + */ +#define SDL_HINT_RENDER_OPENGL_SHADERS "SDL_RENDER_OPENGL_SHADERS" + +/** + * \brief A variable controlling whether the Direct3D device is initialized for thread-safe operations. + * + * This variable can be set to the following values: + * "0" - Thread-safety is not enabled (faster) + * "1" - Thread-safety is enabled + * + * By default the Direct3D device is created with thread-safety disabled. + */ +#define SDL_HINT_RENDER_DIRECT3D_THREADSAFE "SDL_RENDER_DIRECT3D_THREADSAFE" + +/** + * \brief A variable controlling whether to enable Direct3D 11+'s Debug Layer. + * + * This variable does not have any effect on the Direct3D 9 based renderer. + * + * This variable can be set to the following values: + * "0" - Disable Debug Layer use + * "1" - Enable Debug Layer use + * + * By default, SDL does not use Direct3D Debug Layer. + */ +#define SDL_HINT_RENDER_DIRECT3D11_DEBUG "SDL_RENDER_DIRECT3D11_DEBUG" + +/** + * \brief A variable controlling the scaling policy for SDL_RenderSetLogicalSize. + * + * This variable can be set to the following values: + * "0" or "letterbox" - Uses letterbox/sidebars to fit the entire rendering on screen + * "1" or "overscan" - Will zoom the rendering so it fills the entire screen, allowing edges to be drawn offscreen + * + * By default letterbox is used + */ +#define SDL_HINT_RENDER_LOGICAL_SIZE_MODE "SDL_RENDER_LOGICAL_SIZE_MODE" + +/** + * \brief A variable controlling the scaling quality + * + * This variable can be set to the following values: + * "0" or "nearest" - Nearest pixel sampling + * "1" or "linear" - Linear filtering (supported by OpenGL and Direct3D) + * "2" or "best" - Currently this is the same as "linear" + * + * By default nearest pixel sampling is used + */ +#define SDL_HINT_RENDER_SCALE_QUALITY "SDL_RENDER_SCALE_QUALITY" + +/** + * \brief A variable controlling whether updates to the SDL screen surface should be synchronized with the vertical refresh, to avoid tearing. + * + * This variable can be set to the following values: + * "0" - Disable vsync + * "1" - Enable vsync + * + * By default SDL does not sync screen surface updates with vertical refresh. + */ +#define SDL_HINT_RENDER_VSYNC "SDL_RENDER_VSYNC" + +/** + * \brief A variable controlling whether the screensaver is enabled. + * + * This variable can be set to the following values: + * "0" - Disable screensaver + * "1" - Enable screensaver + * + * By default SDL will disable the screensaver. + */ +#define SDL_HINT_VIDEO_ALLOW_SCREENSAVER "SDL_VIDEO_ALLOW_SCREENSAVER" + +/** + * \brief A variable controlling whether the X11 VidMode extension should be used. + * + * This variable can be set to the following values: + * "0" - Disable XVidMode + * "1" - Enable XVidMode + * + * By default SDL will use XVidMode if it is available. + */ +#define SDL_HINT_VIDEO_X11_XVIDMODE "SDL_VIDEO_X11_XVIDMODE" + +/** + * \brief A variable controlling whether the X11 Xinerama extension should be used. + * + * This variable can be set to the following values: + * "0" - Disable Xinerama + * "1" - Enable Xinerama + * + * By default SDL will use Xinerama if it is available. + */ +#define SDL_HINT_VIDEO_X11_XINERAMA "SDL_VIDEO_X11_XINERAMA" + +/** + * \brief A variable controlling whether the X11 XRandR extension should be used. + * + * This variable can be set to the following values: + * "0" - Disable XRandR + * "1" - Enable XRandR + * + * By default SDL will not use XRandR because of window manager issues. + */ +#define SDL_HINT_VIDEO_X11_XRANDR "SDL_VIDEO_X11_XRANDR" + +/** + * \brief A variable forcing the visual ID chosen for new X11 windows + * + */ +#define SDL_HINT_VIDEO_X11_WINDOW_VISUALID "SDL_VIDEO_X11_WINDOW_VISUALID" + +/** + * \brief A variable controlling whether the X11 _NET_WM_PING protocol should be supported. + * + * This variable can be set to the following values: + * "0" - Disable _NET_WM_PING + * "1" - Enable _NET_WM_PING + * + * By default SDL will use _NET_WM_PING, but for applications that know they + * will not always be able to respond to ping requests in a timely manner they can + * turn it off to avoid the window manager thinking the app is hung. + * The hint is checked in CreateWindow. + */ +#define SDL_HINT_VIDEO_X11_NET_WM_PING "SDL_VIDEO_X11_NET_WM_PING" + +/** + * \brief A variable controlling whether the X11 _NET_WM_BYPASS_COMPOSITOR hint should be used. + * + * This variable can be set to the following values: + * "0" - Disable _NET_WM_BYPASS_COMPOSITOR + * "1" - Enable _NET_WM_BYPASS_COMPOSITOR + * + * By default SDL will use _NET_WM_BYPASS_COMPOSITOR + * + */ +#define SDL_HINT_VIDEO_X11_NET_WM_BYPASS_COMPOSITOR "SDL_VIDEO_X11_NET_WM_BYPASS_COMPOSITOR" + +/** + * \brief A variable controlling whether the window frame and title bar are interactive when the cursor is hidden + * + * This variable can be set to the following values: + * "0" - The window frame is not interactive when the cursor is hidden (no move, resize, etc) + * "1" - The window frame is interactive when the cursor is hidden + * + * By default SDL will allow interaction with the window frame when the cursor is hidden + */ +#define SDL_HINT_WINDOW_FRAME_USABLE_WHILE_CURSOR_HIDDEN "SDL_WINDOW_FRAME_USABLE_WHILE_CURSOR_HIDDEN" + +/** + * \brief A variable to specify custom icon resource id from RC file on Windows platform + */ +#define SDL_HINT_WINDOWS_INTRESOURCE_ICON "SDL_WINDOWS_INTRESOURCE_ICON" +#define SDL_HINT_WINDOWS_INTRESOURCE_ICON_SMALL "SDL_WINDOWS_INTRESOURCE_ICON_SMALL" + +/** + * \brief A variable controlling whether the windows message loop is processed by SDL + * + * This variable can be set to the following values: + * "0" - The window message loop is not run + * "1" - The window message loop is processed in SDL_PumpEvents() + * + * By default SDL will process the windows message loop + */ +#define SDL_HINT_WINDOWS_ENABLE_MESSAGELOOP "SDL_WINDOWS_ENABLE_MESSAGELOOP" + +/** + * \brief A variable controlling whether grabbing input grabs the keyboard + * + * This variable can be set to the following values: + * "0" - Grab will affect only the mouse + * "1" - Grab will affect mouse and keyboard + * + * By default SDL will not grab the keyboard so system shortcuts still work. + */ +#define SDL_HINT_GRAB_KEYBOARD "SDL_GRAB_KEYBOARD" + +/** + * \brief A variable setting the double click time, in milliseconds. + */ +#define SDL_HINT_MOUSE_DOUBLE_CLICK_TIME "SDL_MOUSE_DOUBLE_CLICK_TIME" + +/** + * \brief A variable setting the double click radius, in pixels. + */ +#define SDL_HINT_MOUSE_DOUBLE_CLICK_RADIUS "SDL_MOUSE_DOUBLE_CLICK_RADIUS" + +/** + * \brief A variable setting the speed scale for mouse motion, in floating point, when the mouse is not in relative mode + */ +#define SDL_HINT_MOUSE_NORMAL_SPEED_SCALE "SDL_MOUSE_NORMAL_SPEED_SCALE" + +/** + * \brief A variable setting the scale for mouse motion, in floating point, when the mouse is in relative mode + */ +#define SDL_HINT_MOUSE_RELATIVE_SPEED_SCALE "SDL_MOUSE_RELATIVE_SPEED_SCALE" + +/** + * \brief A variable controlling whether relative mouse mode is implemented using mouse warping + * + * This variable can be set to the following values: + * "0" - Relative mouse mode uses raw input + * "1" - Relative mouse mode uses mouse warping + * + * By default SDL will use raw input for relative mouse mode + */ +#define SDL_HINT_MOUSE_RELATIVE_MODE_WARP "SDL_MOUSE_RELATIVE_MODE_WARP" + +/** + * \brief Allow mouse click events when clicking to focus an SDL window + * + * This variable can be set to the following values: + * "0" - Ignore mouse clicks that activate a window + * "1" - Generate events for mouse clicks that activate a window + * + * By default SDL will ignore mouse clicks that activate a window + */ +#define SDL_HINT_MOUSE_FOCUS_CLICKTHROUGH "SDL_MOUSE_FOCUS_CLICKTHROUGH" + +/** + * \brief A variable controlling whether touch events should generate synthetic mouse events + * + * This variable can be set to the following values: + * "0" - Touch events will not generate mouse events + * "1" - Touch events will generate mouse events + * + * By default SDL will generate mouse events for touch events + */ +#define SDL_HINT_TOUCH_MOUSE_EVENTS "SDL_TOUCH_MOUSE_EVENTS" + +/** + * \brief A variable controlling whether mouse events should generate synthetic touch events + * + * This variable can be set to the following values: + * "0" - Mouse events will not generate touch events (default for desktop platforms) + * "1" - Mouse events will generate touch events (default for mobile platforms, such as Android and iOS) + */ + +#define SDL_HINT_MOUSE_TOUCH_EVENTS "SDL_MOUSE_TOUCH_EVENTS" + +/** + * \brief Minimize your SDL_Window if it loses key focus when in fullscreen mode. Defaults to true. + * + */ +#define SDL_HINT_VIDEO_MINIMIZE_ON_FOCUS_LOSS "SDL_VIDEO_MINIMIZE_ON_FOCUS_LOSS" + +/** + * \brief A variable controlling whether the idle timer is disabled on iOS. + * + * When an iOS app does not receive touches for some time, the screen is + * dimmed automatically. For games where the accelerometer is the only input + * this is problematic. This functionality can be disabled by setting this + * hint. + * + * As of SDL 2.0.4, SDL_EnableScreenSaver() and SDL_DisableScreenSaver() + * accomplish the same thing on iOS. They should be preferred over this hint. + * + * This variable can be set to the following values: + * "0" - Enable idle timer + * "1" - Disable idle timer + */ +#define SDL_HINT_IDLE_TIMER_DISABLED "SDL_IOS_IDLE_TIMER_DISABLED" + +/** + * \brief A variable controlling which orientations are allowed on iOS/Android. + * + * In some circumstances it is necessary to be able to explicitly control + * which UI orientations are allowed. + * + * This variable is a space delimited list of the following values: + * "LandscapeLeft", "LandscapeRight", "Portrait" "PortraitUpsideDown" + */ +#define SDL_HINT_ORIENTATIONS "SDL_IOS_ORIENTATIONS" + +/** + * \brief A variable controlling whether controllers used with the Apple TV + * generate UI events. + * + * When UI events are generated by controller input, the app will be + * backgrounded when the Apple TV remote's menu button is pressed, and when the + * pause or B buttons on gamepads are pressed. + * + * More information about properly making use of controllers for the Apple TV + * can be found here: + * https://developer.apple.com/tvos/human-interface-guidelines/remote-and-controllers/ + * + * This variable can be set to the following values: + * "0" - Controller input does not generate UI events (the default). + * "1" - Controller input generates UI events. + */ +#define SDL_HINT_APPLE_TV_CONTROLLER_UI_EVENTS "SDL_APPLE_TV_CONTROLLER_UI_EVENTS" + +/** + * \brief A variable controlling whether the Apple TV remote's joystick axes + * will automatically match the rotation of the remote. + * + * This variable can be set to the following values: + * "0" - Remote orientation does not affect joystick axes (the default). + * "1" - Joystick axes are based on the orientation of the remote. + */ +#define SDL_HINT_APPLE_TV_REMOTE_ALLOW_ROTATION "SDL_APPLE_TV_REMOTE_ALLOW_ROTATION" + +/** + * \brief A variable controlling whether the home indicator bar on iPhone X + * should be hidden. + * + * This variable can be set to the following values: + * "0" - The indicator bar is not hidden (default for windowed applications) + * "1" - The indicator bar is hidden and is shown when the screen is touched (useful for movie playback applications) + * "2" - The indicator bar is dim and the first swipe makes it visible and the second swipe performs the "home" action (default for fullscreen applications) + */ +#define SDL_HINT_IOS_HIDE_HOME_INDICATOR "SDL_IOS_HIDE_HOME_INDICATOR" + +/** + * \brief A variable controlling whether the Android / iOS built-in + * accelerometer should be listed as a joystick device. + * + * This variable can be set to the following values: + * "0" - The accelerometer is not listed as a joystick + * "1" - The accelerometer is available as a 3 axis joystick (the default). + */ +#define SDL_HINT_ACCELEROMETER_AS_JOYSTICK "SDL_ACCELEROMETER_AS_JOYSTICK" + +/** + * \brief A variable controlling whether the Android / tvOS remotes + * should be listed as joystick devices, instead of sending keyboard events. + * + * This variable can be set to the following values: + * "0" - Remotes send enter/escape/arrow key events + * "1" - Remotes are available as 2 axis, 2 button joysticks (the default). + */ +#define SDL_HINT_TV_REMOTE_AS_JOYSTICK "SDL_TV_REMOTE_AS_JOYSTICK" + +/** + * \brief A variable that lets you disable the detection and use of Xinput gamepad devices + * + * The variable can be set to the following values: + * "0" - Disable XInput detection (only uses direct input) + * "1" - Enable XInput detection (the default) + */ +#define SDL_HINT_XINPUT_ENABLED "SDL_XINPUT_ENABLED" + +/** + * \brief A variable that causes SDL to use the old axis and button mapping for XInput devices. + * + * This hint is for backwards compatibility only and will be removed in SDL 2.1 + * + * The default value is "0". This hint must be set before SDL_Init() + */ +#define SDL_HINT_XINPUT_USE_OLD_JOYSTICK_MAPPING "SDL_XINPUT_USE_OLD_JOYSTICK_MAPPING" + +/** + * \brief A variable that lets you manually hint extra gamecontroller db entries. + * + * The variable should be newline delimited rows of gamecontroller config data, see SDL_gamecontroller.h + * + * This hint must be set before calling SDL_Init(SDL_INIT_GAMECONTROLLER) + * You can update mappings after the system is initialized with SDL_GameControllerMappingForGUID() and SDL_GameControllerAddMapping() + */ +#define SDL_HINT_GAMECONTROLLERCONFIG "SDL_GAMECONTROLLERCONFIG" + +/** + * \brief A variable that lets you provide a file with extra gamecontroller db entries. + * + * The file should contain lines of gamecontroller config data, see SDL_gamecontroller.h + * + * This hint must be set before calling SDL_Init(SDL_INIT_GAMECONTROLLER) + * You can update mappings after the system is initialized with SDL_GameControllerMappingForGUID() and SDL_GameControllerAddMapping() + */ +#define SDL_HINT_GAMECONTROLLERCONFIG_FILE "SDL_GAMECONTROLLERCONFIG_FILE" + +/** + * \brief A variable containing a list of devices to skip when scanning for game controllers. + * + * The format of the string is a comma separated list of USB VID/PID pairs + * in hexadecimal form, e.g. + * + * 0xAAAA/0xBBBB,0xCCCC/0xDDDD + * + * The variable can also take the form of @file, in which case the named + * file will be loaded and interpreted as the value of the variable. + */ +#define SDL_HINT_GAMECONTROLLER_IGNORE_DEVICES "SDL_GAMECONTROLLER_IGNORE_DEVICES" + +/** + * \brief If set, all devices will be skipped when scanning for game controllers except for the ones listed in this variable. + * + * The format of the string is a comma separated list of USB VID/PID pairs + * in hexadecimal form, e.g. + * + * 0xAAAA/0xBBBB,0xCCCC/0xDDDD + * + * The variable can also take the form of @file, in which case the named + * file will be loaded and interpreted as the value of the variable. + */ +#define SDL_HINT_GAMECONTROLLER_IGNORE_DEVICES_EXCEPT "SDL_GAMECONTROLLER_IGNORE_DEVICES_EXCEPT" + +/** + * \brief If set, game controller face buttons report their values according to their labels instead of their positional layout. + * + * For example, on Nintendo Switch controllers, normally you'd get: + * + * (Y) + * (X) (B) + * (A) + * + * but if this hint is set, you'll get: + * + * (X) + * (Y) (A) + * (B) + * + * The variable can be set to the following values: + * "0" - Report the face buttons by position, as though they were on an Xbox controller. + * "1" - Report the face buttons by label instead of position + * + * The default value is "0". This hint may be set at any time. + */ +#define SDL_HINT_GAMECONTROLLER_USE_BUTTON_LABELS "SDL_GAMECONTROLLER_USE_BUTTON_LABELS" + +/** + * \brief A variable that lets you enable joystick (and gamecontroller) events even when your app is in the background. + * + * The variable can be set to the following values: + * "0" - Disable joystick & gamecontroller input events when the + * application is in the background. + * "1" - Enable joystick & gamecontroller input events when the + * application is in the background. + * + * The default value is "0". This hint may be set at any time. + */ +#define SDL_HINT_JOYSTICK_ALLOW_BACKGROUND_EVENTS "SDL_JOYSTICK_ALLOW_BACKGROUND_EVENTS" + +/** + * \brief A variable controlling whether the HIDAPI joystick drivers should be used. + * + * This variable can be set to the following values: + * "0" - HIDAPI drivers are not used + * "1" - HIDAPI drivers are used (the default) + * + * This variable is the default for all drivers, but can be overridden by the hints for specific drivers below. + */ +#define SDL_HINT_JOYSTICK_HIDAPI "SDL_JOYSTICK_HIDAPI" + +/** + * \brief A variable controlling whether the HIDAPI driver for PS4 controllers should be used. + * + * This variable can be set to the following values: + * "0" - HIDAPI driver is not used + * "1" - HIDAPI driver is used + * + * The default is the value of SDL_HINT_JOYSTICK_HIDAPI + */ +#define SDL_HINT_JOYSTICK_HIDAPI_PS4 "SDL_JOYSTICK_HIDAPI_PS4" + +/** + * \brief A variable controlling whether extended input reports should be used for PS4 controllers when using the HIDAPI driver. + * + * This variable can be set to the following values: + * "0" - extended reports are not enabled (the default) + * "1" - extended reports + * + * Extended input reports allow rumble on Bluetooth PS4 controllers, but + * break DirectInput handling for applications that don't use SDL. + * + * Once extended reports are enabled, they can not be disabled without + * power cycling the controller. + */ +#define SDL_HINT_JOYSTICK_HIDAPI_PS4_RUMBLE "SDL_JOYSTICK_HIDAPI_PS4_RUMBLE" + +/** + * \brief A variable controlling whether the HIDAPI driver for Steam Controllers should be used. + * + * This variable can be set to the following values: + * "0" - HIDAPI driver is not used + * "1" - HIDAPI driver is used + * + * The default is the value of SDL_HINT_JOYSTICK_HIDAPI + */ +#define SDL_HINT_JOYSTICK_HIDAPI_STEAM "SDL_JOYSTICK_HIDAPI_STEAM" + +/** + * \brief A variable controlling whether the HIDAPI driver for Nintendo Switch controllers should be used. + * + * This variable can be set to the following values: + * "0" - HIDAPI driver is not used + * "1" - HIDAPI driver is used + * + * The default is the value of SDL_HINT_JOYSTICK_HIDAPI + */ +#define SDL_HINT_JOYSTICK_HIDAPI_SWITCH "SDL_JOYSTICK_HIDAPI_SWITCH" + +/** + * \brief A variable controlling whether the HIDAPI driver for XBox controllers should be used. + * + * This variable can be set to the following values: + * "0" - HIDAPI driver is not used + * "1" - HIDAPI driver is used + * + * The default is the value of SDL_HINT_JOYSTICK_HIDAPI + */ +#define SDL_HINT_JOYSTICK_HIDAPI_XBOX "SDL_JOYSTICK_HIDAPI_XBOX" + +/** + * \brief A variable that controls whether Steam Controllers should be exposed using the SDL joystick and game controller APIs + * + * The variable can be set to the following values: + * "0" - Do not scan for Steam Controllers + * "1" - Scan for Steam Controllers (the default) + * + * The default value is "1". This hint must be set before initializing the joystick subsystem. + */ +#define SDL_HINT_ENABLE_STEAM_CONTROLLERS "SDL_ENABLE_STEAM_CONTROLLERS" + + +/** + * \brief If set to "0" then never set the top most bit on a SDL Window, even if the video mode expects it. + * This is a debugging aid for developers and not expected to be used by end users. The default is "1" + * + * This variable can be set to the following values: + * "0" - don't allow topmost + * "1" - allow topmost + */ +#define SDL_HINT_ALLOW_TOPMOST "SDL_ALLOW_TOPMOST" + +/** + * \brief A variable that controls the timer resolution, in milliseconds. + * + * The higher resolution the timer, the more frequently the CPU services + * timer interrupts, and the more precise delays are, but this takes up + * power and CPU time. This hint is only used on Windows 7 and earlier. + * + * See this blog post for more information: + * http://randomascii.wordpress.com/2013/07/08/windows-timer-resolution-megawatts-wasted/ + * + * If this variable is set to "0", the system timer resolution is not set. + * + * The default value is "1". This hint may be set at any time. + */ +#define SDL_HINT_TIMER_RESOLUTION "SDL_TIMER_RESOLUTION" + + +/** + * \brief A variable describing the content orientation on QtWayland-based platforms. + * + * On QtWayland platforms, windows are rotated client-side to allow for custom + * transitions. In order to correctly position overlays (e.g. volume bar) and + * gestures (e.g. events view, close/minimize gestures), the system needs to + * know in which orientation the application is currently drawing its contents. + * + * This does not cause the window to be rotated or resized, the application + * needs to take care of drawing the content in the right orientation (the + * framebuffer is always in portrait mode). + * + * This variable can be one of the following values: + * "primary" (default), "portrait", "landscape", "inverted-portrait", "inverted-landscape" + */ +#define SDL_HINT_QTWAYLAND_CONTENT_ORIENTATION "SDL_QTWAYLAND_CONTENT_ORIENTATION" + +/** + * \brief Flags to set on QtWayland windows to integrate with the native window manager. + * + * On QtWayland platforms, this hint controls the flags to set on the windows. + * For example, on Sailfish OS "OverridesSystemGestures" disables swipe gestures. + * + * This variable is a space-separated list of the following values (empty = no flags): + * "OverridesSystemGestures", "StaysOnTop", "BypassWindowManager" + */ +#define SDL_HINT_QTWAYLAND_WINDOW_FLAGS "SDL_QTWAYLAND_WINDOW_FLAGS" + +/** +* \brief A string specifying SDL's threads stack size in bytes or "0" for the backend's default size +* +* Use this hint in case you need to set SDL's threads stack size to other than the default. +* This is specially useful if you build SDL against a non glibc libc library (such as musl) which +* provides a relatively small default thread stack size (a few kilobytes versus the default 8MB glibc uses). +* Support for this hint is currently available only in the pthread, Windows, and PSP backend. +* +* Instead of this hint, in 2.0.9 and later, you can use +* SDL_CreateThreadWithStackSize(). This hint only works with the classic +* SDL_CreateThread(). +*/ +#define SDL_HINT_THREAD_STACK_SIZE "SDL_THREAD_STACK_SIZE" + +/** + * \brief If set to 1, then do not allow high-DPI windows. ("Retina" on Mac and iOS) + */ +#define SDL_HINT_VIDEO_HIGHDPI_DISABLED "SDL_VIDEO_HIGHDPI_DISABLED" + +/** + * \brief A variable that determines whether ctrl+click should generate a right-click event on Mac + * + * If present, holding ctrl while left clicking will generate a right click + * event when on Mac. + */ +#define SDL_HINT_MAC_CTRL_CLICK_EMULATE_RIGHT_CLICK "SDL_MAC_CTRL_CLICK_EMULATE_RIGHT_CLICK" + +/** +* \brief A variable specifying which shader compiler to preload when using the Chrome ANGLE binaries +* +* SDL has EGL and OpenGL ES2 support on Windows via the ANGLE project. It +* can use two different sets of binaries, those compiled by the user from source +* or those provided by the Chrome browser. In the later case, these binaries require +* that SDL loads a DLL providing the shader compiler. +* +* This variable can be set to the following values: +* "d3dcompiler_46.dll" - default, best for Vista or later. +* "d3dcompiler_43.dll" - for XP support. +* "none" - do not load any library, useful if you compiled ANGLE from source and included the compiler in your binaries. +* +*/ +#define SDL_HINT_VIDEO_WIN_D3DCOMPILER "SDL_VIDEO_WIN_D3DCOMPILER" + +/** +* \brief A variable that is the address of another SDL_Window* (as a hex string formatted with "%p"). +* +* If this hint is set before SDL_CreateWindowFrom() and the SDL_Window* it is set to has +* SDL_WINDOW_OPENGL set (and running on WGL only, currently), then two things will occur on the newly +* created SDL_Window: +* +* 1. Its pixel format will be set to the same pixel format as this SDL_Window. This is +* needed for example when sharing an OpenGL context across multiple windows. +* +* 2. The flag SDL_WINDOW_OPENGL will be set on the new window so it can be used for +* OpenGL rendering. +* +* This variable can be set to the following values: +* The address (as a string "%p") of the SDL_Window* that new windows created with SDL_CreateWindowFrom() should +* share a pixel format with. +*/ +#define SDL_HINT_VIDEO_WINDOW_SHARE_PIXEL_FORMAT "SDL_VIDEO_WINDOW_SHARE_PIXEL_FORMAT" + +/** + * \brief A URL to a WinRT app's privacy policy + * + * All network-enabled WinRT apps must make a privacy policy available to its + * users. On Windows 8, 8.1, and RT, Microsoft mandates that this policy be + * be available in the Windows Settings charm, as accessed from within the app. + * SDL provides code to add a URL-based link there, which can point to the app's + * privacy policy. + * + * To setup a URL to an app's privacy policy, set SDL_HINT_WINRT_PRIVACY_POLICY_URL + * before calling any SDL_Init() functions. The contents of the hint should + * be a valid URL. For example, "http://www.example.com". + * + * The default value is "", which will prevent SDL from adding a privacy policy + * link to the Settings charm. This hint should only be set during app init. + * + * The label text of an app's "Privacy Policy" link may be customized via another + * hint, SDL_HINT_WINRT_PRIVACY_POLICY_LABEL. + * + * Please note that on Windows Phone, Microsoft does not provide standard UI + * for displaying a privacy policy link, and as such, SDL_HINT_WINRT_PRIVACY_POLICY_URL + * will not get used on that platform. Network-enabled phone apps should display + * their privacy policy through some other, in-app means. + */ +#define SDL_HINT_WINRT_PRIVACY_POLICY_URL "SDL_WINRT_PRIVACY_POLICY_URL" + +/** \brief Label text for a WinRT app's privacy policy link + * + * Network-enabled WinRT apps must include a privacy policy. On Windows 8, 8.1, and RT, + * Microsoft mandates that this policy be available via the Windows Settings charm. + * SDL provides code to add a link there, with its label text being set via the + * optional hint, SDL_HINT_WINRT_PRIVACY_POLICY_LABEL. + * + * Please note that a privacy policy's contents are not set via this hint. A separate + * hint, SDL_HINT_WINRT_PRIVACY_POLICY_URL, is used to link to the actual text of the + * policy. + * + * The contents of this hint should be encoded as a UTF8 string. + * + * The default value is "Privacy Policy". This hint should only be set during app + * initialization, preferably before any calls to SDL_Init(). + * + * For additional information on linking to a privacy policy, see the documentation for + * SDL_HINT_WINRT_PRIVACY_POLICY_URL. + */ +#define SDL_HINT_WINRT_PRIVACY_POLICY_LABEL "SDL_WINRT_PRIVACY_POLICY_LABEL" + +/** \brief Allows back-button-press events on Windows Phone to be marked as handled + * + * Windows Phone devices typically feature a Back button. When pressed, + * the OS will emit back-button-press events, which apps are expected to + * handle in an appropriate manner. If apps do not explicitly mark these + * events as 'Handled', then the OS will invoke its default behavior for + * unhandled back-button-press events, which on Windows Phone 8 and 8.1 is to + * terminate the app (and attempt to switch to the previous app, or to the + * device's home screen). + * + * Setting the SDL_HINT_WINRT_HANDLE_BACK_BUTTON hint to "1" will cause SDL + * to mark back-button-press events as Handled, if and when one is sent to + * the app. + * + * Internally, Windows Phone sends back button events as parameters to + * special back-button-press callback functions. Apps that need to respond + * to back-button-press events are expected to register one or more + * callback functions for such, shortly after being launched (during the + * app's initialization phase). After the back button is pressed, the OS + * will invoke these callbacks. If the app's callback(s) do not explicitly + * mark the event as handled by the time they return, or if the app never + * registers one of these callback, the OS will consider the event + * un-handled, and it will apply its default back button behavior (terminate + * the app). + * + * SDL registers its own back-button-press callback with the Windows Phone + * OS. This callback will emit a pair of SDL key-press events (SDL_KEYDOWN + * and SDL_KEYUP), each with a scancode of SDL_SCANCODE_AC_BACK, after which + * it will check the contents of the hint, SDL_HINT_WINRT_HANDLE_BACK_BUTTON. + * If the hint's value is set to "1", the back button event's Handled + * property will get set to 'true'. If the hint's value is set to something + * else, or if it is unset, SDL will leave the event's Handled property + * alone. (By default, the OS sets this property to 'false', to note.) + * + * SDL apps can either set SDL_HINT_WINRT_HANDLE_BACK_BUTTON well before a + * back button is pressed, or can set it in direct-response to a back button + * being pressed. + * + * In order to get notified when a back button is pressed, SDL apps should + * register a callback function with SDL_AddEventWatch(), and have it listen + * for SDL_KEYDOWN events that have a scancode of SDL_SCANCODE_AC_BACK. + * (Alternatively, SDL_KEYUP events can be listened-for. Listening for + * either event type is suitable.) Any value of SDL_HINT_WINRT_HANDLE_BACK_BUTTON + * set by such a callback, will be applied to the OS' current + * back-button-press event. + * + * More details on back button behavior in Windows Phone apps can be found + * at the following page, on Microsoft's developer site: + * http://msdn.microsoft.com/en-us/library/windowsphone/develop/jj247550(v=vs.105).aspx + */ +#define SDL_HINT_WINRT_HANDLE_BACK_BUTTON "SDL_WINRT_HANDLE_BACK_BUTTON" + +/** + * \brief A variable that dictates policy for fullscreen Spaces on Mac OS X. + * + * This hint only applies to Mac OS X. + * + * The variable can be set to the following values: + * "0" - Disable Spaces support (FULLSCREEN_DESKTOP won't use them and + * SDL_WINDOW_RESIZABLE windows won't offer the "fullscreen" + * button on their titlebars). + * "1" - Enable Spaces support (FULLSCREEN_DESKTOP will use them and + * SDL_WINDOW_RESIZABLE windows will offer the "fullscreen" + * button on their titlebars). + * + * The default value is "1". Spaces are disabled regardless of this hint if + * the OS isn't at least Mac OS X Lion (10.7). This hint must be set before + * any windows are created. + */ +#define SDL_HINT_VIDEO_MAC_FULLSCREEN_SPACES "SDL_VIDEO_MAC_FULLSCREEN_SPACES" + +/** +* \brief When set don't force the SDL app to become a foreground process +* +* This hint only applies to Mac OS X. +* +*/ +#define SDL_HINT_MAC_BACKGROUND_APP "SDL_MAC_BACKGROUND_APP" + +/** + * \brief Android APK expansion main file version. Should be a string number like "1", "2" etc. + * + * Must be set together with SDL_HINT_ANDROID_APK_EXPANSION_PATCH_FILE_VERSION. + * + * If both hints were set then SDL_RWFromFile() will look into expansion files + * after a given relative path was not found in the internal storage and assets. + * + * By default this hint is not set and the APK expansion files are not searched. + */ +#define SDL_HINT_ANDROID_APK_EXPANSION_MAIN_FILE_VERSION "SDL_ANDROID_APK_EXPANSION_MAIN_FILE_VERSION" + +/** + * \brief Android APK expansion patch file version. Should be a string number like "1", "2" etc. + * + * Must be set together with SDL_HINT_ANDROID_APK_EXPANSION_MAIN_FILE_VERSION. + * + * If both hints were set then SDL_RWFromFile() will look into expansion files + * after a given relative path was not found in the internal storage and assets. + * + * By default this hint is not set and the APK expansion files are not searched. + */ +#define SDL_HINT_ANDROID_APK_EXPANSION_PATCH_FILE_VERSION "SDL_ANDROID_APK_EXPANSION_PATCH_FILE_VERSION" + +/** + * \brief A variable to control whether certain IMEs should handle text editing internally instead of sending SDL_TEXTEDITING events. + * + * The variable can be set to the following values: + * "0" - SDL_TEXTEDITING events are sent, and it is the application's + * responsibility to render the text from these events and + * differentiate it somehow from committed text. (default) + * "1" - If supported by the IME then SDL_TEXTEDITING events are not sent, + * and text that is being composed will be rendered in its own UI. + */ +#define SDL_HINT_IME_INTERNAL_EDITING "SDL_IME_INTERNAL_EDITING" + +/** + * \brief A variable to control whether we trap the Android back button to handle it manually. + * This is necessary for the right mouse button to work on some Android devices, or + * to be able to trap the back button for use in your code reliably. If set to true, + * the back button will show up as an SDL_KEYDOWN / SDL_KEYUP pair with a keycode of + * SDL_SCANCODE_AC_BACK. + * + * The variable can be set to the following values: + * "0" - Back button will be handled as usual for system. (default) + * "1" - Back button will be trapped, allowing you to handle the key press + * manually. (This will also let right mouse click work on systems + * where the right mouse button functions as back.) + * + * The value of this hint is used at runtime, so it can be changed at any time. + */ +#define SDL_HINT_ANDROID_TRAP_BACK_BUTTON "SDL_ANDROID_TRAP_BACK_BUTTON" + +/** + * \brief A variable to control whether the event loop will block itself when the app is paused. + * + * The variable can be set to the following values: + * "0" - Non blocking. + * "1" - Blocking. (default) + * + * The value should be set before SDL is initialized. + */ +#define SDL_HINT_ANDROID_BLOCK_ON_PAUSE "SDL_ANDROID_BLOCK_ON_PAUSE" + + /** + * \brief A variable to control whether the return key on the soft keyboard + * should hide the soft keyboard on Android and iOS. + * + * The variable can be set to the following values: + * "0" - The return key will be handled as a key event. This is the behaviour of SDL <= 2.0.3. (default) + * "1" - The return key will hide the keyboard. + * + * The value of this hint is used at runtime, so it can be changed at any time. + */ +#define SDL_HINT_RETURN_KEY_HIDES_IME "SDL_RETURN_KEY_HIDES_IME" + +/** + * \brief override the binding element for keyboard inputs for Emscripten builds + * + * This hint only applies to the emscripten platform + * + * The variable can be one of + * "#window" - The javascript window object (this is the default) + * "#document" - The javascript document object + * "#screen" - the javascript window.screen object + * "#canvas" - the WebGL canvas element + * any other string without a leading # sign applies to the element on the page with that ID. + */ +#define SDL_HINT_EMSCRIPTEN_KEYBOARD_ELEMENT "SDL_EMSCRIPTEN_KEYBOARD_ELEMENT" + +/** + * \brief Tell SDL not to catch the SIGINT or SIGTERM signals. + * + * This hint only applies to Unix-like platforms. + * + * The variable can be set to the following values: + * "0" - SDL will install a SIGINT and SIGTERM handler, and when it + * catches a signal, convert it into an SDL_QUIT event. + * "1" - SDL will not install a signal handler at all. + */ +#define SDL_HINT_NO_SIGNAL_HANDLERS "SDL_NO_SIGNAL_HANDLERS" + +/** + * \brief Tell SDL not to generate window-close events for Alt+F4 on Windows. + * + * The variable can be set to the following values: + * "0" - SDL will generate a window-close event when it sees Alt+F4. + * "1" - SDL will only do normal key handling for Alt+F4. + */ +#define SDL_HINT_WINDOWS_NO_CLOSE_ON_ALT_F4 "SDL_WINDOWS_NO_CLOSE_ON_ALT_F4" + +/** + * \brief Prevent SDL from using version 4 of the bitmap header when saving BMPs. + * + * The bitmap header version 4 is required for proper alpha channel support and + * SDL will use it when required. Should this not be desired, this hint can + * force the use of the 40 byte header version which is supported everywhere. + * + * The variable can be set to the following values: + * "0" - Surfaces with a colorkey or an alpha channel are saved to a + * 32-bit BMP file with an alpha mask. SDL will use the bitmap + * header version 4 and set the alpha mask accordingly. + * "1" - Surfaces with a colorkey or an alpha channel are saved to a + * 32-bit BMP file without an alpha mask. The alpha channel data + * will be in the file, but applications are going to ignore it. + * + * The default value is "0". + */ +#define SDL_HINT_BMP_SAVE_LEGACY_FORMAT "SDL_BMP_SAVE_LEGACY_FORMAT" + +/** + * \brief Tell SDL not to name threads on Windows with the 0x406D1388 Exception. + * The 0x406D1388 Exception is a trick used to inform Visual Studio of a + * thread's name, but it tends to cause problems with other debuggers, + * and the .NET runtime. Note that SDL 2.0.6 and later will still use + * the (safer) SetThreadDescription API, introduced in the Windows 10 + * Creators Update, if available. + * + * The variable can be set to the following values: + * "0" - SDL will raise the 0x406D1388 Exception to name threads. + * This is the default behavior of SDL <= 2.0.4. + * "1" - SDL will not raise this exception, and threads will be unnamed. (default) + * This is necessary with .NET languages or debuggers that aren't Visual Studio. + */ +#define SDL_HINT_WINDOWS_DISABLE_THREAD_NAMING "SDL_WINDOWS_DISABLE_THREAD_NAMING" + +/** + * \brief Tell SDL which Dispmanx layer to use on a Raspberry PI + * + * Also known as Z-order. The variable can take a negative or positive value. + * The default is 10000. + */ +#define SDL_HINT_RPI_VIDEO_LAYER "SDL_RPI_VIDEO_LAYER" + +/** + * \brief Tell the video driver that we only want a double buffer. + * + * By default, most lowlevel 2D APIs will use a triple buffer scheme that + * wastes no CPU time on waiting for vsync after issuing a flip, but + * introduces a frame of latency. On the other hand, using a double buffer + * scheme instead is recommended for cases where low latency is an important + * factor because we save a whole frame of latency. + * We do so by waiting for vsync immediately after issuing a flip, usually just + * after eglSwapBuffers call in the backend's *_SwapWindow function. + * + * Since it's driver-specific, it's only supported where possible and + * implemented. Currently supported the following drivers: + * - KMSDRM (kmsdrm) + * - Raspberry Pi (raspberrypi) + */ +#define SDL_HINT_VIDEO_DOUBLE_BUFFER "SDL_VIDEO_DOUBLE_BUFFER" + +/** + * \brief A variable controlling what driver to use for OpenGL ES contexts. + * + * On some platforms, currently Windows and X11, OpenGL drivers may support + * creating contexts with an OpenGL ES profile. By default SDL uses these + * profiles, when available, otherwise it attempts to load an OpenGL ES + * library, e.g. that provided by the ANGLE project. This variable controls + * whether SDL follows this default behaviour or will always load an + * OpenGL ES library. + * + * Circumstances where this is useful include + * - Testing an app with a particular OpenGL ES implementation, e.g ANGLE, + * or emulator, e.g. those from ARM, Imagination or Qualcomm. + * - Resolving OpenGL ES function addresses at link time by linking with + * the OpenGL ES library instead of querying them at run time with + * SDL_GL_GetProcAddress(). + * + * Caution: for an application to work with the default behaviour across + * different OpenGL drivers it must query the OpenGL ES function + * addresses at run time using SDL_GL_GetProcAddress(). + * + * This variable is ignored on most platforms because OpenGL ES is native + * or not supported. + * + * This variable can be set to the following values: + * "0" - Use ES profile of OpenGL, if available. (Default when not set.) + * "1" - Load OpenGL ES library using the default library names. + * + */ +#define SDL_HINT_OPENGL_ES_DRIVER "SDL_OPENGL_ES_DRIVER" + +/** + * \brief A variable controlling speed/quality tradeoff of audio resampling. + * + * If available, SDL can use libsamplerate ( http://www.mega-nerd.com/SRC/ ) + * to handle audio resampling. There are different resampling modes available + * that produce different levels of quality, using more CPU. + * + * If this hint isn't specified to a valid setting, or libsamplerate isn't + * available, SDL will use the default, internal resampling algorithm. + * + * Note that this is currently only applicable to resampling audio that is + * being written to a device for playback or audio being read from a device + * for capture. SDL_AudioCVT always uses the default resampler (although this + * might change for SDL 2.1). + * + * This hint is currently only checked at audio subsystem initialization. + * + * This variable can be set to the following values: + * + * "0" or "default" - Use SDL's internal resampling (Default when not set - low quality, fast) + * "1" or "fast" - Use fast, slightly higher quality resampling, if available + * "2" or "medium" - Use medium quality resampling, if available + * "3" or "best" - Use high quality resampling, if available + */ +#define SDL_HINT_AUDIO_RESAMPLING_MODE "SDL_AUDIO_RESAMPLING_MODE" + +/** + * \brief A variable controlling the audio category on iOS and Mac OS X + * + * This variable can be set to the following values: + * + * "ambient" - Use the AVAudioSessionCategoryAmbient audio category, will be muted by the phone mute switch (default) + * "playback" - Use the AVAudioSessionCategoryPlayback category + * + * For more information, see Apple's documentation: + * https://developer.apple.com/library/content/documentation/Audio/Conceptual/AudioSessionProgrammingGuide/AudioSessionCategoriesandModes/AudioSessionCategoriesandModes.html + */ +#define SDL_HINT_AUDIO_CATEGORY "SDL_AUDIO_CATEGORY" + +/** + * \brief A variable controlling whether the 2D render API is compatible or efficient. + * + * This variable can be set to the following values: + * + * "0" - Don't use batching to make rendering more efficient. + * "1" - Use batching, but might cause problems if app makes its own direct OpenGL calls. + * + * Up to SDL 2.0.9, the render API would draw immediately when requested. Now + * it batches up draw requests and sends them all to the GPU only when forced + * to (during SDL_RenderPresent, when changing render targets, by updating a + * texture that the batch needs, etc). This is significantly more efficient, + * but it can cause problems for apps that expect to render on top of the + * render API's output. As such, SDL will disable batching if a specific + * render backend is requested (since this might indicate that the app is + * planning to use the underlying graphics API directly). This hint can + * be used to explicitly request batching in this instance. It is a contract + * that you will either never use the underlying graphics API directly, or + * if you do, you will call SDL_RenderFlush() before you do so any current + * batch goes to the GPU before your work begins. Not following this contract + * will result in undefined behavior. + */ +#define SDL_HINT_RENDER_BATCHING "SDL_RENDER_BATCHING" + + +/** + * \brief A variable controlling whether SDL logs all events pushed onto its internal queue. + * + * This variable can be set to the following values: + * + * "0" - Don't log any events (default) + * "1" - Log all events except mouse and finger motion, which are pretty spammy. + * "2" - Log all events. + * + * This is generally meant to be used to debug SDL itself, but can be useful + * for application developers that need better visibility into what is going + * on in the event queue. Logged events are sent through SDL_Log(), which + * means by default they appear on stdout on most platforms or maybe + * OutputDebugString() on Windows, and can be funneled by the app with + * SDL_LogSetOutputFunction(), etc. + * + * This hint can be toggled on and off at runtime, if you only need to log + * events for a small subset of program execution. + */ +#define SDL_HINT_EVENT_LOGGING "SDL_EVENT_LOGGING" + + + +/** + * \brief Controls how the size of the RIFF chunk affects the loading of a WAVE file. + * + * The size of the RIFF chunk (which includes all the sub-chunks of the WAVE + * file) is not always reliable. In case the size is wrong, it's possible to + * just ignore it and step through the chunks until a fixed limit is reached. + * + * Note that files that have trailing data unrelated to the WAVE file or + * corrupt files may slow down the loading process without a reliable boundary. + * By default, SDL stops after 10000 chunks to prevent wasting time. Use the + * environment variable SDL_WAVE_CHUNK_LIMIT to adjust this value. + * + * This variable can be set to the following values: + * + * "force" - Always use the RIFF chunk size as a boundary for the chunk search + * "ignorezero" - Like "force", but a zero size searches up to 4 GiB (default) + * "ignore" - Ignore the RIFF chunk size and always search up to 4 GiB + * "maximum" - Search for chunks until the end of file (not recommended) + */ +#define SDL_HINT_WAVE_RIFF_CHUNK_SIZE "SDL_WAVE_RIFF_CHUNK_SIZE" + +/** + * \brief Controls how a truncated WAVE file is handled. + * + * A WAVE file is considered truncated if any of the chunks are incomplete or + * the data chunk size is not a multiple of the block size. By default, SDL + * decodes until the first incomplete block, as most applications seem to do. + * + * This variable can be set to the following values: + * + * "verystrict" - Raise an error if the file is truncated + * "strict" - Like "verystrict", but the size of the RIFF chunk is ignored + * "dropframe" - Decode until the first incomplete sample frame + * "dropblock" - Decode until the first incomplete block (default) + */ +#define SDL_HINT_WAVE_TRUNCATION "SDL_WAVE_TRUNCATION" + +/** + * \brief Controls how the fact chunk affects the loading of a WAVE file. + * + * The fact chunk stores information about the number of samples of a WAVE + * file. The Standards Update from Microsoft notes that this value can be used + * to 'determine the length of the data in seconds'. This is especially useful + * for compressed formats (for which this is a mandatory chunk) if they produce + * multiple sample frames per block and truncating the block is not allowed. + * The fact chunk can exactly specify how many sample frames there should be + * in this case. + * + * Unfortunately, most application seem to ignore the fact chunk and so SDL + * ignores it by default as well. + * + * This variable can be set to the following values: + * + * "truncate" - Use the number of samples to truncate the wave data if + * the fact chunk is present and valid + * "strict" - Like "truncate", but raise an error if the fact chunk + * is invalid, not present for non-PCM formats, or if the + * data chunk doesn't have that many samples + * "ignorezero" - Like "truncate", but ignore fact chunk if the number of + * samples is zero + * "ignore" - Ignore fact chunk entirely (default) + */ +#define SDL_HINT_WAVE_FACT_CHUNK "SDL_WAVE_FACT_CHUNK" + +/** + * \brief An enumeration of hint priorities + */ +typedef enum +{ + SDL_HINT_DEFAULT, + SDL_HINT_NORMAL, + SDL_HINT_OVERRIDE +} SDL_HintPriority; + + +/** + * \brief Set a hint with a specific priority + * + * The priority controls the behavior when setting a hint that already + * has a value. Hints will replace existing hints of their priority and + * lower. Environment variables are considered to have override priority. + * + * \return SDL_TRUE if the hint was set, SDL_FALSE otherwise + */ +extern DECLSPEC SDL_bool SDLCALL SDL_SetHintWithPriority(const char *name, + const char *value, + SDL_HintPriority priority); + +/** + * \brief Set a hint with normal priority + * + * \return SDL_TRUE if the hint was set, SDL_FALSE otherwise + */ +extern DECLSPEC SDL_bool SDLCALL SDL_SetHint(const char *name, + const char *value); + +/** + * \brief Get a hint + * + * \return The string value of a hint variable. + */ +extern DECLSPEC const char * SDLCALL SDL_GetHint(const char *name); + +/** + * \brief Get a hint + * + * \return The boolean value of a hint variable. + */ +extern DECLSPEC SDL_bool SDLCALL SDL_GetHintBoolean(const char *name, SDL_bool default_value); + +/** + * \brief type definition of the hint callback function. + */ +typedef void (SDLCALL *SDL_HintCallback)(void *userdata, const char *name, const char *oldValue, const char *newValue); + +/** + * \brief Add a function to watch a particular hint + * + * \param name The hint to watch + * \param callback The function to call when the hint value changes + * \param userdata A pointer to pass to the callback function + */ +extern DECLSPEC void SDLCALL SDL_AddHintCallback(const char *name, + SDL_HintCallback callback, + void *userdata); + +/** + * \brief Remove a function watching a particular hint + * + * \param name The hint being watched + * \param callback The function being called when the hint value changes + * \param userdata A pointer being passed to the callback function + */ +extern DECLSPEC void SDLCALL SDL_DelHintCallback(const char *name, + SDL_HintCallback callback, + void *userdata); + +/** + * \brief Clear all hints + * + * This function is called during SDL_Quit() to free stored hints. + */ +extern DECLSPEC void SDLCALL SDL_ClearHints(void); + + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_hints_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/engine/Windows/SDL2/include/SDL_joystick.h b/engine/Windows/SDL2/include/SDL_joystick.h new file mode 100644 index 0000000..3a4c5d1 --- /dev/null +++ b/engine/Windows/SDL2/include/SDL_joystick.h @@ -0,0 +1,408 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2019 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_joystick.h + * + * Include file for SDL joystick event handling + * + * The term "device_index" identifies currently plugged in joystick devices between 0 and SDL_NumJoysticks(), with the exact joystick + * behind a device_index changing as joysticks are plugged and unplugged. + * + * The term "instance_id" is the current instantiation of a joystick device in the system, if the joystick is removed and then re-inserted + * then it will get a new instance_id, instance_id's are monotonically increasing identifiers of a joystick plugged in. + * + * The term JoystickGUID is a stable 128-bit identifier for a joystick device that does not change over time, it identifies class of + * the device (a X360 wired controller for example). This identifier is platform dependent. + * + * + */ + +#ifndef SDL_joystick_h_ +#define SDL_joystick_h_ + +#include "SDL_stdinc.h" +#include "SDL_error.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \file SDL_joystick.h + * + * In order to use these functions, SDL_Init() must have been called + * with the ::SDL_INIT_JOYSTICK flag. This causes SDL to scan the system + * for joysticks, and load appropriate drivers. + * + * If you would like to receive joystick updates while the application + * is in the background, you should set the following hint before calling + * SDL_Init(): SDL_HINT_JOYSTICK_ALLOW_BACKGROUND_EVENTS + */ + +/** + * The joystick structure used to identify an SDL joystick + */ +struct _SDL_Joystick; +typedef struct _SDL_Joystick SDL_Joystick; + +/* A structure that encodes the stable unique id for a joystick device */ +typedef struct { + Uint8 data[16]; +} SDL_JoystickGUID; + +/** + * This is a unique ID for a joystick for the time it is connected to the system, + * and is never reused for the lifetime of the application. If the joystick is + * disconnected and reconnected, it will get a new ID. + * + * The ID value starts at 0 and increments from there. The value -1 is an invalid ID. + */ +typedef Sint32 SDL_JoystickID; + +typedef enum +{ + SDL_JOYSTICK_TYPE_UNKNOWN, + SDL_JOYSTICK_TYPE_GAMECONTROLLER, + SDL_JOYSTICK_TYPE_WHEEL, + SDL_JOYSTICK_TYPE_ARCADE_STICK, + SDL_JOYSTICK_TYPE_FLIGHT_STICK, + SDL_JOYSTICK_TYPE_DANCE_PAD, + SDL_JOYSTICK_TYPE_GUITAR, + SDL_JOYSTICK_TYPE_DRUM_KIT, + SDL_JOYSTICK_TYPE_ARCADE_PAD, + SDL_JOYSTICK_TYPE_THROTTLE +} SDL_JoystickType; + +typedef enum +{ + SDL_JOYSTICK_POWER_UNKNOWN = -1, + SDL_JOYSTICK_POWER_EMPTY, /* <= 5% */ + SDL_JOYSTICK_POWER_LOW, /* <= 20% */ + SDL_JOYSTICK_POWER_MEDIUM, /* <= 70% */ + SDL_JOYSTICK_POWER_FULL, /* <= 100% */ + SDL_JOYSTICK_POWER_WIRED, + SDL_JOYSTICK_POWER_MAX +} SDL_JoystickPowerLevel; + +/* Function prototypes */ + +/** + * Locking for multi-threaded access to the joystick API + * + * If you are using the joystick API or handling events from multiple threads + * you should use these locking functions to protect access to the joysticks. + * + * In particular, you are guaranteed that the joystick list won't change, so + * the API functions that take a joystick index will be valid, and joystick + * and game controller events will not be delivered. + */ +extern DECLSPEC void SDLCALL SDL_LockJoysticks(void); +extern DECLSPEC void SDLCALL SDL_UnlockJoysticks(void); + +/** + * Count the number of joysticks attached to the system right now + */ +extern DECLSPEC int SDLCALL SDL_NumJoysticks(void); + +/** + * 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. + */ +extern DECLSPEC const char *SDLCALL SDL_JoystickNameForIndex(int device_index); + +/** + * Get the player index of a joystick, or -1 if it's not available + * This can be called before any joysticks are opened. + */ +extern DECLSPEC int SDLCALL SDL_JoystickGetDevicePlayerIndex(int device_index); + +/** + * Return the GUID for the joystick at this index + * This can be called before any joysticks are opened. + */ +extern DECLSPEC SDL_JoystickGUID SDLCALL SDL_JoystickGetDeviceGUID(int device_index); + +/** + * Get the USB vendor ID of a joystick, if available. + * This can be called before any joysticks are opened. + * If the vendor ID isn't available this function returns 0. + */ +extern DECLSPEC Uint16 SDLCALL SDL_JoystickGetDeviceVendor(int device_index); + +/** + * Get the USB product ID of a joystick, if available. + * This can be called before any joysticks are opened. + * If the product ID isn't available this function returns 0. + */ +extern DECLSPEC Uint16 SDLCALL SDL_JoystickGetDeviceProduct(int device_index); + +/** + * Get the product version of a joystick, if available. + * This can be called before any joysticks are opened. + * If the product version isn't available this function returns 0. + */ +extern DECLSPEC Uint16 SDLCALL SDL_JoystickGetDeviceProductVersion(int device_index); + +/** + * Get the type of a joystick, if available. + * This can be called before any joysticks are opened. + */ +extern DECLSPEC SDL_JoystickType SDLCALL SDL_JoystickGetDeviceType(int device_index); + +/** + * Get the instance ID of a joystick. + * This can be called before any joysticks are opened. + * If the index is out of range, this function will return -1. + */ +extern DECLSPEC SDL_JoystickID SDLCALL SDL_JoystickGetDeviceInstanceID(int device_index); + +/** + * Open a joystick for use. + * The index passed as an argument refers to the N'th joystick on the system. + * This index is not the value which will identify this joystick in future + * joystick events. The joystick's instance id (::SDL_JoystickID) will be used + * there instead. + * + * \return A joystick identifier, or NULL if an error occurred. + */ +extern DECLSPEC SDL_Joystick *SDLCALL SDL_JoystickOpen(int device_index); + +/** + * Return the SDL_Joystick associated with an instance id. + */ +extern DECLSPEC SDL_Joystick *SDLCALL SDL_JoystickFromInstanceID(SDL_JoystickID joyid); + +/** + * Return the name for this currently opened joystick. + * If no name can be found, this function returns NULL. + */ +extern DECLSPEC const char *SDLCALL SDL_JoystickName(SDL_Joystick * joystick); + +/** + * Get the player index of an opened joystick, or -1 if it's not available + * + * For XInput controllers this returns the XInput user index. + */ +extern DECLSPEC int SDLCALL SDL_JoystickGetPlayerIndex(SDL_Joystick * joystick); + +/** + * Return the GUID for this opened joystick + */ +extern DECLSPEC SDL_JoystickGUID SDLCALL SDL_JoystickGetGUID(SDL_Joystick * joystick); + +/** + * Get the USB vendor ID of an opened joystick, if available. + * If the vendor ID isn't available this function returns 0. + */ +extern DECLSPEC Uint16 SDLCALL SDL_JoystickGetVendor(SDL_Joystick * joystick); + +/** + * Get the USB product ID of an opened joystick, if available. + * If the product ID isn't available this function returns 0. + */ +extern DECLSPEC Uint16 SDLCALL SDL_JoystickGetProduct(SDL_Joystick * joystick); + +/** + * Get the product version of an opened joystick, if available. + * If the product version isn't available this function returns 0. + */ +extern DECLSPEC Uint16 SDLCALL SDL_JoystickGetProductVersion(SDL_Joystick * joystick); + +/** + * Get the type of an opened joystick. + */ +extern DECLSPEC SDL_JoystickType SDLCALL SDL_JoystickGetType(SDL_Joystick * joystick); + +/** + * Return a string representation for this guid. pszGUID must point to at least 33 bytes + * (32 for the string plus a NULL terminator). + */ +extern DECLSPEC void SDLCALL SDL_JoystickGetGUIDString(SDL_JoystickGUID guid, char *pszGUID, int cbGUID); + +/** + * Convert a string into a joystick guid + */ +extern DECLSPEC SDL_JoystickGUID SDLCALL SDL_JoystickGetGUIDFromString(const char *pchGUID); + +/** + * Returns SDL_TRUE if the joystick has been opened and currently connected, or SDL_FALSE if it has not. + */ +extern DECLSPEC SDL_bool SDLCALL SDL_JoystickGetAttached(SDL_Joystick * joystick); + +/** + * Get the instance ID of an opened joystick or -1 if the joystick is invalid. + */ +extern DECLSPEC SDL_JoystickID SDLCALL SDL_JoystickInstanceID(SDL_Joystick * joystick); + +/** + * Get the number of general axis controls on a joystick. + */ +extern DECLSPEC int SDLCALL SDL_JoystickNumAxes(SDL_Joystick * joystick); + +/** + * Get the number of trackballs on a joystick. + * + * Joystick trackballs have only relative motion events associated + * with them and their state cannot be polled. + */ +extern DECLSPEC int SDLCALL SDL_JoystickNumBalls(SDL_Joystick * joystick); + +/** + * Get the number of POV hats on a joystick. + */ +extern DECLSPEC int SDLCALL SDL_JoystickNumHats(SDL_Joystick * joystick); + +/** + * Get the number of buttons on a joystick. + */ +extern DECLSPEC int SDLCALL SDL_JoystickNumButtons(SDL_Joystick * joystick); + +/** + * Update the current state of the open joysticks. + * + * This is called automatically by the event loop if any joystick + * events are enabled. + */ +extern DECLSPEC void SDLCALL SDL_JoystickUpdate(void); + +/** + * 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. + */ +extern DECLSPEC int SDLCALL SDL_JoystickEventState(int state); + +#define SDL_JOYSTICK_AXIS_MAX 32767 +#define SDL_JOYSTICK_AXIS_MIN -32768 +/** + * 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. + */ +extern DECLSPEC Sint16 SDLCALL SDL_JoystickGetAxis(SDL_Joystick * joystick, + int axis); + +/** + * Get the initial 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. + * + * \return SDL_TRUE if this axis has any initial value, or SDL_FALSE if not. + */ +extern DECLSPEC SDL_bool SDLCALL SDL_JoystickGetAxisInitialState(SDL_Joystick * joystick, + int axis, Sint16 *state); + +/** + * \name Hat positions + */ +/* @{ */ +#define SDL_HAT_CENTERED 0x00 +#define SDL_HAT_UP 0x01 +#define SDL_HAT_RIGHT 0x02 +#define SDL_HAT_DOWN 0x04 +#define SDL_HAT_LEFT 0x08 +#define SDL_HAT_RIGHTUP (SDL_HAT_RIGHT|SDL_HAT_UP) +#define SDL_HAT_RIGHTDOWN (SDL_HAT_RIGHT|SDL_HAT_DOWN) +#define SDL_HAT_LEFTUP (SDL_HAT_LEFT|SDL_HAT_UP) +#define SDL_HAT_LEFTDOWN (SDL_HAT_LEFT|SDL_HAT_DOWN) +/* @} */ + +/** + * Get the current state of a POV hat on a joystick. + * + * The hat indices start at index 0. + * + * \return The return value is one of the following positions: + * - ::SDL_HAT_CENTERED + * - ::SDL_HAT_UP + * - ::SDL_HAT_RIGHT + * - ::SDL_HAT_DOWN + * - ::SDL_HAT_LEFT + * - ::SDL_HAT_RIGHTUP + * - ::SDL_HAT_RIGHTDOWN + * - ::SDL_HAT_LEFTUP + * - ::SDL_HAT_LEFTDOWN + */ +extern DECLSPEC Uint8 SDLCALL SDL_JoystickGetHat(SDL_Joystick * joystick, + int hat); + +/** + * Get the ball axis change since the last poll. + * + * \return 0, or -1 if you passed it invalid parameters. + * + * The ball indices start at index 0. + */ +extern DECLSPEC int SDLCALL SDL_JoystickGetBall(SDL_Joystick * joystick, + int ball, int *dx, int *dy); + +/** + * Get the current state of a button on a joystick. + * + * The button indices start at index 0. + */ +extern DECLSPEC Uint8 SDLCALL SDL_JoystickGetButton(SDL_Joystick * joystick, + int button); + +/** + * Trigger a rumble effect + * Each call to this function cancels any previous rumble effect, and calling it with 0 intensity stops any rumbling. + * + * \param joystick The joystick to vibrate + * \param low_frequency_rumble The intensity of the low frequency (left) rumble motor, from 0 to 0xFFFF + * \param high_frequency_rumble The intensity of the high frequency (right) rumble motor, from 0 to 0xFFFF + * \param duration_ms The duration of the rumble effect, in milliseconds + * + * \return 0, or -1 if rumble isn't supported on this joystick + */ +extern DECLSPEC int SDLCALL SDL_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble, Uint32 duration_ms); + +/** + * Close a joystick previously opened with SDL_JoystickOpen(). + */ +extern DECLSPEC void SDLCALL SDL_JoystickClose(SDL_Joystick * joystick); + +/** + * Return the battery level of this joystick + */ +extern DECLSPEC SDL_JoystickPowerLevel SDLCALL SDL_JoystickCurrentPowerLevel(SDL_Joystick * joystick); + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_joystick_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/engine/Windows/SDL2/include/SDL_keyboard.h b/engine/Windows/SDL2/include/SDL_keyboard.h new file mode 100644 index 0000000..4b2a055 --- /dev/null +++ b/engine/Windows/SDL2/include/SDL_keyboard.h @@ -0,0 +1,217 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2019 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_keyboard.h + * + * Include file for SDL keyboard event handling + */ + +#ifndef SDL_keyboard_h_ +#define SDL_keyboard_h_ + +#include "SDL_stdinc.h" +#include "SDL_error.h" +#include "SDL_keycode.h" +#include "SDL_video.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief The SDL keysym structure, used in key events. + * + * \note If you are looking for translated character input, see the ::SDL_TEXTINPUT event. + */ +typedef struct SDL_Keysym +{ + SDL_Scancode scancode; /**< SDL physical key code - see ::SDL_Scancode for details */ + SDL_Keycode sym; /**< SDL virtual key code - see ::SDL_Keycode for details */ + Uint16 mod; /**< current key modifiers */ + Uint32 unused; +} SDL_Keysym; + +/* Function prototypes */ + +/** + * \brief Get the window which currently has keyboard focus. + */ +extern DECLSPEC SDL_Window * SDLCALL SDL_GetKeyboardFocus(void); + +/** + * \brief Get a snapshot of the current state of the keyboard. + * + * \param numkeys if non-NULL, receives the length of the returned array. + * + * \return An array of key states. Indexes into this array are obtained by using ::SDL_Scancode values. + * + * \b Example: + * \code + * const Uint8 *state = SDL_GetKeyboardState(NULL); + * if ( state[SDL_SCANCODE_RETURN] ) { + * printf(" is pressed.\n"); + * } + * \endcode + */ +extern DECLSPEC const Uint8 *SDLCALL SDL_GetKeyboardState(int *numkeys); + +/** + * \brief Get the current key modifier state for the keyboard. + */ +extern DECLSPEC SDL_Keymod SDLCALL SDL_GetModState(void); + +/** + * \brief Set the current key modifier state for the keyboard. + * + * \note This does not change the keyboard state, only the key modifier flags. + */ +extern DECLSPEC void SDLCALL SDL_SetModState(SDL_Keymod modstate); + +/** + * \brief Get the key code corresponding to the given scancode according + * to the current keyboard layout. + * + * See ::SDL_Keycode for details. + * + * \sa SDL_GetKeyName() + */ +extern DECLSPEC SDL_Keycode SDLCALL SDL_GetKeyFromScancode(SDL_Scancode scancode); + +/** + * \brief Get the scancode corresponding to the given key code according to the + * current keyboard layout. + * + * See ::SDL_Scancode for details. + * + * \sa SDL_GetScancodeName() + */ +extern DECLSPEC SDL_Scancode SDLCALL SDL_GetScancodeFromKey(SDL_Keycode key); + +/** + * \brief Get a human-readable name for a scancode. + * + * \return A pointer to the name for the scancode. + * If the scancode doesn't have a name, this function returns + * an empty string (""). + * + * \sa SDL_Scancode + */ +extern DECLSPEC const char *SDLCALL SDL_GetScancodeName(SDL_Scancode scancode); + +/** + * \brief Get a scancode from a human-readable name + * + * \return scancode, or SDL_SCANCODE_UNKNOWN if the name wasn't recognized + * + * \sa SDL_Scancode + */ +extern DECLSPEC SDL_Scancode SDLCALL SDL_GetScancodeFromName(const char *name); + +/** + * \brief Get a human-readable name for a key. + * + * \return A pointer to a UTF-8 string that stays valid at least until the next + * call to this function. If you need it around any longer, you must + * copy it. If the key doesn't have a name, this function returns an + * empty string (""). + * + * \sa SDL_Keycode + */ +extern DECLSPEC const char *SDLCALL SDL_GetKeyName(SDL_Keycode key); + +/** + * \brief Get a key code from a human-readable name + * + * \return key code, or SDLK_UNKNOWN if the name wasn't recognized + * + * \sa SDL_Keycode + */ +extern DECLSPEC SDL_Keycode SDLCALL SDL_GetKeyFromName(const char *name); + +/** + * \brief Start accepting Unicode text input events. + * This function will show the on-screen keyboard if supported. + * + * \sa SDL_StopTextInput() + * \sa SDL_SetTextInputRect() + * \sa SDL_HasScreenKeyboardSupport() + */ +extern DECLSPEC void SDLCALL SDL_StartTextInput(void); + +/** + * \brief Return whether or not Unicode text input events are enabled. + * + * \sa SDL_StartTextInput() + * \sa SDL_StopTextInput() + */ +extern DECLSPEC SDL_bool SDLCALL SDL_IsTextInputActive(void); + +/** + * \brief Stop receiving any text input events. + * This function will hide the on-screen keyboard if supported. + * + * \sa SDL_StartTextInput() + * \sa SDL_HasScreenKeyboardSupport() + */ +extern DECLSPEC void SDLCALL SDL_StopTextInput(void); + +/** + * \brief Set the rectangle used to type Unicode text inputs. + * This is used as a hint for IME and on-screen keyboard placement. + * + * \sa SDL_StartTextInput() + */ +extern DECLSPEC void SDLCALL SDL_SetTextInputRect(SDL_Rect *rect); + +/** + * \brief Returns whether the platform has some screen keyboard support. + * + * \return SDL_TRUE if some keyboard support is available else SDL_FALSE. + * + * \note Not all screen keyboard functions are supported on all platforms. + * + * \sa SDL_IsScreenKeyboardShown() + */ +extern DECLSPEC SDL_bool SDLCALL SDL_HasScreenKeyboardSupport(void); + +/** + * \brief Returns whether the screen keyboard is shown for given window. + * + * \param window The window for which screen keyboard should be queried. + * + * \return SDL_TRUE if screen keyboard is shown else SDL_FALSE. + * + * \sa SDL_HasScreenKeyboardSupport() + */ +extern DECLSPEC SDL_bool SDLCALL SDL_IsScreenKeyboardShown(SDL_Window *window); + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_keyboard_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/engine/Windows/SDL2/include/SDL_keycode.h b/engine/Windows/SDL2/include/SDL_keycode.h new file mode 100644 index 0000000..64b72dd --- /dev/null +++ b/engine/Windows/SDL2/include/SDL_keycode.h @@ -0,0 +1,349 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2019 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_keycode.h + * + * Defines constants which identify keyboard keys and modifiers. + */ + +#ifndef SDL_keycode_h_ +#define SDL_keycode_h_ + +#include "SDL_stdinc.h" +#include "SDL_scancode.h" + +/** + * \brief The SDL virtual key representation. + * + * Values of this type are used to represent keyboard keys using the current + * layout of the keyboard. These values include Unicode values representing + * the unmodified character that would be generated by pressing the key, or + * an SDLK_* constant for those keys that do not generate characters. + * + * A special exception is the number keys at the top of the keyboard which + * always map to SDLK_0...SDLK_9, regardless of layout. + */ +typedef Sint32 SDL_Keycode; + +#define SDLK_SCANCODE_MASK (1<<30) +#define SDL_SCANCODE_TO_KEYCODE(X) (X | SDLK_SCANCODE_MASK) + +typedef enum +{ + SDLK_UNKNOWN = 0, + + SDLK_RETURN = '\r', + SDLK_ESCAPE = '\033', + SDLK_BACKSPACE = '\b', + SDLK_TAB = '\t', + SDLK_SPACE = ' ', + SDLK_EXCLAIM = '!', + SDLK_QUOTEDBL = '"', + SDLK_HASH = '#', + SDLK_PERCENT = '%', + SDLK_DOLLAR = '$', + SDLK_AMPERSAND = '&', + SDLK_QUOTE = '\'', + SDLK_LEFTPAREN = '(', + SDLK_RIGHTPAREN = ')', + SDLK_ASTERISK = '*', + SDLK_PLUS = '+', + SDLK_COMMA = ',', + SDLK_MINUS = '-', + SDLK_PERIOD = '.', + SDLK_SLASH = '/', + SDLK_0 = '0', + SDLK_1 = '1', + SDLK_2 = '2', + SDLK_3 = '3', + SDLK_4 = '4', + SDLK_5 = '5', + SDLK_6 = '6', + SDLK_7 = '7', + SDLK_8 = '8', + SDLK_9 = '9', + SDLK_COLON = ':', + SDLK_SEMICOLON = ';', + SDLK_LESS = '<', + SDLK_EQUALS = '=', + SDLK_GREATER = '>', + SDLK_QUESTION = '?', + SDLK_AT = '@', + /* + Skip uppercase letters + */ + SDLK_LEFTBRACKET = '[', + SDLK_BACKSLASH = '\\', + SDLK_RIGHTBRACKET = ']', + SDLK_CARET = '^', + SDLK_UNDERSCORE = '_', + SDLK_BACKQUOTE = '`', + SDLK_a = 'a', + SDLK_b = 'b', + SDLK_c = 'c', + SDLK_d = 'd', + SDLK_e = 'e', + SDLK_f = 'f', + SDLK_g = 'g', + SDLK_h = 'h', + SDLK_i = 'i', + SDLK_j = 'j', + SDLK_k = 'k', + SDLK_l = 'l', + SDLK_m = 'm', + SDLK_n = 'n', + SDLK_o = 'o', + SDLK_p = 'p', + SDLK_q = 'q', + SDLK_r = 'r', + SDLK_s = 's', + SDLK_t = 't', + SDLK_u = 'u', + SDLK_v = 'v', + SDLK_w = 'w', + SDLK_x = 'x', + SDLK_y = 'y', + SDLK_z = 'z', + + SDLK_CAPSLOCK = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_CAPSLOCK), + + SDLK_F1 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F1), + SDLK_F2 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F2), + SDLK_F3 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F3), + SDLK_F4 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F4), + SDLK_F5 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F5), + SDLK_F6 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F6), + SDLK_F7 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F7), + SDLK_F8 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F8), + SDLK_F9 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F9), + SDLK_F10 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F10), + SDLK_F11 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F11), + SDLK_F12 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F12), + + SDLK_PRINTSCREEN = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_PRINTSCREEN), + SDLK_SCROLLLOCK = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_SCROLLLOCK), + SDLK_PAUSE = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_PAUSE), + SDLK_INSERT = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_INSERT), + SDLK_HOME = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_HOME), + SDLK_PAGEUP = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_PAGEUP), + SDLK_DELETE = '\177', + SDLK_END = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_END), + SDLK_PAGEDOWN = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_PAGEDOWN), + SDLK_RIGHT = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_RIGHT), + SDLK_LEFT = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_LEFT), + SDLK_DOWN = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_DOWN), + SDLK_UP = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_UP), + + SDLK_NUMLOCKCLEAR = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_NUMLOCKCLEAR), + SDLK_KP_DIVIDE = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_DIVIDE), + SDLK_KP_MULTIPLY = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_MULTIPLY), + SDLK_KP_MINUS = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_MINUS), + SDLK_KP_PLUS = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_PLUS), + SDLK_KP_ENTER = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_ENTER), + SDLK_KP_1 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_1), + SDLK_KP_2 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_2), + SDLK_KP_3 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_3), + SDLK_KP_4 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_4), + SDLK_KP_5 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_5), + SDLK_KP_6 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_6), + SDLK_KP_7 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_7), + SDLK_KP_8 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_8), + SDLK_KP_9 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_9), + SDLK_KP_0 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_0), + SDLK_KP_PERIOD = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_PERIOD), + + SDLK_APPLICATION = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_APPLICATION), + SDLK_POWER = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_POWER), + SDLK_KP_EQUALS = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_EQUALS), + SDLK_F13 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F13), + SDLK_F14 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F14), + SDLK_F15 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F15), + SDLK_F16 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F16), + SDLK_F17 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F17), + SDLK_F18 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F18), + SDLK_F19 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F19), + SDLK_F20 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F20), + SDLK_F21 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F21), + SDLK_F22 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F22), + SDLK_F23 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F23), + SDLK_F24 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F24), + SDLK_EXECUTE = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_EXECUTE), + SDLK_HELP = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_HELP), + SDLK_MENU = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_MENU), + SDLK_SELECT = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_SELECT), + SDLK_STOP = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_STOP), + SDLK_AGAIN = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_AGAIN), + SDLK_UNDO = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_UNDO), + SDLK_CUT = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_CUT), + SDLK_COPY = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_COPY), + SDLK_PASTE = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_PASTE), + SDLK_FIND = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_FIND), + SDLK_MUTE = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_MUTE), + SDLK_VOLUMEUP = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_VOLUMEUP), + SDLK_VOLUMEDOWN = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_VOLUMEDOWN), + SDLK_KP_COMMA = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_COMMA), + SDLK_KP_EQUALSAS400 = + SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_EQUALSAS400), + + SDLK_ALTERASE = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_ALTERASE), + SDLK_SYSREQ = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_SYSREQ), + SDLK_CANCEL = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_CANCEL), + SDLK_CLEAR = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_CLEAR), + SDLK_PRIOR = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_PRIOR), + SDLK_RETURN2 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_RETURN2), + SDLK_SEPARATOR = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_SEPARATOR), + SDLK_OUT = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_OUT), + SDLK_OPER = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_OPER), + SDLK_CLEARAGAIN = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_CLEARAGAIN), + SDLK_CRSEL = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_CRSEL), + SDLK_EXSEL = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_EXSEL), + + SDLK_KP_00 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_00), + SDLK_KP_000 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_000), + SDLK_THOUSANDSSEPARATOR = + SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_THOUSANDSSEPARATOR), + SDLK_DECIMALSEPARATOR = + SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_DECIMALSEPARATOR), + SDLK_CURRENCYUNIT = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_CURRENCYUNIT), + SDLK_CURRENCYSUBUNIT = + SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_CURRENCYSUBUNIT), + SDLK_KP_LEFTPAREN = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_LEFTPAREN), + SDLK_KP_RIGHTPAREN = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_RIGHTPAREN), + SDLK_KP_LEFTBRACE = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_LEFTBRACE), + SDLK_KP_RIGHTBRACE = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_RIGHTBRACE), + SDLK_KP_TAB = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_TAB), + SDLK_KP_BACKSPACE = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_BACKSPACE), + SDLK_KP_A = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_A), + SDLK_KP_B = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_B), + SDLK_KP_C = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_C), + SDLK_KP_D = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_D), + SDLK_KP_E = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_E), + SDLK_KP_F = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_F), + SDLK_KP_XOR = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_XOR), + SDLK_KP_POWER = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_POWER), + SDLK_KP_PERCENT = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_PERCENT), + SDLK_KP_LESS = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_LESS), + SDLK_KP_GREATER = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_GREATER), + SDLK_KP_AMPERSAND = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_AMPERSAND), + SDLK_KP_DBLAMPERSAND = + SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_DBLAMPERSAND), + SDLK_KP_VERTICALBAR = + SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_VERTICALBAR), + SDLK_KP_DBLVERTICALBAR = + SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_DBLVERTICALBAR), + SDLK_KP_COLON = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_COLON), + SDLK_KP_HASH = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_HASH), + SDLK_KP_SPACE = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_SPACE), + SDLK_KP_AT = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_AT), + SDLK_KP_EXCLAM = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_EXCLAM), + SDLK_KP_MEMSTORE = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_MEMSTORE), + SDLK_KP_MEMRECALL = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_MEMRECALL), + SDLK_KP_MEMCLEAR = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_MEMCLEAR), + SDLK_KP_MEMADD = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_MEMADD), + SDLK_KP_MEMSUBTRACT = + SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_MEMSUBTRACT), + SDLK_KP_MEMMULTIPLY = + SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_MEMMULTIPLY), + SDLK_KP_MEMDIVIDE = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_MEMDIVIDE), + SDLK_KP_PLUSMINUS = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_PLUSMINUS), + SDLK_KP_CLEAR = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_CLEAR), + SDLK_KP_CLEARENTRY = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_CLEARENTRY), + SDLK_KP_BINARY = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_BINARY), + SDLK_KP_OCTAL = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_OCTAL), + SDLK_KP_DECIMAL = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_DECIMAL), + SDLK_KP_HEXADECIMAL = + SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_HEXADECIMAL), + + SDLK_LCTRL = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_LCTRL), + SDLK_LSHIFT = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_LSHIFT), + SDLK_LALT = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_LALT), + SDLK_LGUI = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_LGUI), + SDLK_RCTRL = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_RCTRL), + SDLK_RSHIFT = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_RSHIFT), + SDLK_RALT = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_RALT), + SDLK_RGUI = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_RGUI), + + SDLK_MODE = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_MODE), + + SDLK_AUDIONEXT = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_AUDIONEXT), + SDLK_AUDIOPREV = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_AUDIOPREV), + SDLK_AUDIOSTOP = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_AUDIOSTOP), + SDLK_AUDIOPLAY = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_AUDIOPLAY), + SDLK_AUDIOMUTE = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_AUDIOMUTE), + SDLK_MEDIASELECT = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_MEDIASELECT), + SDLK_WWW = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_WWW), + SDLK_MAIL = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_MAIL), + SDLK_CALCULATOR = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_CALCULATOR), + SDLK_COMPUTER = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_COMPUTER), + SDLK_AC_SEARCH = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_AC_SEARCH), + SDLK_AC_HOME = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_AC_HOME), + SDLK_AC_BACK = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_AC_BACK), + SDLK_AC_FORWARD = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_AC_FORWARD), + SDLK_AC_STOP = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_AC_STOP), + SDLK_AC_REFRESH = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_AC_REFRESH), + SDLK_AC_BOOKMARKS = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_AC_BOOKMARKS), + + SDLK_BRIGHTNESSDOWN = + SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_BRIGHTNESSDOWN), + SDLK_BRIGHTNESSUP = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_BRIGHTNESSUP), + SDLK_DISPLAYSWITCH = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_DISPLAYSWITCH), + SDLK_KBDILLUMTOGGLE = + SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KBDILLUMTOGGLE), + SDLK_KBDILLUMDOWN = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KBDILLUMDOWN), + SDLK_KBDILLUMUP = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KBDILLUMUP), + SDLK_EJECT = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_EJECT), + SDLK_SLEEP = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_SLEEP), + SDLK_APP1 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_APP1), + SDLK_APP2 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_APP2), + + SDLK_AUDIOREWIND = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_AUDIOREWIND), + SDLK_AUDIOFASTFORWARD = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_AUDIOFASTFORWARD) +} SDL_KeyCode; + +/** + * \brief Enumeration of valid key mods (possibly OR'd together). + */ +typedef enum +{ + KMOD_NONE = 0x0000, + KMOD_LSHIFT = 0x0001, + KMOD_RSHIFT = 0x0002, + KMOD_LCTRL = 0x0040, + KMOD_RCTRL = 0x0080, + KMOD_LALT = 0x0100, + KMOD_RALT = 0x0200, + KMOD_LGUI = 0x0400, + KMOD_RGUI = 0x0800, + KMOD_NUM = 0x1000, + KMOD_CAPS = 0x2000, + KMOD_MODE = 0x4000, + KMOD_RESERVED = 0x8000 +} SDL_Keymod; + +#define KMOD_CTRL (KMOD_LCTRL|KMOD_RCTRL) +#define KMOD_SHIFT (KMOD_LSHIFT|KMOD_RSHIFT) +#define KMOD_ALT (KMOD_LALT|KMOD_RALT) +#define KMOD_GUI (KMOD_LGUI|KMOD_RGUI) + +#endif /* SDL_keycode_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/engine/Windows/SDL2/include/SDL_loadso.h b/engine/Windows/SDL2/include/SDL_loadso.h new file mode 100644 index 0000000..793ba53 --- /dev/null +++ b/engine/Windows/SDL2/include/SDL_loadso.h @@ -0,0 +1,81 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2019 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_loadso.h + * + * System dependent library loading routines + * + * Some things to keep in mind: + * \li These functions only work on C function names. Other languages may + * have name mangling and intrinsic language support that varies from + * compiler to compiler. + * \li Make sure you declare your function pointers with the same calling + * convention as the actual library function. Your code will crash + * mysteriously if you do not do this. + * \li Avoid namespace collisions. If you load a symbol from the library, + * it is not defined whether or not it goes into the global symbol + * namespace for the application. If it does and it conflicts with + * symbols in your code or other shared libraries, you will not get + * the results you expect. :) + */ + +#ifndef SDL_loadso_h_ +#define SDL_loadso_h_ + +#include "SDL_stdinc.h" +#include "SDL_error.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/** + * 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. + */ +extern DECLSPEC void *SDLCALL SDL_LoadObject(const char *sofile); + +/** + * 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(). + */ +extern DECLSPEC void *SDLCALL SDL_LoadFunction(void *handle, + const char *name); + +/** + * Unload a shared object from memory. + */ +extern DECLSPEC void SDLCALL SDL_UnloadObject(void *handle); + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_loadso_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/engine/Windows/SDL2/include/SDL_log.h b/engine/Windows/SDL2/include/SDL_log.h new file mode 100644 index 0000000..430e4fd --- /dev/null +++ b/engine/Windows/SDL2/include/SDL_log.h @@ -0,0 +1,211 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2019 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_log.h + * + * Simple log messages with categories and priorities. + * + * By default logs are quiet, but if you're debugging SDL you might want: + * + * SDL_LogSetAllPriority(SDL_LOG_PRIORITY_WARN); + * + * Here's where the messages go on different platforms: + * Windows: debug output stream + * Android: log output + * Others: standard error output (stderr) + */ + +#ifndef SDL_log_h_ +#define SDL_log_h_ + +#include "SDL_stdinc.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + + +/** + * \brief The maximum size of a log message + * + * Messages longer than the maximum size will be truncated + */ +#define SDL_MAX_LOG_MESSAGE 4096 + +/** + * \brief The predefined log categories + * + * By default the application category is enabled at the INFO level, + * the assert category is enabled at the WARN level, test is enabled + * at the VERBOSE level and all other categories are enabled at the + * CRITICAL level. + */ +typedef enum +{ + SDL_LOG_CATEGORY_APPLICATION, + SDL_LOG_CATEGORY_ERROR, + SDL_LOG_CATEGORY_ASSERT, + SDL_LOG_CATEGORY_SYSTEM, + SDL_LOG_CATEGORY_AUDIO, + SDL_LOG_CATEGORY_VIDEO, + SDL_LOG_CATEGORY_RENDER, + SDL_LOG_CATEGORY_INPUT, + SDL_LOG_CATEGORY_TEST, + + /* Reserved for future SDL library use */ + SDL_LOG_CATEGORY_RESERVED1, + SDL_LOG_CATEGORY_RESERVED2, + SDL_LOG_CATEGORY_RESERVED3, + SDL_LOG_CATEGORY_RESERVED4, + SDL_LOG_CATEGORY_RESERVED5, + SDL_LOG_CATEGORY_RESERVED6, + SDL_LOG_CATEGORY_RESERVED7, + SDL_LOG_CATEGORY_RESERVED8, + SDL_LOG_CATEGORY_RESERVED9, + SDL_LOG_CATEGORY_RESERVED10, + + /* Beyond this point is reserved for application use, e.g. + enum { + MYAPP_CATEGORY_AWESOME1 = SDL_LOG_CATEGORY_CUSTOM, + MYAPP_CATEGORY_AWESOME2, + MYAPP_CATEGORY_AWESOME3, + ... + }; + */ + SDL_LOG_CATEGORY_CUSTOM +} SDL_LogCategory; + +/** + * \brief The predefined log priorities + */ +typedef enum +{ + SDL_LOG_PRIORITY_VERBOSE = 1, + SDL_LOG_PRIORITY_DEBUG, + SDL_LOG_PRIORITY_INFO, + SDL_LOG_PRIORITY_WARN, + SDL_LOG_PRIORITY_ERROR, + SDL_LOG_PRIORITY_CRITICAL, + SDL_NUM_LOG_PRIORITIES +} SDL_LogPriority; + + +/** + * \brief Set the priority of all log categories + */ +extern DECLSPEC void SDLCALL SDL_LogSetAllPriority(SDL_LogPriority priority); + +/** + * \brief Set the priority of a particular log category + */ +extern DECLSPEC void SDLCALL SDL_LogSetPriority(int category, + SDL_LogPriority priority); + +/** + * \brief Get the priority of a particular log category + */ +extern DECLSPEC SDL_LogPriority SDLCALL SDL_LogGetPriority(int category); + +/** + * \brief Reset all priorities to default. + * + * \note This is called in SDL_Quit(). + */ +extern DECLSPEC void SDLCALL SDL_LogResetPriorities(void); + +/** + * \brief Log a message with SDL_LOG_CATEGORY_APPLICATION and SDL_LOG_PRIORITY_INFO + */ +extern DECLSPEC void SDLCALL SDL_Log(SDL_PRINTF_FORMAT_STRING const char *fmt, ...) SDL_PRINTF_VARARG_FUNC(1); + +/** + * \brief Log a message with SDL_LOG_PRIORITY_VERBOSE + */ +extern DECLSPEC void SDLCALL SDL_LogVerbose(int category, SDL_PRINTF_FORMAT_STRING const char *fmt, ...) SDL_PRINTF_VARARG_FUNC(2); + +/** + * \brief Log a message with SDL_LOG_PRIORITY_DEBUG + */ +extern DECLSPEC void SDLCALL SDL_LogDebug(int category, SDL_PRINTF_FORMAT_STRING const char *fmt, ...) SDL_PRINTF_VARARG_FUNC(2); + +/** + * \brief Log a message with SDL_LOG_PRIORITY_INFO + */ +extern DECLSPEC void SDLCALL SDL_LogInfo(int category, SDL_PRINTF_FORMAT_STRING const char *fmt, ...) SDL_PRINTF_VARARG_FUNC(2); + +/** + * \brief Log a message with SDL_LOG_PRIORITY_WARN + */ +extern DECLSPEC void SDLCALL SDL_LogWarn(int category, SDL_PRINTF_FORMAT_STRING const char *fmt, ...) SDL_PRINTF_VARARG_FUNC(2); + +/** + * \brief Log a message with SDL_LOG_PRIORITY_ERROR + */ +extern DECLSPEC void SDLCALL SDL_LogError(int category, SDL_PRINTF_FORMAT_STRING const char *fmt, ...) SDL_PRINTF_VARARG_FUNC(2); + +/** + * \brief Log a message with SDL_LOG_PRIORITY_CRITICAL + */ +extern DECLSPEC void SDLCALL SDL_LogCritical(int category, SDL_PRINTF_FORMAT_STRING const char *fmt, ...) SDL_PRINTF_VARARG_FUNC(2); + +/** + * \brief Log a message with the specified category and priority. + */ +extern DECLSPEC void SDLCALL SDL_LogMessage(int category, + SDL_LogPriority priority, + SDL_PRINTF_FORMAT_STRING const char *fmt, ...) SDL_PRINTF_VARARG_FUNC(3); + +/** + * \brief Log a message with the specified category and priority. + */ +extern DECLSPEC void SDLCALL SDL_LogMessageV(int category, + SDL_LogPriority priority, + const char *fmt, va_list ap); + +/** + * \brief The prototype for the log output function + */ +typedef void (SDLCALL *SDL_LogOutputFunction)(void *userdata, int category, SDL_LogPriority priority, const char *message); + +/** + * \brief Get the current log output function. + */ +extern DECLSPEC void SDLCALL SDL_LogGetOutputFunction(SDL_LogOutputFunction *callback, void **userdata); + +/** + * \brief This function allows you to replace the default log output + * function with one of your own. + */ +extern DECLSPEC void SDLCALL SDL_LogSetOutputFunction(SDL_LogOutputFunction callback, void *userdata); + + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_log_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/engine/Windows/SDL2/include/SDL_main.h b/engine/Windows/SDL2/include/SDL_main.h new file mode 100644 index 0000000..623f2d0 --- /dev/null +++ b/engine/Windows/SDL2/include/SDL_main.h @@ -0,0 +1,180 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2019 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef SDL_main_h_ +#define SDL_main_h_ + +#include "SDL_stdinc.h" + +/** + * \file SDL_main.h + * + * Redefine main() on some platforms so that it is called by SDL. + */ + +#ifndef SDL_MAIN_HANDLED +#if defined(__WIN32__) +/* On Windows SDL provides WinMain(), which parses the command line and passes + the arguments to your main function. + + If you provide your own WinMain(), you may define SDL_MAIN_HANDLED + */ +#define SDL_MAIN_AVAILABLE + +#elif defined(__WINRT__) +/* On WinRT, SDL provides a main function that initializes CoreApplication, + creating an instance of IFrameworkView in the process. + + Please note that #include'ing SDL_main.h is not enough to get a main() + function working. In non-XAML apps, the file, + src/main/winrt/SDL_WinRT_main_NonXAML.cpp, or a copy of it, must be compiled + into the app itself. In XAML apps, the function, SDL_WinRTRunApp must be + called, with a pointer to the Direct3D-hosted XAML control passed in. +*/ +#define SDL_MAIN_NEEDED + +#elif defined(__IPHONEOS__) +/* On iOS SDL provides a main function that creates an application delegate + and starts the iOS application run loop. + + If you link with SDL dynamically on iOS, the main function can't be in a + shared library, so you need to link with libSDLmain.a, which includes a + stub main function that calls into the shared library to start execution. + + See src/video/uikit/SDL_uikitappdelegate.m for more details. + */ +#define SDL_MAIN_NEEDED + +#elif defined(__ANDROID__) +/* On Android SDL provides a Java class in SDLActivity.java that is the + main activity entry point. + + See docs/README-android.md for more details on extending that class. + */ +#define SDL_MAIN_NEEDED + +/* We need to export SDL_main so it can be launched from Java */ +#define SDLMAIN_DECLSPEC DECLSPEC + +#elif defined(__NACL__) +/* On NACL we use ppapi_simple to set up the application helper code, + then wait for the first PSE_INSTANCE_DIDCHANGEVIEW event before + starting the user main function. + All user code is run in a separate thread by ppapi_simple, thus + allowing for blocking io to take place via nacl_io +*/ +#define SDL_MAIN_NEEDED + +#endif +#endif /* SDL_MAIN_HANDLED */ + +#ifndef SDLMAIN_DECLSPEC +#define SDLMAIN_DECLSPEC +#endif + +/** + * \file SDL_main.h + * + * The application's main() function must be called with C linkage, + * and should be declared like this: + * \code + * #ifdef __cplusplus + * extern "C" + * #endif + * int main(int argc, char *argv[]) + * { + * } + * \endcode + */ + +#if defined(SDL_MAIN_NEEDED) || defined(SDL_MAIN_AVAILABLE) +#define main SDL_main +#endif + +#include "begin_code.h" +#ifdef __cplusplus +extern "C" { +#endif + +/** + * The prototype for the application's main() function + */ +typedef int (*SDL_main_func)(int argc, char *argv[]); +extern SDLMAIN_DECLSPEC int SDL_main(int argc, char *argv[]); + + +/** + * This is called by the real SDL main function to let the rest of the + * library know that initialization was done properly. + * + * Calling this yourself without knowing what you're doing can cause + * crashes and hard to diagnose problems with your application. + */ +extern DECLSPEC void SDLCALL SDL_SetMainReady(void); + +#ifdef __WIN32__ + +/** + * This can be called to set the application class at startup + */ +extern DECLSPEC int SDLCALL SDL_RegisterApp(char *name, Uint32 style, void *hInst); +extern DECLSPEC void SDLCALL SDL_UnregisterApp(void); + +#endif /* __WIN32__ */ + + +#ifdef __WINRT__ + +/** + * \brief Initializes and launches an SDL/WinRT application. + * + * \param mainFunction The SDL app's C-style main(). + * \param reserved Reserved for future use; should be NULL + * \return 0 on success, -1 on failure. On failure, use SDL_GetError to retrieve more + * information on the failure. + */ +extern DECLSPEC int SDLCALL SDL_WinRTRunApp(SDL_main_func mainFunction, void * reserved); + +#endif /* __WINRT__ */ + +#if defined(__IPHONEOS__) + +/** + * \brief Initializes and launches an SDL application. + * + * \param argc The argc parameter from the application's main() function + * \param argv The argv parameter from the application's main() function + * \param mainFunction The SDL app's C-style main(). + * \return the return value from mainFunction + */ +extern DECLSPEC int SDLCALL SDL_UIKitRunApp(int argc, char *argv[], SDL_main_func mainFunction); + +#endif /* __IPHONEOS__ */ + + +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_main_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/engine/Windows/SDL2/include/SDL_messagebox.h b/engine/Windows/SDL2/include/SDL_messagebox.h new file mode 100644 index 0000000..bf50deb --- /dev/null +++ b/engine/Windows/SDL2/include/SDL_messagebox.h @@ -0,0 +1,146 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2019 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef SDL_messagebox_h_ +#define SDL_messagebox_h_ + +#include "SDL_stdinc.h" +#include "SDL_video.h" /* For SDL_Window */ + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief SDL_MessageBox flags. If supported will display warning icon, etc. + */ +typedef enum +{ + SDL_MESSAGEBOX_ERROR = 0x00000010, /**< error dialog */ + SDL_MESSAGEBOX_WARNING = 0x00000020, /**< warning dialog */ + SDL_MESSAGEBOX_INFORMATION = 0x00000040, /**< informational dialog */ + SDL_MESSAGEBOX_BUTTONS_LEFT_TO_RIGHT = 0x00000080, /**< buttons placed left to right */ + SDL_MESSAGEBOX_BUTTONS_RIGHT_TO_LEFT = 0x00000100 /**< buttons placed right to left */ +} SDL_MessageBoxFlags; + +/** + * \brief Flags for SDL_MessageBoxButtonData. + */ +typedef enum +{ + SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT = 0x00000001, /**< Marks the default button when return is hit */ + SDL_MESSAGEBOX_BUTTON_ESCAPEKEY_DEFAULT = 0x00000002 /**< Marks the default button when escape is hit */ +} SDL_MessageBoxButtonFlags; + +/** + * \brief Individual button data. + */ +typedef struct +{ + Uint32 flags; /**< ::SDL_MessageBoxButtonFlags */ + int buttonid; /**< User defined button id (value returned via SDL_ShowMessageBox) */ + const char * text; /**< The UTF-8 button text */ +} SDL_MessageBoxButtonData; + +/** + * \brief RGB value used in a message box color scheme + */ +typedef struct +{ + Uint8 r, g, b; +} SDL_MessageBoxColor; + +typedef enum +{ + SDL_MESSAGEBOX_COLOR_BACKGROUND, + SDL_MESSAGEBOX_COLOR_TEXT, + SDL_MESSAGEBOX_COLOR_BUTTON_BORDER, + SDL_MESSAGEBOX_COLOR_BUTTON_BACKGROUND, + SDL_MESSAGEBOX_COLOR_BUTTON_SELECTED, + SDL_MESSAGEBOX_COLOR_MAX +} SDL_MessageBoxColorType; + +/** + * \brief A set of colors to use for message box dialogs + */ +typedef struct +{ + SDL_MessageBoxColor colors[SDL_MESSAGEBOX_COLOR_MAX]; +} SDL_MessageBoxColorScheme; + +/** + * \brief MessageBox structure containing title, text, window, etc. + */ +typedef struct +{ + Uint32 flags; /**< ::SDL_MessageBoxFlags */ + SDL_Window *window; /**< Parent window, can be NULL */ + const char *title; /**< UTF-8 title */ + const char *message; /**< UTF-8 message text */ + + int numbuttons; + const SDL_MessageBoxButtonData *buttons; + + const SDL_MessageBoxColorScheme *colorScheme; /**< ::SDL_MessageBoxColorScheme, can be NULL to use system settings */ +} SDL_MessageBoxData; + +/** + * \brief Create a modal message box. + * + * \param messageboxdata The SDL_MessageBoxData structure with title, text, etc. + * \param buttonid The pointer to which user id of hit button should be copied. + * + * \return -1 on error, otherwise 0 and buttonid contains user id of button + * hit or -1 if dialog was closed. + * + * \note This function should be called on the thread that created the parent + * window, or on the main thread if the messagebox has no parent. It will + * block execution of that thread until the user clicks a button or + * closes the messagebox. + */ +extern DECLSPEC int SDLCALL SDL_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid); + +/** + * \brief Create a simple modal message box + * + * \param flags ::SDL_MessageBoxFlags + * \param title UTF-8 title text + * \param message UTF-8 message text + * \param window The parent window, or NULL for no parent + * + * \return 0 on success, -1 on error + * + * \sa SDL_ShowMessageBox + */ +extern DECLSPEC int SDLCALL SDL_ShowSimpleMessageBox(Uint32 flags, const char *title, const char *message, SDL_Window *window); + + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_messagebox_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/engine/Windows/SDL2/include/SDL_metal.h b/engine/Windows/SDL2/include/SDL_metal.h new file mode 100644 index 0000000..0f1e0e9 --- /dev/null +++ b/engine/Windows/SDL2/include/SDL_metal.h @@ -0,0 +1,91 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2019 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_metal.h + * + * Header file for functions to creating Metal layers and views on SDL windows. + */ + +#ifndef SDL_metal_h_ +#define SDL_metal_h_ + +#include "SDL_video.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief A handle to a CAMetalLayer-backed NSView (macOS) or UIView (iOS/tvOS). + * + * \note This can be cast directly to an NSView or UIView. + */ +typedef void *SDL_MetalView; + +/** + * \name Metal support functions + */ +/* @{ */ + +/** + * \brief Create a CAMetalLayer-backed NSView/UIView and attach it to the + * specified window. + * + * On macOS, this does *not* associate a MTLDevice with the CAMetalLayer on its + * own. It is up to user code to do that. + * + * The returned handle can be casted directly to a NSView or UIView, and the + * CAMetalLayer can be accessed from the view's 'layer' property. + * + * \code + * SDL_MetalView metalview = SDL_Metal_CreateView(window); + * UIView *uiview = (__bridge UIView *)metalview; + * CAMetalLayer *metallayer = (CAMetalLayer *)uiview.layer; + * // [...] + * SDL_Metal_DestroyView(metalview); + * \endcode + * + * \sa SDL_Metal_DestroyView + */ +extern DECLSPEC SDL_MetalView SDLCALL SDL_Metal_CreateView(SDL_Window * window); + +/** + * \brief Destroy an existing SDL_MetalView object. + * + * This should be called before SDL_DestroyWindow, if SDL_Metal_CreateView was + * called after SDL_CreateWindow. + * + * \sa SDL_Metal_CreateView + */ +extern DECLSPEC void SDLCALL SDL_Metal_DestroyView(SDL_MetalView view); + +/* @} *//* Metal support functions */ + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_metal_h_ */ diff --git a/engine/Windows/SDL2/include/SDL_mouse.h b/engine/Windows/SDL2/include/SDL_mouse.h new file mode 100644 index 0000000..277559d --- /dev/null +++ b/engine/Windows/SDL2/include/SDL_mouse.h @@ -0,0 +1,302 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2019 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_mouse.h + * + * Include file for SDL mouse event handling. + */ + +#ifndef SDL_mouse_h_ +#define SDL_mouse_h_ + +#include "SDL_stdinc.h" +#include "SDL_error.h" +#include "SDL_video.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct SDL_Cursor SDL_Cursor; /**< Implementation dependent */ + +/** + * \brief Cursor types for SDL_CreateSystemCursor(). + */ +typedef enum +{ + SDL_SYSTEM_CURSOR_ARROW, /**< Arrow */ + SDL_SYSTEM_CURSOR_IBEAM, /**< I-beam */ + SDL_SYSTEM_CURSOR_WAIT, /**< Wait */ + SDL_SYSTEM_CURSOR_CROSSHAIR, /**< Crosshair */ + SDL_SYSTEM_CURSOR_WAITARROW, /**< Small wait cursor (or Wait if not available) */ + SDL_SYSTEM_CURSOR_SIZENWSE, /**< Double arrow pointing northwest and southeast */ + SDL_SYSTEM_CURSOR_SIZENESW, /**< Double arrow pointing northeast and southwest */ + SDL_SYSTEM_CURSOR_SIZEWE, /**< Double arrow pointing west and east */ + SDL_SYSTEM_CURSOR_SIZENS, /**< Double arrow pointing north and south */ + SDL_SYSTEM_CURSOR_SIZEALL, /**< Four pointed arrow pointing north, south, east, and west */ + SDL_SYSTEM_CURSOR_NO, /**< Slashed circle or crossbones */ + SDL_SYSTEM_CURSOR_HAND, /**< Hand */ + SDL_NUM_SYSTEM_CURSORS +} SDL_SystemCursor; + +/** + * \brief Scroll direction types for the Scroll event + */ +typedef enum +{ + SDL_MOUSEWHEEL_NORMAL, /**< The scroll direction is normal */ + SDL_MOUSEWHEEL_FLIPPED /**< The scroll direction is flipped / natural */ +} SDL_MouseWheelDirection; + +/* Function prototypes */ + +/** + * \brief Get the window which currently has mouse focus. + */ +extern DECLSPEC SDL_Window * SDLCALL SDL_GetMouseFocus(void); + +/** + * \brief 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 cursor position relative to the focus window for the currently + * selected mouse. You can pass NULL for either x or y. + */ +extern DECLSPEC Uint32 SDLCALL SDL_GetMouseState(int *x, int *y); + +/** + * \brief Get the current state of the mouse, in relation to the desktop + * + * This works just like SDL_GetMouseState(), but the coordinates will be + * reported relative to the top-left of the desktop. This can be useful if + * you need to track the mouse outside of a specific window and + * SDL_CaptureMouse() doesn't fit your needs. For example, it could be + * useful if you need to track the mouse while dragging a window, where + * coordinates relative to a window might not be in sync at all times. + * + * \note SDL_GetMouseState() returns the mouse position as SDL understands + * it from the last pump of the event queue. This function, however, + * queries the OS for the current mouse position, and as such, might + * be a slightly less efficient function. Unless you know what you're + * doing and have a good reason to use this function, you probably want + * SDL_GetMouseState() instead. + * + * \param x Returns the current X coord, relative to the desktop. Can be NULL. + * \param y Returns the current Y coord, relative to the desktop. Can be NULL. + * \return The current button state as a bitmask, which can be tested using the SDL_BUTTON(X) macros. + * + * \sa SDL_GetMouseState + */ +extern DECLSPEC Uint32 SDLCALL SDL_GetGlobalMouseState(int *x, int *y); + +/** + * \brief Retrieve the relative 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(). + */ +extern DECLSPEC Uint32 SDLCALL SDL_GetRelativeMouseState(int *x, int *y); + +/** + * \brief Moves the mouse to the given position within the window. + * + * \param window The window to move the mouse into, or NULL for the current mouse focus + * \param x The x coordinate within the window + * \param y The y coordinate within the window + * + * \note This function generates a mouse motion event + */ +extern DECLSPEC void SDLCALL SDL_WarpMouseInWindow(SDL_Window * window, + int x, int y); + +/** + * \brief Moves the mouse to the given position in global screen space. + * + * \param x The x coordinate + * \param y The y coordinate + * \return 0 on success, -1 on error (usually: unsupported by a platform). + * + * \note This function generates a mouse motion event + */ +extern DECLSPEC int SDLCALL SDL_WarpMouseGlobal(int x, int y); + +/** + * \brief Set relative mouse mode. + * + * \param enabled Whether or not to enable relative mode + * + * \return 0 on success, or -1 if relative mode is not supported. + * + * While the mouse is in relative mode, the cursor is hidden, and the + * driver will try to report continuous motion in the current window. + * Only relative motion events will be delivered, the mouse position + * will not change. + * + * \note This function will flush any pending mouse motion. + * + * \sa SDL_GetRelativeMouseMode() + */ +extern DECLSPEC int SDLCALL SDL_SetRelativeMouseMode(SDL_bool enabled); + +/** + * \brief Capture the mouse, to track input outside an SDL window. + * + * \param enabled Whether or not to enable capturing + * + * Capturing enables your app to obtain mouse events globally, instead of + * just within your window. Not all video targets support this function. + * When capturing is enabled, the current window will get all mouse events, + * but unlike relative mode, no change is made to the cursor and it is + * not restrained to your window. + * + * This function may also deny mouse input to other windows--both those in + * your application and others on the system--so you should use this + * function sparingly, and in small bursts. For example, you might want to + * track the mouse while the user is dragging something, until the user + * releases a mouse button. It is not recommended that you capture the mouse + * for long periods of time, such as the entire time your app is running. + * + * While captured, mouse events still report coordinates relative to the + * current (foreground) window, but those coordinates may be outside the + * bounds of the window (including negative values). Capturing is only + * allowed for the foreground window. If the window loses focus while + * capturing, the capture will be disabled automatically. + * + * While capturing is enabled, the current window will have the + * SDL_WINDOW_MOUSE_CAPTURE flag set. + * + * \return 0 on success, or -1 if not supported. + */ +extern DECLSPEC int SDLCALL SDL_CaptureMouse(SDL_bool enabled); + +/** + * \brief Query whether relative mouse mode is enabled. + * + * \sa SDL_SetRelativeMouseMode() + */ +extern DECLSPEC SDL_bool SDLCALL SDL_GetRelativeMouseMode(void); + +/** + * \brief Create a cursor, using the specified bitmap 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.
+ * + * \sa SDL_FreeCursor() + */ +extern DECLSPEC SDL_Cursor *SDLCALL SDL_CreateCursor(const Uint8 * data, + const Uint8 * mask, + int w, int h, int hot_x, + int hot_y); + +/** + * \brief Create a color cursor. + * + * \sa SDL_FreeCursor() + */ +extern DECLSPEC SDL_Cursor *SDLCALL SDL_CreateColorCursor(SDL_Surface *surface, + int hot_x, + int hot_y); + +/** + * \brief Create a system cursor. + * + * \sa SDL_FreeCursor() + */ +extern DECLSPEC SDL_Cursor *SDLCALL SDL_CreateSystemCursor(SDL_SystemCursor id); + +/** + * \brief Set the active cursor. + */ +extern DECLSPEC void SDLCALL SDL_SetCursor(SDL_Cursor * cursor); + +/** + * \brief Return the active cursor. + */ +extern DECLSPEC SDL_Cursor *SDLCALL SDL_GetCursor(void); + +/** + * \brief Return the default cursor. + */ +extern DECLSPEC SDL_Cursor *SDLCALL SDL_GetDefaultCursor(void); + +/** + * \brief Frees a cursor created with SDL_CreateCursor() or similar functions. + * + * \sa SDL_CreateCursor() + * \sa SDL_CreateColorCursor() + * \sa SDL_CreateSystemCursor() + */ +extern DECLSPEC void SDLCALL SDL_FreeCursor(SDL_Cursor * cursor); + +/** + * \brief Toggle whether or not the cursor is shown. + * + * \param toggle 1 to show the cursor, 0 to hide it, -1 to query the current + * state. + * + * \return 1 if the cursor is shown, or 0 if the cursor is hidden. + */ +extern DECLSPEC int SDLCALL SDL_ShowCursor(int toggle); + +/** + * Used as a mask when testing buttons in buttonstate. + * - Button 1: Left mouse button + * - Button 2: Middle mouse button + * - Button 3: Right mouse button + */ +#define SDL_BUTTON(X) (1 << ((X)-1)) +#define SDL_BUTTON_LEFT 1 +#define SDL_BUTTON_MIDDLE 2 +#define SDL_BUTTON_RIGHT 3 +#define SDL_BUTTON_X1 4 +#define SDL_BUTTON_X2 5 +#define SDL_BUTTON_LMASK SDL_BUTTON(SDL_BUTTON_LEFT) +#define SDL_BUTTON_MMASK SDL_BUTTON(SDL_BUTTON_MIDDLE) +#define SDL_BUTTON_RMASK SDL_BUTTON(SDL_BUTTON_RIGHT) +#define SDL_BUTTON_X1MASK SDL_BUTTON(SDL_BUTTON_X1) +#define SDL_BUTTON_X2MASK SDL_BUTTON(SDL_BUTTON_X2) + + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_mouse_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/engine/Windows/SDL2/include/SDL_mutex.h b/engine/Windows/SDL2/include/SDL_mutex.h new file mode 100644 index 0000000..970e787 --- /dev/null +++ b/engine/Windows/SDL2/include/SDL_mutex.h @@ -0,0 +1,251 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2019 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef SDL_mutex_h_ +#define SDL_mutex_h_ + +/** + * \file SDL_mutex.h + * + * Functions to provide thread synchronization primitives. + */ + +#include "SDL_stdinc.h" +#include "SDL_error.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Synchronization functions which can time out return this value + * if they time out. + */ +#define SDL_MUTEX_TIMEDOUT 1 + +/** + * This is the timeout value which corresponds to never time out. + */ +#define SDL_MUTEX_MAXWAIT (~(Uint32)0) + + +/** + * \name Mutex functions + */ +/* @{ */ + +/* The SDL mutex structure, defined in SDL_sysmutex.c */ +struct SDL_mutex; +typedef struct SDL_mutex SDL_mutex; + +/** + * Create a mutex, initialized unlocked. + */ +extern DECLSPEC SDL_mutex *SDLCALL SDL_CreateMutex(void); + +/** + * Lock the mutex. + * + * \return 0, or -1 on error. + */ +#define SDL_mutexP(m) SDL_LockMutex(m) +extern DECLSPEC int SDLCALL SDL_LockMutex(SDL_mutex * mutex); + +/** + * Try to lock the mutex + * + * \return 0, SDL_MUTEX_TIMEDOUT, or -1 on error + */ +extern DECLSPEC int SDLCALL SDL_TryLockMutex(SDL_mutex * mutex); + +/** + * Unlock the mutex. + * + * \return 0, or -1 on error. + * + * \warning It is an error to unlock a mutex that has not been locked by + * the current thread, and doing so results in undefined behavior. + */ +#define SDL_mutexV(m) SDL_UnlockMutex(m) +extern DECLSPEC int SDLCALL SDL_UnlockMutex(SDL_mutex * mutex); + +/** + * Destroy a mutex. + */ +extern DECLSPEC void SDLCALL SDL_DestroyMutex(SDL_mutex * mutex); + +/* @} *//* Mutex functions */ + + +/** + * \name Semaphore functions + */ +/* @{ */ + +/* The SDL semaphore structure, defined in SDL_syssem.c */ +struct SDL_semaphore; +typedef struct SDL_semaphore SDL_sem; + +/** + * Create a semaphore, initialized with value, returns NULL on failure. + */ +extern DECLSPEC SDL_sem *SDLCALL SDL_CreateSemaphore(Uint32 initial_value); + +/** + * Destroy a semaphore. + */ +extern DECLSPEC void SDLCALL SDL_DestroySemaphore(SDL_sem * sem); + +/** + * This function suspends the calling thread until the semaphore pointed + * to by \c sem has a positive count. It then atomically decreases the + * semaphore count. + */ +extern DECLSPEC int SDLCALL SDL_SemWait(SDL_sem * sem); + +/** + * Non-blocking variant of SDL_SemWait(). + * + * \return 0 if the wait succeeds, ::SDL_MUTEX_TIMEDOUT if the wait would + * block, and -1 on error. + */ +extern DECLSPEC int SDLCALL SDL_SemTryWait(SDL_sem * sem); + +/** + * Variant of SDL_SemWait() with a timeout in milliseconds. + * + * \return 0 if the wait succeeds, ::SDL_MUTEX_TIMEDOUT if the wait does not + * succeed in the allotted time, and -1 on error. + * + * \warning On some platforms this function is implemented by looping with a + * delay of 1 ms, and so should be avoided if possible. + */ +extern DECLSPEC int SDLCALL SDL_SemWaitTimeout(SDL_sem * sem, Uint32 ms); + +/** + * Atomically increases the semaphore's count (not blocking). + * + * \return 0, or -1 on error. + */ +extern DECLSPEC int SDLCALL SDL_SemPost(SDL_sem * sem); + +/** + * Returns the current count of the semaphore. + */ +extern DECLSPEC Uint32 SDLCALL SDL_SemValue(SDL_sem * sem); + +/* @} *//* Semaphore functions */ + + +/** + * \name Condition variable functions + */ +/* @{ */ + +/* The SDL condition variable structure, defined in SDL_syscond.c */ +struct SDL_cond; +typedef struct SDL_cond SDL_cond; + +/** + * Create a condition variable. + * + * Typical use of condition variables: + * + * Thread A: + * SDL_LockMutex(lock); + * while ( ! condition ) { + * SDL_CondWait(cond, lock); + * } + * SDL_UnlockMutex(lock); + * + * Thread B: + * SDL_LockMutex(lock); + * ... + * condition = true; + * ... + * SDL_CondSignal(cond); + * SDL_UnlockMutex(lock); + * + * There is some discussion whether to signal the condition variable + * with the mutex locked or not. There is some potential performance + * benefit to unlocking first on some platforms, but there are some + * potential race conditions depending on how your code is structured. + * + * In general it's safer to signal the condition variable while the + * mutex is locked. + */ +extern DECLSPEC SDL_cond *SDLCALL SDL_CreateCond(void); + +/** + * Destroy a condition variable. + */ +extern DECLSPEC void SDLCALL SDL_DestroyCond(SDL_cond * cond); + +/** + * Restart one of the threads that are waiting on the condition variable. + * + * \return 0 or -1 on error. + */ +extern DECLSPEC int SDLCALL SDL_CondSignal(SDL_cond * cond); + +/** + * Restart all threads that are waiting on the condition variable. + * + * \return 0 or -1 on error. + */ +extern DECLSPEC int SDLCALL SDL_CondBroadcast(SDL_cond * cond); + +/** + * Wait on the condition variable, unlocking the provided mutex. + * + * \warning The mutex must be locked before entering this function! + * + * The mutex is re-locked once the condition variable is signaled. + * + * \return 0 when it is signaled, or -1 on error. + */ +extern DECLSPEC int SDLCALL SDL_CondWait(SDL_cond * cond, SDL_mutex * mutex); + +/** + * Waits for at most \c 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. + * + * \warning On some platforms this function is implemented by looping with a + * delay of 1 ms, and so should be avoided if possible. + */ +extern DECLSPEC int SDLCALL SDL_CondWaitTimeout(SDL_cond * cond, + SDL_mutex * mutex, Uint32 ms); + +/* @} *//* Condition variable functions */ + + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_mutex_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/engine/Windows/SDL2/include/SDL_name.h b/engine/Windows/SDL2/include/SDL_name.h new file mode 100644 index 0000000..690a819 --- /dev/null +++ b/engine/Windows/SDL2/include/SDL_name.h @@ -0,0 +1,33 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2019 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef SDLname_h_ +#define SDLname_h_ + +#if defined(__STDC__) || defined(__cplusplus) +#define NeedFunctionPrototypes 1 +#endif + +#define SDL_NAME(X) SDL_##X + +#endif /* SDLname_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/engine/Windows/SDL2/include/SDL_opengl.h b/engine/Windows/SDL2/include/SDL_opengl.h new file mode 100644 index 0000000..6685be7 --- /dev/null +++ b/engine/Windows/SDL2/include/SDL_opengl.h @@ -0,0 +1,2183 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2019 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_opengl.h + * + * This is a simple file to encapsulate the OpenGL API headers. + */ + +/** + * \def NO_SDL_GLEXT + * + * Define this if you have your own version of glext.h and want to disable the + * version included in SDL_opengl.h. + */ + +#ifndef SDL_opengl_h_ +#define SDL_opengl_h_ + +#include "SDL_config.h" + +#ifndef __IPHONEOS__ /* No OpenGL on iOS. */ + +/* + * Mesa 3-D graphics library + * + * Copyright (C) 1999-2006 Brian Paul All Rights Reserved. + * Copyright (C) 2009 VMware, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + + +#ifndef __gl_h_ +#define __gl_h_ + +#if defined(USE_MGL_NAMESPACE) +#include "gl_mangle.h" +#endif + + +/********************************************************************** + * Begin system-specific stuff. + */ + +#if defined(_WIN32) && !defined(__WIN32__) && !defined(__CYGWIN__) +#define __WIN32__ +#endif + +#if defined(__WIN32__) && !defined(__CYGWIN__) +# if (defined(_MSC_VER) || defined(__MINGW32__)) && defined(BUILD_GL32) /* tag specify we're building mesa as a DLL */ +# define GLAPI __declspec(dllexport) +# elif (defined(_MSC_VER) || defined(__MINGW32__)) && defined(_DLL) /* tag specifying we're building for DLL runtime support */ +# define GLAPI __declspec(dllimport) +# else /* for use with static link lib build of Win32 edition only */ +# define GLAPI extern +# endif /* _STATIC_MESA support */ +# if defined(__MINGW32__) && defined(GL_NO_STDCALL) || defined(UNDER_CE) /* The generated DLLs by MingW with STDCALL are not compatible with the ones done by Microsoft's compilers */ +# define GLAPIENTRY +# else +# define GLAPIENTRY __stdcall +# endif +#elif defined(__CYGWIN__) && defined(USE_OPENGL32) /* use native windows opengl32 */ +# define GLAPI extern +# define GLAPIENTRY __stdcall +#elif defined(__OS2__) || defined(__EMX__) /* native os/2 opengl */ +# define GLAPI extern +# define GLAPIENTRY _System +# define APIENTRY _System +# if defined(__GNUC__) && !defined(_System) +# define _System +# endif +#elif (defined(__GNUC__) && __GNUC__ >= 4) || (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x590)) +# define GLAPI __attribute__((visibility("default"))) +# define GLAPIENTRY +#endif /* WIN32 && !CYGWIN */ + +/* + * WINDOWS: Include windows.h here to define APIENTRY. + * It is also useful when applications include this file by + * including only glut.h, since glut.h depends on windows.h. + * Applications needing to include windows.h with parms other + * than "WIN32_LEAN_AND_MEAN" may include windows.h before + * glut.h or gl.h. + */ +#if defined(_WIN32) && !defined(APIENTRY) && !defined(__CYGWIN__) +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN 1 +#endif +#ifndef NOMINMAX /* don't define min() and max(). */ +#define NOMINMAX +#endif +#include +#endif + +#ifndef GLAPI +#define GLAPI extern +#endif + +#ifndef GLAPIENTRY +#define GLAPIENTRY +#endif + +#ifndef APIENTRY +#define APIENTRY GLAPIENTRY +#endif + +/* "P" suffix to be used for a pointer to a function */ +#ifndef APIENTRYP +#define APIENTRYP APIENTRY * +#endif + +#ifndef GLAPIENTRYP +#define GLAPIENTRYP GLAPIENTRY * +#endif + +#if defined(PRAGMA_EXPORT_SUPPORTED) +#pragma export on +#endif + +/* + * End system-specific stuff. + **********************************************************************/ + + + +#ifdef __cplusplus +extern "C" { +#endif + + + +#define GL_VERSION_1_1 1 +#define GL_VERSION_1_2 1 +#define GL_VERSION_1_3 1 +#define GL_ARB_imaging 1 + + +/* + * Datatypes + */ +typedef unsigned int GLenum; +typedef unsigned char GLboolean; +typedef unsigned int GLbitfield; +typedef void GLvoid; +typedef signed char GLbyte; /* 1-byte signed */ +typedef short GLshort; /* 2-byte signed */ +typedef int GLint; /* 4-byte signed */ +typedef unsigned char GLubyte; /* 1-byte unsigned */ +typedef unsigned short GLushort; /* 2-byte unsigned */ +typedef unsigned int GLuint; /* 4-byte unsigned */ +typedef int GLsizei; /* 4-byte signed */ +typedef float GLfloat; /* single precision float */ +typedef float GLclampf; /* single precision float in [0,1] */ +typedef double GLdouble; /* double precision float */ +typedef double GLclampd; /* double precision float in [0,1] */ + + + +/* + * Constants + */ + +/* Boolean values */ +#define GL_FALSE 0 +#define GL_TRUE 1 + +/* Data types */ +#define GL_BYTE 0x1400 +#define GL_UNSIGNED_BYTE 0x1401 +#define GL_SHORT 0x1402 +#define GL_UNSIGNED_SHORT 0x1403 +#define GL_INT 0x1404 +#define GL_UNSIGNED_INT 0x1405 +#define GL_FLOAT 0x1406 +#define GL_2_BYTES 0x1407 +#define GL_3_BYTES 0x1408 +#define GL_4_BYTES 0x1409 +#define GL_DOUBLE 0x140A + +/* Primitives */ +#define GL_POINTS 0x0000 +#define GL_LINES 0x0001 +#define GL_LINE_LOOP 0x0002 +#define GL_LINE_STRIP 0x0003 +#define GL_TRIANGLES 0x0004 +#define GL_TRIANGLE_STRIP 0x0005 +#define GL_TRIANGLE_FAN 0x0006 +#define GL_QUADS 0x0007 +#define GL_QUAD_STRIP 0x0008 +#define GL_POLYGON 0x0009 + +/* Vertex Arrays */ +#define GL_VERTEX_ARRAY 0x8074 +#define GL_NORMAL_ARRAY 0x8075 +#define GL_COLOR_ARRAY 0x8076 +#define GL_INDEX_ARRAY 0x8077 +#define GL_TEXTURE_COORD_ARRAY 0x8078 +#define GL_EDGE_FLAG_ARRAY 0x8079 +#define GL_VERTEX_ARRAY_SIZE 0x807A +#define GL_VERTEX_ARRAY_TYPE 0x807B +#define GL_VERTEX_ARRAY_STRIDE 0x807C +#define GL_NORMAL_ARRAY_TYPE 0x807E +#define GL_NORMAL_ARRAY_STRIDE 0x807F +#define GL_COLOR_ARRAY_SIZE 0x8081 +#define GL_COLOR_ARRAY_TYPE 0x8082 +#define GL_COLOR_ARRAY_STRIDE 0x8083 +#define GL_INDEX_ARRAY_TYPE 0x8085 +#define GL_INDEX_ARRAY_STRIDE 0x8086 +#define GL_TEXTURE_COORD_ARRAY_SIZE 0x8088 +#define GL_TEXTURE_COORD_ARRAY_TYPE 0x8089 +#define GL_TEXTURE_COORD_ARRAY_STRIDE 0x808A +#define GL_EDGE_FLAG_ARRAY_STRIDE 0x808C +#define GL_VERTEX_ARRAY_POINTER 0x808E +#define GL_NORMAL_ARRAY_POINTER 0x808F +#define GL_COLOR_ARRAY_POINTER 0x8090 +#define GL_INDEX_ARRAY_POINTER 0x8091 +#define GL_TEXTURE_COORD_ARRAY_POINTER 0x8092 +#define GL_EDGE_FLAG_ARRAY_POINTER 0x8093 +#define GL_V2F 0x2A20 +#define GL_V3F 0x2A21 +#define GL_C4UB_V2F 0x2A22 +#define GL_C4UB_V3F 0x2A23 +#define GL_C3F_V3F 0x2A24 +#define GL_N3F_V3F 0x2A25 +#define GL_C4F_N3F_V3F 0x2A26 +#define GL_T2F_V3F 0x2A27 +#define GL_T4F_V4F 0x2A28 +#define GL_T2F_C4UB_V3F 0x2A29 +#define GL_T2F_C3F_V3F 0x2A2A +#define GL_T2F_N3F_V3F 0x2A2B +#define GL_T2F_C4F_N3F_V3F 0x2A2C +#define GL_T4F_C4F_N3F_V4F 0x2A2D + +/* Matrix Mode */ +#define GL_MATRIX_MODE 0x0BA0 +#define GL_MODELVIEW 0x1700 +#define GL_PROJECTION 0x1701 +#define GL_TEXTURE 0x1702 + +/* Points */ +#define GL_POINT_SMOOTH 0x0B10 +#define GL_POINT_SIZE 0x0B11 +#define GL_POINT_SIZE_GRANULARITY 0x0B13 +#define GL_POINT_SIZE_RANGE 0x0B12 + +/* Lines */ +#define GL_LINE_SMOOTH 0x0B20 +#define GL_LINE_STIPPLE 0x0B24 +#define GL_LINE_STIPPLE_PATTERN 0x0B25 +#define GL_LINE_STIPPLE_REPEAT 0x0B26 +#define GL_LINE_WIDTH 0x0B21 +#define GL_LINE_WIDTH_GRANULARITY 0x0B23 +#define GL_LINE_WIDTH_RANGE 0x0B22 + +/* Polygons */ +#define GL_POINT 0x1B00 +#define GL_LINE 0x1B01 +#define GL_FILL 0x1B02 +#define GL_CW 0x0900 +#define GL_CCW 0x0901 +#define GL_FRONT 0x0404 +#define GL_BACK 0x0405 +#define GL_POLYGON_MODE 0x0B40 +#define GL_POLYGON_SMOOTH 0x0B41 +#define GL_POLYGON_STIPPLE 0x0B42 +#define GL_EDGE_FLAG 0x0B43 +#define GL_CULL_FACE 0x0B44 +#define GL_CULL_FACE_MODE 0x0B45 +#define GL_FRONT_FACE 0x0B46 +#define GL_POLYGON_OFFSET_FACTOR 0x8038 +#define GL_POLYGON_OFFSET_UNITS 0x2A00 +#define GL_POLYGON_OFFSET_POINT 0x2A01 +#define GL_POLYGON_OFFSET_LINE 0x2A02 +#define GL_POLYGON_OFFSET_FILL 0x8037 + +/* Display Lists */ +#define GL_COMPILE 0x1300 +#define GL_COMPILE_AND_EXECUTE 0x1301 +#define GL_LIST_BASE 0x0B32 +#define GL_LIST_INDEX 0x0B33 +#define GL_LIST_MODE 0x0B30 + +/* Depth buffer */ +#define GL_NEVER 0x0200 +#define GL_LESS 0x0201 +#define GL_EQUAL 0x0202 +#define GL_LEQUAL 0x0203 +#define GL_GREATER 0x0204 +#define GL_NOTEQUAL 0x0205 +#define GL_GEQUAL 0x0206 +#define GL_ALWAYS 0x0207 +#define GL_DEPTH_TEST 0x0B71 +#define GL_DEPTH_BITS 0x0D56 +#define GL_DEPTH_CLEAR_VALUE 0x0B73 +#define GL_DEPTH_FUNC 0x0B74 +#define GL_DEPTH_RANGE 0x0B70 +#define GL_DEPTH_WRITEMASK 0x0B72 +#define GL_DEPTH_COMPONENT 0x1902 + +/* Lighting */ +#define GL_LIGHTING 0x0B50 +#define GL_LIGHT0 0x4000 +#define GL_LIGHT1 0x4001 +#define GL_LIGHT2 0x4002 +#define GL_LIGHT3 0x4003 +#define GL_LIGHT4 0x4004 +#define GL_LIGHT5 0x4005 +#define GL_LIGHT6 0x4006 +#define GL_LIGHT7 0x4007 +#define GL_SPOT_EXPONENT 0x1205 +#define GL_SPOT_CUTOFF 0x1206 +#define GL_CONSTANT_ATTENUATION 0x1207 +#define GL_LINEAR_ATTENUATION 0x1208 +#define GL_QUADRATIC_ATTENUATION 0x1209 +#define GL_AMBIENT 0x1200 +#define GL_DIFFUSE 0x1201 +#define GL_SPECULAR 0x1202 +#define GL_SHININESS 0x1601 +#define GL_EMISSION 0x1600 +#define GL_POSITION 0x1203 +#define GL_SPOT_DIRECTION 0x1204 +#define GL_AMBIENT_AND_DIFFUSE 0x1602 +#define GL_COLOR_INDEXES 0x1603 +#define GL_LIGHT_MODEL_TWO_SIDE 0x0B52 +#define GL_LIGHT_MODEL_LOCAL_VIEWER 0x0B51 +#define GL_LIGHT_MODEL_AMBIENT 0x0B53 +#define GL_FRONT_AND_BACK 0x0408 +#define GL_SHADE_MODEL 0x0B54 +#define GL_FLAT 0x1D00 +#define GL_SMOOTH 0x1D01 +#define GL_COLOR_MATERIAL 0x0B57 +#define GL_COLOR_MATERIAL_FACE 0x0B55 +#define GL_COLOR_MATERIAL_PARAMETER 0x0B56 +#define GL_NORMALIZE 0x0BA1 + +/* User clipping planes */ +#define GL_CLIP_PLANE0 0x3000 +#define GL_CLIP_PLANE1 0x3001 +#define GL_CLIP_PLANE2 0x3002 +#define GL_CLIP_PLANE3 0x3003 +#define GL_CLIP_PLANE4 0x3004 +#define GL_CLIP_PLANE5 0x3005 + +/* Accumulation buffer */ +#define GL_ACCUM_RED_BITS 0x0D58 +#define GL_ACCUM_GREEN_BITS 0x0D59 +#define GL_ACCUM_BLUE_BITS 0x0D5A +#define GL_ACCUM_ALPHA_BITS 0x0D5B +#define GL_ACCUM_CLEAR_VALUE 0x0B80 +#define GL_ACCUM 0x0100 +#define GL_ADD 0x0104 +#define GL_LOAD 0x0101 +#define GL_MULT 0x0103 +#define GL_RETURN 0x0102 + +/* Alpha testing */ +#define GL_ALPHA_TEST 0x0BC0 +#define GL_ALPHA_TEST_REF 0x0BC2 +#define GL_ALPHA_TEST_FUNC 0x0BC1 + +/* Blending */ +#define GL_BLEND 0x0BE2 +#define GL_BLEND_SRC 0x0BE1 +#define GL_BLEND_DST 0x0BE0 +#define GL_ZERO 0 +#define GL_ONE 1 +#define GL_SRC_COLOR 0x0300 +#define GL_ONE_MINUS_SRC_COLOR 0x0301 +#define GL_SRC_ALPHA 0x0302 +#define GL_ONE_MINUS_SRC_ALPHA 0x0303 +#define GL_DST_ALPHA 0x0304 +#define GL_ONE_MINUS_DST_ALPHA 0x0305 +#define GL_DST_COLOR 0x0306 +#define GL_ONE_MINUS_DST_COLOR 0x0307 +#define GL_SRC_ALPHA_SATURATE 0x0308 + +/* Render Mode */ +#define GL_FEEDBACK 0x1C01 +#define GL_RENDER 0x1C00 +#define GL_SELECT 0x1C02 + +/* Feedback */ +#define GL_2D 0x0600 +#define GL_3D 0x0601 +#define GL_3D_COLOR 0x0602 +#define GL_3D_COLOR_TEXTURE 0x0603 +#define GL_4D_COLOR_TEXTURE 0x0604 +#define GL_POINT_TOKEN 0x0701 +#define GL_LINE_TOKEN 0x0702 +#define GL_LINE_RESET_TOKEN 0x0707 +#define GL_POLYGON_TOKEN 0x0703 +#define GL_BITMAP_TOKEN 0x0704 +#define GL_DRAW_PIXEL_TOKEN 0x0705 +#define GL_COPY_PIXEL_TOKEN 0x0706 +#define GL_PASS_THROUGH_TOKEN 0x0700 +#define GL_FEEDBACK_BUFFER_POINTER 0x0DF0 +#define GL_FEEDBACK_BUFFER_SIZE 0x0DF1 +#define GL_FEEDBACK_BUFFER_TYPE 0x0DF2 + +/* Selection */ +#define GL_SELECTION_BUFFER_POINTER 0x0DF3 +#define GL_SELECTION_BUFFER_SIZE 0x0DF4 + +/* Fog */ +#define GL_FOG 0x0B60 +#define GL_FOG_MODE 0x0B65 +#define GL_FOG_DENSITY 0x0B62 +#define GL_FOG_COLOR 0x0B66 +#define GL_FOG_INDEX 0x0B61 +#define GL_FOG_START 0x0B63 +#define GL_FOG_END 0x0B64 +#define GL_LINEAR 0x2601 +#define GL_EXP 0x0800 +#define GL_EXP2 0x0801 + +/* Logic Ops */ +#define GL_LOGIC_OP 0x0BF1 +#define GL_INDEX_LOGIC_OP 0x0BF1 +#define GL_COLOR_LOGIC_OP 0x0BF2 +#define GL_LOGIC_OP_MODE 0x0BF0 +#define GL_CLEAR 0x1500 +#define GL_SET 0x150F +#define GL_COPY 0x1503 +#define GL_COPY_INVERTED 0x150C +#define GL_NOOP 0x1505 +#define GL_INVERT 0x150A +#define GL_AND 0x1501 +#define GL_NAND 0x150E +#define GL_OR 0x1507 +#define GL_NOR 0x1508 +#define GL_XOR 0x1506 +#define GL_EQUIV 0x1509 +#define GL_AND_REVERSE 0x1502 +#define GL_AND_INVERTED 0x1504 +#define GL_OR_REVERSE 0x150B +#define GL_OR_INVERTED 0x150D + +/* Stencil */ +#define GL_STENCIL_BITS 0x0D57 +#define GL_STENCIL_TEST 0x0B90 +#define GL_STENCIL_CLEAR_VALUE 0x0B91 +#define GL_STENCIL_FUNC 0x0B92 +#define GL_STENCIL_VALUE_MASK 0x0B93 +#define GL_STENCIL_FAIL 0x0B94 +#define GL_STENCIL_PASS_DEPTH_FAIL 0x0B95 +#define GL_STENCIL_PASS_DEPTH_PASS 0x0B96 +#define GL_STENCIL_REF 0x0B97 +#define GL_STENCIL_WRITEMASK 0x0B98 +#define GL_STENCIL_INDEX 0x1901 +#define GL_KEEP 0x1E00 +#define GL_REPLACE 0x1E01 +#define GL_INCR 0x1E02 +#define GL_DECR 0x1E03 + +/* Buffers, Pixel Drawing/Reading */ +#define GL_NONE 0 +#define GL_LEFT 0x0406 +#define GL_RIGHT 0x0407 +/*GL_FRONT 0x0404 */ +/*GL_BACK 0x0405 */ +/*GL_FRONT_AND_BACK 0x0408 */ +#define GL_FRONT_LEFT 0x0400 +#define GL_FRONT_RIGHT 0x0401 +#define GL_BACK_LEFT 0x0402 +#define GL_BACK_RIGHT 0x0403 +#define GL_AUX0 0x0409 +#define GL_AUX1 0x040A +#define GL_AUX2 0x040B +#define GL_AUX3 0x040C +#define GL_COLOR_INDEX 0x1900 +#define GL_RED 0x1903 +#define GL_GREEN 0x1904 +#define GL_BLUE 0x1905 +#define GL_ALPHA 0x1906 +#define GL_LUMINANCE 0x1909 +#define GL_LUMINANCE_ALPHA 0x190A +#define GL_ALPHA_BITS 0x0D55 +#define GL_RED_BITS 0x0D52 +#define GL_GREEN_BITS 0x0D53 +#define GL_BLUE_BITS 0x0D54 +#define GL_INDEX_BITS 0x0D51 +#define GL_SUBPIXEL_BITS 0x0D50 +#define GL_AUX_BUFFERS 0x0C00 +#define GL_READ_BUFFER 0x0C02 +#define GL_DRAW_BUFFER 0x0C01 +#define GL_DOUBLEBUFFER 0x0C32 +#define GL_STEREO 0x0C33 +#define GL_BITMAP 0x1A00 +#define GL_COLOR 0x1800 +#define GL_DEPTH 0x1801 +#define GL_STENCIL 0x1802 +#define GL_DITHER 0x0BD0 +#define GL_RGB 0x1907 +#define GL_RGBA 0x1908 + +/* Implementation limits */ +#define GL_MAX_LIST_NESTING 0x0B31 +#define GL_MAX_EVAL_ORDER 0x0D30 +#define GL_MAX_LIGHTS 0x0D31 +#define GL_MAX_CLIP_PLANES 0x0D32 +#define GL_MAX_TEXTURE_SIZE 0x0D33 +#define GL_MAX_PIXEL_MAP_TABLE 0x0D34 +#define GL_MAX_ATTRIB_STACK_DEPTH 0x0D35 +#define GL_MAX_MODELVIEW_STACK_DEPTH 0x0D36 +#define GL_MAX_NAME_STACK_DEPTH 0x0D37 +#define GL_MAX_PROJECTION_STACK_DEPTH 0x0D38 +#define GL_MAX_TEXTURE_STACK_DEPTH 0x0D39 +#define GL_MAX_VIEWPORT_DIMS 0x0D3A +#define GL_MAX_CLIENT_ATTRIB_STACK_DEPTH 0x0D3B + +/* Gets */ +#define GL_ATTRIB_STACK_DEPTH 0x0BB0 +#define GL_CLIENT_ATTRIB_STACK_DEPTH 0x0BB1 +#define GL_COLOR_CLEAR_VALUE 0x0C22 +#define GL_COLOR_WRITEMASK 0x0C23 +#define GL_CURRENT_INDEX 0x0B01 +#define GL_CURRENT_COLOR 0x0B00 +#define GL_CURRENT_NORMAL 0x0B02 +#define GL_CURRENT_RASTER_COLOR 0x0B04 +#define GL_CURRENT_RASTER_DISTANCE 0x0B09 +#define GL_CURRENT_RASTER_INDEX 0x0B05 +#define GL_CURRENT_RASTER_POSITION 0x0B07 +#define GL_CURRENT_RASTER_TEXTURE_COORDS 0x0B06 +#define GL_CURRENT_RASTER_POSITION_VALID 0x0B08 +#define GL_CURRENT_TEXTURE_COORDS 0x0B03 +#define GL_INDEX_CLEAR_VALUE 0x0C20 +#define GL_INDEX_MODE 0x0C30 +#define GL_INDEX_WRITEMASK 0x0C21 +#define GL_MODELVIEW_MATRIX 0x0BA6 +#define GL_MODELVIEW_STACK_DEPTH 0x0BA3 +#define GL_NAME_STACK_DEPTH 0x0D70 +#define GL_PROJECTION_MATRIX 0x0BA7 +#define GL_PROJECTION_STACK_DEPTH 0x0BA4 +#define GL_RENDER_MODE 0x0C40 +#define GL_RGBA_MODE 0x0C31 +#define GL_TEXTURE_MATRIX 0x0BA8 +#define GL_TEXTURE_STACK_DEPTH 0x0BA5 +#define GL_VIEWPORT 0x0BA2 + +/* Evaluators */ +#define GL_AUTO_NORMAL 0x0D80 +#define GL_MAP1_COLOR_4 0x0D90 +#define GL_MAP1_INDEX 0x0D91 +#define GL_MAP1_NORMAL 0x0D92 +#define GL_MAP1_TEXTURE_COORD_1 0x0D93 +#define GL_MAP1_TEXTURE_COORD_2 0x0D94 +#define GL_MAP1_TEXTURE_COORD_3 0x0D95 +#define GL_MAP1_TEXTURE_COORD_4 0x0D96 +#define GL_MAP1_VERTEX_3 0x0D97 +#define GL_MAP1_VERTEX_4 0x0D98 +#define GL_MAP2_COLOR_4 0x0DB0 +#define GL_MAP2_INDEX 0x0DB1 +#define GL_MAP2_NORMAL 0x0DB2 +#define GL_MAP2_TEXTURE_COORD_1 0x0DB3 +#define GL_MAP2_TEXTURE_COORD_2 0x0DB4 +#define GL_MAP2_TEXTURE_COORD_3 0x0DB5 +#define GL_MAP2_TEXTURE_COORD_4 0x0DB6 +#define GL_MAP2_VERTEX_3 0x0DB7 +#define GL_MAP2_VERTEX_4 0x0DB8 +#define GL_MAP1_GRID_DOMAIN 0x0DD0 +#define GL_MAP1_GRID_SEGMENTS 0x0DD1 +#define GL_MAP2_GRID_DOMAIN 0x0DD2 +#define GL_MAP2_GRID_SEGMENTS 0x0DD3 +#define GL_COEFF 0x0A00 +#define GL_ORDER 0x0A01 +#define GL_DOMAIN 0x0A02 + +/* Hints */ +#define GL_PERSPECTIVE_CORRECTION_HINT 0x0C50 +#define GL_POINT_SMOOTH_HINT 0x0C51 +#define GL_LINE_SMOOTH_HINT 0x0C52 +#define GL_POLYGON_SMOOTH_HINT 0x0C53 +#define GL_FOG_HINT 0x0C54 +#define GL_DONT_CARE 0x1100 +#define GL_FASTEST 0x1101 +#define GL_NICEST 0x1102 + +/* Scissor box */ +#define GL_SCISSOR_BOX 0x0C10 +#define GL_SCISSOR_TEST 0x0C11 + +/* Pixel Mode / Transfer */ +#define GL_MAP_COLOR 0x0D10 +#define GL_MAP_STENCIL 0x0D11 +#define GL_INDEX_SHIFT 0x0D12 +#define GL_INDEX_OFFSET 0x0D13 +#define GL_RED_SCALE 0x0D14 +#define GL_RED_BIAS 0x0D15 +#define GL_GREEN_SCALE 0x0D18 +#define GL_GREEN_BIAS 0x0D19 +#define GL_BLUE_SCALE 0x0D1A +#define GL_BLUE_BIAS 0x0D1B +#define GL_ALPHA_SCALE 0x0D1C +#define GL_ALPHA_BIAS 0x0D1D +#define GL_DEPTH_SCALE 0x0D1E +#define GL_DEPTH_BIAS 0x0D1F +#define GL_PIXEL_MAP_S_TO_S_SIZE 0x0CB1 +#define GL_PIXEL_MAP_I_TO_I_SIZE 0x0CB0 +#define GL_PIXEL_MAP_I_TO_R_SIZE 0x0CB2 +#define GL_PIXEL_MAP_I_TO_G_SIZE 0x0CB3 +#define GL_PIXEL_MAP_I_TO_B_SIZE 0x0CB4 +#define GL_PIXEL_MAP_I_TO_A_SIZE 0x0CB5 +#define GL_PIXEL_MAP_R_TO_R_SIZE 0x0CB6 +#define GL_PIXEL_MAP_G_TO_G_SIZE 0x0CB7 +#define GL_PIXEL_MAP_B_TO_B_SIZE 0x0CB8 +#define GL_PIXEL_MAP_A_TO_A_SIZE 0x0CB9 +#define GL_PIXEL_MAP_S_TO_S 0x0C71 +#define GL_PIXEL_MAP_I_TO_I 0x0C70 +#define GL_PIXEL_MAP_I_TO_R 0x0C72 +#define GL_PIXEL_MAP_I_TO_G 0x0C73 +#define GL_PIXEL_MAP_I_TO_B 0x0C74 +#define GL_PIXEL_MAP_I_TO_A 0x0C75 +#define GL_PIXEL_MAP_R_TO_R 0x0C76 +#define GL_PIXEL_MAP_G_TO_G 0x0C77 +#define GL_PIXEL_MAP_B_TO_B 0x0C78 +#define GL_PIXEL_MAP_A_TO_A 0x0C79 +#define GL_PACK_ALIGNMENT 0x0D05 +#define GL_PACK_LSB_FIRST 0x0D01 +#define GL_PACK_ROW_LENGTH 0x0D02 +#define GL_PACK_SKIP_PIXELS 0x0D04 +#define GL_PACK_SKIP_ROWS 0x0D03 +#define GL_PACK_SWAP_BYTES 0x0D00 +#define GL_UNPACK_ALIGNMENT 0x0CF5 +#define GL_UNPACK_LSB_FIRST 0x0CF1 +#define GL_UNPACK_ROW_LENGTH 0x0CF2 +#define GL_UNPACK_SKIP_PIXELS 0x0CF4 +#define GL_UNPACK_SKIP_ROWS 0x0CF3 +#define GL_UNPACK_SWAP_BYTES 0x0CF0 +#define GL_ZOOM_X 0x0D16 +#define GL_ZOOM_Y 0x0D17 + +/* Texture mapping */ +#define GL_TEXTURE_ENV 0x2300 +#define GL_TEXTURE_ENV_MODE 0x2200 +#define GL_TEXTURE_1D 0x0DE0 +#define GL_TEXTURE_2D 0x0DE1 +#define GL_TEXTURE_WRAP_S 0x2802 +#define GL_TEXTURE_WRAP_T 0x2803 +#define GL_TEXTURE_MAG_FILTER 0x2800 +#define GL_TEXTURE_MIN_FILTER 0x2801 +#define GL_TEXTURE_ENV_COLOR 0x2201 +#define GL_TEXTURE_GEN_S 0x0C60 +#define GL_TEXTURE_GEN_T 0x0C61 +#define GL_TEXTURE_GEN_R 0x0C62 +#define GL_TEXTURE_GEN_Q 0x0C63 +#define GL_TEXTURE_GEN_MODE 0x2500 +#define GL_TEXTURE_BORDER_COLOR 0x1004 +#define GL_TEXTURE_WIDTH 0x1000 +#define GL_TEXTURE_HEIGHT 0x1001 +#define GL_TEXTURE_BORDER 0x1005 +#define GL_TEXTURE_COMPONENTS 0x1003 +#define GL_TEXTURE_RED_SIZE 0x805C +#define GL_TEXTURE_GREEN_SIZE 0x805D +#define GL_TEXTURE_BLUE_SIZE 0x805E +#define GL_TEXTURE_ALPHA_SIZE 0x805F +#define GL_TEXTURE_LUMINANCE_SIZE 0x8060 +#define GL_TEXTURE_INTENSITY_SIZE 0x8061 +#define GL_NEAREST_MIPMAP_NEAREST 0x2700 +#define GL_NEAREST_MIPMAP_LINEAR 0x2702 +#define GL_LINEAR_MIPMAP_NEAREST 0x2701 +#define GL_LINEAR_MIPMAP_LINEAR 0x2703 +#define GL_OBJECT_LINEAR 0x2401 +#define GL_OBJECT_PLANE 0x2501 +#define GL_EYE_LINEAR 0x2400 +#define GL_EYE_PLANE 0x2502 +#define GL_SPHERE_MAP 0x2402 +#define GL_DECAL 0x2101 +#define GL_MODULATE 0x2100 +#define GL_NEAREST 0x2600 +#define GL_REPEAT 0x2901 +#define GL_CLAMP 0x2900 +#define GL_S 0x2000 +#define GL_T 0x2001 +#define GL_R 0x2002 +#define GL_Q 0x2003 + +/* Utility */ +#define GL_VENDOR 0x1F00 +#define GL_RENDERER 0x1F01 +#define GL_VERSION 0x1F02 +#define GL_EXTENSIONS 0x1F03 + +/* Errors */ +#define GL_NO_ERROR 0 +#define GL_INVALID_ENUM 0x0500 +#define GL_INVALID_VALUE 0x0501 +#define GL_INVALID_OPERATION 0x0502 +#define GL_STACK_OVERFLOW 0x0503 +#define GL_STACK_UNDERFLOW 0x0504 +#define GL_OUT_OF_MEMORY 0x0505 + +/* glPush/PopAttrib bits */ +#define GL_CURRENT_BIT 0x00000001 +#define GL_POINT_BIT 0x00000002 +#define GL_LINE_BIT 0x00000004 +#define GL_POLYGON_BIT 0x00000008 +#define GL_POLYGON_STIPPLE_BIT 0x00000010 +#define GL_PIXEL_MODE_BIT 0x00000020 +#define GL_LIGHTING_BIT 0x00000040 +#define GL_FOG_BIT 0x00000080 +#define GL_DEPTH_BUFFER_BIT 0x00000100 +#define GL_ACCUM_BUFFER_BIT 0x00000200 +#define GL_STENCIL_BUFFER_BIT 0x00000400 +#define GL_VIEWPORT_BIT 0x00000800 +#define GL_TRANSFORM_BIT 0x00001000 +#define GL_ENABLE_BIT 0x00002000 +#define GL_COLOR_BUFFER_BIT 0x00004000 +#define GL_HINT_BIT 0x00008000 +#define GL_EVAL_BIT 0x00010000 +#define GL_LIST_BIT 0x00020000 +#define GL_TEXTURE_BIT 0x00040000 +#define GL_SCISSOR_BIT 0x00080000 +#define GL_ALL_ATTRIB_BITS 0x000FFFFF + + +/* OpenGL 1.1 */ +#define GL_PROXY_TEXTURE_1D 0x8063 +#define GL_PROXY_TEXTURE_2D 0x8064 +#define GL_TEXTURE_PRIORITY 0x8066 +#define GL_TEXTURE_RESIDENT 0x8067 +#define GL_TEXTURE_BINDING_1D 0x8068 +#define GL_TEXTURE_BINDING_2D 0x8069 +#define GL_TEXTURE_INTERNAL_FORMAT 0x1003 +#define GL_ALPHA4 0x803B +#define GL_ALPHA8 0x803C +#define GL_ALPHA12 0x803D +#define GL_ALPHA16 0x803E +#define GL_LUMINANCE4 0x803F +#define GL_LUMINANCE8 0x8040 +#define GL_LUMINANCE12 0x8041 +#define GL_LUMINANCE16 0x8042 +#define GL_LUMINANCE4_ALPHA4 0x8043 +#define GL_LUMINANCE6_ALPHA2 0x8044 +#define GL_LUMINANCE8_ALPHA8 0x8045 +#define GL_LUMINANCE12_ALPHA4 0x8046 +#define GL_LUMINANCE12_ALPHA12 0x8047 +#define GL_LUMINANCE16_ALPHA16 0x8048 +#define GL_INTENSITY 0x8049 +#define GL_INTENSITY4 0x804A +#define GL_INTENSITY8 0x804B +#define GL_INTENSITY12 0x804C +#define GL_INTENSITY16 0x804D +#define GL_R3_G3_B2 0x2A10 +#define GL_RGB4 0x804F +#define GL_RGB5 0x8050 +#define GL_RGB8 0x8051 +#define GL_RGB10 0x8052 +#define GL_RGB12 0x8053 +#define GL_RGB16 0x8054 +#define GL_RGBA2 0x8055 +#define GL_RGBA4 0x8056 +#define GL_RGB5_A1 0x8057 +#define GL_RGBA8 0x8058 +#define GL_RGB10_A2 0x8059 +#define GL_RGBA12 0x805A +#define GL_RGBA16 0x805B +#define GL_CLIENT_PIXEL_STORE_BIT 0x00000001 +#define GL_CLIENT_VERTEX_ARRAY_BIT 0x00000002 +#define GL_ALL_CLIENT_ATTRIB_BITS 0xFFFFFFFF +#define GL_CLIENT_ALL_ATTRIB_BITS 0xFFFFFFFF + + + +/* + * Miscellaneous + */ + +GLAPI void GLAPIENTRY glClearIndex( GLfloat c ); + +GLAPI void GLAPIENTRY glClearColor( GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha ); + +GLAPI void GLAPIENTRY glClear( GLbitfield mask ); + +GLAPI void GLAPIENTRY glIndexMask( GLuint mask ); + +GLAPI void GLAPIENTRY glColorMask( GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha ); + +GLAPI void GLAPIENTRY glAlphaFunc( GLenum func, GLclampf ref ); + +GLAPI void GLAPIENTRY glBlendFunc( GLenum sfactor, GLenum dfactor ); + +GLAPI void GLAPIENTRY glLogicOp( GLenum opcode ); + +GLAPI void GLAPIENTRY glCullFace( GLenum mode ); + +GLAPI void GLAPIENTRY glFrontFace( GLenum mode ); + +GLAPI void GLAPIENTRY glPointSize( GLfloat size ); + +GLAPI void GLAPIENTRY glLineWidth( GLfloat width ); + +GLAPI void GLAPIENTRY glLineStipple( GLint factor, GLushort pattern ); + +GLAPI void GLAPIENTRY glPolygonMode( GLenum face, GLenum mode ); + +GLAPI void GLAPIENTRY glPolygonOffset( GLfloat factor, GLfloat units ); + +GLAPI void GLAPIENTRY glPolygonStipple( const GLubyte *mask ); + +GLAPI void GLAPIENTRY glGetPolygonStipple( GLubyte *mask ); + +GLAPI void GLAPIENTRY glEdgeFlag( GLboolean flag ); + +GLAPI void GLAPIENTRY glEdgeFlagv( const GLboolean *flag ); + +GLAPI void GLAPIENTRY glScissor( GLint x, GLint y, GLsizei width, GLsizei height); + +GLAPI void GLAPIENTRY glClipPlane( GLenum plane, const GLdouble *equation ); + +GLAPI void GLAPIENTRY glGetClipPlane( GLenum plane, GLdouble *equation ); + +GLAPI void GLAPIENTRY glDrawBuffer( GLenum mode ); + +GLAPI void GLAPIENTRY glReadBuffer( GLenum mode ); + +GLAPI void GLAPIENTRY glEnable( GLenum cap ); + +GLAPI void GLAPIENTRY glDisable( GLenum cap ); + +GLAPI GLboolean GLAPIENTRY glIsEnabled( GLenum cap ); + + +GLAPI void GLAPIENTRY glEnableClientState( GLenum cap ); /* 1.1 */ + +GLAPI void GLAPIENTRY glDisableClientState( GLenum cap ); /* 1.1 */ + + +GLAPI void GLAPIENTRY glGetBooleanv( GLenum pname, GLboolean *params ); + +GLAPI void GLAPIENTRY glGetDoublev( GLenum pname, GLdouble *params ); + +GLAPI void GLAPIENTRY glGetFloatv( GLenum pname, GLfloat *params ); + +GLAPI void GLAPIENTRY glGetIntegerv( GLenum pname, GLint *params ); + + +GLAPI void GLAPIENTRY glPushAttrib( GLbitfield mask ); + +GLAPI void GLAPIENTRY glPopAttrib( void ); + + +GLAPI void GLAPIENTRY glPushClientAttrib( GLbitfield mask ); /* 1.1 */ + +GLAPI void GLAPIENTRY glPopClientAttrib( void ); /* 1.1 */ + + +GLAPI GLint GLAPIENTRY glRenderMode( GLenum mode ); + +GLAPI GLenum GLAPIENTRY glGetError( void ); + +GLAPI const GLubyte * GLAPIENTRY glGetString( GLenum name ); + +GLAPI void GLAPIENTRY glFinish( void ); + +GLAPI void GLAPIENTRY glFlush( void ); + +GLAPI void GLAPIENTRY glHint( GLenum target, GLenum mode ); + + +/* + * Depth Buffer + */ + +GLAPI void GLAPIENTRY glClearDepth( GLclampd depth ); + +GLAPI void GLAPIENTRY glDepthFunc( GLenum func ); + +GLAPI void GLAPIENTRY glDepthMask( GLboolean flag ); + +GLAPI void GLAPIENTRY glDepthRange( GLclampd near_val, GLclampd far_val ); + + +/* + * Accumulation Buffer + */ + +GLAPI void GLAPIENTRY glClearAccum( GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha ); + +GLAPI void GLAPIENTRY glAccum( GLenum op, GLfloat value ); + + +/* + * Transformation + */ + +GLAPI void GLAPIENTRY glMatrixMode( GLenum mode ); + +GLAPI void GLAPIENTRY glOrtho( GLdouble left, GLdouble right, + GLdouble bottom, GLdouble top, + GLdouble near_val, GLdouble far_val ); + +GLAPI void GLAPIENTRY glFrustum( GLdouble left, GLdouble right, + GLdouble bottom, GLdouble top, + GLdouble near_val, GLdouble far_val ); + +GLAPI void GLAPIENTRY glViewport( GLint x, GLint y, + GLsizei width, GLsizei height ); + +GLAPI void GLAPIENTRY glPushMatrix( void ); + +GLAPI void GLAPIENTRY glPopMatrix( void ); + +GLAPI void GLAPIENTRY glLoadIdentity( void ); + +GLAPI void GLAPIENTRY glLoadMatrixd( const GLdouble *m ); +GLAPI void GLAPIENTRY glLoadMatrixf( const GLfloat *m ); + +GLAPI void GLAPIENTRY glMultMatrixd( const GLdouble *m ); +GLAPI void GLAPIENTRY glMultMatrixf( const GLfloat *m ); + +GLAPI void GLAPIENTRY glRotated( GLdouble angle, + GLdouble x, GLdouble y, GLdouble z ); +GLAPI void GLAPIENTRY glRotatef( GLfloat angle, + GLfloat x, GLfloat y, GLfloat z ); + +GLAPI void GLAPIENTRY glScaled( GLdouble x, GLdouble y, GLdouble z ); +GLAPI void GLAPIENTRY glScalef( GLfloat x, GLfloat y, GLfloat z ); + +GLAPI void GLAPIENTRY glTranslated( GLdouble x, GLdouble y, GLdouble z ); +GLAPI void GLAPIENTRY glTranslatef( GLfloat x, GLfloat y, GLfloat z ); + + +/* + * Display Lists + */ + +GLAPI GLboolean GLAPIENTRY glIsList( GLuint list ); + +GLAPI void GLAPIENTRY glDeleteLists( GLuint list, GLsizei range ); + +GLAPI GLuint GLAPIENTRY glGenLists( GLsizei range ); + +GLAPI void GLAPIENTRY glNewList( GLuint list, GLenum mode ); + +GLAPI void GLAPIENTRY glEndList( void ); + +GLAPI void GLAPIENTRY glCallList( GLuint list ); + +GLAPI void GLAPIENTRY glCallLists( GLsizei n, GLenum type, + const GLvoid *lists ); + +GLAPI void GLAPIENTRY glListBase( GLuint base ); + + +/* + * Drawing Functions + */ + +GLAPI void GLAPIENTRY glBegin( GLenum mode ); + +GLAPI void GLAPIENTRY glEnd( void ); + + +GLAPI void GLAPIENTRY glVertex2d( GLdouble x, GLdouble y ); +GLAPI void GLAPIENTRY glVertex2f( GLfloat x, GLfloat y ); +GLAPI void GLAPIENTRY glVertex2i( GLint x, GLint y ); +GLAPI void GLAPIENTRY glVertex2s( GLshort x, GLshort y ); + +GLAPI void GLAPIENTRY glVertex3d( GLdouble x, GLdouble y, GLdouble z ); +GLAPI void GLAPIENTRY glVertex3f( GLfloat x, GLfloat y, GLfloat z ); +GLAPI void GLAPIENTRY glVertex3i( GLint x, GLint y, GLint z ); +GLAPI void GLAPIENTRY glVertex3s( GLshort x, GLshort y, GLshort z ); + +GLAPI void GLAPIENTRY glVertex4d( GLdouble x, GLdouble y, GLdouble z, GLdouble w ); +GLAPI void GLAPIENTRY glVertex4f( GLfloat x, GLfloat y, GLfloat z, GLfloat w ); +GLAPI void GLAPIENTRY glVertex4i( GLint x, GLint y, GLint z, GLint w ); +GLAPI void GLAPIENTRY glVertex4s( GLshort x, GLshort y, GLshort z, GLshort w ); + +GLAPI void GLAPIENTRY glVertex2dv( const GLdouble *v ); +GLAPI void GLAPIENTRY glVertex2fv( const GLfloat *v ); +GLAPI void GLAPIENTRY glVertex2iv( const GLint *v ); +GLAPI void GLAPIENTRY glVertex2sv( const GLshort *v ); + +GLAPI void GLAPIENTRY glVertex3dv( const GLdouble *v ); +GLAPI void GLAPIENTRY glVertex3fv( const GLfloat *v ); +GLAPI void GLAPIENTRY glVertex3iv( const GLint *v ); +GLAPI void GLAPIENTRY glVertex3sv( const GLshort *v ); + +GLAPI void GLAPIENTRY glVertex4dv( const GLdouble *v ); +GLAPI void GLAPIENTRY glVertex4fv( const GLfloat *v ); +GLAPI void GLAPIENTRY glVertex4iv( const GLint *v ); +GLAPI void GLAPIENTRY glVertex4sv( const GLshort *v ); + + +GLAPI void GLAPIENTRY glNormal3b( GLbyte nx, GLbyte ny, GLbyte nz ); +GLAPI void GLAPIENTRY glNormal3d( GLdouble nx, GLdouble ny, GLdouble nz ); +GLAPI void GLAPIENTRY glNormal3f( GLfloat nx, GLfloat ny, GLfloat nz ); +GLAPI void GLAPIENTRY glNormal3i( GLint nx, GLint ny, GLint nz ); +GLAPI void GLAPIENTRY glNormal3s( GLshort nx, GLshort ny, GLshort nz ); + +GLAPI void GLAPIENTRY glNormal3bv( const GLbyte *v ); +GLAPI void GLAPIENTRY glNormal3dv( const GLdouble *v ); +GLAPI void GLAPIENTRY glNormal3fv( const GLfloat *v ); +GLAPI void GLAPIENTRY glNormal3iv( const GLint *v ); +GLAPI void GLAPIENTRY glNormal3sv( const GLshort *v ); + + +GLAPI void GLAPIENTRY glIndexd( GLdouble c ); +GLAPI void GLAPIENTRY glIndexf( GLfloat c ); +GLAPI void GLAPIENTRY glIndexi( GLint c ); +GLAPI void GLAPIENTRY glIndexs( GLshort c ); +GLAPI void GLAPIENTRY glIndexub( GLubyte c ); /* 1.1 */ + +GLAPI void GLAPIENTRY glIndexdv( const GLdouble *c ); +GLAPI void GLAPIENTRY glIndexfv( const GLfloat *c ); +GLAPI void GLAPIENTRY glIndexiv( const GLint *c ); +GLAPI void GLAPIENTRY glIndexsv( const GLshort *c ); +GLAPI void GLAPIENTRY glIndexubv( const GLubyte *c ); /* 1.1 */ + +GLAPI void GLAPIENTRY glColor3b( GLbyte red, GLbyte green, GLbyte blue ); +GLAPI void GLAPIENTRY glColor3d( GLdouble red, GLdouble green, GLdouble blue ); +GLAPI void GLAPIENTRY glColor3f( GLfloat red, GLfloat green, GLfloat blue ); +GLAPI void GLAPIENTRY glColor3i( GLint red, GLint green, GLint blue ); +GLAPI void GLAPIENTRY glColor3s( GLshort red, GLshort green, GLshort blue ); +GLAPI void GLAPIENTRY glColor3ub( GLubyte red, GLubyte green, GLubyte blue ); +GLAPI void GLAPIENTRY glColor3ui( GLuint red, GLuint green, GLuint blue ); +GLAPI void GLAPIENTRY glColor3us( GLushort red, GLushort green, GLushort blue ); + +GLAPI void GLAPIENTRY glColor4b( GLbyte red, GLbyte green, + GLbyte blue, GLbyte alpha ); +GLAPI void GLAPIENTRY glColor4d( GLdouble red, GLdouble green, + GLdouble blue, GLdouble alpha ); +GLAPI void GLAPIENTRY glColor4f( GLfloat red, GLfloat green, + GLfloat blue, GLfloat alpha ); +GLAPI void GLAPIENTRY glColor4i( GLint red, GLint green, + GLint blue, GLint alpha ); +GLAPI void GLAPIENTRY glColor4s( GLshort red, GLshort green, + GLshort blue, GLshort alpha ); +GLAPI void GLAPIENTRY glColor4ub( GLubyte red, GLubyte green, + GLubyte blue, GLubyte alpha ); +GLAPI void GLAPIENTRY glColor4ui( GLuint red, GLuint green, + GLuint blue, GLuint alpha ); +GLAPI void GLAPIENTRY glColor4us( GLushort red, GLushort green, + GLushort blue, GLushort alpha ); + + +GLAPI void GLAPIENTRY glColor3bv( const GLbyte *v ); +GLAPI void GLAPIENTRY glColor3dv( const GLdouble *v ); +GLAPI void GLAPIENTRY glColor3fv( const GLfloat *v ); +GLAPI void GLAPIENTRY glColor3iv( const GLint *v ); +GLAPI void GLAPIENTRY glColor3sv( const GLshort *v ); +GLAPI void GLAPIENTRY glColor3ubv( const GLubyte *v ); +GLAPI void GLAPIENTRY glColor3uiv( const GLuint *v ); +GLAPI void GLAPIENTRY glColor3usv( const GLushort *v ); + +GLAPI void GLAPIENTRY glColor4bv( const GLbyte *v ); +GLAPI void GLAPIENTRY glColor4dv( const GLdouble *v ); +GLAPI void GLAPIENTRY glColor4fv( const GLfloat *v ); +GLAPI void GLAPIENTRY glColor4iv( const GLint *v ); +GLAPI void GLAPIENTRY glColor4sv( const GLshort *v ); +GLAPI void GLAPIENTRY glColor4ubv( const GLubyte *v ); +GLAPI void GLAPIENTRY glColor4uiv( const GLuint *v ); +GLAPI void GLAPIENTRY glColor4usv( const GLushort *v ); + + +GLAPI void GLAPIENTRY glTexCoord1d( GLdouble s ); +GLAPI void GLAPIENTRY glTexCoord1f( GLfloat s ); +GLAPI void GLAPIENTRY glTexCoord1i( GLint s ); +GLAPI void GLAPIENTRY glTexCoord1s( GLshort s ); + +GLAPI void GLAPIENTRY glTexCoord2d( GLdouble s, GLdouble t ); +GLAPI void GLAPIENTRY glTexCoord2f( GLfloat s, GLfloat t ); +GLAPI void GLAPIENTRY glTexCoord2i( GLint s, GLint t ); +GLAPI void GLAPIENTRY glTexCoord2s( GLshort s, GLshort t ); + +GLAPI void GLAPIENTRY glTexCoord3d( GLdouble s, GLdouble t, GLdouble r ); +GLAPI void GLAPIENTRY glTexCoord3f( GLfloat s, GLfloat t, GLfloat r ); +GLAPI void GLAPIENTRY glTexCoord3i( GLint s, GLint t, GLint r ); +GLAPI void GLAPIENTRY glTexCoord3s( GLshort s, GLshort t, GLshort r ); + +GLAPI void GLAPIENTRY glTexCoord4d( GLdouble s, GLdouble t, GLdouble r, GLdouble q ); +GLAPI void GLAPIENTRY glTexCoord4f( GLfloat s, GLfloat t, GLfloat r, GLfloat q ); +GLAPI void GLAPIENTRY glTexCoord4i( GLint s, GLint t, GLint r, GLint q ); +GLAPI void GLAPIENTRY glTexCoord4s( GLshort s, GLshort t, GLshort r, GLshort q ); + +GLAPI void GLAPIENTRY glTexCoord1dv( const GLdouble *v ); +GLAPI void GLAPIENTRY glTexCoord1fv( const GLfloat *v ); +GLAPI void GLAPIENTRY glTexCoord1iv( const GLint *v ); +GLAPI void GLAPIENTRY glTexCoord1sv( const GLshort *v ); + +GLAPI void GLAPIENTRY glTexCoord2dv( const GLdouble *v ); +GLAPI void GLAPIENTRY glTexCoord2fv( const GLfloat *v ); +GLAPI void GLAPIENTRY glTexCoord2iv( const GLint *v ); +GLAPI void GLAPIENTRY glTexCoord2sv( const GLshort *v ); + +GLAPI void GLAPIENTRY glTexCoord3dv( const GLdouble *v ); +GLAPI void GLAPIENTRY glTexCoord3fv( const GLfloat *v ); +GLAPI void GLAPIENTRY glTexCoord3iv( const GLint *v ); +GLAPI void GLAPIENTRY glTexCoord3sv( const GLshort *v ); + +GLAPI void GLAPIENTRY glTexCoord4dv( const GLdouble *v ); +GLAPI void GLAPIENTRY glTexCoord4fv( const GLfloat *v ); +GLAPI void GLAPIENTRY glTexCoord4iv( const GLint *v ); +GLAPI void GLAPIENTRY glTexCoord4sv( const GLshort *v ); + + +GLAPI void GLAPIENTRY glRasterPos2d( GLdouble x, GLdouble y ); +GLAPI void GLAPIENTRY glRasterPos2f( GLfloat x, GLfloat y ); +GLAPI void GLAPIENTRY glRasterPos2i( GLint x, GLint y ); +GLAPI void GLAPIENTRY glRasterPos2s( GLshort x, GLshort y ); + +GLAPI void GLAPIENTRY glRasterPos3d( GLdouble x, GLdouble y, GLdouble z ); +GLAPI void GLAPIENTRY glRasterPos3f( GLfloat x, GLfloat y, GLfloat z ); +GLAPI void GLAPIENTRY glRasterPos3i( GLint x, GLint y, GLint z ); +GLAPI void GLAPIENTRY glRasterPos3s( GLshort x, GLshort y, GLshort z ); + +GLAPI void GLAPIENTRY glRasterPos4d( GLdouble x, GLdouble y, GLdouble z, GLdouble w ); +GLAPI void GLAPIENTRY glRasterPos4f( GLfloat x, GLfloat y, GLfloat z, GLfloat w ); +GLAPI void GLAPIENTRY glRasterPos4i( GLint x, GLint y, GLint z, GLint w ); +GLAPI void GLAPIENTRY glRasterPos4s( GLshort x, GLshort y, GLshort z, GLshort w ); + +GLAPI void GLAPIENTRY glRasterPos2dv( const GLdouble *v ); +GLAPI void GLAPIENTRY glRasterPos2fv( const GLfloat *v ); +GLAPI void GLAPIENTRY glRasterPos2iv( const GLint *v ); +GLAPI void GLAPIENTRY glRasterPos2sv( const GLshort *v ); + +GLAPI void GLAPIENTRY glRasterPos3dv( const GLdouble *v ); +GLAPI void GLAPIENTRY glRasterPos3fv( const GLfloat *v ); +GLAPI void GLAPIENTRY glRasterPos3iv( const GLint *v ); +GLAPI void GLAPIENTRY glRasterPos3sv( const GLshort *v ); + +GLAPI void GLAPIENTRY glRasterPos4dv( const GLdouble *v ); +GLAPI void GLAPIENTRY glRasterPos4fv( const GLfloat *v ); +GLAPI void GLAPIENTRY glRasterPos4iv( const GLint *v ); +GLAPI void GLAPIENTRY glRasterPos4sv( const GLshort *v ); + + +GLAPI void GLAPIENTRY glRectd( GLdouble x1, GLdouble y1, GLdouble x2, GLdouble y2 ); +GLAPI void GLAPIENTRY glRectf( GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2 ); +GLAPI void GLAPIENTRY glRecti( GLint x1, GLint y1, GLint x2, GLint y2 ); +GLAPI void GLAPIENTRY glRects( GLshort x1, GLshort y1, GLshort x2, GLshort y2 ); + + +GLAPI void GLAPIENTRY glRectdv( const GLdouble *v1, const GLdouble *v2 ); +GLAPI void GLAPIENTRY glRectfv( const GLfloat *v1, const GLfloat *v2 ); +GLAPI void GLAPIENTRY glRectiv( const GLint *v1, const GLint *v2 ); +GLAPI void GLAPIENTRY glRectsv( const GLshort *v1, const GLshort *v2 ); + + +/* + * Vertex Arrays (1.1) + */ + +GLAPI void GLAPIENTRY glVertexPointer( GLint size, GLenum type, + GLsizei stride, const GLvoid *ptr ); + +GLAPI void GLAPIENTRY glNormalPointer( GLenum type, GLsizei stride, + const GLvoid *ptr ); + +GLAPI void GLAPIENTRY glColorPointer( GLint size, GLenum type, + GLsizei stride, const GLvoid *ptr ); + +GLAPI void GLAPIENTRY glIndexPointer( GLenum type, GLsizei stride, + const GLvoid *ptr ); + +GLAPI void GLAPIENTRY glTexCoordPointer( GLint size, GLenum type, + GLsizei stride, const GLvoid *ptr ); + +GLAPI void GLAPIENTRY glEdgeFlagPointer( GLsizei stride, const GLvoid *ptr ); + +GLAPI void GLAPIENTRY glGetPointerv( GLenum pname, GLvoid **params ); + +GLAPI void GLAPIENTRY glArrayElement( GLint i ); + +GLAPI void GLAPIENTRY glDrawArrays( GLenum mode, GLint first, GLsizei count ); + +GLAPI void GLAPIENTRY glDrawElements( GLenum mode, GLsizei count, + GLenum type, const GLvoid *indices ); + +GLAPI void GLAPIENTRY glInterleavedArrays( GLenum format, GLsizei stride, + const GLvoid *pointer ); + +/* + * Lighting + */ + +GLAPI void GLAPIENTRY glShadeModel( GLenum mode ); + +GLAPI void GLAPIENTRY glLightf( GLenum light, GLenum pname, GLfloat param ); +GLAPI void GLAPIENTRY glLighti( GLenum light, GLenum pname, GLint param ); +GLAPI void GLAPIENTRY glLightfv( GLenum light, GLenum pname, + const GLfloat *params ); +GLAPI void GLAPIENTRY glLightiv( GLenum light, GLenum pname, + const GLint *params ); + +GLAPI void GLAPIENTRY glGetLightfv( GLenum light, GLenum pname, + GLfloat *params ); +GLAPI void GLAPIENTRY glGetLightiv( GLenum light, GLenum pname, + GLint *params ); + +GLAPI void GLAPIENTRY glLightModelf( GLenum pname, GLfloat param ); +GLAPI void GLAPIENTRY glLightModeli( GLenum pname, GLint param ); +GLAPI void GLAPIENTRY glLightModelfv( GLenum pname, const GLfloat *params ); +GLAPI void GLAPIENTRY glLightModeliv( GLenum pname, const GLint *params ); + +GLAPI void GLAPIENTRY glMaterialf( GLenum face, GLenum pname, GLfloat param ); +GLAPI void GLAPIENTRY glMateriali( GLenum face, GLenum pname, GLint param ); +GLAPI void GLAPIENTRY glMaterialfv( GLenum face, GLenum pname, const GLfloat *params ); +GLAPI void GLAPIENTRY glMaterialiv( GLenum face, GLenum pname, const GLint *params ); + +GLAPI void GLAPIENTRY glGetMaterialfv( GLenum face, GLenum pname, GLfloat *params ); +GLAPI void GLAPIENTRY glGetMaterialiv( GLenum face, GLenum pname, GLint *params ); + +GLAPI void GLAPIENTRY glColorMaterial( GLenum face, GLenum mode ); + + +/* + * Raster functions + */ + +GLAPI void GLAPIENTRY glPixelZoom( GLfloat xfactor, GLfloat yfactor ); + +GLAPI void GLAPIENTRY glPixelStoref( GLenum pname, GLfloat param ); +GLAPI void GLAPIENTRY glPixelStorei( GLenum pname, GLint param ); + +GLAPI void GLAPIENTRY glPixelTransferf( GLenum pname, GLfloat param ); +GLAPI void GLAPIENTRY glPixelTransferi( GLenum pname, GLint param ); + +GLAPI void GLAPIENTRY glPixelMapfv( GLenum map, GLsizei mapsize, + const GLfloat *values ); +GLAPI void GLAPIENTRY glPixelMapuiv( GLenum map, GLsizei mapsize, + const GLuint *values ); +GLAPI void GLAPIENTRY glPixelMapusv( GLenum map, GLsizei mapsize, + const GLushort *values ); + +GLAPI void GLAPIENTRY glGetPixelMapfv( GLenum map, GLfloat *values ); +GLAPI void GLAPIENTRY glGetPixelMapuiv( GLenum map, GLuint *values ); +GLAPI void GLAPIENTRY glGetPixelMapusv( GLenum map, GLushort *values ); + +GLAPI void GLAPIENTRY glBitmap( GLsizei width, GLsizei height, + GLfloat xorig, GLfloat yorig, + GLfloat xmove, GLfloat ymove, + const GLubyte *bitmap ); + +GLAPI void GLAPIENTRY glReadPixels( GLint x, GLint y, + GLsizei width, GLsizei height, + GLenum format, GLenum type, + GLvoid *pixels ); + +GLAPI void GLAPIENTRY glDrawPixels( GLsizei width, GLsizei height, + GLenum format, GLenum type, + const GLvoid *pixels ); + +GLAPI void GLAPIENTRY glCopyPixels( GLint x, GLint y, + GLsizei width, GLsizei height, + GLenum type ); + +/* + * Stenciling + */ + +GLAPI void GLAPIENTRY glStencilFunc( GLenum func, GLint ref, GLuint mask ); + +GLAPI void GLAPIENTRY glStencilMask( GLuint mask ); + +GLAPI void GLAPIENTRY glStencilOp( GLenum fail, GLenum zfail, GLenum zpass ); + +GLAPI void GLAPIENTRY glClearStencil( GLint s ); + + + +/* + * Texture mapping + */ + +GLAPI void GLAPIENTRY glTexGend( GLenum coord, GLenum pname, GLdouble param ); +GLAPI void GLAPIENTRY glTexGenf( GLenum coord, GLenum pname, GLfloat param ); +GLAPI void GLAPIENTRY glTexGeni( GLenum coord, GLenum pname, GLint param ); + +GLAPI void GLAPIENTRY glTexGendv( GLenum coord, GLenum pname, const GLdouble *params ); +GLAPI void GLAPIENTRY glTexGenfv( GLenum coord, GLenum pname, const GLfloat *params ); +GLAPI void GLAPIENTRY glTexGeniv( GLenum coord, GLenum pname, const GLint *params ); + +GLAPI void GLAPIENTRY glGetTexGendv( GLenum coord, GLenum pname, GLdouble *params ); +GLAPI void GLAPIENTRY glGetTexGenfv( GLenum coord, GLenum pname, GLfloat *params ); +GLAPI void GLAPIENTRY glGetTexGeniv( GLenum coord, GLenum pname, GLint *params ); + + +GLAPI void GLAPIENTRY glTexEnvf( GLenum target, GLenum pname, GLfloat param ); +GLAPI void GLAPIENTRY glTexEnvi( GLenum target, GLenum pname, GLint param ); + +GLAPI void GLAPIENTRY glTexEnvfv( GLenum target, GLenum pname, const GLfloat *params ); +GLAPI void GLAPIENTRY glTexEnviv( GLenum target, GLenum pname, const GLint *params ); + +GLAPI void GLAPIENTRY glGetTexEnvfv( GLenum target, GLenum pname, GLfloat *params ); +GLAPI void GLAPIENTRY glGetTexEnviv( GLenum target, GLenum pname, GLint *params ); + + +GLAPI void GLAPIENTRY glTexParameterf( GLenum target, GLenum pname, GLfloat param ); +GLAPI void GLAPIENTRY glTexParameteri( GLenum target, GLenum pname, GLint param ); + +GLAPI void GLAPIENTRY glTexParameterfv( GLenum target, GLenum pname, + const GLfloat *params ); +GLAPI void GLAPIENTRY glTexParameteriv( GLenum target, GLenum pname, + const GLint *params ); + +GLAPI void GLAPIENTRY glGetTexParameterfv( GLenum target, + GLenum pname, GLfloat *params); +GLAPI void GLAPIENTRY glGetTexParameteriv( GLenum target, + GLenum pname, GLint *params ); + +GLAPI void GLAPIENTRY glGetTexLevelParameterfv( GLenum target, GLint level, + GLenum pname, GLfloat *params ); +GLAPI void GLAPIENTRY glGetTexLevelParameteriv( GLenum target, GLint level, + GLenum pname, GLint *params ); + + +GLAPI void GLAPIENTRY glTexImage1D( GLenum target, GLint level, + GLint internalFormat, + GLsizei width, GLint border, + GLenum format, GLenum type, + const GLvoid *pixels ); + +GLAPI void GLAPIENTRY glTexImage2D( GLenum target, GLint level, + GLint internalFormat, + GLsizei width, GLsizei height, + GLint border, GLenum format, GLenum type, + const GLvoid *pixels ); + +GLAPI void GLAPIENTRY glGetTexImage( GLenum target, GLint level, + GLenum format, GLenum type, + GLvoid *pixels ); + + +/* 1.1 functions */ + +GLAPI void GLAPIENTRY glGenTextures( GLsizei n, GLuint *textures ); + +GLAPI void GLAPIENTRY glDeleteTextures( GLsizei n, const GLuint *textures); + +GLAPI void GLAPIENTRY glBindTexture( GLenum target, GLuint texture ); + +GLAPI void GLAPIENTRY glPrioritizeTextures( GLsizei n, + const GLuint *textures, + const GLclampf *priorities ); + +GLAPI GLboolean GLAPIENTRY glAreTexturesResident( GLsizei n, + const GLuint *textures, + GLboolean *residences ); + +GLAPI GLboolean GLAPIENTRY glIsTexture( GLuint texture ); + + +GLAPI void GLAPIENTRY glTexSubImage1D( GLenum target, GLint level, + GLint xoffset, + GLsizei width, GLenum format, + GLenum type, const GLvoid *pixels ); + + +GLAPI void GLAPIENTRY glTexSubImage2D( GLenum target, GLint level, + GLint xoffset, GLint yoffset, + GLsizei width, GLsizei height, + GLenum format, GLenum type, + const GLvoid *pixels ); + + +GLAPI void GLAPIENTRY glCopyTexImage1D( GLenum target, GLint level, + GLenum internalformat, + GLint x, GLint y, + GLsizei width, GLint border ); + + +GLAPI void GLAPIENTRY glCopyTexImage2D( GLenum target, GLint level, + GLenum internalformat, + GLint x, GLint y, + GLsizei width, GLsizei height, + GLint border ); + + +GLAPI void GLAPIENTRY glCopyTexSubImage1D( GLenum target, GLint level, + GLint xoffset, GLint x, GLint y, + GLsizei width ); + + +GLAPI void GLAPIENTRY glCopyTexSubImage2D( GLenum target, GLint level, + GLint xoffset, GLint yoffset, + GLint x, GLint y, + GLsizei width, GLsizei height ); + + +/* + * Evaluators + */ + +GLAPI void GLAPIENTRY glMap1d( GLenum target, GLdouble u1, GLdouble u2, + GLint stride, + GLint order, const GLdouble *points ); +GLAPI void GLAPIENTRY glMap1f( GLenum target, GLfloat u1, GLfloat u2, + GLint stride, + GLint order, const GLfloat *points ); + +GLAPI void GLAPIENTRY glMap2d( GLenum target, + GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, + GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, + const GLdouble *points ); +GLAPI void GLAPIENTRY glMap2f( GLenum target, + GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, + GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, + const GLfloat *points ); + +GLAPI void GLAPIENTRY glGetMapdv( GLenum target, GLenum query, GLdouble *v ); +GLAPI void GLAPIENTRY glGetMapfv( GLenum target, GLenum query, GLfloat *v ); +GLAPI void GLAPIENTRY glGetMapiv( GLenum target, GLenum query, GLint *v ); + +GLAPI void GLAPIENTRY glEvalCoord1d( GLdouble u ); +GLAPI void GLAPIENTRY glEvalCoord1f( GLfloat u ); + +GLAPI void GLAPIENTRY glEvalCoord1dv( const GLdouble *u ); +GLAPI void GLAPIENTRY glEvalCoord1fv( const GLfloat *u ); + +GLAPI void GLAPIENTRY glEvalCoord2d( GLdouble u, GLdouble v ); +GLAPI void GLAPIENTRY glEvalCoord2f( GLfloat u, GLfloat v ); + +GLAPI void GLAPIENTRY glEvalCoord2dv( const GLdouble *u ); +GLAPI void GLAPIENTRY glEvalCoord2fv( const GLfloat *u ); + +GLAPI void GLAPIENTRY glMapGrid1d( GLint un, GLdouble u1, GLdouble u2 ); +GLAPI void GLAPIENTRY glMapGrid1f( GLint un, GLfloat u1, GLfloat u2 ); + +GLAPI void GLAPIENTRY glMapGrid2d( GLint un, GLdouble u1, GLdouble u2, + GLint vn, GLdouble v1, GLdouble v2 ); +GLAPI void GLAPIENTRY glMapGrid2f( GLint un, GLfloat u1, GLfloat u2, + GLint vn, GLfloat v1, GLfloat v2 ); + +GLAPI void GLAPIENTRY glEvalPoint1( GLint i ); + +GLAPI void GLAPIENTRY glEvalPoint2( GLint i, GLint j ); + +GLAPI void GLAPIENTRY glEvalMesh1( GLenum mode, GLint i1, GLint i2 ); + +GLAPI void GLAPIENTRY glEvalMesh2( GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2 ); + + +/* + * Fog + */ + +GLAPI void GLAPIENTRY glFogf( GLenum pname, GLfloat param ); + +GLAPI void GLAPIENTRY glFogi( GLenum pname, GLint param ); + +GLAPI void GLAPIENTRY glFogfv( GLenum pname, const GLfloat *params ); + +GLAPI void GLAPIENTRY glFogiv( GLenum pname, const GLint *params ); + + +/* + * Selection and Feedback + */ + +GLAPI void GLAPIENTRY glFeedbackBuffer( GLsizei size, GLenum type, GLfloat *buffer ); + +GLAPI void GLAPIENTRY glPassThrough( GLfloat token ); + +GLAPI void GLAPIENTRY glSelectBuffer( GLsizei size, GLuint *buffer ); + +GLAPI void GLAPIENTRY glInitNames( void ); + +GLAPI void GLAPIENTRY glLoadName( GLuint name ); + +GLAPI void GLAPIENTRY glPushName( GLuint name ); + +GLAPI void GLAPIENTRY glPopName( void ); + + + +/* + * OpenGL 1.2 + */ + +#define GL_RESCALE_NORMAL 0x803A +#define GL_CLAMP_TO_EDGE 0x812F +#define GL_MAX_ELEMENTS_VERTICES 0x80E8 +#define GL_MAX_ELEMENTS_INDICES 0x80E9 +#define GL_BGR 0x80E0 +#define GL_BGRA 0x80E1 +#define GL_UNSIGNED_BYTE_3_3_2 0x8032 +#define GL_UNSIGNED_BYTE_2_3_3_REV 0x8362 +#define GL_UNSIGNED_SHORT_5_6_5 0x8363 +#define GL_UNSIGNED_SHORT_5_6_5_REV 0x8364 +#define GL_UNSIGNED_SHORT_4_4_4_4 0x8033 +#define GL_UNSIGNED_SHORT_4_4_4_4_REV 0x8365 +#define GL_UNSIGNED_SHORT_5_5_5_1 0x8034 +#define GL_UNSIGNED_SHORT_1_5_5_5_REV 0x8366 +#define GL_UNSIGNED_INT_8_8_8_8 0x8035 +#define GL_UNSIGNED_INT_8_8_8_8_REV 0x8367 +#define GL_UNSIGNED_INT_10_10_10_2 0x8036 +#define GL_UNSIGNED_INT_2_10_10_10_REV 0x8368 +#define GL_LIGHT_MODEL_COLOR_CONTROL 0x81F8 +#define GL_SINGLE_COLOR 0x81F9 +#define GL_SEPARATE_SPECULAR_COLOR 0x81FA +#define GL_TEXTURE_MIN_LOD 0x813A +#define GL_TEXTURE_MAX_LOD 0x813B +#define GL_TEXTURE_BASE_LEVEL 0x813C +#define GL_TEXTURE_MAX_LEVEL 0x813D +#define GL_SMOOTH_POINT_SIZE_RANGE 0x0B12 +#define GL_SMOOTH_POINT_SIZE_GRANULARITY 0x0B13 +#define GL_SMOOTH_LINE_WIDTH_RANGE 0x0B22 +#define GL_SMOOTH_LINE_WIDTH_GRANULARITY 0x0B23 +#define GL_ALIASED_POINT_SIZE_RANGE 0x846D +#define GL_ALIASED_LINE_WIDTH_RANGE 0x846E +#define GL_PACK_SKIP_IMAGES 0x806B +#define GL_PACK_IMAGE_HEIGHT 0x806C +#define GL_UNPACK_SKIP_IMAGES 0x806D +#define GL_UNPACK_IMAGE_HEIGHT 0x806E +#define GL_TEXTURE_3D 0x806F +#define GL_PROXY_TEXTURE_3D 0x8070 +#define GL_TEXTURE_DEPTH 0x8071 +#define GL_TEXTURE_WRAP_R 0x8072 +#define GL_MAX_3D_TEXTURE_SIZE 0x8073 +#define GL_TEXTURE_BINDING_3D 0x806A + +GLAPI void GLAPIENTRY glDrawRangeElements( GLenum mode, GLuint start, + GLuint end, GLsizei count, GLenum type, const GLvoid *indices ); + +GLAPI void GLAPIENTRY glTexImage3D( GLenum target, GLint level, + GLint internalFormat, + GLsizei width, GLsizei height, + GLsizei depth, GLint border, + GLenum format, GLenum type, + const GLvoid *pixels ); + +GLAPI void GLAPIENTRY glTexSubImage3D( GLenum target, GLint level, + GLint xoffset, GLint yoffset, + GLint zoffset, GLsizei width, + GLsizei height, GLsizei depth, + GLenum format, + GLenum type, const GLvoid *pixels); + +GLAPI void GLAPIENTRY glCopyTexSubImage3D( GLenum target, GLint level, + GLint xoffset, GLint yoffset, + GLint zoffset, GLint x, + GLint y, GLsizei width, + GLsizei height ); + +typedef void (APIENTRYP PFNGLDRAWRANGEELEMENTSPROC) (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices); +typedef void (APIENTRYP PFNGLTEXIMAGE3DPROC) (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels); +typedef void (APIENTRYP PFNGLTEXSUBIMAGE3DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels); +typedef void (APIENTRYP PFNGLCOPYTEXSUBIMAGE3DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); + + +/* + * GL_ARB_imaging + */ + +#define GL_CONSTANT_COLOR 0x8001 +#define GL_ONE_MINUS_CONSTANT_COLOR 0x8002 +#define GL_CONSTANT_ALPHA 0x8003 +#define GL_ONE_MINUS_CONSTANT_ALPHA 0x8004 +#define GL_COLOR_TABLE 0x80D0 +#define GL_POST_CONVOLUTION_COLOR_TABLE 0x80D1 +#define GL_POST_COLOR_MATRIX_COLOR_TABLE 0x80D2 +#define GL_PROXY_COLOR_TABLE 0x80D3 +#define GL_PROXY_POST_CONVOLUTION_COLOR_TABLE 0x80D4 +#define GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE 0x80D5 +#define GL_COLOR_TABLE_SCALE 0x80D6 +#define GL_COLOR_TABLE_BIAS 0x80D7 +#define GL_COLOR_TABLE_FORMAT 0x80D8 +#define GL_COLOR_TABLE_WIDTH 0x80D9 +#define GL_COLOR_TABLE_RED_SIZE 0x80DA +#define GL_COLOR_TABLE_GREEN_SIZE 0x80DB +#define GL_COLOR_TABLE_BLUE_SIZE 0x80DC +#define GL_COLOR_TABLE_ALPHA_SIZE 0x80DD +#define GL_COLOR_TABLE_LUMINANCE_SIZE 0x80DE +#define GL_COLOR_TABLE_INTENSITY_SIZE 0x80DF +#define GL_CONVOLUTION_1D 0x8010 +#define GL_CONVOLUTION_2D 0x8011 +#define GL_SEPARABLE_2D 0x8012 +#define GL_CONVOLUTION_BORDER_MODE 0x8013 +#define GL_CONVOLUTION_FILTER_SCALE 0x8014 +#define GL_CONVOLUTION_FILTER_BIAS 0x8015 +#define GL_REDUCE 0x8016 +#define GL_CONVOLUTION_FORMAT 0x8017 +#define GL_CONVOLUTION_WIDTH 0x8018 +#define GL_CONVOLUTION_HEIGHT 0x8019 +#define GL_MAX_CONVOLUTION_WIDTH 0x801A +#define GL_MAX_CONVOLUTION_HEIGHT 0x801B +#define GL_POST_CONVOLUTION_RED_SCALE 0x801C +#define GL_POST_CONVOLUTION_GREEN_SCALE 0x801D +#define GL_POST_CONVOLUTION_BLUE_SCALE 0x801E +#define GL_POST_CONVOLUTION_ALPHA_SCALE 0x801F +#define GL_POST_CONVOLUTION_RED_BIAS 0x8020 +#define GL_POST_CONVOLUTION_GREEN_BIAS 0x8021 +#define GL_POST_CONVOLUTION_BLUE_BIAS 0x8022 +#define GL_POST_CONVOLUTION_ALPHA_BIAS 0x8023 +#define GL_CONSTANT_BORDER 0x8151 +#define GL_REPLICATE_BORDER 0x8153 +#define GL_CONVOLUTION_BORDER_COLOR 0x8154 +#define GL_COLOR_MATRIX 0x80B1 +#define GL_COLOR_MATRIX_STACK_DEPTH 0x80B2 +#define GL_MAX_COLOR_MATRIX_STACK_DEPTH 0x80B3 +#define GL_POST_COLOR_MATRIX_RED_SCALE 0x80B4 +#define GL_POST_COLOR_MATRIX_GREEN_SCALE 0x80B5 +#define GL_POST_COLOR_MATRIX_BLUE_SCALE 0x80B6 +#define GL_POST_COLOR_MATRIX_ALPHA_SCALE 0x80B7 +#define GL_POST_COLOR_MATRIX_RED_BIAS 0x80B8 +#define GL_POST_COLOR_MATRIX_GREEN_BIAS 0x80B9 +#define GL_POST_COLOR_MATRIX_BLUE_BIAS 0x80BA +#define GL_POST_COLOR_MATRIX_ALPHA_BIAS 0x80BB +#define GL_HISTOGRAM 0x8024 +#define GL_PROXY_HISTOGRAM 0x8025 +#define GL_HISTOGRAM_WIDTH 0x8026 +#define GL_HISTOGRAM_FORMAT 0x8027 +#define GL_HISTOGRAM_RED_SIZE 0x8028 +#define GL_HISTOGRAM_GREEN_SIZE 0x8029 +#define GL_HISTOGRAM_BLUE_SIZE 0x802A +#define GL_HISTOGRAM_ALPHA_SIZE 0x802B +#define GL_HISTOGRAM_LUMINANCE_SIZE 0x802C +#define GL_HISTOGRAM_SINK 0x802D +#define GL_MINMAX 0x802E +#define GL_MINMAX_FORMAT 0x802F +#define GL_MINMAX_SINK 0x8030 +#define GL_TABLE_TOO_LARGE 0x8031 +#define GL_BLEND_EQUATION 0x8009 +#define GL_MIN 0x8007 +#define GL_MAX 0x8008 +#define GL_FUNC_ADD 0x8006 +#define GL_FUNC_SUBTRACT 0x800A +#define GL_FUNC_REVERSE_SUBTRACT 0x800B +#define GL_BLEND_COLOR 0x8005 + + +GLAPI void GLAPIENTRY glColorTable( GLenum target, GLenum internalformat, + GLsizei width, GLenum format, + GLenum type, const GLvoid *table ); + +GLAPI void GLAPIENTRY glColorSubTable( GLenum target, + GLsizei start, GLsizei count, + GLenum format, GLenum type, + const GLvoid *data ); + +GLAPI void GLAPIENTRY glColorTableParameteriv(GLenum target, GLenum pname, + const GLint *params); + +GLAPI void GLAPIENTRY glColorTableParameterfv(GLenum target, GLenum pname, + const GLfloat *params); + +GLAPI void GLAPIENTRY glCopyColorSubTable( GLenum target, GLsizei start, + GLint x, GLint y, GLsizei width ); + +GLAPI void GLAPIENTRY glCopyColorTable( GLenum target, GLenum internalformat, + GLint x, GLint y, GLsizei width ); + +GLAPI void GLAPIENTRY glGetColorTable( GLenum target, GLenum format, + GLenum type, GLvoid *table ); + +GLAPI void GLAPIENTRY glGetColorTableParameterfv( GLenum target, GLenum pname, + GLfloat *params ); + +GLAPI void GLAPIENTRY glGetColorTableParameteriv( GLenum target, GLenum pname, + GLint *params ); + +GLAPI void GLAPIENTRY glBlendEquation( GLenum mode ); + +GLAPI void GLAPIENTRY glBlendColor( GLclampf red, GLclampf green, + GLclampf blue, GLclampf alpha ); + +GLAPI void GLAPIENTRY glHistogram( GLenum target, GLsizei width, + GLenum internalformat, GLboolean sink ); + +GLAPI void GLAPIENTRY glResetHistogram( GLenum target ); + +GLAPI void GLAPIENTRY glGetHistogram( GLenum target, GLboolean reset, + GLenum format, GLenum type, + GLvoid *values ); + +GLAPI void GLAPIENTRY glGetHistogramParameterfv( GLenum target, GLenum pname, + GLfloat *params ); + +GLAPI void GLAPIENTRY glGetHistogramParameteriv( GLenum target, GLenum pname, + GLint *params ); + +GLAPI void GLAPIENTRY glMinmax( GLenum target, GLenum internalformat, + GLboolean sink ); + +GLAPI void GLAPIENTRY glResetMinmax( GLenum target ); + +GLAPI void GLAPIENTRY glGetMinmax( GLenum target, GLboolean reset, + GLenum format, GLenum types, + GLvoid *values ); + +GLAPI void GLAPIENTRY glGetMinmaxParameterfv( GLenum target, GLenum pname, + GLfloat *params ); + +GLAPI void GLAPIENTRY glGetMinmaxParameteriv( GLenum target, GLenum pname, + GLint *params ); + +GLAPI void GLAPIENTRY glConvolutionFilter1D( GLenum target, + GLenum internalformat, GLsizei width, GLenum format, GLenum type, + const GLvoid *image ); + +GLAPI void GLAPIENTRY glConvolutionFilter2D( GLenum target, + GLenum internalformat, GLsizei width, GLsizei height, GLenum format, + GLenum type, const GLvoid *image ); + +GLAPI void GLAPIENTRY glConvolutionParameterf( GLenum target, GLenum pname, + GLfloat params ); + +GLAPI void GLAPIENTRY glConvolutionParameterfv( GLenum target, GLenum pname, + const GLfloat *params ); + +GLAPI void GLAPIENTRY glConvolutionParameteri( GLenum target, GLenum pname, + GLint params ); + +GLAPI void GLAPIENTRY glConvolutionParameteriv( GLenum target, GLenum pname, + const GLint *params ); + +GLAPI void GLAPIENTRY glCopyConvolutionFilter1D( GLenum target, + GLenum internalformat, GLint x, GLint y, GLsizei width ); + +GLAPI void GLAPIENTRY glCopyConvolutionFilter2D( GLenum target, + GLenum internalformat, GLint x, GLint y, GLsizei width, + GLsizei height); + +GLAPI void GLAPIENTRY glGetConvolutionFilter( GLenum target, GLenum format, + GLenum type, GLvoid *image ); + +GLAPI void GLAPIENTRY glGetConvolutionParameterfv( GLenum target, GLenum pname, + GLfloat *params ); + +GLAPI void GLAPIENTRY glGetConvolutionParameteriv( GLenum target, GLenum pname, + GLint *params ); + +GLAPI void GLAPIENTRY glSeparableFilter2D( GLenum target, + GLenum internalformat, GLsizei width, GLsizei height, GLenum format, + GLenum type, const GLvoid *row, const GLvoid *column ); + +GLAPI void GLAPIENTRY glGetSeparableFilter( GLenum target, GLenum format, + GLenum type, GLvoid *row, GLvoid *column, GLvoid *span ); + + + + +/* + * OpenGL 1.3 + */ + +/* multitexture */ +#define GL_TEXTURE0 0x84C0 +#define GL_TEXTURE1 0x84C1 +#define GL_TEXTURE2 0x84C2 +#define GL_TEXTURE3 0x84C3 +#define GL_TEXTURE4 0x84C4 +#define GL_TEXTURE5 0x84C5 +#define GL_TEXTURE6 0x84C6 +#define GL_TEXTURE7 0x84C7 +#define GL_TEXTURE8 0x84C8 +#define GL_TEXTURE9 0x84C9 +#define GL_TEXTURE10 0x84CA +#define GL_TEXTURE11 0x84CB +#define GL_TEXTURE12 0x84CC +#define GL_TEXTURE13 0x84CD +#define GL_TEXTURE14 0x84CE +#define GL_TEXTURE15 0x84CF +#define GL_TEXTURE16 0x84D0 +#define GL_TEXTURE17 0x84D1 +#define GL_TEXTURE18 0x84D2 +#define GL_TEXTURE19 0x84D3 +#define GL_TEXTURE20 0x84D4 +#define GL_TEXTURE21 0x84D5 +#define GL_TEXTURE22 0x84D6 +#define GL_TEXTURE23 0x84D7 +#define GL_TEXTURE24 0x84D8 +#define GL_TEXTURE25 0x84D9 +#define GL_TEXTURE26 0x84DA +#define GL_TEXTURE27 0x84DB +#define GL_TEXTURE28 0x84DC +#define GL_TEXTURE29 0x84DD +#define GL_TEXTURE30 0x84DE +#define GL_TEXTURE31 0x84DF +#define GL_ACTIVE_TEXTURE 0x84E0 +#define GL_CLIENT_ACTIVE_TEXTURE 0x84E1 +#define GL_MAX_TEXTURE_UNITS 0x84E2 +/* texture_cube_map */ +#define GL_NORMAL_MAP 0x8511 +#define GL_REFLECTION_MAP 0x8512 +#define GL_TEXTURE_CUBE_MAP 0x8513 +#define GL_TEXTURE_BINDING_CUBE_MAP 0x8514 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_X 0x8515 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X 0x8516 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y 0x8517 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y 0x8518 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z 0x8519 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z 0x851A +#define GL_PROXY_TEXTURE_CUBE_MAP 0x851B +#define GL_MAX_CUBE_MAP_TEXTURE_SIZE 0x851C +/* texture_compression */ +#define GL_COMPRESSED_ALPHA 0x84E9 +#define GL_COMPRESSED_LUMINANCE 0x84EA +#define GL_COMPRESSED_LUMINANCE_ALPHA 0x84EB +#define GL_COMPRESSED_INTENSITY 0x84EC +#define GL_COMPRESSED_RGB 0x84ED +#define GL_COMPRESSED_RGBA 0x84EE +#define GL_TEXTURE_COMPRESSION_HINT 0x84EF +#define GL_TEXTURE_COMPRESSED_IMAGE_SIZE 0x86A0 +#define GL_TEXTURE_COMPRESSED 0x86A1 +#define GL_NUM_COMPRESSED_TEXTURE_FORMATS 0x86A2 +#define GL_COMPRESSED_TEXTURE_FORMATS 0x86A3 +/* multisample */ +#define GL_MULTISAMPLE 0x809D +#define GL_SAMPLE_ALPHA_TO_COVERAGE 0x809E +#define GL_SAMPLE_ALPHA_TO_ONE 0x809F +#define GL_SAMPLE_COVERAGE 0x80A0 +#define GL_SAMPLE_BUFFERS 0x80A8 +#define GL_SAMPLES 0x80A9 +#define GL_SAMPLE_COVERAGE_VALUE 0x80AA +#define GL_SAMPLE_COVERAGE_INVERT 0x80AB +#define GL_MULTISAMPLE_BIT 0x20000000 +/* transpose_matrix */ +#define GL_TRANSPOSE_MODELVIEW_MATRIX 0x84E3 +#define GL_TRANSPOSE_PROJECTION_MATRIX 0x84E4 +#define GL_TRANSPOSE_TEXTURE_MATRIX 0x84E5 +#define GL_TRANSPOSE_COLOR_MATRIX 0x84E6 +/* texture_env_combine */ +#define GL_COMBINE 0x8570 +#define GL_COMBINE_RGB 0x8571 +#define GL_COMBINE_ALPHA 0x8572 +#define GL_SOURCE0_RGB 0x8580 +#define GL_SOURCE1_RGB 0x8581 +#define GL_SOURCE2_RGB 0x8582 +#define GL_SOURCE0_ALPHA 0x8588 +#define GL_SOURCE1_ALPHA 0x8589 +#define GL_SOURCE2_ALPHA 0x858A +#define GL_OPERAND0_RGB 0x8590 +#define GL_OPERAND1_RGB 0x8591 +#define GL_OPERAND2_RGB 0x8592 +#define GL_OPERAND0_ALPHA 0x8598 +#define GL_OPERAND1_ALPHA 0x8599 +#define GL_OPERAND2_ALPHA 0x859A +#define GL_RGB_SCALE 0x8573 +#define GL_ADD_SIGNED 0x8574 +#define GL_INTERPOLATE 0x8575 +#define GL_SUBTRACT 0x84E7 +#define GL_CONSTANT 0x8576 +#define GL_PRIMARY_COLOR 0x8577 +#define GL_PREVIOUS 0x8578 +/* texture_env_dot3 */ +#define GL_DOT3_RGB 0x86AE +#define GL_DOT3_RGBA 0x86AF +/* texture_border_clamp */ +#define GL_CLAMP_TO_BORDER 0x812D + +GLAPI void GLAPIENTRY glActiveTexture( GLenum texture ); + +GLAPI void GLAPIENTRY glClientActiveTexture( GLenum texture ); + +GLAPI void GLAPIENTRY glCompressedTexImage1D( GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const GLvoid *data ); + +GLAPI void GLAPIENTRY glCompressedTexImage2D( GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data ); + +GLAPI void GLAPIENTRY glCompressedTexImage3D( GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *data ); + +GLAPI void GLAPIENTRY glCompressedTexSubImage1D( GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const GLvoid *data ); + +GLAPI void GLAPIENTRY glCompressedTexSubImage2D( GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *data ); + +GLAPI void GLAPIENTRY glCompressedTexSubImage3D( GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid *data ); + +GLAPI void GLAPIENTRY glGetCompressedTexImage( GLenum target, GLint lod, GLvoid *img ); + +GLAPI void GLAPIENTRY glMultiTexCoord1d( GLenum target, GLdouble s ); + +GLAPI void GLAPIENTRY glMultiTexCoord1dv( GLenum target, const GLdouble *v ); + +GLAPI void GLAPIENTRY glMultiTexCoord1f( GLenum target, GLfloat s ); + +GLAPI void GLAPIENTRY glMultiTexCoord1fv( GLenum target, const GLfloat *v ); + +GLAPI void GLAPIENTRY glMultiTexCoord1i( GLenum target, GLint s ); + +GLAPI void GLAPIENTRY glMultiTexCoord1iv( GLenum target, const GLint *v ); + +GLAPI void GLAPIENTRY glMultiTexCoord1s( GLenum target, GLshort s ); + +GLAPI void GLAPIENTRY glMultiTexCoord1sv( GLenum target, const GLshort *v ); + +GLAPI void GLAPIENTRY glMultiTexCoord2d( GLenum target, GLdouble s, GLdouble t ); + +GLAPI void GLAPIENTRY glMultiTexCoord2dv( GLenum target, const GLdouble *v ); + +GLAPI void GLAPIENTRY glMultiTexCoord2f( GLenum target, GLfloat s, GLfloat t ); + +GLAPI void GLAPIENTRY glMultiTexCoord2fv( GLenum target, const GLfloat *v ); + +GLAPI void GLAPIENTRY glMultiTexCoord2i( GLenum target, GLint s, GLint t ); + +GLAPI void GLAPIENTRY glMultiTexCoord2iv( GLenum target, const GLint *v ); + +GLAPI void GLAPIENTRY glMultiTexCoord2s( GLenum target, GLshort s, GLshort t ); + +GLAPI void GLAPIENTRY glMultiTexCoord2sv( GLenum target, const GLshort *v ); + +GLAPI void GLAPIENTRY glMultiTexCoord3d( GLenum target, GLdouble s, GLdouble t, GLdouble r ); + +GLAPI void GLAPIENTRY glMultiTexCoord3dv( GLenum target, const GLdouble *v ); + +GLAPI void GLAPIENTRY glMultiTexCoord3f( GLenum target, GLfloat s, GLfloat t, GLfloat r ); + +GLAPI void GLAPIENTRY glMultiTexCoord3fv( GLenum target, const GLfloat *v ); + +GLAPI void GLAPIENTRY glMultiTexCoord3i( GLenum target, GLint s, GLint t, GLint r ); + +GLAPI void GLAPIENTRY glMultiTexCoord3iv( GLenum target, const GLint *v ); + +GLAPI void GLAPIENTRY glMultiTexCoord3s( GLenum target, GLshort s, GLshort t, GLshort r ); + +GLAPI void GLAPIENTRY glMultiTexCoord3sv( GLenum target, const GLshort *v ); + +GLAPI void GLAPIENTRY glMultiTexCoord4d( GLenum target, GLdouble s, GLdouble t, GLdouble r, GLdouble q ); + +GLAPI void GLAPIENTRY glMultiTexCoord4dv( GLenum target, const GLdouble *v ); + +GLAPI void GLAPIENTRY glMultiTexCoord4f( GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q ); + +GLAPI void GLAPIENTRY glMultiTexCoord4fv( GLenum target, const GLfloat *v ); + +GLAPI void GLAPIENTRY glMultiTexCoord4i( GLenum target, GLint s, GLint t, GLint r, GLint q ); + +GLAPI void GLAPIENTRY glMultiTexCoord4iv( GLenum target, const GLint *v ); + +GLAPI void GLAPIENTRY glMultiTexCoord4s( GLenum target, GLshort s, GLshort t, GLshort r, GLshort q ); + +GLAPI void GLAPIENTRY glMultiTexCoord4sv( GLenum target, const GLshort *v ); + + +GLAPI void GLAPIENTRY glLoadTransposeMatrixd( const GLdouble m[16] ); + +GLAPI void GLAPIENTRY glLoadTransposeMatrixf( const GLfloat m[16] ); + +GLAPI void GLAPIENTRY glMultTransposeMatrixd( const GLdouble m[16] ); + +GLAPI void GLAPIENTRY glMultTransposeMatrixf( const GLfloat m[16] ); + +GLAPI void GLAPIENTRY glSampleCoverage( GLclampf value, GLboolean invert ); + + +typedef void (APIENTRYP PFNGLACTIVETEXTUREPROC) (GLenum texture); +typedef void (APIENTRYP PFNGLSAMPLECOVERAGEPROC) (GLclampf value, GLboolean invert); +typedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE3DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *data); +typedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE2DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data); +typedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE1DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const GLvoid *data); +typedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid *data); +typedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *data); +typedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC) (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const GLvoid *data); +typedef void (APIENTRYP PFNGLGETCOMPRESSEDTEXIMAGEPROC) (GLenum target, GLint level, GLvoid *img); + + + +/* + * GL_ARB_multitexture (ARB extension 1 and OpenGL 1.2.1) + */ +#ifndef GL_ARB_multitexture +#define GL_ARB_multitexture 1 + +#define GL_TEXTURE0_ARB 0x84C0 +#define GL_TEXTURE1_ARB 0x84C1 +#define GL_TEXTURE2_ARB 0x84C2 +#define GL_TEXTURE3_ARB 0x84C3 +#define GL_TEXTURE4_ARB 0x84C4 +#define GL_TEXTURE5_ARB 0x84C5 +#define GL_TEXTURE6_ARB 0x84C6 +#define GL_TEXTURE7_ARB 0x84C7 +#define GL_TEXTURE8_ARB 0x84C8 +#define GL_TEXTURE9_ARB 0x84C9 +#define GL_TEXTURE10_ARB 0x84CA +#define GL_TEXTURE11_ARB 0x84CB +#define GL_TEXTURE12_ARB 0x84CC +#define GL_TEXTURE13_ARB 0x84CD +#define GL_TEXTURE14_ARB 0x84CE +#define GL_TEXTURE15_ARB 0x84CF +#define GL_TEXTURE16_ARB 0x84D0 +#define GL_TEXTURE17_ARB 0x84D1 +#define GL_TEXTURE18_ARB 0x84D2 +#define GL_TEXTURE19_ARB 0x84D3 +#define GL_TEXTURE20_ARB 0x84D4 +#define GL_TEXTURE21_ARB 0x84D5 +#define GL_TEXTURE22_ARB 0x84D6 +#define GL_TEXTURE23_ARB 0x84D7 +#define GL_TEXTURE24_ARB 0x84D8 +#define GL_TEXTURE25_ARB 0x84D9 +#define GL_TEXTURE26_ARB 0x84DA +#define GL_TEXTURE27_ARB 0x84DB +#define GL_TEXTURE28_ARB 0x84DC +#define GL_TEXTURE29_ARB 0x84DD +#define GL_TEXTURE30_ARB 0x84DE +#define GL_TEXTURE31_ARB 0x84DF +#define GL_ACTIVE_TEXTURE_ARB 0x84E0 +#define GL_CLIENT_ACTIVE_TEXTURE_ARB 0x84E1 +#define GL_MAX_TEXTURE_UNITS_ARB 0x84E2 + +GLAPI void GLAPIENTRY glActiveTextureARB(GLenum texture); +GLAPI void GLAPIENTRY glClientActiveTextureARB(GLenum texture); +GLAPI void GLAPIENTRY glMultiTexCoord1dARB(GLenum target, GLdouble s); +GLAPI void GLAPIENTRY glMultiTexCoord1dvARB(GLenum target, const GLdouble *v); +GLAPI void GLAPIENTRY glMultiTexCoord1fARB(GLenum target, GLfloat s); +GLAPI void GLAPIENTRY glMultiTexCoord1fvARB(GLenum target, const GLfloat *v); +GLAPI void GLAPIENTRY glMultiTexCoord1iARB(GLenum target, GLint s); +GLAPI void GLAPIENTRY glMultiTexCoord1ivARB(GLenum target, const GLint *v); +GLAPI void GLAPIENTRY glMultiTexCoord1sARB(GLenum target, GLshort s); +GLAPI void GLAPIENTRY glMultiTexCoord1svARB(GLenum target, const GLshort *v); +GLAPI void GLAPIENTRY glMultiTexCoord2dARB(GLenum target, GLdouble s, GLdouble t); +GLAPI void GLAPIENTRY glMultiTexCoord2dvARB(GLenum target, const GLdouble *v); +GLAPI void GLAPIENTRY glMultiTexCoord2fARB(GLenum target, GLfloat s, GLfloat t); +GLAPI void GLAPIENTRY glMultiTexCoord2fvARB(GLenum target, const GLfloat *v); +GLAPI void GLAPIENTRY glMultiTexCoord2iARB(GLenum target, GLint s, GLint t); +GLAPI void GLAPIENTRY glMultiTexCoord2ivARB(GLenum target, const GLint *v); +GLAPI void GLAPIENTRY glMultiTexCoord2sARB(GLenum target, GLshort s, GLshort t); +GLAPI void GLAPIENTRY glMultiTexCoord2svARB(GLenum target, const GLshort *v); +GLAPI void GLAPIENTRY glMultiTexCoord3dARB(GLenum target, GLdouble s, GLdouble t, GLdouble r); +GLAPI void GLAPIENTRY glMultiTexCoord3dvARB(GLenum target, const GLdouble *v); +GLAPI void GLAPIENTRY glMultiTexCoord3fARB(GLenum target, GLfloat s, GLfloat t, GLfloat r); +GLAPI void GLAPIENTRY glMultiTexCoord3fvARB(GLenum target, const GLfloat *v); +GLAPI void GLAPIENTRY glMultiTexCoord3iARB(GLenum target, GLint s, GLint t, GLint r); +GLAPI void GLAPIENTRY glMultiTexCoord3ivARB(GLenum target, const GLint *v); +GLAPI void GLAPIENTRY glMultiTexCoord3sARB(GLenum target, GLshort s, GLshort t, GLshort r); +GLAPI void GLAPIENTRY glMultiTexCoord3svARB(GLenum target, const GLshort *v); +GLAPI void GLAPIENTRY glMultiTexCoord4dARB(GLenum target, GLdouble s, GLdouble t, GLdouble r, GLdouble q); +GLAPI void GLAPIENTRY glMultiTexCoord4dvARB(GLenum target, const GLdouble *v); +GLAPI void GLAPIENTRY glMultiTexCoord4fARB(GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q); +GLAPI void GLAPIENTRY glMultiTexCoord4fvARB(GLenum target, const GLfloat *v); +GLAPI void GLAPIENTRY glMultiTexCoord4iARB(GLenum target, GLint s, GLint t, GLint r, GLint q); +GLAPI void GLAPIENTRY glMultiTexCoord4ivARB(GLenum target, const GLint *v); +GLAPI void GLAPIENTRY glMultiTexCoord4sARB(GLenum target, GLshort s, GLshort t, GLshort r, GLshort q); +GLAPI void GLAPIENTRY glMultiTexCoord4svARB(GLenum target, const GLshort *v); + +typedef void (APIENTRYP PFNGLACTIVETEXTUREARBPROC) (GLenum texture); +typedef void (APIENTRYP PFNGLCLIENTACTIVETEXTUREARBPROC) (GLenum texture); +typedef void (APIENTRYP PFNGLMULTITEXCOORD1DARBPROC) (GLenum target, GLdouble s); +typedef void (APIENTRYP PFNGLMULTITEXCOORD1DVARBPROC) (GLenum target, const GLdouble *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD1FARBPROC) (GLenum target, GLfloat s); +typedef void (APIENTRYP PFNGLMULTITEXCOORD1FVARBPROC) (GLenum target, const GLfloat *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD1IARBPROC) (GLenum target, GLint s); +typedef void (APIENTRYP PFNGLMULTITEXCOORD1IVARBPROC) (GLenum target, const GLint *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD1SARBPROC) (GLenum target, GLshort s); +typedef void (APIENTRYP PFNGLMULTITEXCOORD1SVARBPROC) (GLenum target, const GLshort *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD2DARBPROC) (GLenum target, GLdouble s, GLdouble t); +typedef void (APIENTRYP PFNGLMULTITEXCOORD2DVARBPROC) (GLenum target, const GLdouble *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD2FARBPROC) (GLenum target, GLfloat s, GLfloat t); +typedef void (APIENTRYP PFNGLMULTITEXCOORD2FVARBPROC) (GLenum target, const GLfloat *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD2IARBPROC) (GLenum target, GLint s, GLint t); +typedef void (APIENTRYP PFNGLMULTITEXCOORD2IVARBPROC) (GLenum target, const GLint *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD2SARBPROC) (GLenum target, GLshort s, GLshort t); +typedef void (APIENTRYP PFNGLMULTITEXCOORD2SVARBPROC) (GLenum target, const GLshort *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD3DARBPROC) (GLenum target, GLdouble s, GLdouble t, GLdouble r); +typedef void (APIENTRYP PFNGLMULTITEXCOORD3DVARBPROC) (GLenum target, const GLdouble *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD3FARBPROC) (GLenum target, GLfloat s, GLfloat t, GLfloat r); +typedef void (APIENTRYP PFNGLMULTITEXCOORD3FVARBPROC) (GLenum target, const GLfloat *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD3IARBPROC) (GLenum target, GLint s, GLint t, GLint r); +typedef void (APIENTRYP PFNGLMULTITEXCOORD3IVARBPROC) (GLenum target, const GLint *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD3SARBPROC) (GLenum target, GLshort s, GLshort t, GLshort r); +typedef void (APIENTRYP PFNGLMULTITEXCOORD3SVARBPROC) (GLenum target, const GLshort *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD4DARBPROC) (GLenum target, GLdouble s, GLdouble t, GLdouble r, GLdouble q); +typedef void (APIENTRYP PFNGLMULTITEXCOORD4DVARBPROC) (GLenum target, const GLdouble *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD4FARBPROC) (GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q); +typedef void (APIENTRYP PFNGLMULTITEXCOORD4FVARBPROC) (GLenum target, const GLfloat *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD4IARBPROC) (GLenum target, GLint s, GLint t, GLint r, GLint q); +typedef void (APIENTRYP PFNGLMULTITEXCOORD4IVARBPROC) (GLenum target, const GLint *v); +typedef void (APIENTRYP PFNGLMULTITEXCOORD4SARBPROC) (GLenum target, GLshort s, GLshort t, GLshort r, GLshort q); +typedef void (APIENTRYP PFNGLMULTITEXCOORD4SVARBPROC) (GLenum target, const GLshort *v); + +#endif /* GL_ARB_multitexture */ + + + +/* + * Define this token if you want "old-style" header file behaviour (extensions + * defined in gl.h). Otherwise, extensions will be included from glext.h. + */ +#if !defined(NO_SDL_GLEXT) && !defined(GL_GLEXT_LEGACY) +#include "SDL_opengl_glext.h" +#endif /* GL_GLEXT_LEGACY */ + + + +/* + * ???. GL_MESA_packed_depth_stencil + * XXX obsolete + */ +#ifndef GL_MESA_packed_depth_stencil +#define GL_MESA_packed_depth_stencil 1 + +#define GL_DEPTH_STENCIL_MESA 0x8750 +#define GL_UNSIGNED_INT_24_8_MESA 0x8751 +#define GL_UNSIGNED_INT_8_24_REV_MESA 0x8752 +#define GL_UNSIGNED_SHORT_15_1_MESA 0x8753 +#define GL_UNSIGNED_SHORT_1_15_REV_MESA 0x8754 + +#endif /* GL_MESA_packed_depth_stencil */ + + +#ifndef GL_ATI_blend_equation_separate +#define GL_ATI_blend_equation_separate 1 + +#define GL_ALPHA_BLEND_EQUATION_ATI 0x883D + +GLAPI void GLAPIENTRY glBlendEquationSeparateATI( GLenum modeRGB, GLenum modeA ); +typedef void (APIENTRYP PFNGLBLENDEQUATIONSEPARATEATIPROC) (GLenum modeRGB, GLenum modeA); + +#endif /* GL_ATI_blend_equation_separate */ + + +/* GL_OES_EGL_image */ +#ifndef GL_OES_EGL_image +typedef void* GLeglImageOES; +#endif + +#ifndef GL_OES_EGL_image +#define GL_OES_EGL_image 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glEGLImageTargetTexture2DOES (GLenum target, GLeglImageOES image); +GLAPI void APIENTRY glEGLImageTargetRenderbufferStorageOES (GLenum target, GLeglImageOES image); +#endif +typedef void (APIENTRYP PFNGLEGLIMAGETARGETTEXTURE2DOESPROC) (GLenum target, GLeglImageOES image); +typedef void (APIENTRYP PFNGLEGLIMAGETARGETRENDERBUFFERSTORAGEOESPROC) (GLenum target, GLeglImageOES image); +#endif + + +/** + ** NOTE!!!!! If you add new functions to this file, or update + ** glext.h be sure to regenerate the gl_mangle.h file. See comments + ** in that file for details. + **/ + + + +/********************************************************************** + * Begin system-specific stuff + */ +#if defined(PRAGMA_EXPORT_SUPPORTED) +#pragma export off +#endif + +/* + * End system-specific stuff + **********************************************************************/ + + +#ifdef __cplusplus +} +#endif + +#endif /* __gl_h_ */ + +#endif /* !__IPHONEOS__ */ + +#endif /* SDL_opengl_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/engine/code/glext.h b/engine/Windows/SDL2/include/SDL_opengl_glext.h similarity index 91% rename from engine/code/glext.h rename to engine/Windows/SDL2/include/SDL_opengl_glext.h index 4fcc17a..6a402b1 100644 --- a/engine/code/glext.h +++ b/engine/Windows/SDL2/include/SDL_opengl_glext.h @@ -6,7 +6,7 @@ extern "C" { #endif /* -** Copyright (c) 2013-2016 The Khronos Group Inc. +** Copyright (c) 2013-2014 The Khronos Group Inc. ** ** Permission is hereby granted, free of charge, to any person obtaining a ** copy of this software and/or associated documentation files (the @@ -33,13 +33,16 @@ extern "C" { ** used to make the header, and the header can be found at ** http://www.opengl.org/registry/ ** -** Khronos $Revision: 32518 $ on $Date: 2016-03-11 05:42:11 -0500 (Fri, 11 Mar 2016) $ +** Khronos $Revision: 26745 $ on $Date: 2014-05-21 03:12:26 -0700 (Wed, 21 May 2014) $ */ #if defined(_WIN32) && !defined(APIENTRY) && !defined(__CYGWIN__) && !defined(__SCITECH_SNAP__) #ifndef WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN 1 #endif +#ifndef NOMINMAX /* don't define min() and max(). */ +#define NOMINMAX +#endif #include #endif @@ -53,7 +56,7 @@ extern "C" { #define GLAPI extern #endif -#define GL_GLEXT_VERSION 20160311 +#define GL_GLEXT_VERSION 20140521 /* Generated C header for: * API: gl @@ -465,8 +468,13 @@ GLAPI void APIENTRY glBlendEquation (GLenum mode); #ifndef GL_VERSION_1_5 #define GL_VERSION_1_5 1 #include +#ifdef __MACOSX__ +typedef long GLsizeiptr; +typedef long GLintptr; +#else typedef ptrdiff_t GLsizeiptr; typedef ptrdiff_t GLintptr; +#endif #define GL_BUFFER_SIZE 0x8764 #define GL_BUFFER_USAGE 0x8765 #define GL_QUERY_COUNTER_BITS 0x8864 @@ -1041,22 +1049,6 @@ typedef unsigned short GLhalf; #define GL_COLOR_ATTACHMENT13 0x8CED #define GL_COLOR_ATTACHMENT14 0x8CEE #define GL_COLOR_ATTACHMENT15 0x8CEF -#define GL_COLOR_ATTACHMENT16 0x8CF0 -#define GL_COLOR_ATTACHMENT17 0x8CF1 -#define GL_COLOR_ATTACHMENT18 0x8CF2 -#define GL_COLOR_ATTACHMENT19 0x8CF3 -#define GL_COLOR_ATTACHMENT20 0x8CF4 -#define GL_COLOR_ATTACHMENT21 0x8CF5 -#define GL_COLOR_ATTACHMENT22 0x8CF6 -#define GL_COLOR_ATTACHMENT23 0x8CF7 -#define GL_COLOR_ATTACHMENT24 0x8CF8 -#define GL_COLOR_ATTACHMENT25 0x8CF9 -#define GL_COLOR_ATTACHMENT26 0x8CFA -#define GL_COLOR_ATTACHMENT27 0x8CFB -#define GL_COLOR_ATTACHMENT28 0x8CFC -#define GL_COLOR_ATTACHMENT29 0x8CFD -#define GL_COLOR_ATTACHMENT30 0x8CFE -#define GL_COLOR_ATTACHMENT31 0x8CFF #define GL_DEPTH_ATTACHMENT 0x8D00 #define GL_STENCIL_ATTACHMENT 0x8D20 #define GL_FRAMEBUFFER 0x8D40 @@ -1324,13 +1316,11 @@ GLAPI GLboolean APIENTRY glIsVertexArray (GLuint array); #define GL_UNIFORM_BUFFER_START 0x8A29 #define GL_UNIFORM_BUFFER_SIZE 0x8A2A #define GL_MAX_VERTEX_UNIFORM_BLOCKS 0x8A2B -#define GL_MAX_GEOMETRY_UNIFORM_BLOCKS 0x8A2C #define GL_MAX_FRAGMENT_UNIFORM_BLOCKS 0x8A2D #define GL_MAX_COMBINED_UNIFORM_BLOCKS 0x8A2E #define GL_MAX_UNIFORM_BUFFER_BINDINGS 0x8A2F #define GL_MAX_UNIFORM_BLOCK_SIZE 0x8A30 #define GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS 0x8A31 -#define GL_MAX_COMBINED_GEOMETRY_UNIFORM_COMPONENTS 0x8A32 #define GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS 0x8A33 #define GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT 0x8A34 #define GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH 0x8A35 @@ -1349,7 +1339,6 @@ GLAPI GLboolean APIENTRY glIsVertexArray (GLuint array); #define GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS 0x8A42 #define GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES 0x8A43 #define GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER 0x8A44 -#define GL_UNIFORM_BLOCK_REFERENCED_BY_GEOMETRY_SHADER 0x8A45 #define GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER 0x8A46 #define GL_INVALID_INDEX 0xFFFFFFFFu typedef void (APIENTRYP PFNGLDRAWARRAYSINSTANCEDPROC) (GLenum mode, GLint first, GLsizei count, GLsizei instancecount); @@ -2060,10 +2049,6 @@ GLAPI void APIENTRY glGetDoublei_v (GLenum target, GLuint index, GLdouble *data) #ifndef GL_VERSION_4_2 #define GL_VERSION_4_2 1 -#define GL_COPY_READ_BUFFER_BINDING 0x8F36 -#define GL_COPY_WRITE_BUFFER_BINDING 0x8F37 -#define GL_TRANSFORM_FEEDBACK_ACTIVE 0x8E24 -#define GL_TRANSFORM_FEEDBACK_PAUSED 0x8E23 #define GL_UNPACK_COMPRESSED_BLOCK_WIDTH 0x9127 #define GL_UNPACK_COMPRESSED_BLOCK_HEIGHT 0x9128 #define GL_UNPACK_COMPRESSED_BLOCK_DEPTH 0x9129 @@ -2235,7 +2220,6 @@ typedef void (APIENTRY *GLDEBUGPROC)(GLenum source,GLenum type,GLuint id,GLenum #define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_COMPUTE_SHADER 0x90ED #define GL_DISPATCH_INDIRECT_BUFFER 0x90EE #define GL_DISPATCH_INDIRECT_BUFFER_BINDING 0x90EF -#define GL_COMPUTE_SHADER_BIT 0x00000020 #define GL_DEBUG_OUTPUT_SYNCHRONOUS 0x8242 #define GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH 0x8243 #define GL_DEBUG_CALLBACK_FUNCTION 0x8244 @@ -2595,297 +2579,10 @@ GLAPI void APIENTRY glBindVertexBuffers (GLuint first, GLsizei count, const GLui #endif #endif /* GL_VERSION_4_4 */ -#ifndef GL_VERSION_4_5 -#define GL_VERSION_4_5 1 -#define GL_CONTEXT_LOST 0x0507 -#define GL_NEGATIVE_ONE_TO_ONE 0x935E -#define GL_ZERO_TO_ONE 0x935F -#define GL_CLIP_ORIGIN 0x935C -#define GL_CLIP_DEPTH_MODE 0x935D -#define GL_QUERY_WAIT_INVERTED 0x8E17 -#define GL_QUERY_NO_WAIT_INVERTED 0x8E18 -#define GL_QUERY_BY_REGION_WAIT_INVERTED 0x8E19 -#define GL_QUERY_BY_REGION_NO_WAIT_INVERTED 0x8E1A -#define GL_MAX_CULL_DISTANCES 0x82F9 -#define GL_MAX_COMBINED_CLIP_AND_CULL_DISTANCES 0x82FA -#define GL_TEXTURE_TARGET 0x1006 -#define GL_QUERY_TARGET 0x82EA -#define GL_GUILTY_CONTEXT_RESET 0x8253 -#define GL_INNOCENT_CONTEXT_RESET 0x8254 -#define GL_UNKNOWN_CONTEXT_RESET 0x8255 -#define GL_RESET_NOTIFICATION_STRATEGY 0x8256 -#define GL_LOSE_CONTEXT_ON_RESET 0x8252 -#define GL_NO_RESET_NOTIFICATION 0x8261 -#define GL_CONTEXT_FLAG_ROBUST_ACCESS_BIT 0x00000004 -#define GL_CONTEXT_RELEASE_BEHAVIOR 0x82FB -#define GL_CONTEXT_RELEASE_BEHAVIOR_FLUSH 0x82FC -typedef void (APIENTRYP PFNGLCLIPCONTROLPROC) (GLenum origin, GLenum depth); -typedef void (APIENTRYP PFNGLCREATETRANSFORMFEEDBACKSPROC) (GLsizei n, GLuint *ids); -typedef void (APIENTRYP PFNGLTRANSFORMFEEDBACKBUFFERBASEPROC) (GLuint xfb, GLuint index, GLuint buffer); -typedef void (APIENTRYP PFNGLTRANSFORMFEEDBACKBUFFERRANGEPROC) (GLuint xfb, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size); -typedef void (APIENTRYP PFNGLGETTRANSFORMFEEDBACKIVPROC) (GLuint xfb, GLenum pname, GLint *param); -typedef void (APIENTRYP PFNGLGETTRANSFORMFEEDBACKI_VPROC) (GLuint xfb, GLenum pname, GLuint index, GLint *param); -typedef void (APIENTRYP PFNGLGETTRANSFORMFEEDBACKI64_VPROC) (GLuint xfb, GLenum pname, GLuint index, GLint64 *param); -typedef void (APIENTRYP PFNGLCREATEBUFFERSPROC) (GLsizei n, GLuint *buffers); -typedef void (APIENTRYP PFNGLNAMEDBUFFERSTORAGEPROC) (GLuint buffer, GLsizeiptr size, const void *data, GLbitfield flags); -typedef void (APIENTRYP PFNGLNAMEDBUFFERDATAPROC) (GLuint buffer, GLsizeiptr size, const void *data, GLenum usage); -typedef void (APIENTRYP PFNGLNAMEDBUFFERSUBDATAPROC) (GLuint buffer, GLintptr offset, GLsizeiptr size, const void *data); -typedef void (APIENTRYP PFNGLCOPYNAMEDBUFFERSUBDATAPROC) (GLuint readBuffer, GLuint writeBuffer, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size); -typedef void (APIENTRYP PFNGLCLEARNAMEDBUFFERDATAPROC) (GLuint buffer, GLenum internalformat, GLenum format, GLenum type, const void *data); -typedef void (APIENTRYP PFNGLCLEARNAMEDBUFFERSUBDATAPROC) (GLuint buffer, GLenum internalformat, GLintptr offset, GLsizeiptr size, GLenum format, GLenum type, const void *data); -typedef void *(APIENTRYP PFNGLMAPNAMEDBUFFERPROC) (GLuint buffer, GLenum access); -typedef void *(APIENTRYP PFNGLMAPNAMEDBUFFERRANGEPROC) (GLuint buffer, GLintptr offset, GLsizeiptr length, GLbitfield access); -typedef GLboolean (APIENTRYP PFNGLUNMAPNAMEDBUFFERPROC) (GLuint buffer); -typedef void (APIENTRYP PFNGLFLUSHMAPPEDNAMEDBUFFERRANGEPROC) (GLuint buffer, GLintptr offset, GLsizeiptr length); -typedef void (APIENTRYP PFNGLGETNAMEDBUFFERPARAMETERIVPROC) (GLuint buffer, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETNAMEDBUFFERPARAMETERI64VPROC) (GLuint buffer, GLenum pname, GLint64 *params); -typedef void (APIENTRYP PFNGLGETNAMEDBUFFERPOINTERVPROC) (GLuint buffer, GLenum pname, void **params); -typedef void (APIENTRYP PFNGLGETNAMEDBUFFERSUBDATAPROC) (GLuint buffer, GLintptr offset, GLsizeiptr size, void *data); -typedef void (APIENTRYP PFNGLCREATEFRAMEBUFFERSPROC) (GLsizei n, GLuint *framebuffers); -typedef void (APIENTRYP PFNGLNAMEDFRAMEBUFFERRENDERBUFFERPROC) (GLuint framebuffer, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); -typedef void (APIENTRYP PFNGLNAMEDFRAMEBUFFERPARAMETERIPROC) (GLuint framebuffer, GLenum pname, GLint param); -typedef void (APIENTRYP PFNGLNAMEDFRAMEBUFFERTEXTUREPROC) (GLuint framebuffer, GLenum attachment, GLuint texture, GLint level); -typedef void (APIENTRYP PFNGLNAMEDFRAMEBUFFERTEXTURELAYERPROC) (GLuint framebuffer, GLenum attachment, GLuint texture, GLint level, GLint layer); -typedef void (APIENTRYP PFNGLNAMEDFRAMEBUFFERDRAWBUFFERPROC) (GLuint framebuffer, GLenum buf); -typedef void (APIENTRYP PFNGLNAMEDFRAMEBUFFERDRAWBUFFERSPROC) (GLuint framebuffer, GLsizei n, const GLenum *bufs); -typedef void (APIENTRYP PFNGLNAMEDFRAMEBUFFERREADBUFFERPROC) (GLuint framebuffer, GLenum src); -typedef void (APIENTRYP PFNGLINVALIDATENAMEDFRAMEBUFFERDATAPROC) (GLuint framebuffer, GLsizei numAttachments, const GLenum *attachments); -typedef void (APIENTRYP PFNGLINVALIDATENAMEDFRAMEBUFFERSUBDATAPROC) (GLuint framebuffer, GLsizei numAttachments, const GLenum *attachments, GLint x, GLint y, GLsizei width, GLsizei height); -typedef void (APIENTRYP PFNGLCLEARNAMEDFRAMEBUFFERIVPROC) (GLuint framebuffer, GLenum buffer, GLint drawbuffer, const GLint *value); -typedef void (APIENTRYP PFNGLCLEARNAMEDFRAMEBUFFERUIVPROC) (GLuint framebuffer, GLenum buffer, GLint drawbuffer, const GLuint *value); -typedef void (APIENTRYP PFNGLCLEARNAMEDFRAMEBUFFERFVPROC) (GLuint framebuffer, GLenum buffer, GLint drawbuffer, const GLfloat *value); -typedef void (APIENTRYP PFNGLCLEARNAMEDFRAMEBUFFERFIPROC) (GLuint framebuffer, GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil); -typedef void (APIENTRYP PFNGLBLITNAMEDFRAMEBUFFERPROC) (GLuint readFramebuffer, GLuint drawFramebuffer, GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); -typedef GLenum (APIENTRYP PFNGLCHECKNAMEDFRAMEBUFFERSTATUSPROC) (GLuint framebuffer, GLenum target); -typedef void (APIENTRYP PFNGLGETNAMEDFRAMEBUFFERPARAMETERIVPROC) (GLuint framebuffer, GLenum pname, GLint *param); -typedef void (APIENTRYP PFNGLGETNAMEDFRAMEBUFFERATTACHMENTPARAMETERIVPROC) (GLuint framebuffer, GLenum attachment, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLCREATERENDERBUFFERSPROC) (GLsizei n, GLuint *renderbuffers); -typedef void (APIENTRYP PFNGLNAMEDRENDERBUFFERSTORAGEPROC) (GLuint renderbuffer, GLenum internalformat, GLsizei width, GLsizei height); -typedef void (APIENTRYP PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLEPROC) (GLuint renderbuffer, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); -typedef void (APIENTRYP PFNGLGETNAMEDRENDERBUFFERPARAMETERIVPROC) (GLuint renderbuffer, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLCREATETEXTURESPROC) (GLenum target, GLsizei n, GLuint *textures); -typedef void (APIENTRYP PFNGLTEXTUREBUFFERPROC) (GLuint texture, GLenum internalformat, GLuint buffer); -typedef void (APIENTRYP PFNGLTEXTUREBUFFERRANGEPROC) (GLuint texture, GLenum internalformat, GLuint buffer, GLintptr offset, GLsizeiptr size); -typedef void (APIENTRYP PFNGLTEXTURESTORAGE1DPROC) (GLuint texture, GLsizei levels, GLenum internalformat, GLsizei width); -typedef void (APIENTRYP PFNGLTEXTURESTORAGE2DPROC) (GLuint texture, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height); -typedef void (APIENTRYP PFNGLTEXTURESTORAGE3DPROC) (GLuint texture, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); -typedef void (APIENTRYP PFNGLTEXTURESTORAGE2DMULTISAMPLEPROC) (GLuint texture, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations); -typedef void (APIENTRYP PFNGLTEXTURESTORAGE3DMULTISAMPLEPROC) (GLuint texture, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations); -typedef void (APIENTRYP PFNGLTEXTURESUBIMAGE1DPROC) (GLuint texture, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const void *pixels); -typedef void (APIENTRYP PFNGLTEXTURESUBIMAGE2DPROC) (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels); -typedef void (APIENTRYP PFNGLTEXTURESUBIMAGE3DPROC) (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *pixels); -typedef void (APIENTRYP PFNGLCOMPRESSEDTEXTURESUBIMAGE1DPROC) (GLuint texture, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const void *data); -typedef void (APIENTRYP PFNGLCOMPRESSEDTEXTURESUBIMAGE2DPROC) (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *data); -typedef void (APIENTRYP PFNGLCOMPRESSEDTEXTURESUBIMAGE3DPROC) (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *data); -typedef void (APIENTRYP PFNGLCOPYTEXTURESUBIMAGE1DPROC) (GLuint texture, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width); -typedef void (APIENTRYP PFNGLCOPYTEXTURESUBIMAGE2DPROC) (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); -typedef void (APIENTRYP PFNGLCOPYTEXTURESUBIMAGE3DPROC) (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); -typedef void (APIENTRYP PFNGLTEXTUREPARAMETERFPROC) (GLuint texture, GLenum pname, GLfloat param); -typedef void (APIENTRYP PFNGLTEXTUREPARAMETERFVPROC) (GLuint texture, GLenum pname, const GLfloat *param); -typedef void (APIENTRYP PFNGLTEXTUREPARAMETERIPROC) (GLuint texture, GLenum pname, GLint param); -typedef void (APIENTRYP PFNGLTEXTUREPARAMETERIIVPROC) (GLuint texture, GLenum pname, const GLint *params); -typedef void (APIENTRYP PFNGLTEXTUREPARAMETERIUIVPROC) (GLuint texture, GLenum pname, const GLuint *params); -typedef void (APIENTRYP PFNGLTEXTUREPARAMETERIVPROC) (GLuint texture, GLenum pname, const GLint *param); -typedef void (APIENTRYP PFNGLGENERATETEXTUREMIPMAPPROC) (GLuint texture); -typedef void (APIENTRYP PFNGLBINDTEXTUREUNITPROC) (GLuint unit, GLuint texture); -typedef void (APIENTRYP PFNGLGETTEXTUREIMAGEPROC) (GLuint texture, GLint level, GLenum format, GLenum type, GLsizei bufSize, void *pixels); -typedef void (APIENTRYP PFNGLGETCOMPRESSEDTEXTUREIMAGEPROC) (GLuint texture, GLint level, GLsizei bufSize, void *pixels); -typedef void (APIENTRYP PFNGLGETTEXTURELEVELPARAMETERFVPROC) (GLuint texture, GLint level, GLenum pname, GLfloat *params); -typedef void (APIENTRYP PFNGLGETTEXTURELEVELPARAMETERIVPROC) (GLuint texture, GLint level, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETTEXTUREPARAMETERFVPROC) (GLuint texture, GLenum pname, GLfloat *params); -typedef void (APIENTRYP PFNGLGETTEXTUREPARAMETERIIVPROC) (GLuint texture, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETTEXTUREPARAMETERIUIVPROC) (GLuint texture, GLenum pname, GLuint *params); -typedef void (APIENTRYP PFNGLGETTEXTUREPARAMETERIVPROC) (GLuint texture, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLCREATEVERTEXARRAYSPROC) (GLsizei n, GLuint *arrays); -typedef void (APIENTRYP PFNGLDISABLEVERTEXARRAYATTRIBPROC) (GLuint vaobj, GLuint index); -typedef void (APIENTRYP PFNGLENABLEVERTEXARRAYATTRIBPROC) (GLuint vaobj, GLuint index); -typedef void (APIENTRYP PFNGLVERTEXARRAYELEMENTBUFFERPROC) (GLuint vaobj, GLuint buffer); -typedef void (APIENTRYP PFNGLVERTEXARRAYVERTEXBUFFERPROC) (GLuint vaobj, GLuint bindingindex, GLuint buffer, GLintptr offset, GLsizei stride); -typedef void (APIENTRYP PFNGLVERTEXARRAYVERTEXBUFFERSPROC) (GLuint vaobj, GLuint first, GLsizei count, const GLuint *buffers, const GLintptr *offsets, const GLsizei *strides); -typedef void (APIENTRYP PFNGLVERTEXARRAYATTRIBBINDINGPROC) (GLuint vaobj, GLuint attribindex, GLuint bindingindex); -typedef void (APIENTRYP PFNGLVERTEXARRAYATTRIBFORMATPROC) (GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLboolean normalized, GLuint relativeoffset); -typedef void (APIENTRYP PFNGLVERTEXARRAYATTRIBIFORMATPROC) (GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset); -typedef void (APIENTRYP PFNGLVERTEXARRAYATTRIBLFORMATPROC) (GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset); -typedef void (APIENTRYP PFNGLVERTEXARRAYBINDINGDIVISORPROC) (GLuint vaobj, GLuint bindingindex, GLuint divisor); -typedef void (APIENTRYP PFNGLGETVERTEXARRAYIVPROC) (GLuint vaobj, GLenum pname, GLint *param); -typedef void (APIENTRYP PFNGLGETVERTEXARRAYINDEXEDIVPROC) (GLuint vaobj, GLuint index, GLenum pname, GLint *param); -typedef void (APIENTRYP PFNGLGETVERTEXARRAYINDEXED64IVPROC) (GLuint vaobj, GLuint index, GLenum pname, GLint64 *param); -typedef void (APIENTRYP PFNGLCREATESAMPLERSPROC) (GLsizei n, GLuint *samplers); -typedef void (APIENTRYP PFNGLCREATEPROGRAMPIPELINESPROC) (GLsizei n, GLuint *pipelines); -typedef void (APIENTRYP PFNGLCREATEQUERIESPROC) (GLenum target, GLsizei n, GLuint *ids); -typedef void (APIENTRYP PFNGLGETQUERYBUFFEROBJECTI64VPROC) (GLuint id, GLuint buffer, GLenum pname, GLintptr offset); -typedef void (APIENTRYP PFNGLGETQUERYBUFFEROBJECTIVPROC) (GLuint id, GLuint buffer, GLenum pname, GLintptr offset); -typedef void (APIENTRYP PFNGLGETQUERYBUFFEROBJECTUI64VPROC) (GLuint id, GLuint buffer, GLenum pname, GLintptr offset); -typedef void (APIENTRYP PFNGLGETQUERYBUFFEROBJECTUIVPROC) (GLuint id, GLuint buffer, GLenum pname, GLintptr offset); -typedef void (APIENTRYP PFNGLMEMORYBARRIERBYREGIONPROC) (GLbitfield barriers); -typedef void (APIENTRYP PFNGLGETTEXTURESUBIMAGEPROC) (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, GLsizei bufSize, void *pixels); -typedef void (APIENTRYP PFNGLGETCOMPRESSEDTEXTURESUBIMAGEPROC) (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLsizei bufSize, void *pixels); -typedef GLenum (APIENTRYP PFNGLGETGRAPHICSRESETSTATUSPROC) (void); -typedef void (APIENTRYP PFNGLGETNCOMPRESSEDTEXIMAGEPROC) (GLenum target, GLint lod, GLsizei bufSize, void *pixels); -typedef void (APIENTRYP PFNGLGETNTEXIMAGEPROC) (GLenum target, GLint level, GLenum format, GLenum type, GLsizei bufSize, void *pixels); -typedef void (APIENTRYP PFNGLGETNUNIFORMDVPROC) (GLuint program, GLint location, GLsizei bufSize, GLdouble *params); -typedef void (APIENTRYP PFNGLGETNUNIFORMFVPROC) (GLuint program, GLint location, GLsizei bufSize, GLfloat *params); -typedef void (APIENTRYP PFNGLGETNUNIFORMIVPROC) (GLuint program, GLint location, GLsizei bufSize, GLint *params); -typedef void (APIENTRYP PFNGLGETNUNIFORMUIVPROC) (GLuint program, GLint location, GLsizei bufSize, GLuint *params); -typedef void (APIENTRYP PFNGLREADNPIXELSPROC) (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei bufSize, void *data); -typedef void (APIENTRYP PFNGLGETNMAPDVPROC) (GLenum target, GLenum query, GLsizei bufSize, GLdouble *v); -typedef void (APIENTRYP PFNGLGETNMAPFVPROC) (GLenum target, GLenum query, GLsizei bufSize, GLfloat *v); -typedef void (APIENTRYP PFNGLGETNMAPIVPROC) (GLenum target, GLenum query, GLsizei bufSize, GLint *v); -typedef void (APIENTRYP PFNGLGETNPIXELMAPFVPROC) (GLenum map, GLsizei bufSize, GLfloat *values); -typedef void (APIENTRYP PFNGLGETNPIXELMAPUIVPROC) (GLenum map, GLsizei bufSize, GLuint *values); -typedef void (APIENTRYP PFNGLGETNPIXELMAPUSVPROC) (GLenum map, GLsizei bufSize, GLushort *values); -typedef void (APIENTRYP PFNGLGETNPOLYGONSTIPPLEPROC) (GLsizei bufSize, GLubyte *pattern); -typedef void (APIENTRYP PFNGLGETNCOLORTABLEPROC) (GLenum target, GLenum format, GLenum type, GLsizei bufSize, void *table); -typedef void (APIENTRYP PFNGLGETNCONVOLUTIONFILTERPROC) (GLenum target, GLenum format, GLenum type, GLsizei bufSize, void *image); -typedef void (APIENTRYP PFNGLGETNSEPARABLEFILTERPROC) (GLenum target, GLenum format, GLenum type, GLsizei rowBufSize, void *row, GLsizei columnBufSize, void *column, void *span); -typedef void (APIENTRYP PFNGLGETNHISTOGRAMPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, GLsizei bufSize, void *values); -typedef void (APIENTRYP PFNGLGETNMINMAXPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, GLsizei bufSize, void *values); -typedef void (APIENTRYP PFNGLTEXTUREBARRIERPROC) (void); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glClipControl (GLenum origin, GLenum depth); -GLAPI void APIENTRY glCreateTransformFeedbacks (GLsizei n, GLuint *ids); -GLAPI void APIENTRY glTransformFeedbackBufferBase (GLuint xfb, GLuint index, GLuint buffer); -GLAPI void APIENTRY glTransformFeedbackBufferRange (GLuint xfb, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size); -GLAPI void APIENTRY glGetTransformFeedbackiv (GLuint xfb, GLenum pname, GLint *param); -GLAPI void APIENTRY glGetTransformFeedbacki_v (GLuint xfb, GLenum pname, GLuint index, GLint *param); -GLAPI void APIENTRY glGetTransformFeedbacki64_v (GLuint xfb, GLenum pname, GLuint index, GLint64 *param); -GLAPI void APIENTRY glCreateBuffers (GLsizei n, GLuint *buffers); -GLAPI void APIENTRY glNamedBufferStorage (GLuint buffer, GLsizeiptr size, const void *data, GLbitfield flags); -GLAPI void APIENTRY glNamedBufferData (GLuint buffer, GLsizeiptr size, const void *data, GLenum usage); -GLAPI void APIENTRY glNamedBufferSubData (GLuint buffer, GLintptr offset, GLsizeiptr size, const void *data); -GLAPI void APIENTRY glCopyNamedBufferSubData (GLuint readBuffer, GLuint writeBuffer, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size); -GLAPI void APIENTRY glClearNamedBufferData (GLuint buffer, GLenum internalformat, GLenum format, GLenum type, const void *data); -GLAPI void APIENTRY glClearNamedBufferSubData (GLuint buffer, GLenum internalformat, GLintptr offset, GLsizeiptr size, GLenum format, GLenum type, const void *data); -GLAPI void *APIENTRY glMapNamedBuffer (GLuint buffer, GLenum access); -GLAPI void *APIENTRY glMapNamedBufferRange (GLuint buffer, GLintptr offset, GLsizeiptr length, GLbitfield access); -GLAPI GLboolean APIENTRY glUnmapNamedBuffer (GLuint buffer); -GLAPI void APIENTRY glFlushMappedNamedBufferRange (GLuint buffer, GLintptr offset, GLsizeiptr length); -GLAPI void APIENTRY glGetNamedBufferParameteriv (GLuint buffer, GLenum pname, GLint *params); -GLAPI void APIENTRY glGetNamedBufferParameteri64v (GLuint buffer, GLenum pname, GLint64 *params); -GLAPI void APIENTRY glGetNamedBufferPointerv (GLuint buffer, GLenum pname, void **params); -GLAPI void APIENTRY glGetNamedBufferSubData (GLuint buffer, GLintptr offset, GLsizeiptr size, void *data); -GLAPI void APIENTRY glCreateFramebuffers (GLsizei n, GLuint *framebuffers); -GLAPI void APIENTRY glNamedFramebufferRenderbuffer (GLuint framebuffer, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); -GLAPI void APIENTRY glNamedFramebufferParameteri (GLuint framebuffer, GLenum pname, GLint param); -GLAPI void APIENTRY glNamedFramebufferTexture (GLuint framebuffer, GLenum attachment, GLuint texture, GLint level); -GLAPI void APIENTRY glNamedFramebufferTextureLayer (GLuint framebuffer, GLenum attachment, GLuint texture, GLint level, GLint layer); -GLAPI void APIENTRY glNamedFramebufferDrawBuffer (GLuint framebuffer, GLenum buf); -GLAPI void APIENTRY glNamedFramebufferDrawBuffers (GLuint framebuffer, GLsizei n, const GLenum *bufs); -GLAPI void APIENTRY glNamedFramebufferReadBuffer (GLuint framebuffer, GLenum src); -GLAPI void APIENTRY glInvalidateNamedFramebufferData (GLuint framebuffer, GLsizei numAttachments, const GLenum *attachments); -GLAPI void APIENTRY glInvalidateNamedFramebufferSubData (GLuint framebuffer, GLsizei numAttachments, const GLenum *attachments, GLint x, GLint y, GLsizei width, GLsizei height); -GLAPI void APIENTRY glClearNamedFramebufferiv (GLuint framebuffer, GLenum buffer, GLint drawbuffer, const GLint *value); -GLAPI void APIENTRY glClearNamedFramebufferuiv (GLuint framebuffer, GLenum buffer, GLint drawbuffer, const GLuint *value); -GLAPI void APIENTRY glClearNamedFramebufferfv (GLuint framebuffer, GLenum buffer, GLint drawbuffer, const GLfloat *value); -GLAPI void APIENTRY glClearNamedFramebufferfi (GLuint framebuffer, GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil); -GLAPI void APIENTRY glBlitNamedFramebuffer (GLuint readFramebuffer, GLuint drawFramebuffer, GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); -GLAPI GLenum APIENTRY glCheckNamedFramebufferStatus (GLuint framebuffer, GLenum target); -GLAPI void APIENTRY glGetNamedFramebufferParameteriv (GLuint framebuffer, GLenum pname, GLint *param); -GLAPI void APIENTRY glGetNamedFramebufferAttachmentParameteriv (GLuint framebuffer, GLenum attachment, GLenum pname, GLint *params); -GLAPI void APIENTRY glCreateRenderbuffers (GLsizei n, GLuint *renderbuffers); -GLAPI void APIENTRY glNamedRenderbufferStorage (GLuint renderbuffer, GLenum internalformat, GLsizei width, GLsizei height); -GLAPI void APIENTRY glNamedRenderbufferStorageMultisample (GLuint renderbuffer, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); -GLAPI void APIENTRY glGetNamedRenderbufferParameteriv (GLuint renderbuffer, GLenum pname, GLint *params); -GLAPI void APIENTRY glCreateTextures (GLenum target, GLsizei n, GLuint *textures); -GLAPI void APIENTRY glTextureBuffer (GLuint texture, GLenum internalformat, GLuint buffer); -GLAPI void APIENTRY glTextureBufferRange (GLuint texture, GLenum internalformat, GLuint buffer, GLintptr offset, GLsizeiptr size); -GLAPI void APIENTRY glTextureStorage1D (GLuint texture, GLsizei levels, GLenum internalformat, GLsizei width); -GLAPI void APIENTRY glTextureStorage2D (GLuint texture, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height); -GLAPI void APIENTRY glTextureStorage3D (GLuint texture, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); -GLAPI void APIENTRY glTextureStorage2DMultisample (GLuint texture, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations); -GLAPI void APIENTRY glTextureStorage3DMultisample (GLuint texture, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations); -GLAPI void APIENTRY glTextureSubImage1D (GLuint texture, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const void *pixels); -GLAPI void APIENTRY glTextureSubImage2D (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels); -GLAPI void APIENTRY glTextureSubImage3D (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *pixels); -GLAPI void APIENTRY glCompressedTextureSubImage1D (GLuint texture, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const void *data); -GLAPI void APIENTRY glCompressedTextureSubImage2D (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *data); -GLAPI void APIENTRY glCompressedTextureSubImage3D (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *data); -GLAPI void APIENTRY glCopyTextureSubImage1D (GLuint texture, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width); -GLAPI void APIENTRY glCopyTextureSubImage2D (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); -GLAPI void APIENTRY glCopyTextureSubImage3D (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); -GLAPI void APIENTRY glTextureParameterf (GLuint texture, GLenum pname, GLfloat param); -GLAPI void APIENTRY glTextureParameterfv (GLuint texture, GLenum pname, const GLfloat *param); -GLAPI void APIENTRY glTextureParameteri (GLuint texture, GLenum pname, GLint param); -GLAPI void APIENTRY glTextureParameterIiv (GLuint texture, GLenum pname, const GLint *params); -GLAPI void APIENTRY glTextureParameterIuiv (GLuint texture, GLenum pname, const GLuint *params); -GLAPI void APIENTRY glTextureParameteriv (GLuint texture, GLenum pname, const GLint *param); -GLAPI void APIENTRY glGenerateTextureMipmap (GLuint texture); -GLAPI void APIENTRY glBindTextureUnit (GLuint unit, GLuint texture); -GLAPI void APIENTRY glGetTextureImage (GLuint texture, GLint level, GLenum format, GLenum type, GLsizei bufSize, void *pixels); -GLAPI void APIENTRY glGetCompressedTextureImage (GLuint texture, GLint level, GLsizei bufSize, void *pixels); -GLAPI void APIENTRY glGetTextureLevelParameterfv (GLuint texture, GLint level, GLenum pname, GLfloat *params); -GLAPI void APIENTRY glGetTextureLevelParameteriv (GLuint texture, GLint level, GLenum pname, GLint *params); -GLAPI void APIENTRY glGetTextureParameterfv (GLuint texture, GLenum pname, GLfloat *params); -GLAPI void APIENTRY glGetTextureParameterIiv (GLuint texture, GLenum pname, GLint *params); -GLAPI void APIENTRY glGetTextureParameterIuiv (GLuint texture, GLenum pname, GLuint *params); -GLAPI void APIENTRY glGetTextureParameteriv (GLuint texture, GLenum pname, GLint *params); -GLAPI void APIENTRY glCreateVertexArrays (GLsizei n, GLuint *arrays); -GLAPI void APIENTRY glDisableVertexArrayAttrib (GLuint vaobj, GLuint index); -GLAPI void APIENTRY glEnableVertexArrayAttrib (GLuint vaobj, GLuint index); -GLAPI void APIENTRY glVertexArrayElementBuffer (GLuint vaobj, GLuint buffer); -GLAPI void APIENTRY glVertexArrayVertexBuffer (GLuint vaobj, GLuint bindingindex, GLuint buffer, GLintptr offset, GLsizei stride); -GLAPI void APIENTRY glVertexArrayVertexBuffers (GLuint vaobj, GLuint first, GLsizei count, const GLuint *buffers, const GLintptr *offsets, const GLsizei *strides); -GLAPI void APIENTRY glVertexArrayAttribBinding (GLuint vaobj, GLuint attribindex, GLuint bindingindex); -GLAPI void APIENTRY glVertexArrayAttribFormat (GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLboolean normalized, GLuint relativeoffset); -GLAPI void APIENTRY glVertexArrayAttribIFormat (GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset); -GLAPI void APIENTRY glVertexArrayAttribLFormat (GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset); -GLAPI void APIENTRY glVertexArrayBindingDivisor (GLuint vaobj, GLuint bindingindex, GLuint divisor); -GLAPI void APIENTRY glGetVertexArrayiv (GLuint vaobj, GLenum pname, GLint *param); -GLAPI void APIENTRY glGetVertexArrayIndexediv (GLuint vaobj, GLuint index, GLenum pname, GLint *param); -GLAPI void APIENTRY glGetVertexArrayIndexed64iv (GLuint vaobj, GLuint index, GLenum pname, GLint64 *param); -GLAPI void APIENTRY glCreateSamplers (GLsizei n, GLuint *samplers); -GLAPI void APIENTRY glCreateProgramPipelines (GLsizei n, GLuint *pipelines); -GLAPI void APIENTRY glCreateQueries (GLenum target, GLsizei n, GLuint *ids); -GLAPI void APIENTRY glGetQueryBufferObjecti64v (GLuint id, GLuint buffer, GLenum pname, GLintptr offset); -GLAPI void APIENTRY glGetQueryBufferObjectiv (GLuint id, GLuint buffer, GLenum pname, GLintptr offset); -GLAPI void APIENTRY glGetQueryBufferObjectui64v (GLuint id, GLuint buffer, GLenum pname, GLintptr offset); -GLAPI void APIENTRY glGetQueryBufferObjectuiv (GLuint id, GLuint buffer, GLenum pname, GLintptr offset); -GLAPI void APIENTRY glMemoryBarrierByRegion (GLbitfield barriers); -GLAPI void APIENTRY glGetTextureSubImage (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, GLsizei bufSize, void *pixels); -GLAPI void APIENTRY glGetCompressedTextureSubImage (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLsizei bufSize, void *pixels); -GLAPI GLenum APIENTRY glGetGraphicsResetStatus (void); -GLAPI void APIENTRY glGetnCompressedTexImage (GLenum target, GLint lod, GLsizei bufSize, void *pixels); -GLAPI void APIENTRY glGetnTexImage (GLenum target, GLint level, GLenum format, GLenum type, GLsizei bufSize, void *pixels); -GLAPI void APIENTRY glGetnUniformdv (GLuint program, GLint location, GLsizei bufSize, GLdouble *params); -GLAPI void APIENTRY glGetnUniformfv (GLuint program, GLint location, GLsizei bufSize, GLfloat *params); -GLAPI void APIENTRY glGetnUniformiv (GLuint program, GLint location, GLsizei bufSize, GLint *params); -GLAPI void APIENTRY glGetnUniformuiv (GLuint program, GLint location, GLsizei bufSize, GLuint *params); -GLAPI void APIENTRY glReadnPixels (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei bufSize, void *data); -GLAPI void APIENTRY glGetnMapdv (GLenum target, GLenum query, GLsizei bufSize, GLdouble *v); -GLAPI void APIENTRY glGetnMapfv (GLenum target, GLenum query, GLsizei bufSize, GLfloat *v); -GLAPI void APIENTRY glGetnMapiv (GLenum target, GLenum query, GLsizei bufSize, GLint *v); -GLAPI void APIENTRY glGetnPixelMapfv (GLenum map, GLsizei bufSize, GLfloat *values); -GLAPI void APIENTRY glGetnPixelMapuiv (GLenum map, GLsizei bufSize, GLuint *values); -GLAPI void APIENTRY glGetnPixelMapusv (GLenum map, GLsizei bufSize, GLushort *values); -GLAPI void APIENTRY glGetnPolygonStipple (GLsizei bufSize, GLubyte *pattern); -GLAPI void APIENTRY glGetnColorTable (GLenum target, GLenum format, GLenum type, GLsizei bufSize, void *table); -GLAPI void APIENTRY glGetnConvolutionFilter (GLenum target, GLenum format, GLenum type, GLsizei bufSize, void *image); -GLAPI void APIENTRY glGetnSeparableFilter (GLenum target, GLenum format, GLenum type, GLsizei rowBufSize, void *row, GLsizei columnBufSize, void *column, void *span); -GLAPI void APIENTRY glGetnHistogram (GLenum target, GLboolean reset, GLenum format, GLenum type, GLsizei bufSize, void *values); -GLAPI void APIENTRY glGetnMinmax (GLenum target, GLboolean reset, GLenum format, GLenum type, GLsizei bufSize, void *values); -GLAPI void APIENTRY glTextureBarrier (void); -#endif -#endif /* GL_VERSION_4_5 */ - #ifndef GL_ARB_ES2_compatibility #define GL_ARB_ES2_compatibility 1 #endif /* GL_ARB_ES2_compatibility */ -#ifndef GL_ARB_ES3_1_compatibility -#define GL_ARB_ES3_1_compatibility 1 -#endif /* GL_ARB_ES3_1_compatibility */ - -#ifndef GL_ARB_ES3_2_compatibility -#define GL_ARB_ES3_2_compatibility 1 -#define GL_PRIMITIVE_BOUNDING_BOX_ARB 0x92BE -#define GL_MULTISAMPLE_LINE_WIDTH_RANGE_ARB 0x9381 -#define GL_MULTISAMPLE_LINE_WIDTH_GRANULARITY_ARB 0x9382 -typedef void (APIENTRYP PFNGLPRIMITIVEBOUNDINGBOXARBPROC) (GLfloat minX, GLfloat minY, GLfloat minZ, GLfloat minW, GLfloat maxX, GLfloat maxY, GLfloat maxZ, GLfloat maxW); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glPrimitiveBoundingBoxARB (GLfloat minX, GLfloat minY, GLfloat minZ, GLfloat minW, GLfloat maxX, GLfloat maxY, GLfloat maxZ, GLfloat maxW); -#endif -#endif /* GL_ARB_ES3_2_compatibility */ - #ifndef GL_ARB_ES3_compatibility #define GL_ARB_ES3_compatibility 1 #endif /* GL_ARB_ES3_compatibility */ @@ -2966,10 +2663,6 @@ GLAPI GLsync APIENTRY glCreateSyncFromCLeventARB (struct _cl_context *context, s #define GL_ARB_clear_texture 1 #endif /* GL_ARB_clear_texture */ -#ifndef GL_ARB_clip_control -#define GL_ARB_clip_control 1 -#endif /* GL_ARB_clip_control */ - #ifndef GL_ARB_color_buffer_float #define GL_ARB_color_buffer_float 1 #define GL_RGBA_FLOAT_MODE_ARB 0x8820 @@ -2993,6 +2686,7 @@ GLAPI void APIENTRY glClampColorARB (GLenum target, GLenum clamp); #ifndef GL_ARB_compute_shader #define GL_ARB_compute_shader 1 +#define GL_COMPUTE_SHADER_BIT 0x00000020 #endif /* GL_ARB_compute_shader */ #ifndef GL_ARB_compute_variable_group_size @@ -3007,26 +2701,20 @@ GLAPI void APIENTRY glDispatchComputeGroupSizeARB (GLuint num_groups_x, GLuint n #endif #endif /* GL_ARB_compute_variable_group_size */ -#ifndef GL_ARB_conditional_render_inverted -#define GL_ARB_conditional_render_inverted 1 -#endif /* GL_ARB_conditional_render_inverted */ - #ifndef GL_ARB_conservative_depth #define GL_ARB_conservative_depth 1 #endif /* GL_ARB_conservative_depth */ #ifndef GL_ARB_copy_buffer #define GL_ARB_copy_buffer 1 +#define GL_COPY_READ_BUFFER_BINDING 0x8F36 +#define GL_COPY_WRITE_BUFFER_BINDING 0x8F37 #endif /* GL_ARB_copy_buffer */ #ifndef GL_ARB_copy_image #define GL_ARB_copy_image 1 #endif /* GL_ARB_copy_image */ -#ifndef GL_ARB_cull_distance -#define GL_ARB_cull_distance 1 -#endif /* GL_ARB_cull_distance */ - #ifndef GL_ARB_debug_output #define GL_ARB_debug_output 1 typedef void (APIENTRY *GLDEBUGPROCARB)(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar *message,const void *userParam); @@ -3081,14 +2769,6 @@ GLAPI GLuint APIENTRY glGetDebugMessageLogARB (GLuint count, GLsizei bufSize, GL #define GL_DEPTH_TEXTURE_MODE_ARB 0x884B #endif /* GL_ARB_depth_texture */ -#ifndef GL_ARB_derivative_control -#define GL_ARB_derivative_control 1 -#endif /* GL_ARB_derivative_control */ - -#ifndef GL_ARB_direct_state_access -#define GL_ARB_direct_state_access 1 -#endif /* GL_ARB_direct_state_access */ - #ifndef GL_ARB_draw_buffers #define GL_ARB_draw_buffers 1 #define GL_MAX_DRAW_BUFFERS_ARB 0x8824 @@ -3299,10 +2979,6 @@ GLAPI GLboolean APIENTRY glIsProgramARB (GLuint program); #define GL_FRAGMENT_SHADER_DERIVATIVE_HINT_ARB 0x8B8B #endif /* GL_ARB_fragment_shader */ -#ifndef GL_ARB_fragment_shader_interlock -#define GL_ARB_fragment_shader_interlock 1 -#endif /* GL_ARB_fragment_shader_interlock */ - #ifndef GL_ARB_framebuffer_no_attachments #define GL_ARB_framebuffer_no_attachments 1 #endif /* GL_ARB_framebuffer_no_attachments */ @@ -3315,6 +2991,11 @@ GLAPI GLboolean APIENTRY glIsProgramARB (GLuint program); #define GL_ARB_framebuffer_sRGB 1 #endif /* GL_ARB_framebuffer_sRGB */ +#ifndef GL_KHR_context_flush_control +#define GL_CONTEXT_RELEASE_BEHAVIOR 0x82FB +#define GL_CONTEXT_RELEASE_BEHAVIOR_FLUSH 0x82FC +#endif /* GL_KHR_context_flush_control */ + #ifndef GL_ARB_geometry_shader4 #define GL_ARB_geometry_shader4 1 #define GL_LINES_ADJACENCY_ARB 0x000A @@ -3351,10 +3032,6 @@ GLAPI void APIENTRY glFramebufferTextureFaceARB (GLenum target, GLenum attachmen #define GL_ARB_get_program_binary 1 #endif /* GL_ARB_get_program_binary */ -#ifndef GL_ARB_get_texture_sub_image -#define GL_ARB_get_texture_sub_image 1 -#endif /* GL_ARB_get_texture_sub_image */ - #ifndef GL_ARB_gpu_shader5 #define GL_ARB_gpu_shader5 1 #endif /* GL_ARB_gpu_shader5 */ @@ -3363,91 +3040,6 @@ GLAPI void APIENTRY glFramebufferTextureFaceARB (GLenum target, GLenum attachmen #define GL_ARB_gpu_shader_fp64 1 #endif /* GL_ARB_gpu_shader_fp64 */ -#ifndef GL_ARB_gpu_shader_int64 -#define GL_ARB_gpu_shader_int64 1 -#define GL_INT64_ARB 0x140E -#define GL_INT64_VEC2_ARB 0x8FE9 -#define GL_INT64_VEC3_ARB 0x8FEA -#define GL_INT64_VEC4_ARB 0x8FEB -#define GL_UNSIGNED_INT64_VEC2_ARB 0x8FF5 -#define GL_UNSIGNED_INT64_VEC3_ARB 0x8FF6 -#define GL_UNSIGNED_INT64_VEC4_ARB 0x8FF7 -typedef void (APIENTRYP PFNGLUNIFORM1I64ARBPROC) (GLint location, GLint64 x); -typedef void (APIENTRYP PFNGLUNIFORM2I64ARBPROC) (GLint location, GLint64 x, GLint64 y); -typedef void (APIENTRYP PFNGLUNIFORM3I64ARBPROC) (GLint location, GLint64 x, GLint64 y, GLint64 z); -typedef void (APIENTRYP PFNGLUNIFORM4I64ARBPROC) (GLint location, GLint64 x, GLint64 y, GLint64 z, GLint64 w); -typedef void (APIENTRYP PFNGLUNIFORM1I64VARBPROC) (GLint location, GLsizei count, const GLint64 *value); -typedef void (APIENTRYP PFNGLUNIFORM2I64VARBPROC) (GLint location, GLsizei count, const GLint64 *value); -typedef void (APIENTRYP PFNGLUNIFORM3I64VARBPROC) (GLint location, GLsizei count, const GLint64 *value); -typedef void (APIENTRYP PFNGLUNIFORM4I64VARBPROC) (GLint location, GLsizei count, const GLint64 *value); -typedef void (APIENTRYP PFNGLUNIFORM1UI64ARBPROC) (GLint location, GLuint64 x); -typedef void (APIENTRYP PFNGLUNIFORM2UI64ARBPROC) (GLint location, GLuint64 x, GLuint64 y); -typedef void (APIENTRYP PFNGLUNIFORM3UI64ARBPROC) (GLint location, GLuint64 x, GLuint64 y, GLuint64 z); -typedef void (APIENTRYP PFNGLUNIFORM4UI64ARBPROC) (GLint location, GLuint64 x, GLuint64 y, GLuint64 z, GLuint64 w); -typedef void (APIENTRYP PFNGLUNIFORM1UI64VARBPROC) (GLint location, GLsizei count, const GLuint64 *value); -typedef void (APIENTRYP PFNGLUNIFORM2UI64VARBPROC) (GLint location, GLsizei count, const GLuint64 *value); -typedef void (APIENTRYP PFNGLUNIFORM3UI64VARBPROC) (GLint location, GLsizei count, const GLuint64 *value); -typedef void (APIENTRYP PFNGLUNIFORM4UI64VARBPROC) (GLint location, GLsizei count, const GLuint64 *value); -typedef void (APIENTRYP PFNGLGETUNIFORMI64VARBPROC) (GLuint program, GLint location, GLint64 *params); -typedef void (APIENTRYP PFNGLGETUNIFORMUI64VARBPROC) (GLuint program, GLint location, GLuint64 *params); -typedef void (APIENTRYP PFNGLGETNUNIFORMI64VARBPROC) (GLuint program, GLint location, GLsizei bufSize, GLint64 *params); -typedef void (APIENTRYP PFNGLGETNUNIFORMUI64VARBPROC) (GLuint program, GLint location, GLsizei bufSize, GLuint64 *params); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1I64ARBPROC) (GLuint program, GLint location, GLint64 x); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2I64ARBPROC) (GLuint program, GLint location, GLint64 x, GLint64 y); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3I64ARBPROC) (GLuint program, GLint location, GLint64 x, GLint64 y, GLint64 z); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4I64ARBPROC) (GLuint program, GLint location, GLint64 x, GLint64 y, GLint64 z, GLint64 w); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1I64VARBPROC) (GLuint program, GLint location, GLsizei count, const GLint64 *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2I64VARBPROC) (GLuint program, GLint location, GLsizei count, const GLint64 *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3I64VARBPROC) (GLuint program, GLint location, GLsizei count, const GLint64 *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4I64VARBPROC) (GLuint program, GLint location, GLsizei count, const GLint64 *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1UI64ARBPROC) (GLuint program, GLint location, GLuint64 x); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2UI64ARBPROC) (GLuint program, GLint location, GLuint64 x, GLuint64 y); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3UI64ARBPROC) (GLuint program, GLint location, GLuint64 x, GLuint64 y, GLuint64 z); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4UI64ARBPROC) (GLuint program, GLint location, GLuint64 x, GLuint64 y, GLuint64 z, GLuint64 w); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1UI64VARBPROC) (GLuint program, GLint location, GLsizei count, const GLuint64 *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2UI64VARBPROC) (GLuint program, GLint location, GLsizei count, const GLuint64 *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3UI64VARBPROC) (GLuint program, GLint location, GLsizei count, const GLuint64 *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4UI64VARBPROC) (GLuint program, GLint location, GLsizei count, const GLuint64 *value); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glUniform1i64ARB (GLint location, GLint64 x); -GLAPI void APIENTRY glUniform2i64ARB (GLint location, GLint64 x, GLint64 y); -GLAPI void APIENTRY glUniform3i64ARB (GLint location, GLint64 x, GLint64 y, GLint64 z); -GLAPI void APIENTRY glUniform4i64ARB (GLint location, GLint64 x, GLint64 y, GLint64 z, GLint64 w); -GLAPI void APIENTRY glUniform1i64vARB (GLint location, GLsizei count, const GLint64 *value); -GLAPI void APIENTRY glUniform2i64vARB (GLint location, GLsizei count, const GLint64 *value); -GLAPI void APIENTRY glUniform3i64vARB (GLint location, GLsizei count, const GLint64 *value); -GLAPI void APIENTRY glUniform4i64vARB (GLint location, GLsizei count, const GLint64 *value); -GLAPI void APIENTRY glUniform1ui64ARB (GLint location, GLuint64 x); -GLAPI void APIENTRY glUniform2ui64ARB (GLint location, GLuint64 x, GLuint64 y); -GLAPI void APIENTRY glUniform3ui64ARB (GLint location, GLuint64 x, GLuint64 y, GLuint64 z); -GLAPI void APIENTRY glUniform4ui64ARB (GLint location, GLuint64 x, GLuint64 y, GLuint64 z, GLuint64 w); -GLAPI void APIENTRY glUniform1ui64vARB (GLint location, GLsizei count, const GLuint64 *value); -GLAPI void APIENTRY glUniform2ui64vARB (GLint location, GLsizei count, const GLuint64 *value); -GLAPI void APIENTRY glUniform3ui64vARB (GLint location, GLsizei count, const GLuint64 *value); -GLAPI void APIENTRY glUniform4ui64vARB (GLint location, GLsizei count, const GLuint64 *value); -GLAPI void APIENTRY glGetUniformi64vARB (GLuint program, GLint location, GLint64 *params); -GLAPI void APIENTRY glGetUniformui64vARB (GLuint program, GLint location, GLuint64 *params); -GLAPI void APIENTRY glGetnUniformi64vARB (GLuint program, GLint location, GLsizei bufSize, GLint64 *params); -GLAPI void APIENTRY glGetnUniformui64vARB (GLuint program, GLint location, GLsizei bufSize, GLuint64 *params); -GLAPI void APIENTRY glProgramUniform1i64ARB (GLuint program, GLint location, GLint64 x); -GLAPI void APIENTRY glProgramUniform2i64ARB (GLuint program, GLint location, GLint64 x, GLint64 y); -GLAPI void APIENTRY glProgramUniform3i64ARB (GLuint program, GLint location, GLint64 x, GLint64 y, GLint64 z); -GLAPI void APIENTRY glProgramUniform4i64ARB (GLuint program, GLint location, GLint64 x, GLint64 y, GLint64 z, GLint64 w); -GLAPI void APIENTRY glProgramUniform1i64vARB (GLuint program, GLint location, GLsizei count, const GLint64 *value); -GLAPI void APIENTRY glProgramUniform2i64vARB (GLuint program, GLint location, GLsizei count, const GLint64 *value); -GLAPI void APIENTRY glProgramUniform3i64vARB (GLuint program, GLint location, GLsizei count, const GLint64 *value); -GLAPI void APIENTRY glProgramUniform4i64vARB (GLuint program, GLint location, GLsizei count, const GLint64 *value); -GLAPI void APIENTRY glProgramUniform1ui64ARB (GLuint program, GLint location, GLuint64 x); -GLAPI void APIENTRY glProgramUniform2ui64ARB (GLuint program, GLint location, GLuint64 x, GLuint64 y); -GLAPI void APIENTRY glProgramUniform3ui64ARB (GLuint program, GLint location, GLuint64 x, GLuint64 y, GLuint64 z); -GLAPI void APIENTRY glProgramUniform4ui64ARB (GLuint program, GLint location, GLuint64 x, GLuint64 y, GLuint64 z, GLuint64 w); -GLAPI void APIENTRY glProgramUniform1ui64vARB (GLuint program, GLint location, GLsizei count, const GLuint64 *value); -GLAPI void APIENTRY glProgramUniform2ui64vARB (GLuint program, GLint location, GLsizei count, const GLuint64 *value); -GLAPI void APIENTRY glProgramUniform3ui64vARB (GLuint program, GLint location, GLsizei count, const GLuint64 *value); -GLAPI void APIENTRY glProgramUniform4ui64vARB (GLuint program, GLint location, GLsizei count, const GLuint64 *value); -#endif -#endif /* GL_ARB_gpu_shader_int64 */ - #ifndef GL_ARB_half_float_pixel #define GL_ARB_half_float_pixel 1 typedef unsigned short GLhalfARB; @@ -3827,30 +3419,6 @@ GLAPI void APIENTRY glGetQueryObjectuivARB (GLuint id, GLenum pname, GLuint *par #define GL_ARB_occlusion_query2 1 #endif /* GL_ARB_occlusion_query2 */ -#ifndef GL_ARB_parallel_shader_compile -#define GL_ARB_parallel_shader_compile 1 -#define GL_MAX_SHADER_COMPILER_THREADS_ARB 0x91B0 -#define GL_COMPLETION_STATUS_ARB 0x91B1 -typedef void (APIENTRYP PFNGLMAXSHADERCOMPILERTHREADSARBPROC) (GLuint count); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glMaxShaderCompilerThreadsARB (GLuint count); -#endif -#endif /* GL_ARB_parallel_shader_compile */ - -#ifndef GL_ARB_pipeline_statistics_query -#define GL_ARB_pipeline_statistics_query 1 -#define GL_VERTICES_SUBMITTED_ARB 0x82EE -#define GL_PRIMITIVES_SUBMITTED_ARB 0x82EF -#define GL_VERTEX_SHADER_INVOCATIONS_ARB 0x82F0 -#define GL_TESS_CONTROL_SHADER_PATCHES_ARB 0x82F1 -#define GL_TESS_EVALUATION_SHADER_INVOCATIONS_ARB 0x82F2 -#define GL_GEOMETRY_SHADER_PRIMITIVES_EMITTED_ARB 0x82F3 -#define GL_FRAGMENT_SHADER_INVOCATIONS_ARB 0x82F4 -#define GL_COMPUTE_SHADER_INVOCATIONS_ARB 0x82F5 -#define GL_CLIPPING_INPUT_PRIMITIVES_ARB 0x82F6 -#define GL_CLIPPING_OUTPUT_PRIMITIVES_ARB 0x82F7 -#endif /* GL_ARB_pipeline_statistics_query */ - #ifndef GL_ARB_pixel_buffer_object #define GL_ARB_pixel_buffer_object 1 #define GL_PIXEL_PACK_BUFFER_ARB 0x88EB @@ -3879,10 +3447,6 @@ GLAPI void APIENTRY glPointParameterfvARB (GLenum pname, const GLfloat *params); #define GL_COORD_REPLACE_ARB 0x8862 #endif /* GL_ARB_point_sprite */ -#ifndef GL_ARB_post_depth_coverage -#define GL_ARB_post_depth_coverage 1 -#endif /* GL_ARB_post_depth_coverage */ - #ifndef GL_ARB_program_interface_query #define GL_ARB_program_interface_query 1 #endif /* GL_ARB_program_interface_query */ @@ -3956,26 +3520,6 @@ GLAPI void APIENTRY glGetnMinmaxARB (GLenum target, GLboolean reset, GLenum form #define GL_ARB_robustness_isolation 1 #endif /* GL_ARB_robustness_isolation */ -#ifndef GL_ARB_sample_locations -#define GL_ARB_sample_locations 1 -#define GL_SAMPLE_LOCATION_SUBPIXEL_BITS_ARB 0x933D -#define GL_SAMPLE_LOCATION_PIXEL_GRID_WIDTH_ARB 0x933E -#define GL_SAMPLE_LOCATION_PIXEL_GRID_HEIGHT_ARB 0x933F -#define GL_PROGRAMMABLE_SAMPLE_LOCATION_TABLE_SIZE_ARB 0x9340 -#define GL_SAMPLE_LOCATION_ARB 0x8E50 -#define GL_PROGRAMMABLE_SAMPLE_LOCATION_ARB 0x9341 -#define GL_FRAMEBUFFER_PROGRAMMABLE_SAMPLE_LOCATIONS_ARB 0x9342 -#define GL_FRAMEBUFFER_SAMPLE_LOCATION_PIXEL_GRID_ARB 0x9343 -typedef void (APIENTRYP PFNGLFRAMEBUFFERSAMPLELOCATIONSFVARBPROC) (GLenum target, GLuint start, GLsizei count, const GLfloat *v); -typedef void (APIENTRYP PFNGLNAMEDFRAMEBUFFERSAMPLELOCATIONSFVARBPROC) (GLuint framebuffer, GLuint start, GLsizei count, const GLfloat *v); -typedef void (APIENTRYP PFNGLEVALUATEDEPTHVALUESARBPROC) (void); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glFramebufferSampleLocationsfvARB (GLenum target, GLuint start, GLsizei count, const GLfloat *v); -GLAPI void APIENTRY glNamedFramebufferSampleLocationsfvARB (GLuint framebuffer, GLuint start, GLsizei count, const GLfloat *v); -GLAPI void APIENTRY glEvaluateDepthValuesARB (void); -#endif -#endif /* GL_ARB_sample_locations */ - #ifndef GL_ARB_sample_shading #define GL_ARB_sample_shading 1 #define GL_SAMPLE_SHADING_ARB 0x8C36 @@ -4002,26 +3546,14 @@ GLAPI void APIENTRY glMinSampleShadingARB (GLfloat value); #define GL_ARB_separate_shader_objects 1 #endif /* GL_ARB_separate_shader_objects */ -#ifndef GL_ARB_shader_atomic_counter_ops -#define GL_ARB_shader_atomic_counter_ops 1 -#endif /* GL_ARB_shader_atomic_counter_ops */ - #ifndef GL_ARB_shader_atomic_counters #define GL_ARB_shader_atomic_counters 1 #endif /* GL_ARB_shader_atomic_counters */ -#ifndef GL_ARB_shader_ballot -#define GL_ARB_shader_ballot 1 -#endif /* GL_ARB_shader_ballot */ - #ifndef GL_ARB_shader_bit_encoding #define GL_ARB_shader_bit_encoding 1 #endif /* GL_ARB_shader_bit_encoding */ -#ifndef GL_ARB_shader_clock -#define GL_ARB_shader_clock 1 -#endif /* GL_ARB_shader_clock */ - #ifndef GL_ARB_shader_draw_parameters #define GL_ARB_shader_draw_parameters 1 #endif /* GL_ARB_shader_draw_parameters */ @@ -4178,18 +3710,10 @@ GLAPI void APIENTRY glGetShaderSourceARB (GLhandleARB obj, GLsizei maxLength, GL #define GL_ARB_shader_subroutine 1 #endif /* GL_ARB_shader_subroutine */ -#ifndef GL_ARB_shader_texture_image_samples -#define GL_ARB_shader_texture_image_samples 1 -#endif /* GL_ARB_shader_texture_image_samples */ - #ifndef GL_ARB_shader_texture_lod #define GL_ARB_shader_texture_lod 1 #endif /* GL_ARB_shader_texture_lod */ -#ifndef GL_ARB_shader_viewport_layer_array -#define GL_ARB_shader_viewport_layer_array 1 -#endif /* GL_ARB_shader_viewport_layer_array */ - #ifndef GL_ARB_shading_language_100 #define GL_ARB_shading_language_100 1 #define GL_SHADING_LANGUAGE_VERSION_ARB 0x8B8C @@ -4236,25 +3760,11 @@ GLAPI void APIENTRY glGetNamedStringivARB (GLint namelen, const GLchar *name, GL #define GL_TEXTURE_COMPARE_FAIL_VALUE_ARB 0x80BF #endif /* GL_ARB_shadow_ambient */ -#ifndef GL_ARB_sparse_buffer -#define GL_ARB_sparse_buffer 1 -#define GL_SPARSE_STORAGE_BIT_ARB 0x0400 -#define GL_SPARSE_BUFFER_PAGE_SIZE_ARB 0x82F8 -typedef void (APIENTRYP PFNGLBUFFERPAGECOMMITMENTARBPROC) (GLenum target, GLintptr offset, GLsizeiptr size, GLboolean commit); -typedef void (APIENTRYP PFNGLNAMEDBUFFERPAGECOMMITMENTEXTPROC) (GLuint buffer, GLintptr offset, GLsizeiptr size, GLboolean commit); -typedef void (APIENTRYP PFNGLNAMEDBUFFERPAGECOMMITMENTARBPROC) (GLuint buffer, GLintptr offset, GLsizeiptr size, GLboolean commit); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glBufferPageCommitmentARB (GLenum target, GLintptr offset, GLsizeiptr size, GLboolean commit); -GLAPI void APIENTRY glNamedBufferPageCommitmentEXT (GLuint buffer, GLintptr offset, GLsizeiptr size, GLboolean commit); -GLAPI void APIENTRY glNamedBufferPageCommitmentARB (GLuint buffer, GLintptr offset, GLsizeiptr size, GLboolean commit); -#endif -#endif /* GL_ARB_sparse_buffer */ - #ifndef GL_ARB_sparse_texture #define GL_ARB_sparse_texture 1 #define GL_TEXTURE_SPARSE_ARB 0x91A6 #define GL_VIRTUAL_PAGE_SIZE_INDEX_ARB 0x91A7 -#define GL_NUM_SPARSE_LEVELS_ARB 0x91AA +#define GL_MIN_SPARSE_LEVEL_ARB 0x919B #define GL_NUM_VIRTUAL_PAGE_SIZES_ARB 0x91A8 #define GL_VIRTUAL_PAGE_SIZE_X_ARB 0x9195 #define GL_VIRTUAL_PAGE_SIZE_Y_ARB 0x9196 @@ -4263,20 +3773,12 @@ GLAPI void APIENTRY glNamedBufferPageCommitmentARB (GLuint buffer, GLintptr offs #define GL_MAX_SPARSE_3D_TEXTURE_SIZE_ARB 0x9199 #define GL_MAX_SPARSE_ARRAY_TEXTURE_LAYERS_ARB 0x919A #define GL_SPARSE_TEXTURE_FULL_ARRAY_CUBE_MIPMAPS_ARB 0x91A9 -typedef void (APIENTRYP PFNGLTEXPAGECOMMITMENTARBPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLboolean commit); +typedef void (APIENTRYP PFNGLTEXPAGECOMMITMENTARBPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLboolean resident); #ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glTexPageCommitmentARB (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLboolean commit); +GLAPI void APIENTRY glTexPageCommitmentARB (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLboolean resident); #endif #endif /* GL_ARB_sparse_texture */ -#ifndef GL_ARB_sparse_texture2 -#define GL_ARB_sparse_texture2 1 -#endif /* GL_ARB_sparse_texture2 */ - -#ifndef GL_ARB_sparse_texture_clamp -#define GL_ARB_sparse_texture_clamp 1 -#endif /* GL_ARB_sparse_texture_clamp */ - #ifndef GL_ARB_stencil_texturing #define GL_ARB_stencil_texturing 1 #endif /* GL_ARB_stencil_texturing */ @@ -4289,10 +3791,6 @@ GLAPI void APIENTRY glTexPageCommitmentARB (GLenum target, GLint level, GLint xo #define GL_ARB_tessellation_shader 1 #endif /* GL_ARB_tessellation_shader */ -#ifndef GL_ARB_texture_barrier -#define GL_ARB_texture_barrier 1 -#endif /* GL_ARB_texture_barrier */ - #ifndef GL_ARB_texture_border_clamp #define GL_ARB_texture_border_clamp 1 #define GL_CLAMP_TO_BORDER_ARB 0x812D @@ -4429,12 +3927,6 @@ GLAPI void APIENTRY glGetCompressedTexImageARB (GLenum target, GLint level, void #define GL_DOT3_RGBA_ARB 0x86AF #endif /* GL_ARB_texture_env_dot3 */ -#ifndef GL_ARB_texture_filter_minmax -#define GL_ARB_texture_filter_minmax 1 -#define GL_TEXTURE_REDUCTION_MODE_ARB 0x9366 -#define GL_WEIGHTED_AVERAGE_ARB 0x9367 -#endif /* GL_ARB_texture_filter_minmax */ - #ifndef GL_ARB_texture_float #define GL_ARB_texture_float 1 #define GL_TEXTURE_RED_TYPE_ARB 0x8C10 @@ -4533,6 +4025,8 @@ GLAPI void APIENTRY glGetCompressedTexImageARB (GLenum target, GLint level, void #ifndef GL_ARB_transform_feedback2 #define GL_ARB_transform_feedback2 1 +#define GL_TRANSFORM_FEEDBACK_PAUSED 0x8E23 +#define GL_TRANSFORM_FEEDBACK_ACTIVE 0x8E24 #endif /* GL_ARB_transform_feedback2 */ #ifndef GL_ARB_transform_feedback3 @@ -4543,12 +4037,6 @@ GLAPI void APIENTRY glGetCompressedTexImageARB (GLenum target, GLint level, void #define GL_ARB_transform_feedback_instanced 1 #endif /* GL_ARB_transform_feedback_instanced */ -#ifndef GL_ARB_transform_feedback_overflow_query -#define GL_ARB_transform_feedback_overflow_query 1 -#define GL_TRANSFORM_FEEDBACK_OVERFLOW_ARB 0x82EC -#define GL_TRANSFORM_FEEDBACK_STREAM_OVERFLOW_ARB 0x82ED -#endif /* GL_ARB_transform_feedback_overflow_query */ - #ifndef GL_ARB_transpose_matrix #define GL_ARB_transpose_matrix 1 #define GL_TRANSPOSE_MODELVIEW_MATRIX_ARB 0x84E3 @@ -4569,6 +4057,9 @@ GLAPI void APIENTRY glMultTransposeMatrixdARB (const GLdouble *m); #ifndef GL_ARB_uniform_buffer_object #define GL_ARB_uniform_buffer_object 1 +#define GL_MAX_GEOMETRY_UNIFORM_BLOCKS 0x8A2C +#define GL_MAX_COMBINED_GEOMETRY_UNIFORM_COMPONENTS 0x8A32 +#define GL_UNIFORM_BLOCK_REFERENCED_BY_GEOMETRY_SHADER 0x8A45 #endif /* GL_ARB_uniform_buffer_object */ #ifndef GL_ARB_vertex_array_bgra @@ -4657,8 +4148,13 @@ GLAPI void APIENTRY glVertexBlendARB (GLint count); #ifndef GL_ARB_vertex_buffer_object #define GL_ARB_vertex_buffer_object 1 +#ifdef __MACOSX__ /* The OS X headers haven't caught up with Khronos yet */ +typedef long GLsizeiptrARB; +typedef long GLintptrARB; +#else typedef ptrdiff_t GLsizeiptrARB; typedef ptrdiff_t GLintptrARB; +#endif #define GL_BUFFER_SIZE_ARB 0x8764 #define GL_BUFFER_USAGE_ARB 0x8765 #define GL_ARRAY_BUFFER_ARB 0x8892 @@ -4893,56 +4389,10 @@ GLAPI void APIENTRY glWindowPos3svARB (const GLshort *v); #endif #endif /* GL_ARB_window_pos */ -#ifndef GL_KHR_blend_equation_advanced -#define GL_KHR_blend_equation_advanced 1 -#define GL_MULTIPLY_KHR 0x9294 -#define GL_SCREEN_KHR 0x9295 -#define GL_OVERLAY_KHR 0x9296 -#define GL_DARKEN_KHR 0x9297 -#define GL_LIGHTEN_KHR 0x9298 -#define GL_COLORDODGE_KHR 0x9299 -#define GL_COLORBURN_KHR 0x929A -#define GL_HARDLIGHT_KHR 0x929B -#define GL_SOFTLIGHT_KHR 0x929C -#define GL_DIFFERENCE_KHR 0x929E -#define GL_EXCLUSION_KHR 0x92A0 -#define GL_HSL_HUE_KHR 0x92AD -#define GL_HSL_SATURATION_KHR 0x92AE -#define GL_HSL_COLOR_KHR 0x92AF -#define GL_HSL_LUMINOSITY_KHR 0x92B0 -typedef void (APIENTRYP PFNGLBLENDBARRIERKHRPROC) (void); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glBlendBarrierKHR (void); -#endif -#endif /* GL_KHR_blend_equation_advanced */ - -#ifndef GL_KHR_blend_equation_advanced_coherent -#define GL_KHR_blend_equation_advanced_coherent 1 -#define GL_BLEND_ADVANCED_COHERENT_KHR 0x9285 -#endif /* GL_KHR_blend_equation_advanced_coherent */ - -#ifndef GL_KHR_context_flush_control -#define GL_KHR_context_flush_control 1 -#endif /* GL_KHR_context_flush_control */ - #ifndef GL_KHR_debug #define GL_KHR_debug 1 #endif /* GL_KHR_debug */ -#ifndef GL_KHR_no_error -#define GL_KHR_no_error 1 -#define GL_CONTEXT_FLAG_NO_ERROR_BIT_KHR 0x00000008 -#endif /* GL_KHR_no_error */ - -#ifndef GL_KHR_robust_buffer_access_behavior -#define GL_KHR_robust_buffer_access_behavior 1 -#endif /* GL_KHR_robust_buffer_access_behavior */ - -#ifndef GL_KHR_robustness -#define GL_KHR_robustness 1 -#define GL_CONTEXT_ROBUST_ACCESS 0x90F3 -#endif /* GL_KHR_robustness */ - #ifndef GL_KHR_texture_compression_astc_hdr #define GL_KHR_texture_compression_astc_hdr 1 #define GL_COMPRESSED_RGBA_ASTC_4x4_KHR 0x93B0 @@ -4979,10 +4429,6 @@ GLAPI void APIENTRY glBlendBarrierKHR (void); #define GL_KHR_texture_compression_astc_ldr 1 #endif /* GL_KHR_texture_compression_astc_ldr */ -#ifndef GL_KHR_texture_compression_astc_sliced_3d -#define GL_KHR_texture_compression_astc_sliced_3d 1 -#endif /* GL_KHR_texture_compression_astc_sliced_3d */ - #ifndef GL_OES_byte_coordinates #define GL_OES_byte_coordinates 1 typedef void (APIENTRYP PFNGLMULTITEXCOORD1BOESPROC) (GLenum texture, GLbyte s); @@ -5001,11 +4447,11 @@ typedef void (APIENTRYP PFNGLTEXCOORD3BOESPROC) (GLbyte s, GLbyte t, GLbyte r); typedef void (APIENTRYP PFNGLTEXCOORD3BVOESPROC) (const GLbyte *coords); typedef void (APIENTRYP PFNGLTEXCOORD4BOESPROC) (GLbyte s, GLbyte t, GLbyte r, GLbyte q); typedef void (APIENTRYP PFNGLTEXCOORD4BVOESPROC) (const GLbyte *coords); -typedef void (APIENTRYP PFNGLVERTEX2BOESPROC) (GLbyte x, GLbyte y); +typedef void (APIENTRYP PFNGLVERTEX2BOESPROC) (GLbyte x); typedef void (APIENTRYP PFNGLVERTEX2BVOESPROC) (const GLbyte *coords); -typedef void (APIENTRYP PFNGLVERTEX3BOESPROC) (GLbyte x, GLbyte y, GLbyte z); +typedef void (APIENTRYP PFNGLVERTEX3BOESPROC) (GLbyte x, GLbyte y); typedef void (APIENTRYP PFNGLVERTEX3BVOESPROC) (const GLbyte *coords); -typedef void (APIENTRYP PFNGLVERTEX4BOESPROC) (GLbyte x, GLbyte y, GLbyte z, GLbyte w); +typedef void (APIENTRYP PFNGLVERTEX4BOESPROC) (GLbyte x, GLbyte y, GLbyte z); typedef void (APIENTRYP PFNGLVERTEX4BVOESPROC) (const GLbyte *coords); #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glMultiTexCoord1bOES (GLenum texture, GLbyte s); @@ -5024,11 +4470,11 @@ GLAPI void APIENTRY glTexCoord3bOES (GLbyte s, GLbyte t, GLbyte r); GLAPI void APIENTRY glTexCoord3bvOES (const GLbyte *coords); GLAPI void APIENTRY glTexCoord4bOES (GLbyte s, GLbyte t, GLbyte r, GLbyte q); GLAPI void APIENTRY glTexCoord4bvOES (const GLbyte *coords); -GLAPI void APIENTRY glVertex2bOES (GLbyte x, GLbyte y); +GLAPI void APIENTRY glVertex2bOES (GLbyte x); GLAPI void APIENTRY glVertex2bvOES (const GLbyte *coords); -GLAPI void APIENTRY glVertex3bOES (GLbyte x, GLbyte y, GLbyte z); +GLAPI void APIENTRY glVertex3bOES (GLbyte x, GLbyte y); GLAPI void APIENTRY glVertex3bvOES (const GLbyte *coords); -GLAPI void APIENTRY glVertex4bOES (GLbyte x, GLbyte y, GLbyte z, GLbyte w); +GLAPI void APIENTRY glVertex4bOES (GLbyte x, GLbyte y, GLbyte z); GLAPI void APIENTRY glVertex4bvOES (const GLbyte *coords); #endif #endif /* GL_OES_byte_coordinates */ @@ -5080,6 +4526,7 @@ typedef void (APIENTRYP PFNGLPOINTPARAMETERXVOESPROC) (GLenum pname, const GLfix typedef void (APIENTRYP PFNGLPOINTSIZEXOESPROC) (GLfixed size); typedef void (APIENTRYP PFNGLPOLYGONOFFSETXOESPROC) (GLfixed factor, GLfixed units); typedef void (APIENTRYP PFNGLROTATEXOESPROC) (GLfixed angle, GLfixed x, GLfixed y, GLfixed z); +typedef void (APIENTRYP PFNGLSAMPLECOVERAGEOESPROC) (GLfixed value, GLboolean invert); typedef void (APIENTRYP PFNGLSCALEXOESPROC) (GLfixed x, GLfixed y, GLfixed z); typedef void (APIENTRYP PFNGLTEXENVXOESPROC) (GLenum target, GLenum pname, GLfixed param); typedef void (APIENTRYP PFNGLTEXENVXVOESPROC) (GLenum target, GLenum pname, const GLfixed *params); @@ -5184,6 +4631,7 @@ GLAPI void APIENTRY glPointParameterxvOES (GLenum pname, const GLfixed *params); GLAPI void APIENTRY glPointSizexOES (GLfixed size); GLAPI void APIENTRY glPolygonOffsetxOES (GLfixed factor, GLfixed units); GLAPI void APIENTRY glRotatexOES (GLfixed angle, GLfixed x, GLfixed y, GLfixed z); +GLAPI void APIENTRY glSampleCoverageOES (GLfixed value, GLboolean invert); GLAPI void APIENTRY glScalexOES (GLfixed x, GLfixed y, GLfixed z); GLAPI void APIENTRY glTexEnvxOES (GLenum target, GLenum pname, GLfixed param); GLAPI void APIENTRY glTexEnvxvOES (GLenum target, GLenum pname, const GLfixed *params); @@ -6897,7 +6345,7 @@ typedef void (APIENTRYP PFNGLVERTEXARRAYVERTEXATTRIBLFORMATEXTPROC) (GLuint vaob typedef void (APIENTRYP PFNGLVERTEXARRAYVERTEXATTRIBBINDINGEXTPROC) (GLuint vaobj, GLuint attribindex, GLuint bindingindex); typedef void (APIENTRYP PFNGLVERTEXARRAYVERTEXBINDINGDIVISOREXTPROC) (GLuint vaobj, GLuint bindingindex, GLuint divisor); typedef void (APIENTRYP PFNGLVERTEXARRAYVERTEXATTRIBLOFFSETEXTPROC) (GLuint vaobj, GLuint buffer, GLuint index, GLint size, GLenum type, GLsizei stride, GLintptr offset); -typedef void (APIENTRYP PFNGLTEXTUREPAGECOMMITMENTEXTPROC) (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLboolean commit); +typedef void (APIENTRYP PFNGLTEXTUREPAGECOMMITMENTEXTPROC) (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLboolean resident); typedef void (APIENTRYP PFNGLVERTEXARRAYVERTEXATTRIBDIVISOREXTPROC) (GLuint vaobj, GLuint index, GLuint divisor); #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glMatrixLoadfEXT (GLenum mode, const GLfloat *m); @@ -7153,7 +6601,7 @@ GLAPI void APIENTRY glVertexArrayVertexAttribLFormatEXT (GLuint vaobj, GLuint at GLAPI void APIENTRY glVertexArrayVertexAttribBindingEXT (GLuint vaobj, GLuint attribindex, GLuint bindingindex); GLAPI void APIENTRY glVertexArrayVertexBindingDivisorEXT (GLuint vaobj, GLuint bindingindex, GLuint divisor); GLAPI void APIENTRY glVertexArrayVertexAttribLOffsetEXT (GLuint vaobj, GLuint buffer, GLuint index, GLint size, GLenum type, GLsizei stride, GLintptr offset); -GLAPI void APIENTRY glTexturePageCommitmentEXT (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLboolean commit); +GLAPI void APIENTRY glTexturePageCommitmentEXT (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLboolean resident); GLAPI void APIENTRY glVertexArrayVertexAttribDivisorEXT (GLuint vaobj, GLuint index, GLuint divisor); #endif #endif /* GL_EXT_direct_state_access */ @@ -7679,19 +7127,6 @@ GLAPI void APIENTRY glPolygonOffsetEXT (GLfloat factor, GLfloat bias); #endif #endif /* GL_EXT_polygon_offset */ -#ifndef GL_EXT_polygon_offset_clamp -#define GL_EXT_polygon_offset_clamp 1 -#define GL_POLYGON_OFFSET_CLAMP_EXT 0x8E1B -typedef void (APIENTRYP PFNGLPOLYGONOFFSETCLAMPEXTPROC) (GLfloat factor, GLfloat units, GLfloat clamp); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glPolygonOffsetClampEXT (GLfloat factor, GLfloat units, GLfloat clamp); -#endif -#endif /* GL_EXT_polygon_offset_clamp */ - -#ifndef GL_EXT_post_depth_coverage -#define GL_EXT_post_depth_coverage 1 -#endif /* GL_EXT_post_depth_coverage */ - #ifndef GL_EXT_provoking_vertex #define GL_EXT_provoking_vertex 1 #define GL_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION_EXT 0x8E4C @@ -7704,20 +7139,6 @@ GLAPI void APIENTRY glProvokingVertexEXT (GLenum mode); #endif #endif /* GL_EXT_provoking_vertex */ -#ifndef GL_EXT_raster_multisample -#define GL_EXT_raster_multisample 1 -#define GL_RASTER_MULTISAMPLE_EXT 0x9327 -#define GL_RASTER_SAMPLES_EXT 0x9328 -#define GL_MAX_RASTER_SAMPLES_EXT 0x9329 -#define GL_RASTER_FIXED_SAMPLE_LOCATIONS_EXT 0x932A -#define GL_MULTISAMPLE_RASTERIZATION_ALLOWED_EXT 0x932B -#define GL_EFFECTIVE_RASTER_SAMPLES_EXT 0x932C -typedef void (APIENTRYP PFNGLRASTERSAMPLESEXTPROC) (GLuint samples, GLboolean fixedsamplelocations); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glRasterSamplesEXT (GLuint samples, GLboolean fixedsamplelocations); -#endif -#endif /* GL_EXT_raster_multisample */ - #ifndef GL_EXT_rescale_normal #define GL_EXT_rescale_normal 1 #define GL_RESCALE_NORMAL_EXT 0x803A @@ -7872,10 +7293,6 @@ GLAPI void APIENTRY glMemoryBarrierEXT (GLbitfield barriers); #define GL_SHARED_TEXTURE_PALETTE_EXT 0x81FB #endif /* GL_EXT_shared_texture_palette */ -#ifndef GL_EXT_sparse_texture2 -#define GL_EXT_sparse_texture2 1 -#endif /* GL_EXT_sparse_texture2 */ - #ifndef GL_EXT_stencil_clear_tag #define GL_EXT_stencil_clear_tag 1 #define GL_STENCIL_TAG_BITS_EXT 0x88F2 @@ -7988,10 +7405,6 @@ GLAPI void APIENTRY glTexSubImage3DEXT (GLenum target, GLint level, GLint xoffse #define GL_TEXTURE_BINDING_2D_ARRAY_EXT 0x8C1D #define GL_MAX_ARRAY_TEXTURE_LAYERS_EXT 0x88FF #define GL_COMPARE_REF_DEPTH_TO_TEXTURE_EXT 0x884E -typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURELAYEREXTPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glFramebufferTextureLayerEXT (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer); -#endif #endif /* GL_EXT_texture_array */ #ifndef GL_EXT_texture_buffer_object @@ -8088,10 +7501,6 @@ GLAPI void APIENTRY glTexBufferEXT (GLenum target, GLenum internalformat, GLuint #define GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT 0x84FF #endif /* GL_EXT_texture_filter_anisotropic */ -#ifndef GL_EXT_texture_filter_minmax -#define GL_EXT_texture_filter_minmax 1 -#endif /* GL_EXT_texture_filter_minmax */ - #ifndef GL_EXT_texture_integer #define GL_EXT_texture_integer 1 #define GL_RGBA32UI_EXT 0x8D70 @@ -8817,14 +8226,6 @@ GLAPI void APIENTRY glBlendFuncSeparateINGR (GLenum sfactorRGB, GLenum dfactorRG #define GL_INTEL_fragment_shader_ordering 1 #endif /* GL_INTEL_fragment_shader_ordering */ -#ifndef GL_INTEL_framebuffer_CMAA -#define GL_INTEL_framebuffer_CMAA 1 -typedef void (APIENTRYP PFNGLAPPLYFRAMEBUFFERATTACHMENTCMAAINTELPROC) (void); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glApplyFramebufferAttachmentCMAAINTEL (void); -#endif -#endif /* GL_INTEL_framebuffer_CMAA */ - #ifndef GL_INTEL_map_texture #define GL_INTEL_map_texture 1 #define GL_TEXTURE_MEMORY_LAYOUT_INTEL 0x83FF @@ -9019,16 +8420,6 @@ GLAPI void APIENTRY glMultiDrawElementsIndirectBindlessNV (GLenum mode, GLenum t #endif #endif /* GL_NV_bindless_multi_draw_indirect */ -#ifndef GL_NV_bindless_multi_draw_indirect_count -#define GL_NV_bindless_multi_draw_indirect_count 1 -typedef void (APIENTRYP PFNGLMULTIDRAWARRAYSINDIRECTBINDLESSCOUNTNVPROC) (GLenum mode, const void *indirect, GLsizei drawCount, GLsizei maxDrawCount, GLsizei stride, GLint vertexBufferCount); -typedef void (APIENTRYP PFNGLMULTIDRAWELEMENTSINDIRECTBINDLESSCOUNTNVPROC) (GLenum mode, GLenum type, const void *indirect, GLsizei drawCount, GLsizei maxDrawCount, GLsizei stride, GLint vertexBufferCount); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glMultiDrawArraysIndirectBindlessCountNV (GLenum mode, const void *indirect, GLsizei drawCount, GLsizei maxDrawCount, GLsizei stride, GLint vertexBufferCount); -GLAPI void APIENTRY glMultiDrawElementsIndirectBindlessCountNV (GLenum mode, GLenum type, const void *indirect, GLsizei drawCount, GLsizei maxDrawCount, GLsizei stride, GLint vertexBufferCount); -#endif -#endif /* GL_NV_bindless_multi_draw_indirect_count */ - #ifndef GL_NV_bindless_texture #define GL_NV_bindless_texture 1 typedef GLuint64 (APIENTRYP PFNGLGETTEXTUREHANDLENVPROC) (GLuint texture); @@ -9129,65 +8520,6 @@ GLAPI void APIENTRY glBlendBarrierNV (void); #define GL_NV_blend_square 1 #endif /* GL_NV_blend_square */ -#ifndef GL_NV_command_list -#define GL_NV_command_list 1 -#define GL_TERMINATE_SEQUENCE_COMMAND_NV 0x0000 -#define GL_NOP_COMMAND_NV 0x0001 -#define GL_DRAW_ELEMENTS_COMMAND_NV 0x0002 -#define GL_DRAW_ARRAYS_COMMAND_NV 0x0003 -#define GL_DRAW_ELEMENTS_STRIP_COMMAND_NV 0x0004 -#define GL_DRAW_ARRAYS_STRIP_COMMAND_NV 0x0005 -#define GL_DRAW_ELEMENTS_INSTANCED_COMMAND_NV 0x0006 -#define GL_DRAW_ARRAYS_INSTANCED_COMMAND_NV 0x0007 -#define GL_ELEMENT_ADDRESS_COMMAND_NV 0x0008 -#define GL_ATTRIBUTE_ADDRESS_COMMAND_NV 0x0009 -#define GL_UNIFORM_ADDRESS_COMMAND_NV 0x000A -#define GL_BLEND_COLOR_COMMAND_NV 0x000B -#define GL_STENCIL_REF_COMMAND_NV 0x000C -#define GL_LINE_WIDTH_COMMAND_NV 0x000D -#define GL_POLYGON_OFFSET_COMMAND_NV 0x000E -#define GL_ALPHA_REF_COMMAND_NV 0x000F -#define GL_VIEWPORT_COMMAND_NV 0x0010 -#define GL_SCISSOR_COMMAND_NV 0x0011 -#define GL_FRONT_FACE_COMMAND_NV 0x0012 -typedef void (APIENTRYP PFNGLCREATESTATESNVPROC) (GLsizei n, GLuint *states); -typedef void (APIENTRYP PFNGLDELETESTATESNVPROC) (GLsizei n, const GLuint *states); -typedef GLboolean (APIENTRYP PFNGLISSTATENVPROC) (GLuint state); -typedef void (APIENTRYP PFNGLSTATECAPTURENVPROC) (GLuint state, GLenum mode); -typedef GLuint (APIENTRYP PFNGLGETCOMMANDHEADERNVPROC) (GLenum tokenID, GLuint size); -typedef GLushort (APIENTRYP PFNGLGETSTAGEINDEXNVPROC) (GLenum shadertype); -typedef void (APIENTRYP PFNGLDRAWCOMMANDSNVPROC) (GLenum primitiveMode, GLuint buffer, const GLintptr *indirects, const GLsizei *sizes, GLuint count); -typedef void (APIENTRYP PFNGLDRAWCOMMANDSADDRESSNVPROC) (GLenum primitiveMode, const GLuint64 *indirects, const GLsizei *sizes, GLuint count); -typedef void (APIENTRYP PFNGLDRAWCOMMANDSSTATESNVPROC) (GLuint buffer, const GLintptr *indirects, const GLsizei *sizes, const GLuint *states, const GLuint *fbos, GLuint count); -typedef void (APIENTRYP PFNGLDRAWCOMMANDSSTATESADDRESSNVPROC) (const GLuint64 *indirects, const GLsizei *sizes, const GLuint *states, const GLuint *fbos, GLuint count); -typedef void (APIENTRYP PFNGLCREATECOMMANDLISTSNVPROC) (GLsizei n, GLuint *lists); -typedef void (APIENTRYP PFNGLDELETECOMMANDLISTSNVPROC) (GLsizei n, const GLuint *lists); -typedef GLboolean (APIENTRYP PFNGLISCOMMANDLISTNVPROC) (GLuint list); -typedef void (APIENTRYP PFNGLLISTDRAWCOMMANDSSTATESCLIENTNVPROC) (GLuint list, GLuint segment, const void **indirects, const GLsizei *sizes, const GLuint *states, const GLuint *fbos, GLuint count); -typedef void (APIENTRYP PFNGLCOMMANDLISTSEGMENTSNVPROC) (GLuint list, GLuint segments); -typedef void (APIENTRYP PFNGLCOMPILECOMMANDLISTNVPROC) (GLuint list); -typedef void (APIENTRYP PFNGLCALLCOMMANDLISTNVPROC) (GLuint list); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glCreateStatesNV (GLsizei n, GLuint *states); -GLAPI void APIENTRY glDeleteStatesNV (GLsizei n, const GLuint *states); -GLAPI GLboolean APIENTRY glIsStateNV (GLuint state); -GLAPI void APIENTRY glStateCaptureNV (GLuint state, GLenum mode); -GLAPI GLuint APIENTRY glGetCommandHeaderNV (GLenum tokenID, GLuint size); -GLAPI GLushort APIENTRY glGetStageIndexNV (GLenum shadertype); -GLAPI void APIENTRY glDrawCommandsNV (GLenum primitiveMode, GLuint buffer, const GLintptr *indirects, const GLsizei *sizes, GLuint count); -GLAPI void APIENTRY glDrawCommandsAddressNV (GLenum primitiveMode, const GLuint64 *indirects, const GLsizei *sizes, GLuint count); -GLAPI void APIENTRY glDrawCommandsStatesNV (GLuint buffer, const GLintptr *indirects, const GLsizei *sizes, const GLuint *states, const GLuint *fbos, GLuint count); -GLAPI void APIENTRY glDrawCommandsStatesAddressNV (const GLuint64 *indirects, const GLsizei *sizes, const GLuint *states, const GLuint *fbos, GLuint count); -GLAPI void APIENTRY glCreateCommandListsNV (GLsizei n, GLuint *lists); -GLAPI void APIENTRY glDeleteCommandListsNV (GLsizei n, const GLuint *lists); -GLAPI GLboolean APIENTRY glIsCommandListNV (GLuint list); -GLAPI void APIENTRY glListDrawCommandsStatesClientNV (GLuint list, GLuint segment, const void **indirects, const GLsizei *sizes, const GLuint *states, const GLuint *fbos, GLuint count); -GLAPI void APIENTRY glCommandListSegmentsNV (GLuint list, GLuint segments); -GLAPI void APIENTRY glCompileCommandListNV (GLuint list); -GLAPI void APIENTRY glCallCommandListNV (GLuint list); -#endif -#endif /* GL_NV_command_list */ - #ifndef GL_NV_compute_program5 #define GL_NV_compute_program5 1 #define GL_COMPUTE_PROGRAM_NV 0x90FB @@ -9208,29 +8540,6 @@ GLAPI void APIENTRY glEndConditionalRenderNV (void); #endif #endif /* GL_NV_conditional_render */ -#ifndef GL_NV_conservative_raster -#define GL_NV_conservative_raster 1 -#define GL_CONSERVATIVE_RASTERIZATION_NV 0x9346 -#define GL_SUBPIXEL_PRECISION_BIAS_X_BITS_NV 0x9347 -#define GL_SUBPIXEL_PRECISION_BIAS_Y_BITS_NV 0x9348 -#define GL_MAX_SUBPIXEL_PRECISION_BIAS_BITS_NV 0x9349 -typedef void (APIENTRYP PFNGLSUBPIXELPRECISIONBIASNVPROC) (GLuint xbits, GLuint ybits); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glSubpixelPrecisionBiasNV (GLuint xbits, GLuint ybits); -#endif -#endif /* GL_NV_conservative_raster */ - -#ifndef GL_NV_conservative_raster_dilate -#define GL_NV_conservative_raster_dilate 1 -#define GL_CONSERVATIVE_RASTER_DILATE_NV 0x9379 -#define GL_CONSERVATIVE_RASTER_DILATE_RANGE_NV 0x937A -#define GL_CONSERVATIVE_RASTER_DILATE_GRANULARITY_NV 0x937B -typedef void (APIENTRYP PFNGLCONSERVATIVERASTERPARAMETERFNVPROC) (GLenum pname, GLfloat value); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glConservativeRasterParameterfNV (GLenum pname, GLfloat value); -#endif -#endif /* GL_NV_conservative_raster_dilate */ - #ifndef GL_NV_copy_depth_to_color #define GL_NV_copy_depth_to_color 1 #define GL_DEPTH_STENCIL_TO_RGBA_NV 0x886E @@ -9373,11 +8682,6 @@ GLAPI void APIENTRY glSetFenceNV (GLuint fence, GLenum condition); #endif #endif /* GL_NV_fence */ -#ifndef GL_NV_fill_rectangle -#define GL_NV_fill_rectangle 1 -#define GL_FILL_RECTANGLE_NV 0x933C -#endif /* GL_NV_fill_rectangle */ - #ifndef GL_NV_float_buffer #define GL_NV_float_buffer 1 #define GL_FLOAT_R_NV 0x8880 @@ -9404,16 +8708,6 @@ GLAPI void APIENTRY glSetFenceNV (GLuint fence, GLenum condition); #define GL_EYE_PLANE_ABSOLUTE_NV 0x855C #endif /* GL_NV_fog_distance */ -#ifndef GL_NV_fragment_coverage_to_color -#define GL_NV_fragment_coverage_to_color 1 -#define GL_FRAGMENT_COVERAGE_TO_COLOR_NV 0x92DD -#define GL_FRAGMENT_COVERAGE_COLOR_NV 0x92DE -typedef void (APIENTRYP PFNGLFRAGMENTCOVERAGECOLORNVPROC) (GLuint color); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glFragmentCoverageColorNV (GLuint color); -#endif -#endif /* GL_NV_fragment_coverage_to_color */ - #ifndef GL_NV_fragment_program #define GL_NV_fragment_program 1 #define GL_MAX_FRAGMENT_PROGRAM_LOCAL_PARAMETERS_NV 0x8868 @@ -9455,30 +8749,6 @@ GLAPI void APIENTRY glGetProgramNamedParameterdvNV (GLuint id, GLsizei len, cons #define GL_NV_fragment_program_option 1 #endif /* GL_NV_fragment_program_option */ -#ifndef GL_NV_fragment_shader_interlock -#define GL_NV_fragment_shader_interlock 1 -#endif /* GL_NV_fragment_shader_interlock */ - -#ifndef GL_NV_framebuffer_mixed_samples -#define GL_NV_framebuffer_mixed_samples 1 -#define GL_COVERAGE_MODULATION_TABLE_NV 0x9331 -#define GL_COLOR_SAMPLES_NV 0x8E20 -#define GL_DEPTH_SAMPLES_NV 0x932D -#define GL_STENCIL_SAMPLES_NV 0x932E -#define GL_MIXED_DEPTH_SAMPLES_SUPPORTED_NV 0x932F -#define GL_MIXED_STENCIL_SAMPLES_SUPPORTED_NV 0x9330 -#define GL_COVERAGE_MODULATION_NV 0x9332 -#define GL_COVERAGE_MODULATION_TABLE_SIZE_NV 0x9333 -typedef void (APIENTRYP PFNGLCOVERAGEMODULATIONTABLENVPROC) (GLsizei n, const GLfloat *v); -typedef void (APIENTRYP PFNGLGETCOVERAGEMODULATIONTABLENVPROC) (GLsizei bufsize, GLfloat *v); -typedef void (APIENTRYP PFNGLCOVERAGEMODULATIONNVPROC) (GLenum components); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glCoverageModulationTableNV (GLsizei n, const GLfloat *v); -GLAPI void APIENTRY glGetCoverageModulationTableNV (GLsizei bufsize, GLfloat *v); -GLAPI void APIENTRY glCoverageModulationNV (GLenum components); -#endif -#endif /* GL_NV_framebuffer_mixed_samples */ - #ifndef GL_NV_framebuffer_multisample_coverage #define GL_NV_framebuffer_multisample_coverage 1 #define GL_RENDERBUFFER_COVERAGE_SAMPLES_NV 0x8CAB @@ -9498,10 +8768,12 @@ GLAPI void APIENTRY glRenderbufferStorageMultisampleCoverageNV (GLenum target, G #define GL_MAX_PROGRAM_TOTAL_OUTPUT_COMPONENTS_NV 0x8C28 typedef void (APIENTRYP PFNGLPROGRAMVERTEXLIMITNVPROC) (GLenum target, GLint limit); typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTUREEXTPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level); +typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURELAYEREXTPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer); typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTUREFACEEXTPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLenum face); #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glProgramVertexLimitNV (GLenum target, GLint limit); GLAPI void APIENTRY glFramebufferTextureEXT (GLenum target, GLenum attachment, GLuint texture, GLint level); +GLAPI void APIENTRY glFramebufferTextureLayerEXT (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer); GLAPI void APIENTRY glFramebufferTextureFaceEXT (GLenum target, GLenum attachment, GLuint texture, GLint level, GLenum face); #endif #endif /* GL_NV_geometry_program4 */ @@ -9510,10 +8782,6 @@ GLAPI void APIENTRY glFramebufferTextureFaceEXT (GLenum target, GLenum attachmen #define GL_NV_geometry_shader4 1 #endif /* GL_NV_geometry_shader4 */ -#ifndef GL_NV_geometry_shader_passthrough -#define GL_NV_geometry_shader_passthrough 1 -#endif /* GL_NV_geometry_shader_passthrough */ - #ifndef GL_NV_gpu_program4 #define GL_NV_gpu_program4 1 #define GL_MIN_PROGRAM_TEXEL_OFFSET_NV 0x8904 @@ -9686,18 +8954,6 @@ GLAPI void APIENTRY glVertexAttribs4hvNV (GLuint index, GLsizei n, const GLhalfN #endif #endif /* GL_NV_half_float */ -#ifndef GL_NV_internalformat_sample_query -#define GL_NV_internalformat_sample_query 1 -#define GL_MULTISAMPLES_NV 0x9371 -#define GL_SUPERSAMPLE_SCALE_X_NV 0x9372 -#define GL_SUPERSAMPLE_SCALE_Y_NV 0x9373 -#define GL_CONFORMANT_NV 0x9374 -typedef void (APIENTRYP PFNGLGETINTERNALFORMATSAMPLEIVNVPROC) (GLenum target, GLenum internalformat, GLsizei samples, GLenum pname, GLsizei bufSize, GLint *params); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glGetInternalformatSampleivNV (GLenum target, GLenum internalformat, GLsizei samples, GLenum pname, GLsizei bufSize, GLint *params); -#endif -#endif /* GL_NV_internalformat_sample_query */ - #ifndef GL_NV_light_max_exponent #define GL_NV_light_max_exponent 1 #define GL_MAX_SHININESS_NV 0x8504 @@ -9706,6 +8962,7 @@ GLAPI void APIENTRY glGetInternalformatSampleivNV (GLenum target, GLenum interna #ifndef GL_NV_multisample_coverage #define GL_NV_multisample_coverage 1 +#define GL_COLOR_SAMPLES_NV 0x8E20 #endif /* GL_NV_multisample_coverage */ #ifndef GL_NV_multisample_filter_hint @@ -9818,11 +9075,13 @@ GLAPI void APIENTRY glProgramBufferParametersIuivNV (GLenum target, GLuint bindi #define GL_SKIP_MISSING_GLYPH_NV 0x90A9 #define GL_USE_MISSING_GLYPH_NV 0x90AA #define GL_PATH_ERROR_POSITION_NV 0x90AB +#define GL_PATH_FOG_GEN_MODE_NV 0x90AC #define GL_ACCUM_ADJACENT_PAIRS_NV 0x90AD #define GL_ADJACENT_PAIRS_NV 0x90AE #define GL_FIRST_TO_REST_NV 0x90AF #define GL_PATH_GEN_MODE_NV 0x90B0 #define GL_PATH_GEN_COEFF_NV 0x90B1 +#define GL_PATH_GEN_COLOR_FORMAT_NV 0x90B2 #define GL_PATH_GEN_COMPONENTS_NV 0x90B3 #define GL_PATH_STENCIL_FUNC_NV 0x90B7 #define GL_PATH_STENCIL_REF_NV 0x90B8 @@ -9891,44 +9150,8 @@ GLAPI void APIENTRY glProgramBufferParametersIuivNV (GLenum target, GLuint bindi #define GL_FONT_UNDERLINE_POSITION_BIT_NV 0x04000000 #define GL_FONT_UNDERLINE_THICKNESS_BIT_NV 0x08000000 #define GL_FONT_HAS_KERNING_BIT_NV 0x10000000 -#define GL_ROUNDED_RECT_NV 0xE8 -#define GL_RELATIVE_ROUNDED_RECT_NV 0xE9 -#define GL_ROUNDED_RECT2_NV 0xEA -#define GL_RELATIVE_ROUNDED_RECT2_NV 0xEB -#define GL_ROUNDED_RECT4_NV 0xEC -#define GL_RELATIVE_ROUNDED_RECT4_NV 0xED -#define GL_ROUNDED_RECT8_NV 0xEE -#define GL_RELATIVE_ROUNDED_RECT8_NV 0xEF -#define GL_RELATIVE_RECT_NV 0xF7 -#define GL_FONT_GLYPHS_AVAILABLE_NV 0x9368 -#define GL_FONT_TARGET_UNAVAILABLE_NV 0x9369 -#define GL_FONT_UNAVAILABLE_NV 0x936A -#define GL_FONT_UNINTELLIGIBLE_NV 0x936B -#define GL_CONIC_CURVE_TO_NV 0x1A -#define GL_RELATIVE_CONIC_CURVE_TO_NV 0x1B -#define GL_FONT_NUM_GLYPH_INDICES_BIT_NV 0x20000000 -#define GL_STANDARD_FONT_FORMAT_NV 0x936C -#define GL_2_BYTES_NV 0x1407 -#define GL_3_BYTES_NV 0x1408 -#define GL_4_BYTES_NV 0x1409 -#define GL_EYE_LINEAR_NV 0x2400 -#define GL_OBJECT_LINEAR_NV 0x2401 -#define GL_CONSTANT_NV 0x8576 -#define GL_PATH_FOG_GEN_MODE_NV 0x90AC #define GL_PRIMARY_COLOR_NV 0x852C #define GL_SECONDARY_COLOR_NV 0x852D -#define GL_PATH_GEN_COLOR_FORMAT_NV 0x90B2 -#define GL_PATH_PROJECTION_NV 0x1701 -#define GL_PATH_MODELVIEW_NV 0x1700 -#define GL_PATH_MODELVIEW_STACK_DEPTH_NV 0x0BA3 -#define GL_PATH_MODELVIEW_MATRIX_NV 0x0BA6 -#define GL_PATH_MAX_MODELVIEW_STACK_DEPTH_NV 0x0D36 -#define GL_PATH_TRANSPOSE_MODELVIEW_MATRIX_NV 0x84E3 -#define GL_PATH_PROJECTION_STACK_DEPTH_NV 0x0BA4 -#define GL_PATH_PROJECTION_MATRIX_NV 0x0BA7 -#define GL_PATH_MAX_PROJECTION_STACK_DEPTH_NV 0x0D38 -#define GL_PATH_TRANSPOSE_PROJECTION_MATRIX_NV 0x84E4 -#define GL_FRAGMENT_INPUT_NV 0x936D typedef GLuint (APIENTRYP PFNGLGENPATHSNVPROC) (GLsizei range); typedef void (APIENTRYP PFNGLDELETEPATHSNVPROC) (GLuint path, GLsizei range); typedef GLboolean (APIENTRYP PFNGLISPATHNVPROC) (GLuint path); @@ -9955,6 +9178,9 @@ typedef void (APIENTRYP PFNGLSTENCILSTROKEPATHNVPROC) (GLuint path, GLint refere typedef void (APIENTRYP PFNGLSTENCILFILLPATHINSTANCEDNVPROC) (GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLenum fillMode, GLuint mask, GLenum transformType, const GLfloat *transformValues); typedef void (APIENTRYP PFNGLSTENCILSTROKEPATHINSTANCEDNVPROC) (GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLint reference, GLuint mask, GLenum transformType, const GLfloat *transformValues); typedef void (APIENTRYP PFNGLPATHCOVERDEPTHFUNCNVPROC) (GLenum func); +typedef void (APIENTRYP PFNGLPATHCOLORGENNVPROC) (GLenum color, GLenum genMode, GLenum colorFormat, const GLfloat *coeffs); +typedef void (APIENTRYP PFNGLPATHTEXGENNVPROC) (GLenum texCoordSet, GLenum genMode, GLint components, const GLfloat *coeffs); +typedef void (APIENTRYP PFNGLPATHFOGGENNVPROC) (GLenum genMode); typedef void (APIENTRYP PFNGLCOVERFILLPATHNVPROC) (GLuint path, GLenum coverMode); typedef void (APIENTRYP PFNGLCOVERSTROKEPATHNVPROC) (GLuint path, GLenum coverMode); typedef void (APIENTRYP PFNGLCOVERFILLPATHINSTANCEDNVPROC) (GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLenum coverMode, GLenum transformType, const GLfloat *transformValues); @@ -9967,32 +9193,14 @@ typedef void (APIENTRYP PFNGLGETPATHDASHARRAYNVPROC) (GLuint path, GLfloat *dash typedef void (APIENTRYP PFNGLGETPATHMETRICSNVPROC) (GLbitfield metricQueryMask, GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLsizei stride, GLfloat *metrics); typedef void (APIENTRYP PFNGLGETPATHMETRICRANGENVPROC) (GLbitfield metricQueryMask, GLuint firstPathName, GLsizei numPaths, GLsizei stride, GLfloat *metrics); typedef void (APIENTRYP PFNGLGETPATHSPACINGNVPROC) (GLenum pathListMode, GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLfloat advanceScale, GLfloat kerningScale, GLenum transformType, GLfloat *returnedSpacing); -typedef GLboolean (APIENTRYP PFNGLISPOINTINFILLPATHNVPROC) (GLuint path, GLuint mask, GLfloat x, GLfloat y); -typedef GLboolean (APIENTRYP PFNGLISPOINTINSTROKEPATHNVPROC) (GLuint path, GLfloat x, GLfloat y); -typedef GLfloat (APIENTRYP PFNGLGETPATHLENGTHNVPROC) (GLuint path, GLsizei startSegment, GLsizei numSegments); -typedef GLboolean (APIENTRYP PFNGLPOINTALONGPATHNVPROC) (GLuint path, GLsizei startSegment, GLsizei numSegments, GLfloat distance, GLfloat *x, GLfloat *y, GLfloat *tangentX, GLfloat *tangentY); -typedef void (APIENTRYP PFNGLMATRIXLOAD3X2FNVPROC) (GLenum matrixMode, const GLfloat *m); -typedef void (APIENTRYP PFNGLMATRIXLOAD3X3FNVPROC) (GLenum matrixMode, const GLfloat *m); -typedef void (APIENTRYP PFNGLMATRIXLOADTRANSPOSE3X3FNVPROC) (GLenum matrixMode, const GLfloat *m); -typedef void (APIENTRYP PFNGLMATRIXMULT3X2FNVPROC) (GLenum matrixMode, const GLfloat *m); -typedef void (APIENTRYP PFNGLMATRIXMULT3X3FNVPROC) (GLenum matrixMode, const GLfloat *m); -typedef void (APIENTRYP PFNGLMATRIXMULTTRANSPOSE3X3FNVPROC) (GLenum matrixMode, const GLfloat *m); -typedef void (APIENTRYP PFNGLSTENCILTHENCOVERFILLPATHNVPROC) (GLuint path, GLenum fillMode, GLuint mask, GLenum coverMode); -typedef void (APIENTRYP PFNGLSTENCILTHENCOVERSTROKEPATHNVPROC) (GLuint path, GLint reference, GLuint mask, GLenum coverMode); -typedef void (APIENTRYP PFNGLSTENCILTHENCOVERFILLPATHINSTANCEDNVPROC) (GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLenum fillMode, GLuint mask, GLenum coverMode, GLenum transformType, const GLfloat *transformValues); -typedef void (APIENTRYP PFNGLSTENCILTHENCOVERSTROKEPATHINSTANCEDNVPROC) (GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLint reference, GLuint mask, GLenum coverMode, GLenum transformType, const GLfloat *transformValues); -typedef GLenum (APIENTRYP PFNGLPATHGLYPHINDEXRANGENVPROC) (GLenum fontTarget, const void *fontName, GLbitfield fontStyle, GLuint pathParameterTemplate, GLfloat emScale, GLuint baseAndCount[2]); -typedef GLenum (APIENTRYP PFNGLPATHGLYPHINDEXARRAYNVPROC) (GLuint firstPathName, GLenum fontTarget, const void *fontName, GLbitfield fontStyle, GLuint firstGlyphIndex, GLsizei numGlyphs, GLuint pathParameterTemplate, GLfloat emScale); -typedef GLenum (APIENTRYP PFNGLPATHMEMORYGLYPHINDEXARRAYNVPROC) (GLuint firstPathName, GLenum fontTarget, GLsizeiptr fontSize, const void *fontData, GLsizei faceIndex, GLuint firstGlyphIndex, GLsizei numGlyphs, GLuint pathParameterTemplate, GLfloat emScale); -typedef void (APIENTRYP PFNGLPROGRAMPATHFRAGMENTINPUTGENNVPROC) (GLuint program, GLint location, GLenum genMode, GLint components, const GLfloat *coeffs); -typedef void (APIENTRYP PFNGLGETPROGRAMRESOURCEFVNVPROC) (GLuint program, GLenum programInterface, GLuint index, GLsizei propCount, const GLenum *props, GLsizei bufSize, GLsizei *length, GLfloat *params); -typedef void (APIENTRYP PFNGLPATHCOLORGENNVPROC) (GLenum color, GLenum genMode, GLenum colorFormat, const GLfloat *coeffs); -typedef void (APIENTRYP PFNGLPATHTEXGENNVPROC) (GLenum texCoordSet, GLenum genMode, GLint components, const GLfloat *coeffs); -typedef void (APIENTRYP PFNGLPATHFOGGENNVPROC) (GLenum genMode); typedef void (APIENTRYP PFNGLGETPATHCOLORGENIVNVPROC) (GLenum color, GLenum pname, GLint *value); typedef void (APIENTRYP PFNGLGETPATHCOLORGENFVNVPROC) (GLenum color, GLenum pname, GLfloat *value); typedef void (APIENTRYP PFNGLGETPATHTEXGENIVNVPROC) (GLenum texCoordSet, GLenum pname, GLint *value); typedef void (APIENTRYP PFNGLGETPATHTEXGENFVNVPROC) (GLenum texCoordSet, GLenum pname, GLfloat *value); +typedef GLboolean (APIENTRYP PFNGLISPOINTINFILLPATHNVPROC) (GLuint path, GLuint mask, GLfloat x, GLfloat y); +typedef GLboolean (APIENTRYP PFNGLISPOINTINSTROKEPATHNVPROC) (GLuint path, GLfloat x, GLfloat y); +typedef GLfloat (APIENTRYP PFNGLGETPATHLENGTHNVPROC) (GLuint path, GLsizei startSegment, GLsizei numSegments); +typedef GLboolean (APIENTRYP PFNGLPOINTALONGPATHNVPROC) (GLuint path, GLsizei startSegment, GLsizei numSegments, GLfloat distance, GLfloat *x, GLfloat *y, GLfloat *tangentX, GLfloat *tangentY); #ifdef GL_GLEXT_PROTOTYPES GLAPI GLuint APIENTRY glGenPathsNV (GLsizei range); GLAPI void APIENTRY glDeletePathsNV (GLuint path, GLsizei range); @@ -10020,6 +9228,9 @@ GLAPI void APIENTRY glStencilStrokePathNV (GLuint path, GLint reference, GLuint GLAPI void APIENTRY glStencilFillPathInstancedNV (GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLenum fillMode, GLuint mask, GLenum transformType, const GLfloat *transformValues); GLAPI void APIENTRY glStencilStrokePathInstancedNV (GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLint reference, GLuint mask, GLenum transformType, const GLfloat *transformValues); GLAPI void APIENTRY glPathCoverDepthFuncNV (GLenum func); +GLAPI void APIENTRY glPathColorGenNV (GLenum color, GLenum genMode, GLenum colorFormat, const GLfloat *coeffs); +GLAPI void APIENTRY glPathTexGenNV (GLenum texCoordSet, GLenum genMode, GLint components, const GLfloat *coeffs); +GLAPI void APIENTRY glPathFogGenNV (GLenum genMode); GLAPI void APIENTRY glCoverFillPathNV (GLuint path, GLenum coverMode); GLAPI void APIENTRY glCoverStrokePathNV (GLuint path, GLenum coverMode); GLAPI void APIENTRY glCoverFillPathInstancedNV (GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLenum coverMode, GLenum transformType, const GLfloat *transformValues); @@ -10032,40 +9243,17 @@ GLAPI void APIENTRY glGetPathDashArrayNV (GLuint path, GLfloat *dashArray); GLAPI void APIENTRY glGetPathMetricsNV (GLbitfield metricQueryMask, GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLsizei stride, GLfloat *metrics); GLAPI void APIENTRY glGetPathMetricRangeNV (GLbitfield metricQueryMask, GLuint firstPathName, GLsizei numPaths, GLsizei stride, GLfloat *metrics); GLAPI void APIENTRY glGetPathSpacingNV (GLenum pathListMode, GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLfloat advanceScale, GLfloat kerningScale, GLenum transformType, GLfloat *returnedSpacing); -GLAPI GLboolean APIENTRY glIsPointInFillPathNV (GLuint path, GLuint mask, GLfloat x, GLfloat y); -GLAPI GLboolean APIENTRY glIsPointInStrokePathNV (GLuint path, GLfloat x, GLfloat y); -GLAPI GLfloat APIENTRY glGetPathLengthNV (GLuint path, GLsizei startSegment, GLsizei numSegments); -GLAPI GLboolean APIENTRY glPointAlongPathNV (GLuint path, GLsizei startSegment, GLsizei numSegments, GLfloat distance, GLfloat *x, GLfloat *y, GLfloat *tangentX, GLfloat *tangentY); -GLAPI void APIENTRY glMatrixLoad3x2fNV (GLenum matrixMode, const GLfloat *m); -GLAPI void APIENTRY glMatrixLoad3x3fNV (GLenum matrixMode, const GLfloat *m); -GLAPI void APIENTRY glMatrixLoadTranspose3x3fNV (GLenum matrixMode, const GLfloat *m); -GLAPI void APIENTRY glMatrixMult3x2fNV (GLenum matrixMode, const GLfloat *m); -GLAPI void APIENTRY glMatrixMult3x3fNV (GLenum matrixMode, const GLfloat *m); -GLAPI void APIENTRY glMatrixMultTranspose3x3fNV (GLenum matrixMode, const GLfloat *m); -GLAPI void APIENTRY glStencilThenCoverFillPathNV (GLuint path, GLenum fillMode, GLuint mask, GLenum coverMode); -GLAPI void APIENTRY glStencilThenCoverStrokePathNV (GLuint path, GLint reference, GLuint mask, GLenum coverMode); -GLAPI void APIENTRY glStencilThenCoverFillPathInstancedNV (GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLenum fillMode, GLuint mask, GLenum coverMode, GLenum transformType, const GLfloat *transformValues); -GLAPI void APIENTRY glStencilThenCoverStrokePathInstancedNV (GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLint reference, GLuint mask, GLenum coverMode, GLenum transformType, const GLfloat *transformValues); -GLAPI GLenum APIENTRY glPathGlyphIndexRangeNV (GLenum fontTarget, const void *fontName, GLbitfield fontStyle, GLuint pathParameterTemplate, GLfloat emScale, GLuint baseAndCount[2]); -GLAPI GLenum APIENTRY glPathGlyphIndexArrayNV (GLuint firstPathName, GLenum fontTarget, const void *fontName, GLbitfield fontStyle, GLuint firstGlyphIndex, GLsizei numGlyphs, GLuint pathParameterTemplate, GLfloat emScale); -GLAPI GLenum APIENTRY glPathMemoryGlyphIndexArrayNV (GLuint firstPathName, GLenum fontTarget, GLsizeiptr fontSize, const void *fontData, GLsizei faceIndex, GLuint firstGlyphIndex, GLsizei numGlyphs, GLuint pathParameterTemplate, GLfloat emScale); -GLAPI void APIENTRY glProgramPathFragmentInputGenNV (GLuint program, GLint location, GLenum genMode, GLint components, const GLfloat *coeffs); -GLAPI void APIENTRY glGetProgramResourcefvNV (GLuint program, GLenum programInterface, GLuint index, GLsizei propCount, const GLenum *props, GLsizei bufSize, GLsizei *length, GLfloat *params); -GLAPI void APIENTRY glPathColorGenNV (GLenum color, GLenum genMode, GLenum colorFormat, const GLfloat *coeffs); -GLAPI void APIENTRY glPathTexGenNV (GLenum texCoordSet, GLenum genMode, GLint components, const GLfloat *coeffs); -GLAPI void APIENTRY glPathFogGenNV (GLenum genMode); GLAPI void APIENTRY glGetPathColorGenivNV (GLenum color, GLenum pname, GLint *value); GLAPI void APIENTRY glGetPathColorGenfvNV (GLenum color, GLenum pname, GLfloat *value); GLAPI void APIENTRY glGetPathTexGenivNV (GLenum texCoordSet, GLenum pname, GLint *value); GLAPI void APIENTRY glGetPathTexGenfvNV (GLenum texCoordSet, GLenum pname, GLfloat *value); +GLAPI GLboolean APIENTRY glIsPointInFillPathNV (GLuint path, GLuint mask, GLfloat x, GLfloat y); +GLAPI GLboolean APIENTRY glIsPointInStrokePathNV (GLuint path, GLfloat x, GLfloat y); +GLAPI GLfloat APIENTRY glGetPathLengthNV (GLuint path, GLsizei startSegment, GLsizei numSegments); +GLAPI GLboolean APIENTRY glPointAlongPathNV (GLuint path, GLsizei startSegment, GLsizei numSegments, GLfloat distance, GLfloat *x, GLfloat *y, GLfloat *tangentX, GLfloat *tangentY); #endif #endif /* GL_NV_path_rendering */ -#ifndef GL_NV_path_rendering_shared_edge -#define GL_NV_path_rendering_shared_edge 1 -#define GL_SHARED_EDGE_NV 0xC0 -#endif /* GL_NV_path_rendering_shared_edge */ - #ifndef GL_NV_pixel_data_range #define GL_NV_pixel_data_range 1 #define GL_WRITE_PIXEL_DATA_RANGE_NV 0x8878 @@ -10223,30 +9411,6 @@ GLAPI void APIENTRY glGetCombinerStageParameterfvNV (GLenum stage, GLenum pname, #endif #endif /* GL_NV_register_combiners2 */ -#ifndef GL_NV_sample_locations -#define GL_NV_sample_locations 1 -#define GL_SAMPLE_LOCATION_SUBPIXEL_BITS_NV 0x933D -#define GL_SAMPLE_LOCATION_PIXEL_GRID_WIDTH_NV 0x933E -#define GL_SAMPLE_LOCATION_PIXEL_GRID_HEIGHT_NV 0x933F -#define GL_PROGRAMMABLE_SAMPLE_LOCATION_TABLE_SIZE_NV 0x9340 -#define GL_SAMPLE_LOCATION_NV 0x8E50 -#define GL_PROGRAMMABLE_SAMPLE_LOCATION_NV 0x9341 -#define GL_FRAMEBUFFER_PROGRAMMABLE_SAMPLE_LOCATIONS_NV 0x9342 -#define GL_FRAMEBUFFER_SAMPLE_LOCATION_PIXEL_GRID_NV 0x9343 -typedef void (APIENTRYP PFNGLFRAMEBUFFERSAMPLELOCATIONSFVNVPROC) (GLenum target, GLuint start, GLsizei count, const GLfloat *v); -typedef void (APIENTRYP PFNGLNAMEDFRAMEBUFFERSAMPLELOCATIONSFVNVPROC) (GLuint framebuffer, GLuint start, GLsizei count, const GLfloat *v); -typedef void (APIENTRYP PFNGLRESOLVEDEPTHVALUESNVPROC) (void); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glFramebufferSampleLocationsfvNV (GLenum target, GLuint start, GLsizei count, const GLfloat *v); -GLAPI void APIENTRY glNamedFramebufferSampleLocationsfvNV (GLuint framebuffer, GLuint start, GLsizei count, const GLfloat *v); -GLAPI void APIENTRY glResolveDepthValuesNV (void); -#endif -#endif /* GL_NV_sample_locations */ - -#ifndef GL_NV_sample_mask_override_coverage -#define GL_NV_sample_mask_override_coverage 1 -#endif /* GL_NV_sample_mask_override_coverage */ - #ifndef GL_NV_shader_atomic_counters #define GL_NV_shader_atomic_counters 1 #endif /* GL_NV_shader_atomic_counters */ @@ -10255,14 +9419,6 @@ GLAPI void APIENTRY glResolveDepthValuesNV (void); #define GL_NV_shader_atomic_float 1 #endif /* GL_NV_shader_atomic_float */ -#ifndef GL_NV_shader_atomic_fp16_vector -#define GL_NV_shader_atomic_fp16_vector 1 -#endif /* GL_NV_shader_atomic_fp16_vector */ - -#ifndef GL_NV_shader_atomic_int64 -#define GL_NV_shader_atomic_int64 1 -#endif /* GL_NV_shader_atomic_int64 */ - #ifndef GL_NV_shader_buffer_load #define GL_NV_shader_buffer_load 1 #define GL_BUFFER_GPU_ADDRESS_NV 0x8F1D @@ -10532,7 +9688,7 @@ GLAPI void APIENTRY glTextureImage3DMultisampleCoverageNV (GLuint texture, GLenu #define GL_SKIP_COMPONENTS1_NV -6 typedef void (APIENTRYP PFNGLBEGINTRANSFORMFEEDBACKNVPROC) (GLenum primitiveMode); typedef void (APIENTRYP PFNGLENDTRANSFORMFEEDBACKNVPROC) (void); -typedef void (APIENTRYP PFNGLTRANSFORMFEEDBACKATTRIBSNVPROC) (GLsizei count, const GLint *attribs, GLenum bufferMode); +typedef void (APIENTRYP PFNGLTRANSFORMFEEDBACKATTRIBSNVPROC) (GLuint count, const GLint *attribs, GLenum bufferMode); typedef void (APIENTRYP PFNGLBINDBUFFERRANGENVPROC) (GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size); typedef void (APIENTRYP PFNGLBINDBUFFEROFFSETNVPROC) (GLenum target, GLuint index, GLuint buffer, GLintptr offset); typedef void (APIENTRYP PFNGLBINDBUFFERBASENVPROC) (GLenum target, GLuint index, GLuint buffer); @@ -10545,7 +9701,7 @@ typedef void (APIENTRYP PFNGLTRANSFORMFEEDBACKSTREAMATTRIBSNVPROC) (GLsizei coun #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glBeginTransformFeedbackNV (GLenum primitiveMode); GLAPI void APIENTRY glEndTransformFeedbackNV (void); -GLAPI void APIENTRY glTransformFeedbackAttribsNV (GLsizei count, const GLint *attribs, GLenum bufferMode); +GLAPI void APIENTRY glTransformFeedbackAttribsNV (GLuint count, const GLint *attribs, GLenum bufferMode); GLAPI void APIENTRY glBindBufferRangeNV (GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size); GLAPI void APIENTRY glBindBufferOffsetNV (GLenum target, GLuint index, GLuint buffer, GLintptr offset); GLAPI void APIENTRY glBindBufferBaseNV (GLenum target, GLuint index, GLuint buffer); @@ -10582,13 +9738,6 @@ GLAPI void APIENTRY glDrawTransformFeedbackNV (GLenum mode, GLuint id); #endif #endif /* GL_NV_transform_feedback2 */ -#ifndef GL_NV_uniform_buffer_unified_memory -#define GL_NV_uniform_buffer_unified_memory 1 -#define GL_UNIFORM_BUFFER_UNIFIED_NV 0x936E -#define GL_UNIFORM_BUFFER_ADDRESS_NV 0x936F -#define GL_UNIFORM_BUFFER_LENGTH_NV 0x9370 -#endif /* GL_NV_uniform_buffer_unified_memory */ - #ifndef GL_NV_vdpau_interop #define GL_NV_vdpau_interop 1 typedef GLintptr GLvdpauSurfaceNV; @@ -11084,10 +10233,6 @@ GLAPI void APIENTRY glVideoCaptureStreamParameterdvNV (GLuint video_capture_slot #endif #endif /* GL_NV_video_capture */ -#ifndef GL_NV_viewport_array2 -#define GL_NV_viewport_array2 1 -#endif /* GL_NV_viewport_array2 */ - #ifndef GL_OML_interlace #define GL_OML_interlace 1 #define GL_INTERLACE_OML 0x8980 @@ -11110,21 +10255,6 @@ GLAPI void APIENTRY glVideoCaptureStreamParameterdvNV (GLuint video_capture_slot #define GL_FORMAT_SUBSAMPLE_244_244_OML 0x8983 #endif /* GL_OML_subsample */ -#ifndef GL_OVR_multiview -#define GL_OVR_multiview 1 -#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_NUM_VIEWS_OVR 0x9630 -#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_BASE_VIEW_INDEX_OVR 0x9632 -#define GL_MAX_VIEWS_OVR 0x9631 -typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTUREMULTIVIEWOVRPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint baseViewIndex, GLsizei numViews); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glFramebufferTextureMultiviewOVR (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint baseViewIndex, GLsizei numViews); -#endif -#endif /* GL_OVR_multiview */ - -#ifndef GL_OVR_multiview2 -#define GL_OVR_multiview2 1 -#endif /* GL_OVR_multiview2 */ - #ifndef GL_PGI_misc_hints #define GL_PGI_misc_hints 1 #define GL_PREFER_DOUBLEBUFFER_HINT_PGI 0x1A1F8 @@ -11681,10 +10811,10 @@ GLAPI void APIENTRY glReferencePlaneSGIX (const GLdouble *equation); #ifndef GL_SGIX_resample #define GL_SGIX_resample 1 -#define GL_PACK_RESAMPLE_SGIX 0x842E -#define GL_UNPACK_RESAMPLE_SGIX 0x842F -#define GL_RESAMPLE_REPLICATE_SGIX 0x8433 -#define GL_RESAMPLE_ZERO_FILL_SGIX 0x8434 +#define GL_PACK_RESAMPLE_SGIX 0x842C +#define GL_UNPACK_RESAMPLE_SGIX 0x842D +#define GL_RESAMPLE_REPLICATE_SGIX 0x842E +#define GL_RESAMPLE_ZERO_FILL_SGIX 0x842F #define GL_RESAMPLE_DECIMATE_SGIX 0x8430 #endif /* GL_SGIX_resample */ diff --git a/engine/Windows/SDL2/include/SDL_opengles.h b/engine/Windows/SDL2/include/SDL_opengles.h new file mode 100644 index 0000000..1e0660c --- /dev/null +++ b/engine/Windows/SDL2/include/SDL_opengles.h @@ -0,0 +1,39 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2019 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_opengles.h + * + * This is a simple file to encapsulate the OpenGL ES 1.X API headers. + */ +#include "SDL_config.h" + +#ifdef __IPHONEOS__ +#include +#include +#else +#include +#include +#endif + +#ifndef APIENTRY +#define APIENTRY +#endif diff --git a/engine/Windows/SDL2/include/SDL_opengles2.h b/engine/Windows/SDL2/include/SDL_opengles2.h new file mode 100644 index 0000000..df29d38 --- /dev/null +++ b/engine/Windows/SDL2/include/SDL_opengles2.h @@ -0,0 +1,52 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2019 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_opengles2.h + * + * This is a simple file to encapsulate the OpenGL ES 2.0 API headers. + */ +#include "SDL_config.h" + +#ifndef _MSC_VER + +#ifdef __IPHONEOS__ +#include +#include +#else +#include +#include +#include +#endif + +#else /* _MSC_VER */ + +/* OpenGL ES2 headers for Visual Studio */ +#include "SDL_opengles2_khrplatform.h" +#include "SDL_opengles2_gl2platform.h" +#include "SDL_opengles2_gl2.h" +#include "SDL_opengles2_gl2ext.h" + +#endif /* _MSC_VER */ + +#ifndef APIENTRY +#define APIENTRY GL_APIENTRY +#endif diff --git a/engine/Windows/SDL2/include/SDL_opengles2_gl2.h b/engine/Windows/SDL2/include/SDL_opengles2_gl2.h new file mode 100644 index 0000000..c62fb0a --- /dev/null +++ b/engine/Windows/SDL2/include/SDL_opengles2_gl2.h @@ -0,0 +1,621 @@ +#ifndef __gl2_h_ +#define __gl2_h_ + +/* $Revision: 20555 $ on $Date:: 2013-02-12 14:32:47 -0800 #$ */ + +/*#include */ + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * This document is licensed under the SGI Free Software B License Version + * 2.0. For details, see http://oss.sgi.com/projects/FreeB/ . + */ + +/*------------------------------------------------------------------------- + * Data type definitions + *-----------------------------------------------------------------------*/ + +typedef void GLvoid; +typedef char GLchar; +typedef unsigned int GLenum; +typedef unsigned char GLboolean; +typedef unsigned int GLbitfield; +typedef khronos_int8_t GLbyte; +typedef short GLshort; +typedef int GLint; +typedef int GLsizei; +typedef khronos_uint8_t GLubyte; +typedef unsigned short GLushort; +typedef unsigned int GLuint; +typedef khronos_float_t GLfloat; +typedef khronos_float_t GLclampf; +typedef khronos_int32_t GLfixed; + +/* GL types for handling large vertex buffer objects */ +typedef khronos_intptr_t GLintptr; +typedef khronos_ssize_t GLsizeiptr; + +/* OpenGL ES core versions */ +#define GL_ES_VERSION_2_0 1 + +/* ClearBufferMask */ +#define GL_DEPTH_BUFFER_BIT 0x00000100 +#define GL_STENCIL_BUFFER_BIT 0x00000400 +#define GL_COLOR_BUFFER_BIT 0x00004000 + +/* Boolean */ +#define GL_FALSE 0 +#define GL_TRUE 1 + +/* BeginMode */ +#define GL_POINTS 0x0000 +#define GL_LINES 0x0001 +#define GL_LINE_LOOP 0x0002 +#define GL_LINE_STRIP 0x0003 +#define GL_TRIANGLES 0x0004 +#define GL_TRIANGLE_STRIP 0x0005 +#define GL_TRIANGLE_FAN 0x0006 + +/* AlphaFunction (not supported in ES20) */ +/* GL_NEVER */ +/* GL_LESS */ +/* GL_EQUAL */ +/* GL_LEQUAL */ +/* GL_GREATER */ +/* GL_NOTEQUAL */ +/* GL_GEQUAL */ +/* GL_ALWAYS */ + +/* BlendingFactorDest */ +#define GL_ZERO 0 +#define GL_ONE 1 +#define GL_SRC_COLOR 0x0300 +#define GL_ONE_MINUS_SRC_COLOR 0x0301 +#define GL_SRC_ALPHA 0x0302 +#define GL_ONE_MINUS_SRC_ALPHA 0x0303 +#define GL_DST_ALPHA 0x0304 +#define GL_ONE_MINUS_DST_ALPHA 0x0305 + +/* BlendingFactorSrc */ +/* GL_ZERO */ +/* GL_ONE */ +#define GL_DST_COLOR 0x0306 +#define GL_ONE_MINUS_DST_COLOR 0x0307 +#define GL_SRC_ALPHA_SATURATE 0x0308 +/* GL_SRC_ALPHA */ +/* GL_ONE_MINUS_SRC_ALPHA */ +/* GL_DST_ALPHA */ +/* GL_ONE_MINUS_DST_ALPHA */ + +/* BlendEquationSeparate */ +#define GL_FUNC_ADD 0x8006 +#define GL_BLEND_EQUATION 0x8009 +#define GL_BLEND_EQUATION_RGB 0x8009 /* same as BLEND_EQUATION */ +#define GL_BLEND_EQUATION_ALPHA 0x883D + +/* BlendSubtract */ +#define GL_FUNC_SUBTRACT 0x800A +#define GL_FUNC_REVERSE_SUBTRACT 0x800B + +/* Separate Blend Functions */ +#define GL_BLEND_DST_RGB 0x80C8 +#define GL_BLEND_SRC_RGB 0x80C9 +#define GL_BLEND_DST_ALPHA 0x80CA +#define GL_BLEND_SRC_ALPHA 0x80CB +#define GL_CONSTANT_COLOR 0x8001 +#define GL_ONE_MINUS_CONSTANT_COLOR 0x8002 +#define GL_CONSTANT_ALPHA 0x8003 +#define GL_ONE_MINUS_CONSTANT_ALPHA 0x8004 +#define GL_BLEND_COLOR 0x8005 + +/* Buffer Objects */ +#define GL_ARRAY_BUFFER 0x8892 +#define GL_ELEMENT_ARRAY_BUFFER 0x8893 +#define GL_ARRAY_BUFFER_BINDING 0x8894 +#define GL_ELEMENT_ARRAY_BUFFER_BINDING 0x8895 + +#define GL_STREAM_DRAW 0x88E0 +#define GL_STATIC_DRAW 0x88E4 +#define GL_DYNAMIC_DRAW 0x88E8 + +#define GL_BUFFER_SIZE 0x8764 +#define GL_BUFFER_USAGE 0x8765 + +#define GL_CURRENT_VERTEX_ATTRIB 0x8626 + +/* CullFaceMode */ +#define GL_FRONT 0x0404 +#define GL_BACK 0x0405 +#define GL_FRONT_AND_BACK 0x0408 + +/* DepthFunction */ +/* GL_NEVER */ +/* GL_LESS */ +/* GL_EQUAL */ +/* GL_LEQUAL */ +/* GL_GREATER */ +/* GL_NOTEQUAL */ +/* GL_GEQUAL */ +/* GL_ALWAYS */ + +/* EnableCap */ +#define GL_TEXTURE_2D 0x0DE1 +#define GL_CULL_FACE 0x0B44 +#define GL_BLEND 0x0BE2 +#define GL_DITHER 0x0BD0 +#define GL_STENCIL_TEST 0x0B90 +#define GL_DEPTH_TEST 0x0B71 +#define GL_SCISSOR_TEST 0x0C11 +#define GL_POLYGON_OFFSET_FILL 0x8037 +#define GL_SAMPLE_ALPHA_TO_COVERAGE 0x809E +#define GL_SAMPLE_COVERAGE 0x80A0 + +/* ErrorCode */ +#define GL_NO_ERROR 0 +#define GL_INVALID_ENUM 0x0500 +#define GL_INVALID_VALUE 0x0501 +#define GL_INVALID_OPERATION 0x0502 +#define GL_OUT_OF_MEMORY 0x0505 + +/* FrontFaceDirection */ +#define GL_CW 0x0900 +#define GL_CCW 0x0901 + +/* GetPName */ +#define GL_LINE_WIDTH 0x0B21 +#define GL_ALIASED_POINT_SIZE_RANGE 0x846D +#define GL_ALIASED_LINE_WIDTH_RANGE 0x846E +#define GL_CULL_FACE_MODE 0x0B45 +#define GL_FRONT_FACE 0x0B46 +#define GL_DEPTH_RANGE 0x0B70 +#define GL_DEPTH_WRITEMASK 0x0B72 +#define GL_DEPTH_CLEAR_VALUE 0x0B73 +#define GL_DEPTH_FUNC 0x0B74 +#define GL_STENCIL_CLEAR_VALUE 0x0B91 +#define GL_STENCIL_FUNC 0x0B92 +#define GL_STENCIL_FAIL 0x0B94 +#define GL_STENCIL_PASS_DEPTH_FAIL 0x0B95 +#define GL_STENCIL_PASS_DEPTH_PASS 0x0B96 +#define GL_STENCIL_REF 0x0B97 +#define GL_STENCIL_VALUE_MASK 0x0B93 +#define GL_STENCIL_WRITEMASK 0x0B98 +#define GL_STENCIL_BACK_FUNC 0x8800 +#define GL_STENCIL_BACK_FAIL 0x8801 +#define GL_STENCIL_BACK_PASS_DEPTH_FAIL 0x8802 +#define GL_STENCIL_BACK_PASS_DEPTH_PASS 0x8803 +#define GL_STENCIL_BACK_REF 0x8CA3 +#define GL_STENCIL_BACK_VALUE_MASK 0x8CA4 +#define GL_STENCIL_BACK_WRITEMASK 0x8CA5 +#define GL_VIEWPORT 0x0BA2 +#define GL_SCISSOR_BOX 0x0C10 +/* GL_SCISSOR_TEST */ +#define GL_COLOR_CLEAR_VALUE 0x0C22 +#define GL_COLOR_WRITEMASK 0x0C23 +#define GL_UNPACK_ALIGNMENT 0x0CF5 +#define GL_PACK_ALIGNMENT 0x0D05 +#define GL_MAX_TEXTURE_SIZE 0x0D33 +#define GL_MAX_VIEWPORT_DIMS 0x0D3A +#define GL_SUBPIXEL_BITS 0x0D50 +#define GL_RED_BITS 0x0D52 +#define GL_GREEN_BITS 0x0D53 +#define GL_BLUE_BITS 0x0D54 +#define GL_ALPHA_BITS 0x0D55 +#define GL_DEPTH_BITS 0x0D56 +#define GL_STENCIL_BITS 0x0D57 +#define GL_POLYGON_OFFSET_UNITS 0x2A00 +/* GL_POLYGON_OFFSET_FILL */ +#define GL_POLYGON_OFFSET_FACTOR 0x8038 +#define GL_TEXTURE_BINDING_2D 0x8069 +#define GL_SAMPLE_BUFFERS 0x80A8 +#define GL_SAMPLES 0x80A9 +#define GL_SAMPLE_COVERAGE_VALUE 0x80AA +#define GL_SAMPLE_COVERAGE_INVERT 0x80AB + +/* GetTextureParameter */ +/* GL_TEXTURE_MAG_FILTER */ +/* GL_TEXTURE_MIN_FILTER */ +/* GL_TEXTURE_WRAP_S */ +/* GL_TEXTURE_WRAP_T */ + +#define GL_NUM_COMPRESSED_TEXTURE_FORMATS 0x86A2 +#define GL_COMPRESSED_TEXTURE_FORMATS 0x86A3 + +/* HintMode */ +#define GL_DONT_CARE 0x1100 +#define GL_FASTEST 0x1101 +#define GL_NICEST 0x1102 + +/* HintTarget */ +#define GL_GENERATE_MIPMAP_HINT 0x8192 + +/* DataType */ +#define GL_BYTE 0x1400 +#define GL_UNSIGNED_BYTE 0x1401 +#define GL_SHORT 0x1402 +#define GL_UNSIGNED_SHORT 0x1403 +#define GL_INT 0x1404 +#define GL_UNSIGNED_INT 0x1405 +#define GL_FLOAT 0x1406 +#define GL_FIXED 0x140C + +/* PixelFormat */ +#define GL_DEPTH_COMPONENT 0x1902 +#define GL_ALPHA 0x1906 +#define GL_RGB 0x1907 +#define GL_RGBA 0x1908 +#define GL_LUMINANCE 0x1909 +#define GL_LUMINANCE_ALPHA 0x190A + +/* PixelType */ +/* GL_UNSIGNED_BYTE */ +#define GL_UNSIGNED_SHORT_4_4_4_4 0x8033 +#define GL_UNSIGNED_SHORT_5_5_5_1 0x8034 +#define GL_UNSIGNED_SHORT_5_6_5 0x8363 + +/* Shaders */ +#define GL_FRAGMENT_SHADER 0x8B30 +#define GL_VERTEX_SHADER 0x8B31 +#define GL_MAX_VERTEX_ATTRIBS 0x8869 +#define GL_MAX_VERTEX_UNIFORM_VECTORS 0x8DFB +#define GL_MAX_VARYING_VECTORS 0x8DFC +#define GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS 0x8B4D +#define GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS 0x8B4C +#define GL_MAX_TEXTURE_IMAGE_UNITS 0x8872 +#define GL_MAX_FRAGMENT_UNIFORM_VECTORS 0x8DFD +#define GL_SHADER_TYPE 0x8B4F +#define GL_DELETE_STATUS 0x8B80 +#define GL_LINK_STATUS 0x8B82 +#define GL_VALIDATE_STATUS 0x8B83 +#define GL_ATTACHED_SHADERS 0x8B85 +#define GL_ACTIVE_UNIFORMS 0x8B86 +#define GL_ACTIVE_UNIFORM_MAX_LENGTH 0x8B87 +#define GL_ACTIVE_ATTRIBUTES 0x8B89 +#define GL_ACTIVE_ATTRIBUTE_MAX_LENGTH 0x8B8A +#define GL_SHADING_LANGUAGE_VERSION 0x8B8C +#define GL_CURRENT_PROGRAM 0x8B8D + +/* StencilFunction */ +#define GL_NEVER 0x0200 +#define GL_LESS 0x0201 +#define GL_EQUAL 0x0202 +#define GL_LEQUAL 0x0203 +#define GL_GREATER 0x0204 +#define GL_NOTEQUAL 0x0205 +#define GL_GEQUAL 0x0206 +#define GL_ALWAYS 0x0207 + +/* StencilOp */ +/* GL_ZERO */ +#define GL_KEEP 0x1E00 +#define GL_REPLACE 0x1E01 +#define GL_INCR 0x1E02 +#define GL_DECR 0x1E03 +#define GL_INVERT 0x150A +#define GL_INCR_WRAP 0x8507 +#define GL_DECR_WRAP 0x8508 + +/* StringName */ +#define GL_VENDOR 0x1F00 +#define GL_RENDERER 0x1F01 +#define GL_VERSION 0x1F02 +#define GL_EXTENSIONS 0x1F03 + +/* TextureMagFilter */ +#define GL_NEAREST 0x2600 +#define GL_LINEAR 0x2601 + +/* TextureMinFilter */ +/* GL_NEAREST */ +/* GL_LINEAR */ +#define GL_NEAREST_MIPMAP_NEAREST 0x2700 +#define GL_LINEAR_MIPMAP_NEAREST 0x2701 +#define GL_NEAREST_MIPMAP_LINEAR 0x2702 +#define GL_LINEAR_MIPMAP_LINEAR 0x2703 + +/* TextureParameterName */ +#define GL_TEXTURE_MAG_FILTER 0x2800 +#define GL_TEXTURE_MIN_FILTER 0x2801 +#define GL_TEXTURE_WRAP_S 0x2802 +#define GL_TEXTURE_WRAP_T 0x2803 + +/* TextureTarget */ +/* GL_TEXTURE_2D */ +#define GL_TEXTURE 0x1702 + +#define GL_TEXTURE_CUBE_MAP 0x8513 +#define GL_TEXTURE_BINDING_CUBE_MAP 0x8514 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_X 0x8515 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X 0x8516 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y 0x8517 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y 0x8518 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z 0x8519 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z 0x851A +#define GL_MAX_CUBE_MAP_TEXTURE_SIZE 0x851C + +/* TextureUnit */ +#define GL_TEXTURE0 0x84C0 +#define GL_TEXTURE1 0x84C1 +#define GL_TEXTURE2 0x84C2 +#define GL_TEXTURE3 0x84C3 +#define GL_TEXTURE4 0x84C4 +#define GL_TEXTURE5 0x84C5 +#define GL_TEXTURE6 0x84C6 +#define GL_TEXTURE7 0x84C7 +#define GL_TEXTURE8 0x84C8 +#define GL_TEXTURE9 0x84C9 +#define GL_TEXTURE10 0x84CA +#define GL_TEXTURE11 0x84CB +#define GL_TEXTURE12 0x84CC +#define GL_TEXTURE13 0x84CD +#define GL_TEXTURE14 0x84CE +#define GL_TEXTURE15 0x84CF +#define GL_TEXTURE16 0x84D0 +#define GL_TEXTURE17 0x84D1 +#define GL_TEXTURE18 0x84D2 +#define GL_TEXTURE19 0x84D3 +#define GL_TEXTURE20 0x84D4 +#define GL_TEXTURE21 0x84D5 +#define GL_TEXTURE22 0x84D6 +#define GL_TEXTURE23 0x84D7 +#define GL_TEXTURE24 0x84D8 +#define GL_TEXTURE25 0x84D9 +#define GL_TEXTURE26 0x84DA +#define GL_TEXTURE27 0x84DB +#define GL_TEXTURE28 0x84DC +#define GL_TEXTURE29 0x84DD +#define GL_TEXTURE30 0x84DE +#define GL_TEXTURE31 0x84DF +#define GL_ACTIVE_TEXTURE 0x84E0 + +/* TextureWrapMode */ +#define GL_REPEAT 0x2901 +#define GL_CLAMP_TO_EDGE 0x812F +#define GL_MIRRORED_REPEAT 0x8370 + +/* Uniform Types */ +#define GL_FLOAT_VEC2 0x8B50 +#define GL_FLOAT_VEC3 0x8B51 +#define GL_FLOAT_VEC4 0x8B52 +#define GL_INT_VEC2 0x8B53 +#define GL_INT_VEC3 0x8B54 +#define GL_INT_VEC4 0x8B55 +#define GL_BOOL 0x8B56 +#define GL_BOOL_VEC2 0x8B57 +#define GL_BOOL_VEC3 0x8B58 +#define GL_BOOL_VEC4 0x8B59 +#define GL_FLOAT_MAT2 0x8B5A +#define GL_FLOAT_MAT3 0x8B5B +#define GL_FLOAT_MAT4 0x8B5C +#define GL_SAMPLER_2D 0x8B5E +#define GL_SAMPLER_CUBE 0x8B60 + +/* Vertex Arrays */ +#define GL_VERTEX_ATTRIB_ARRAY_ENABLED 0x8622 +#define GL_VERTEX_ATTRIB_ARRAY_SIZE 0x8623 +#define GL_VERTEX_ATTRIB_ARRAY_STRIDE 0x8624 +#define GL_VERTEX_ATTRIB_ARRAY_TYPE 0x8625 +#define GL_VERTEX_ATTRIB_ARRAY_NORMALIZED 0x886A +#define GL_VERTEX_ATTRIB_ARRAY_POINTER 0x8645 +#define GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING 0x889F + +/* Read Format */ +#define GL_IMPLEMENTATION_COLOR_READ_TYPE 0x8B9A +#define GL_IMPLEMENTATION_COLOR_READ_FORMAT 0x8B9B + +/* Shader Source */ +#define GL_COMPILE_STATUS 0x8B81 +#define GL_INFO_LOG_LENGTH 0x8B84 +#define GL_SHADER_SOURCE_LENGTH 0x8B88 +#define GL_SHADER_COMPILER 0x8DFA + +/* Shader Binary */ +#define GL_SHADER_BINARY_FORMATS 0x8DF8 +#define GL_NUM_SHADER_BINARY_FORMATS 0x8DF9 + +/* Shader Precision-Specified Types */ +#define GL_LOW_FLOAT 0x8DF0 +#define GL_MEDIUM_FLOAT 0x8DF1 +#define GL_HIGH_FLOAT 0x8DF2 +#define GL_LOW_INT 0x8DF3 +#define GL_MEDIUM_INT 0x8DF4 +#define GL_HIGH_INT 0x8DF5 + +/* Framebuffer Object. */ +#define GL_FRAMEBUFFER 0x8D40 +#define GL_RENDERBUFFER 0x8D41 + +#define GL_RGBA4 0x8056 +#define GL_RGB5_A1 0x8057 +#define GL_RGB565 0x8D62 +#define GL_DEPTH_COMPONENT16 0x81A5 +#define GL_STENCIL_INDEX8 0x8D48 + +#define GL_RENDERBUFFER_WIDTH 0x8D42 +#define GL_RENDERBUFFER_HEIGHT 0x8D43 +#define GL_RENDERBUFFER_INTERNAL_FORMAT 0x8D44 +#define GL_RENDERBUFFER_RED_SIZE 0x8D50 +#define GL_RENDERBUFFER_GREEN_SIZE 0x8D51 +#define GL_RENDERBUFFER_BLUE_SIZE 0x8D52 +#define GL_RENDERBUFFER_ALPHA_SIZE 0x8D53 +#define GL_RENDERBUFFER_DEPTH_SIZE 0x8D54 +#define GL_RENDERBUFFER_STENCIL_SIZE 0x8D55 + +#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE 0x8CD0 +#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME 0x8CD1 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL 0x8CD2 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE 0x8CD3 + +#define GL_COLOR_ATTACHMENT0 0x8CE0 +#define GL_DEPTH_ATTACHMENT 0x8D00 +#define GL_STENCIL_ATTACHMENT 0x8D20 + +#define GL_NONE 0 + +#define GL_FRAMEBUFFER_COMPLETE 0x8CD5 +#define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT 0x8CD6 +#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT 0x8CD7 +#define GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS 0x8CD9 +#define GL_FRAMEBUFFER_UNSUPPORTED 0x8CDD + +#define GL_FRAMEBUFFER_BINDING 0x8CA6 +#define GL_RENDERBUFFER_BINDING 0x8CA7 +#define GL_MAX_RENDERBUFFER_SIZE 0x84E8 + +#define GL_INVALID_FRAMEBUFFER_OPERATION 0x0506 + +/*------------------------------------------------------------------------- + * GL core functions. + *-----------------------------------------------------------------------*/ + +GL_APICALL void GL_APIENTRY glActiveTexture (GLenum texture); +GL_APICALL void GL_APIENTRY glAttachShader (GLuint program, GLuint shader); +GL_APICALL void GL_APIENTRY glBindAttribLocation (GLuint program, GLuint index, const GLchar* name); +GL_APICALL void GL_APIENTRY glBindBuffer (GLenum target, GLuint buffer); +GL_APICALL void GL_APIENTRY glBindFramebuffer (GLenum target, GLuint framebuffer); +GL_APICALL void GL_APIENTRY glBindRenderbuffer (GLenum target, GLuint renderbuffer); +GL_APICALL void GL_APIENTRY glBindTexture (GLenum target, GLuint texture); +GL_APICALL void GL_APIENTRY glBlendColor (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha); +GL_APICALL void GL_APIENTRY glBlendEquation ( GLenum mode ); +GL_APICALL void GL_APIENTRY glBlendEquationSeparate (GLenum modeRGB, GLenum modeAlpha); +GL_APICALL void GL_APIENTRY glBlendFunc (GLenum sfactor, GLenum dfactor); +GL_APICALL void GL_APIENTRY glBlendFuncSeparate (GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha); +GL_APICALL void GL_APIENTRY glBufferData (GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage); +GL_APICALL void GL_APIENTRY glBufferSubData (GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data); +GL_APICALL GLenum GL_APIENTRY glCheckFramebufferStatus (GLenum target); +GL_APICALL void GL_APIENTRY glClear (GLbitfield mask); +GL_APICALL void GL_APIENTRY glClearColor (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha); +GL_APICALL void GL_APIENTRY glClearDepthf (GLclampf depth); +GL_APICALL void GL_APIENTRY glClearStencil (GLint s); +GL_APICALL void GL_APIENTRY glColorMask (GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha); +GL_APICALL void GL_APIENTRY glCompileShader (GLuint shader); +GL_APICALL void GL_APIENTRY glCompressedTexImage2D (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid* data); +GL_APICALL void GL_APIENTRY glCompressedTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid* data); +GL_APICALL void GL_APIENTRY glCopyTexImage2D (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); +GL_APICALL void GL_APIENTRY glCopyTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); +GL_APICALL GLuint GL_APIENTRY glCreateProgram (void); +GL_APICALL GLuint GL_APIENTRY glCreateShader (GLenum type); +GL_APICALL void GL_APIENTRY glCullFace (GLenum mode); +GL_APICALL void GL_APIENTRY glDeleteBuffers (GLsizei n, const GLuint* buffers); +GL_APICALL void GL_APIENTRY glDeleteFramebuffers (GLsizei n, const GLuint* framebuffers); +GL_APICALL void GL_APIENTRY glDeleteProgram (GLuint program); +GL_APICALL void GL_APIENTRY glDeleteRenderbuffers (GLsizei n, const GLuint* renderbuffers); +GL_APICALL void GL_APIENTRY glDeleteShader (GLuint shader); +GL_APICALL void GL_APIENTRY glDeleteTextures (GLsizei n, const GLuint* textures); +GL_APICALL void GL_APIENTRY glDepthFunc (GLenum func); +GL_APICALL void GL_APIENTRY glDepthMask (GLboolean flag); +GL_APICALL void GL_APIENTRY glDepthRangef (GLclampf zNear, GLclampf zFar); +GL_APICALL void GL_APIENTRY glDetachShader (GLuint program, GLuint shader); +GL_APICALL void GL_APIENTRY glDisable (GLenum cap); +GL_APICALL void GL_APIENTRY glDisableVertexAttribArray (GLuint index); +GL_APICALL void GL_APIENTRY glDrawArrays (GLenum mode, GLint first, GLsizei count); +GL_APICALL void GL_APIENTRY glDrawElements (GLenum mode, GLsizei count, GLenum type, const GLvoid* indices); +GL_APICALL void GL_APIENTRY glEnable (GLenum cap); +GL_APICALL void GL_APIENTRY glEnableVertexAttribArray (GLuint index); +GL_APICALL void GL_APIENTRY glFinish (void); +GL_APICALL void GL_APIENTRY glFlush (void); +GL_APICALL void GL_APIENTRY glFramebufferRenderbuffer (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); +GL_APICALL void GL_APIENTRY glFramebufferTexture2D (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); +GL_APICALL void GL_APIENTRY glFrontFace (GLenum mode); +GL_APICALL void GL_APIENTRY glGenBuffers (GLsizei n, GLuint* buffers); +GL_APICALL void GL_APIENTRY glGenerateMipmap (GLenum target); +GL_APICALL void GL_APIENTRY glGenFramebuffers (GLsizei n, GLuint* framebuffers); +GL_APICALL void GL_APIENTRY glGenRenderbuffers (GLsizei n, GLuint* renderbuffers); +GL_APICALL void GL_APIENTRY glGenTextures (GLsizei n, GLuint* textures); +GL_APICALL void GL_APIENTRY glGetActiveAttrib (GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name); +GL_APICALL void GL_APIENTRY glGetActiveUniform (GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name); +GL_APICALL void GL_APIENTRY glGetAttachedShaders (GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders); +GL_APICALL GLint GL_APIENTRY glGetAttribLocation (GLuint program, const GLchar* name); +GL_APICALL void GL_APIENTRY glGetBooleanv (GLenum pname, GLboolean* params); +GL_APICALL void GL_APIENTRY glGetBufferParameteriv (GLenum target, GLenum pname, GLint* params); +GL_APICALL GLenum GL_APIENTRY glGetError (void); +GL_APICALL void GL_APIENTRY glGetFloatv (GLenum pname, GLfloat* params); +GL_APICALL void GL_APIENTRY glGetFramebufferAttachmentParameteriv (GLenum target, GLenum attachment, GLenum pname, GLint* params); +GL_APICALL void GL_APIENTRY glGetIntegerv (GLenum pname, GLint* params); +GL_APICALL void GL_APIENTRY glGetProgramiv (GLuint program, GLenum pname, GLint* params); +GL_APICALL void GL_APIENTRY glGetProgramInfoLog (GLuint program, GLsizei bufsize, GLsizei* length, GLchar* infolog); +GL_APICALL void GL_APIENTRY glGetRenderbufferParameteriv (GLenum target, GLenum pname, GLint* params); +GL_APICALL void GL_APIENTRY glGetShaderiv (GLuint shader, GLenum pname, GLint* params); +GL_APICALL void GL_APIENTRY glGetShaderInfoLog (GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* infolog); +GL_APICALL void GL_APIENTRY glGetShaderPrecisionFormat (GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision); +GL_APICALL void GL_APIENTRY glGetShaderSource (GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source); +GL_APICALL const GLubyte* GL_APIENTRY glGetString (GLenum name); +GL_APICALL void GL_APIENTRY glGetTexParameterfv (GLenum target, GLenum pname, GLfloat* params); +GL_APICALL void GL_APIENTRY glGetTexParameteriv (GLenum target, GLenum pname, GLint* params); +GL_APICALL void GL_APIENTRY glGetUniformfv (GLuint program, GLint location, GLfloat* params); +GL_APICALL void GL_APIENTRY glGetUniformiv (GLuint program, GLint location, GLint* params); +GL_APICALL GLint GL_APIENTRY glGetUniformLocation (GLuint program, const GLchar* name); +GL_APICALL void GL_APIENTRY glGetVertexAttribfv (GLuint index, GLenum pname, GLfloat* params); +GL_APICALL void GL_APIENTRY glGetVertexAttribiv (GLuint index, GLenum pname, GLint* params); +GL_APICALL void GL_APIENTRY glGetVertexAttribPointerv (GLuint index, GLenum pname, GLvoid** pointer); +GL_APICALL void GL_APIENTRY glHint (GLenum target, GLenum mode); +GL_APICALL GLboolean GL_APIENTRY glIsBuffer (GLuint buffer); +GL_APICALL GLboolean GL_APIENTRY glIsEnabled (GLenum cap); +GL_APICALL GLboolean GL_APIENTRY glIsFramebuffer (GLuint framebuffer); +GL_APICALL GLboolean GL_APIENTRY glIsProgram (GLuint program); +GL_APICALL GLboolean GL_APIENTRY glIsRenderbuffer (GLuint renderbuffer); +GL_APICALL GLboolean GL_APIENTRY glIsShader (GLuint shader); +GL_APICALL GLboolean GL_APIENTRY glIsTexture (GLuint texture); +GL_APICALL void GL_APIENTRY glLineWidth (GLfloat width); +GL_APICALL void GL_APIENTRY glLinkProgram (GLuint program); +GL_APICALL void GL_APIENTRY glPixelStorei (GLenum pname, GLint param); +GL_APICALL void GL_APIENTRY glPolygonOffset (GLfloat factor, GLfloat units); +GL_APICALL void GL_APIENTRY glReadPixels (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid* pixels); +GL_APICALL void GL_APIENTRY glReleaseShaderCompiler (void); +GL_APICALL void GL_APIENTRY glRenderbufferStorage (GLenum target, GLenum internalformat, GLsizei width, GLsizei height); +GL_APICALL void GL_APIENTRY glSampleCoverage (GLclampf value, GLboolean invert); +GL_APICALL void GL_APIENTRY glScissor (GLint x, GLint y, GLsizei width, GLsizei height); +GL_APICALL void GL_APIENTRY glShaderBinary (GLsizei n, const GLuint* shaders, GLenum binaryformat, const GLvoid* binary, GLsizei length); +GL_APICALL void GL_APIENTRY glShaderSource (GLuint shader, GLsizei count, const GLchar* const* string, const GLint* length); +GL_APICALL void GL_APIENTRY glStencilFunc (GLenum func, GLint ref, GLuint mask); +GL_APICALL void GL_APIENTRY glStencilFuncSeparate (GLenum face, GLenum func, GLint ref, GLuint mask); +GL_APICALL void GL_APIENTRY glStencilMask (GLuint mask); +GL_APICALL void GL_APIENTRY glStencilMaskSeparate (GLenum face, GLuint mask); +GL_APICALL void GL_APIENTRY glStencilOp (GLenum fail, GLenum zfail, GLenum zpass); +GL_APICALL void GL_APIENTRY glStencilOpSeparate (GLenum face, GLenum fail, GLenum zfail, GLenum zpass); +GL_APICALL void GL_APIENTRY glTexImage2D (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid* pixels); +GL_APICALL void GL_APIENTRY glTexParameterf (GLenum target, GLenum pname, GLfloat param); +GL_APICALL void GL_APIENTRY glTexParameterfv (GLenum target, GLenum pname, const GLfloat* params); +GL_APICALL void GL_APIENTRY glTexParameteri (GLenum target, GLenum pname, GLint param); +GL_APICALL void GL_APIENTRY glTexParameteriv (GLenum target, GLenum pname, const GLint* params); +GL_APICALL void GL_APIENTRY glTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid* pixels); +GL_APICALL void GL_APIENTRY glUniform1f (GLint location, GLfloat x); +GL_APICALL void GL_APIENTRY glUniform1fv (GLint location, GLsizei count, const GLfloat* v); +GL_APICALL void GL_APIENTRY glUniform1i (GLint location, GLint x); +GL_APICALL void GL_APIENTRY glUniform1iv (GLint location, GLsizei count, const GLint* v); +GL_APICALL void GL_APIENTRY glUniform2f (GLint location, GLfloat x, GLfloat y); +GL_APICALL void GL_APIENTRY glUniform2fv (GLint location, GLsizei count, const GLfloat* v); +GL_APICALL void GL_APIENTRY glUniform2i (GLint location, GLint x, GLint y); +GL_APICALL void GL_APIENTRY glUniform2iv (GLint location, GLsizei count, const GLint* v); +GL_APICALL void GL_APIENTRY glUniform3f (GLint location, GLfloat x, GLfloat y, GLfloat z); +GL_APICALL void GL_APIENTRY glUniform3fv (GLint location, GLsizei count, const GLfloat* v); +GL_APICALL void GL_APIENTRY glUniform3i (GLint location, GLint x, GLint y, GLint z); +GL_APICALL void GL_APIENTRY glUniform3iv (GLint location, GLsizei count, const GLint* v); +GL_APICALL void GL_APIENTRY glUniform4f (GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +GL_APICALL void GL_APIENTRY glUniform4fv (GLint location, GLsizei count, const GLfloat* v); +GL_APICALL void GL_APIENTRY glUniform4i (GLint location, GLint x, GLint y, GLint z, GLint w); +GL_APICALL void GL_APIENTRY glUniform4iv (GLint location, GLsizei count, const GLint* v); +GL_APICALL void GL_APIENTRY glUniformMatrix2fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); +GL_APICALL void GL_APIENTRY glUniformMatrix3fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); +GL_APICALL void GL_APIENTRY glUniformMatrix4fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); +GL_APICALL void GL_APIENTRY glUseProgram (GLuint program); +GL_APICALL void GL_APIENTRY glValidateProgram (GLuint program); +GL_APICALL void GL_APIENTRY glVertexAttrib1f (GLuint indx, GLfloat x); +GL_APICALL void GL_APIENTRY glVertexAttrib1fv (GLuint indx, const GLfloat* values); +GL_APICALL void GL_APIENTRY glVertexAttrib2f (GLuint indx, GLfloat x, GLfloat y); +GL_APICALL void GL_APIENTRY glVertexAttrib2fv (GLuint indx, const GLfloat* values); +GL_APICALL void GL_APIENTRY glVertexAttrib3f (GLuint indx, GLfloat x, GLfloat y, GLfloat z); +GL_APICALL void GL_APIENTRY glVertexAttrib3fv (GLuint indx, const GLfloat* values); +GL_APICALL void GL_APIENTRY glVertexAttrib4f (GLuint indx, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +GL_APICALL void GL_APIENTRY glVertexAttrib4fv (GLuint indx, const GLfloat* values); +GL_APICALL void GL_APIENTRY glVertexAttribPointer (GLuint indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr); +GL_APICALL void GL_APIENTRY glViewport (GLint x, GLint y, GLsizei width, GLsizei height); + +#ifdef __cplusplus +} +#endif + +#endif /* __gl2_h_ */ + diff --git a/engine/Windows/SDL2/include/SDL_opengles2_gl2ext.h b/engine/Windows/SDL2/include/SDL_opengles2_gl2ext.h new file mode 100644 index 0000000..e8ca8b1 --- /dev/null +++ b/engine/Windows/SDL2/include/SDL_opengles2_gl2ext.h @@ -0,0 +1,2050 @@ +#ifndef __gl2ext_h_ +#define __gl2ext_h_ + +/* $Revision: 22801 $ on $Date:: 2013-08-21 03:20:48 -0700 #$ */ + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * This document is licensed under the SGI Free Software B License Version + * 2.0. For details, see http://oss.sgi.com/projects/FreeB/ . + */ + +#ifndef GL_APIENTRYP +# define GL_APIENTRYP GL_APIENTRY* +#endif + +/* New types shared by several extensions */ + +#ifndef __gl3_h_ +/* These are defined with respect to in the + * Apple extension spec, but they are also used by non-APPLE + * extensions, and in the Khronos header we use the Khronos + * portable types in khrplatform.h, which must be defined. + */ +typedef khronos_int64_t GLint64; +typedef khronos_uint64_t GLuint64; +typedef struct __GLsync *GLsync; +#endif + + +/*------------------------------------------------------------------------* + * OES extension tokens + *------------------------------------------------------------------------*/ + +/* GL_OES_compressed_ETC1_RGB8_texture */ +#ifndef GL_OES_compressed_ETC1_RGB8_texture +#define GL_ETC1_RGB8_OES 0x8D64 +#endif + +/* GL_OES_compressed_paletted_texture */ +#ifndef GL_OES_compressed_paletted_texture +#define GL_PALETTE4_RGB8_OES 0x8B90 +#define GL_PALETTE4_RGBA8_OES 0x8B91 +#define GL_PALETTE4_R5_G6_B5_OES 0x8B92 +#define GL_PALETTE4_RGBA4_OES 0x8B93 +#define GL_PALETTE4_RGB5_A1_OES 0x8B94 +#define GL_PALETTE8_RGB8_OES 0x8B95 +#define GL_PALETTE8_RGBA8_OES 0x8B96 +#define GL_PALETTE8_R5_G6_B5_OES 0x8B97 +#define GL_PALETTE8_RGBA4_OES 0x8B98 +#define GL_PALETTE8_RGB5_A1_OES 0x8B99 +#endif + +/* GL_OES_depth24 */ +#ifndef GL_OES_depth24 +#define GL_DEPTH_COMPONENT24_OES 0x81A6 +#endif + +/* GL_OES_depth32 */ +#ifndef GL_OES_depth32 +#define GL_DEPTH_COMPONENT32_OES 0x81A7 +#endif + +/* GL_OES_depth_texture */ +/* No new tokens introduced by this extension. */ + +/* GL_OES_EGL_image */ +#ifndef GL_OES_EGL_image +typedef void* GLeglImageOES; +#endif + +/* GL_OES_EGL_image_external */ +#ifndef GL_OES_EGL_image_external +/* GLeglImageOES defined in GL_OES_EGL_image already. */ +#define GL_TEXTURE_EXTERNAL_OES 0x8D65 +#define GL_SAMPLER_EXTERNAL_OES 0x8D66 +#define GL_TEXTURE_BINDING_EXTERNAL_OES 0x8D67 +#define GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES 0x8D68 +#endif + +/* GL_OES_element_index_uint */ +#ifndef GL_OES_element_index_uint +#define GL_UNSIGNED_INT 0x1405 +#endif + +/* GL_OES_get_program_binary */ +#ifndef GL_OES_get_program_binary +#define GL_PROGRAM_BINARY_LENGTH_OES 0x8741 +#define GL_NUM_PROGRAM_BINARY_FORMATS_OES 0x87FE +#define GL_PROGRAM_BINARY_FORMATS_OES 0x87FF +#endif + +/* GL_OES_mapbuffer */ +#ifndef GL_OES_mapbuffer +#define GL_WRITE_ONLY_OES 0x88B9 +#define GL_BUFFER_ACCESS_OES 0x88BB +#define GL_BUFFER_MAPPED_OES 0x88BC +#define GL_BUFFER_MAP_POINTER_OES 0x88BD +#endif + +/* GL_OES_packed_depth_stencil */ +#ifndef GL_OES_packed_depth_stencil +#define GL_DEPTH_STENCIL_OES 0x84F9 +#define GL_UNSIGNED_INT_24_8_OES 0x84FA +#define GL_DEPTH24_STENCIL8_OES 0x88F0 +#endif + +/* GL_OES_required_internalformat */ +#ifndef GL_OES_required_internalformat +#define GL_ALPHA8_OES 0x803C +#define GL_DEPTH_COMPONENT16_OES 0x81A5 +/* reuse GL_DEPTH_COMPONENT24_OES */ +/* reuse GL_DEPTH24_STENCIL8_OES */ +/* reuse GL_DEPTH_COMPONENT32_OES */ +#define GL_LUMINANCE4_ALPHA4_OES 0x8043 +#define GL_LUMINANCE8_ALPHA8_OES 0x8045 +#define GL_LUMINANCE8_OES 0x8040 +#define GL_RGBA4_OES 0x8056 +#define GL_RGB5_A1_OES 0x8057 +#define GL_RGB565_OES 0x8D62 +/* reuse GL_RGB8_OES */ +/* reuse GL_RGBA8_OES */ +/* reuse GL_RGB10_EXT */ +/* reuse GL_RGB10_A2_EXT */ +#endif + +/* GL_OES_rgb8_rgba8 */ +#ifndef GL_OES_rgb8_rgba8 +#define GL_RGB8_OES 0x8051 +#define GL_RGBA8_OES 0x8058 +#endif + +/* GL_OES_standard_derivatives */ +#ifndef GL_OES_standard_derivatives +#define GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES 0x8B8B +#endif + +/* GL_OES_stencil1 */ +#ifndef GL_OES_stencil1 +#define GL_STENCIL_INDEX1_OES 0x8D46 +#endif + +/* GL_OES_stencil4 */ +#ifndef GL_OES_stencil4 +#define GL_STENCIL_INDEX4_OES 0x8D47 +#endif + +#ifndef GL_OES_surfaceless_context +#define GL_FRAMEBUFFER_UNDEFINED_OES 0x8219 +#endif + +/* GL_OES_texture_3D */ +#ifndef GL_OES_texture_3D +#define GL_TEXTURE_WRAP_R_OES 0x8072 +#define GL_TEXTURE_3D_OES 0x806F +#define GL_TEXTURE_BINDING_3D_OES 0x806A +#define GL_MAX_3D_TEXTURE_SIZE_OES 0x8073 +#define GL_SAMPLER_3D_OES 0x8B5F +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET_OES 0x8CD4 +#endif + +/* GL_OES_texture_float */ +/* No new tokens introduced by this extension. */ + +/* GL_OES_texture_float_linear */ +/* No new tokens introduced by this extension. */ + +/* GL_OES_texture_half_float */ +#ifndef GL_OES_texture_half_float +#define GL_HALF_FLOAT_OES 0x8D61 +#endif + +/* GL_OES_texture_half_float_linear */ +/* No new tokens introduced by this extension. */ + +/* GL_OES_texture_npot */ +/* No new tokens introduced by this extension. */ + +/* GL_OES_vertex_array_object */ +#ifndef GL_OES_vertex_array_object +#define GL_VERTEX_ARRAY_BINDING_OES 0x85B5 +#endif + +/* GL_OES_vertex_half_float */ +/* GL_HALF_FLOAT_OES defined in GL_OES_texture_half_float already. */ + +/* GL_OES_vertex_type_10_10_10_2 */ +#ifndef GL_OES_vertex_type_10_10_10_2 +#define GL_UNSIGNED_INT_10_10_10_2_OES 0x8DF6 +#define GL_INT_10_10_10_2_OES 0x8DF7 +#endif + +/*------------------------------------------------------------------------* + * KHR extension tokens + *------------------------------------------------------------------------*/ + +#ifndef GL_KHR_debug +typedef void (GL_APIENTRYP GLDEBUGPROCKHR)(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar *message,const void *userParam); +#define GL_DEBUG_OUTPUT_SYNCHRONOUS_KHR 0x8242 +#define GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH_KHR 0x8243 +#define GL_DEBUG_CALLBACK_FUNCTION_KHR 0x8244 +#define GL_DEBUG_CALLBACK_USER_PARAM_KHR 0x8245 +#define GL_DEBUG_SOURCE_API_KHR 0x8246 +#define GL_DEBUG_SOURCE_WINDOW_SYSTEM_KHR 0x8247 +#define GL_DEBUG_SOURCE_SHADER_COMPILER_KHR 0x8248 +#define GL_DEBUG_SOURCE_THIRD_PARTY_KHR 0x8249 +#define GL_DEBUG_SOURCE_APPLICATION_KHR 0x824A +#define GL_DEBUG_SOURCE_OTHER_KHR 0x824B +#define GL_DEBUG_TYPE_ERROR_KHR 0x824C +#define GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_KHR 0x824D +#define GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_KHR 0x824E +#define GL_DEBUG_TYPE_PORTABILITY_KHR 0x824F +#define GL_DEBUG_TYPE_PERFORMANCE_KHR 0x8250 +#define GL_DEBUG_TYPE_OTHER_KHR 0x8251 +#define GL_DEBUG_TYPE_MARKER_KHR 0x8268 +#define GL_DEBUG_TYPE_PUSH_GROUP_KHR 0x8269 +#define GL_DEBUG_TYPE_POP_GROUP_KHR 0x826A +#define GL_DEBUG_SEVERITY_NOTIFICATION_KHR 0x826B +#define GL_MAX_DEBUG_GROUP_STACK_DEPTH_KHR 0x826C +#define GL_DEBUG_GROUP_STACK_DEPTH_KHR 0x826D +#define GL_BUFFER_KHR 0x82E0 +#define GL_SHADER_KHR 0x82E1 +#define GL_PROGRAM_KHR 0x82E2 +#define GL_QUERY_KHR 0x82E3 +/* PROGRAM_PIPELINE only in GL */ +#define GL_SAMPLER_KHR 0x82E6 +/* DISPLAY_LIST only in GL */ +#define GL_MAX_LABEL_LENGTH_KHR 0x82E8 +#define GL_MAX_DEBUG_MESSAGE_LENGTH_KHR 0x9143 +#define GL_MAX_DEBUG_LOGGED_MESSAGES_KHR 0x9144 +#define GL_DEBUG_LOGGED_MESSAGES_KHR 0x9145 +#define GL_DEBUG_SEVERITY_HIGH_KHR 0x9146 +#define GL_DEBUG_SEVERITY_MEDIUM_KHR 0x9147 +#define GL_DEBUG_SEVERITY_LOW_KHR 0x9148 +#define GL_DEBUG_OUTPUT_KHR 0x92E0 +#define GL_CONTEXT_FLAG_DEBUG_BIT_KHR 0x00000002 +#define GL_STACK_OVERFLOW_KHR 0x0503 +#define GL_STACK_UNDERFLOW_KHR 0x0504 +#endif + +#ifndef GL_KHR_texture_compression_astc_ldr +#define GL_COMPRESSED_RGBA_ASTC_4x4_KHR 0x93B0 +#define GL_COMPRESSED_RGBA_ASTC_5x4_KHR 0x93B1 +#define GL_COMPRESSED_RGBA_ASTC_5x5_KHR 0x93B2 +#define GL_COMPRESSED_RGBA_ASTC_6x5_KHR 0x93B3 +#define GL_COMPRESSED_RGBA_ASTC_6x6_KHR 0x93B4 +#define GL_COMPRESSED_RGBA_ASTC_8x5_KHR 0x93B5 +#define GL_COMPRESSED_RGBA_ASTC_8x6_KHR 0x93B6 +#define GL_COMPRESSED_RGBA_ASTC_8x8_KHR 0x93B7 +#define GL_COMPRESSED_RGBA_ASTC_10x5_KHR 0x93B8 +#define GL_COMPRESSED_RGBA_ASTC_10x6_KHR 0x93B9 +#define GL_COMPRESSED_RGBA_ASTC_10x8_KHR 0x93BA +#define GL_COMPRESSED_RGBA_ASTC_10x10_KHR 0x93BB +#define GL_COMPRESSED_RGBA_ASTC_12x10_KHR 0x93BC +#define GL_COMPRESSED_RGBA_ASTC_12x12_KHR 0x93BD +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR 0x93D0 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR 0x93D1 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR 0x93D2 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR 0x93D3 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR 0x93D4 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR 0x93D5 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR 0x93D6 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR 0x93D7 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR 0x93D8 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR 0x93D9 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR 0x93DA +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR 0x93DB +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR 0x93DC +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR 0x93DD +#endif + +/*------------------------------------------------------------------------* + * AMD extension tokens + *------------------------------------------------------------------------*/ + +/* GL_AMD_compressed_3DC_texture */ +#ifndef GL_AMD_compressed_3DC_texture +#define GL_3DC_X_AMD 0x87F9 +#define GL_3DC_XY_AMD 0x87FA +#endif + +/* GL_AMD_compressed_ATC_texture */ +#ifndef GL_AMD_compressed_ATC_texture +#define GL_ATC_RGB_AMD 0x8C92 +#define GL_ATC_RGBA_EXPLICIT_ALPHA_AMD 0x8C93 +#define GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD 0x87EE +#endif + +/* GL_AMD_performance_monitor */ +#ifndef GL_AMD_performance_monitor +#define GL_COUNTER_TYPE_AMD 0x8BC0 +#define GL_COUNTER_RANGE_AMD 0x8BC1 +#define GL_UNSIGNED_INT64_AMD 0x8BC2 +#define GL_PERCENTAGE_AMD 0x8BC3 +#define GL_PERFMON_RESULT_AVAILABLE_AMD 0x8BC4 +#define GL_PERFMON_RESULT_SIZE_AMD 0x8BC5 +#define GL_PERFMON_RESULT_AMD 0x8BC6 +#endif + +/* GL_AMD_program_binary_Z400 */ +#ifndef GL_AMD_program_binary_Z400 +#define GL_Z400_BINARY_AMD 0x8740 +#endif + +/*------------------------------------------------------------------------* + * ANGLE extension tokens + *------------------------------------------------------------------------*/ + +/* GL_ANGLE_depth_texture */ +#ifndef GL_ANGLE_depth_texture +#define GL_DEPTH_COMPONENT 0x1902 +#define GL_DEPTH_STENCIL_OES 0x84F9 +#define GL_UNSIGNED_SHORT 0x1403 +#define GL_UNSIGNED_INT 0x1405 +#define GL_UNSIGNED_INT_24_8_OES 0x84FA +#define GL_DEPTH_COMPONENT16 0x81A5 +#define GL_DEPTH_COMPONENT32_OES 0x81A7 +#define GL_DEPTH24_STENCIL8_OES 0x88F0 +#endif + +/* GL_ANGLE_framebuffer_blit */ +#ifndef GL_ANGLE_framebuffer_blit +#define GL_READ_FRAMEBUFFER_ANGLE 0x8CA8 +#define GL_DRAW_FRAMEBUFFER_ANGLE 0x8CA9 +#define GL_DRAW_FRAMEBUFFER_BINDING_ANGLE 0x8CA6 +#define GL_READ_FRAMEBUFFER_BINDING_ANGLE 0x8CAA +#endif + +/* GL_ANGLE_framebuffer_multisample */ +#ifndef GL_ANGLE_framebuffer_multisample +#define GL_RENDERBUFFER_SAMPLES_ANGLE 0x8CAB +#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_ANGLE 0x8D56 +#define GL_MAX_SAMPLES_ANGLE 0x8D57 +#endif + +/* GL_ANGLE_instanced_arrays */ +#ifndef GL_ANGLE_instanced_arrays +#define GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE 0x88FE +#endif + +/* GL_ANGLE_pack_reverse_row_order */ +#ifndef GL_ANGLE_pack_reverse_row_order +#define GL_PACK_REVERSE_ROW_ORDER_ANGLE 0x93A4 +#endif + +/* GL_ANGLE_program_binary */ +#ifndef GL_ANGLE_program_binary +#define GL_PROGRAM_BINARY_ANGLE 0x93A6 +#endif + +/* GL_ANGLE_texture_compression_dxt3 */ +#ifndef GL_ANGLE_texture_compression_dxt3 +#define GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE 0x83F2 +#endif + +/* GL_ANGLE_texture_compression_dxt5 */ +#ifndef GL_ANGLE_texture_compression_dxt5 +#define GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE 0x83F3 +#endif + +/* GL_ANGLE_texture_usage */ +#ifndef GL_ANGLE_texture_usage +#define GL_TEXTURE_USAGE_ANGLE 0x93A2 +#define GL_FRAMEBUFFER_ATTACHMENT_ANGLE 0x93A3 +#endif + +/* GL_ANGLE_translated_shader_source */ +#ifndef GL_ANGLE_translated_shader_source +#define GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE 0x93A0 +#endif + +/*------------------------------------------------------------------------* + * APPLE extension tokens + *------------------------------------------------------------------------*/ + +/* GL_APPLE_copy_texture_levels */ +/* No new tokens introduced by this extension. */ + +/* GL_APPLE_framebuffer_multisample */ +#ifndef GL_APPLE_framebuffer_multisample +#define GL_RENDERBUFFER_SAMPLES_APPLE 0x8CAB +#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_APPLE 0x8D56 +#define GL_MAX_SAMPLES_APPLE 0x8D57 +#define GL_READ_FRAMEBUFFER_APPLE 0x8CA8 +#define GL_DRAW_FRAMEBUFFER_APPLE 0x8CA9 +#define GL_DRAW_FRAMEBUFFER_BINDING_APPLE 0x8CA6 +#define GL_READ_FRAMEBUFFER_BINDING_APPLE 0x8CAA +#endif + +/* GL_APPLE_rgb_422 */ +#ifndef GL_APPLE_rgb_422 +#define GL_RGB_422_APPLE 0x8A1F +#define GL_UNSIGNED_SHORT_8_8_APPLE 0x85BA +#define GL_UNSIGNED_SHORT_8_8_REV_APPLE 0x85BB +#endif + +/* GL_APPLE_sync */ +#ifndef GL_APPLE_sync + +#define GL_SYNC_OBJECT_APPLE 0x8A53 +#define GL_MAX_SERVER_WAIT_TIMEOUT_APPLE 0x9111 +#define GL_OBJECT_TYPE_APPLE 0x9112 +#define GL_SYNC_CONDITION_APPLE 0x9113 +#define GL_SYNC_STATUS_APPLE 0x9114 +#define GL_SYNC_FLAGS_APPLE 0x9115 +#define GL_SYNC_FENCE_APPLE 0x9116 +#define GL_SYNC_GPU_COMMANDS_COMPLETE_APPLE 0x9117 +#define GL_UNSIGNALED_APPLE 0x9118 +#define GL_SIGNALED_APPLE 0x9119 +#define GL_ALREADY_SIGNALED_APPLE 0x911A +#define GL_TIMEOUT_EXPIRED_APPLE 0x911B +#define GL_CONDITION_SATISFIED_APPLE 0x911C +#define GL_WAIT_FAILED_APPLE 0x911D +#define GL_SYNC_FLUSH_COMMANDS_BIT_APPLE 0x00000001 +#define GL_TIMEOUT_IGNORED_APPLE 0xFFFFFFFFFFFFFFFFull +#endif + +/* GL_APPLE_texture_format_BGRA8888 */ +#ifndef GL_APPLE_texture_format_BGRA8888 +#define GL_BGRA_EXT 0x80E1 +#endif + +/* GL_APPLE_texture_max_level */ +#ifndef GL_APPLE_texture_max_level +#define GL_TEXTURE_MAX_LEVEL_APPLE 0x813D +#endif + +/*------------------------------------------------------------------------* + * ARM extension tokens + *------------------------------------------------------------------------*/ + +/* GL_ARM_mali_program_binary */ +#ifndef GL_ARM_mali_program_binary +#define GL_MALI_PROGRAM_BINARY_ARM 0x8F61 +#endif + +/* GL_ARM_mali_shader_binary */ +#ifndef GL_ARM_mali_shader_binary +#define GL_MALI_SHADER_BINARY_ARM 0x8F60 +#endif + +/* GL_ARM_rgba8 */ +/* No new tokens introduced by this extension. */ + +/*------------------------------------------------------------------------* + * EXT extension tokens + *------------------------------------------------------------------------*/ + +/* GL_EXT_blend_minmax */ +#ifndef GL_EXT_blend_minmax +#define GL_MIN_EXT 0x8007 +#define GL_MAX_EXT 0x8008 +#endif + +/* GL_EXT_color_buffer_half_float */ +#ifndef GL_EXT_color_buffer_half_float +#define GL_RGBA16F_EXT 0x881A +#define GL_RGB16F_EXT 0x881B +#define GL_RG16F_EXT 0x822F +#define GL_R16F_EXT 0x822D +#define GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE_EXT 0x8211 +#define GL_UNSIGNED_NORMALIZED_EXT 0x8C17 +#endif + +/* GL_EXT_debug_label */ +#ifndef GL_EXT_debug_label +#define GL_PROGRAM_PIPELINE_OBJECT_EXT 0x8A4F +#define GL_PROGRAM_OBJECT_EXT 0x8B40 +#define GL_SHADER_OBJECT_EXT 0x8B48 +#define GL_BUFFER_OBJECT_EXT 0x9151 +#define GL_QUERY_OBJECT_EXT 0x9153 +#define GL_VERTEX_ARRAY_OBJECT_EXT 0x9154 +#endif + +/* GL_EXT_debug_marker */ +/* No new tokens introduced by this extension. */ + +/* GL_EXT_discard_framebuffer */ +#ifndef GL_EXT_discard_framebuffer +#define GL_COLOR_EXT 0x1800 +#define GL_DEPTH_EXT 0x1801 +#define GL_STENCIL_EXT 0x1802 +#endif + +#ifndef GL_EXT_disjoint_timer_query +#define GL_QUERY_COUNTER_BITS_EXT 0x8864 +#define GL_CURRENT_QUERY_EXT 0x8865 +#define GL_QUERY_RESULT_EXT 0x8866 +#define GL_QUERY_RESULT_AVAILABLE_EXT 0x8867 +#define GL_TIME_ELAPSED_EXT 0x88BF +#define GL_TIMESTAMP_EXT 0x8E28 +#define GL_GPU_DISJOINT_EXT 0x8FBB +#endif + +#ifndef GL_EXT_draw_buffers +#define GL_EXT_draw_buffers 1 +#define GL_MAX_COLOR_ATTACHMENTS_EXT 0x8CDF +#define GL_MAX_DRAW_BUFFERS_EXT 0x8824 +#define GL_DRAW_BUFFER0_EXT 0x8825 +#define GL_DRAW_BUFFER1_EXT 0x8826 +#define GL_DRAW_BUFFER2_EXT 0x8827 +#define GL_DRAW_BUFFER3_EXT 0x8828 +#define GL_DRAW_BUFFER4_EXT 0x8829 +#define GL_DRAW_BUFFER5_EXT 0x882A +#define GL_DRAW_BUFFER6_EXT 0x882B +#define GL_DRAW_BUFFER7_EXT 0x882C +#define GL_DRAW_BUFFER8_EXT 0x882D +#define GL_DRAW_BUFFER9_EXT 0x882E +#define GL_DRAW_BUFFER10_EXT 0x882F +#define GL_DRAW_BUFFER11_EXT 0x8830 +#define GL_DRAW_BUFFER12_EXT 0x8831 +#define GL_DRAW_BUFFER13_EXT 0x8832 +#define GL_DRAW_BUFFER14_EXT 0x8833 +#define GL_DRAW_BUFFER15_EXT 0x8834 +#define GL_COLOR_ATTACHMENT0_EXT 0x8CE0 +#define GL_COLOR_ATTACHMENT1_EXT 0x8CE1 +#define GL_COLOR_ATTACHMENT2_EXT 0x8CE2 +#define GL_COLOR_ATTACHMENT3_EXT 0x8CE3 +#define GL_COLOR_ATTACHMENT4_EXT 0x8CE4 +#define GL_COLOR_ATTACHMENT5_EXT 0x8CE5 +#define GL_COLOR_ATTACHMENT6_EXT 0x8CE6 +#define GL_COLOR_ATTACHMENT7_EXT 0x8CE7 +#define GL_COLOR_ATTACHMENT8_EXT 0x8CE8 +#define GL_COLOR_ATTACHMENT9_EXT 0x8CE9 +#define GL_COLOR_ATTACHMENT10_EXT 0x8CEA +#define GL_COLOR_ATTACHMENT11_EXT 0x8CEB +#define GL_COLOR_ATTACHMENT12_EXT 0x8CEC +#define GL_COLOR_ATTACHMENT13_EXT 0x8CED +#define GL_COLOR_ATTACHMENT14_EXT 0x8CEE +#define GL_COLOR_ATTACHMENT15_EXT 0x8CEF +#endif + +/* GL_EXT_map_buffer_range */ +#ifndef GL_EXT_map_buffer_range +#define GL_MAP_READ_BIT_EXT 0x0001 +#define GL_MAP_WRITE_BIT_EXT 0x0002 +#define GL_MAP_INVALIDATE_RANGE_BIT_EXT 0x0004 +#define GL_MAP_INVALIDATE_BUFFER_BIT_EXT 0x0008 +#define GL_MAP_FLUSH_EXPLICIT_BIT_EXT 0x0010 +#define GL_MAP_UNSYNCHRONIZED_BIT_EXT 0x0020 +#endif + +/* GL_EXT_multisampled_render_to_texture */ +#ifndef GL_EXT_multisampled_render_to_texture +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_SAMPLES_EXT 0x8D6C +/* reuse values from GL_EXT_framebuffer_multisample (desktop extension) */ +#define GL_RENDERBUFFER_SAMPLES_EXT 0x8CAB +#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT 0x8D56 +#define GL_MAX_SAMPLES_EXT 0x8D57 +#endif + +/* GL_EXT_multiview_draw_buffers */ +#ifndef GL_EXT_multiview_draw_buffers +#define GL_COLOR_ATTACHMENT_EXT 0x90F0 +#define GL_MULTIVIEW_EXT 0x90F1 +#define GL_DRAW_BUFFER_EXT 0x0C01 +#define GL_READ_BUFFER_EXT 0x0C02 +#define GL_MAX_MULTIVIEW_BUFFERS_EXT 0x90F2 +#endif + +/* GL_EXT_multi_draw_arrays */ +/* No new tokens introduced by this extension. */ + +/* GL_EXT_occlusion_query_boolean */ +#ifndef GL_EXT_occlusion_query_boolean +#define GL_ANY_SAMPLES_PASSED_EXT 0x8C2F +#define GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT 0x8D6A +#define GL_CURRENT_QUERY_EXT 0x8865 +#define GL_QUERY_RESULT_EXT 0x8866 +#define GL_QUERY_RESULT_AVAILABLE_EXT 0x8867 +#endif + +/* GL_EXT_read_format_bgra */ +#ifndef GL_EXT_read_format_bgra +#define GL_BGRA_EXT 0x80E1 +#define GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT 0x8365 +#define GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT 0x8366 +#endif + +/* GL_EXT_robustness */ +#ifndef GL_EXT_robustness +/* reuse GL_NO_ERROR */ +#define GL_GUILTY_CONTEXT_RESET_EXT 0x8253 +#define GL_INNOCENT_CONTEXT_RESET_EXT 0x8254 +#define GL_UNKNOWN_CONTEXT_RESET_EXT 0x8255 +#define GL_CONTEXT_ROBUST_ACCESS_EXT 0x90F3 +#define GL_RESET_NOTIFICATION_STRATEGY_EXT 0x8256 +#define GL_LOSE_CONTEXT_ON_RESET_EXT 0x8252 +#define GL_NO_RESET_NOTIFICATION_EXT 0x8261 +#endif + +/* GL_EXT_separate_shader_objects */ +#ifndef GL_EXT_separate_shader_objects +#define GL_VERTEX_SHADER_BIT_EXT 0x00000001 +#define GL_FRAGMENT_SHADER_BIT_EXT 0x00000002 +#define GL_ALL_SHADER_BITS_EXT 0xFFFFFFFF +#define GL_PROGRAM_SEPARABLE_EXT 0x8258 +#define GL_ACTIVE_PROGRAM_EXT 0x8259 +#define GL_PROGRAM_PIPELINE_BINDING_EXT 0x825A +#endif + +/* GL_EXT_shader_framebuffer_fetch */ +#ifndef GL_EXT_shader_framebuffer_fetch +#define GL_FRAGMENT_SHADER_DISCARDS_SAMPLES_EXT 0x8A52 +#endif + +/* GL_EXT_shader_texture_lod */ +/* No new tokens introduced by this extension. */ + +/* GL_EXT_shadow_samplers */ +#ifndef GL_EXT_shadow_samplers +#define GL_TEXTURE_COMPARE_MODE_EXT 0x884C +#define GL_TEXTURE_COMPARE_FUNC_EXT 0x884D +#define GL_COMPARE_REF_TO_TEXTURE_EXT 0x884E +#define GL_SAMPLER_2D_SHADOW_EXT 0x8B62 +#endif + +/* GL_EXT_sRGB */ +#ifndef GL_EXT_sRGB +#define GL_SRGB_EXT 0x8C40 +#define GL_SRGB_ALPHA_EXT 0x8C42 +#define GL_SRGB8_ALPHA8_EXT 0x8C43 +#define GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING_EXT 0x8210 +#endif + +/* GL_EXT_sRGB_write_control */ +#ifndef GL_EXT_sRGB_write_control +#define GL_EXT_sRGB_write_control 1 +#define GL_FRAMEBUFFER_SRGB_EXT 0x8DB9 +#endif + +/* GL_EXT_texture_compression_dxt1 */ +#ifndef GL_EXT_texture_compression_dxt1 +#define GL_COMPRESSED_RGB_S3TC_DXT1_EXT 0x83F0 +#define GL_COMPRESSED_RGBA_S3TC_DXT1_EXT 0x83F1 +#endif + +/* GL_EXT_texture_filter_anisotropic */ +#ifndef GL_EXT_texture_filter_anisotropic +#define GL_TEXTURE_MAX_ANISOTROPY_EXT 0x84FE +#define GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT 0x84FF +#endif + +/* GL_EXT_texture_format_BGRA8888 */ +#ifndef GL_EXT_texture_format_BGRA8888 +#define GL_BGRA_EXT 0x80E1 +#endif + +/* GL_EXT_texture_rg */ +#ifndef GL_EXT_texture_rg +#define GL_RED_EXT 0x1903 +#define GL_RG_EXT 0x8227 +#define GL_R8_EXT 0x8229 +#define GL_RG8_EXT 0x822B +#endif + +/* GL_EXT_texture_sRGB_decode */ +#ifndef GL_EXT_texture_sRGB_decode +#define GL_EXT_texture_sRGB_decode 1 +#define GL_TEXTURE_SRGB_DECODE_EXT 0x8A48 +#define GL_DECODE_EXT 0x8A49 +#define GL_SKIP_DECODE_EXT 0x8A4A +#endif + +/* GL_EXT_texture_storage */ +#ifndef GL_EXT_texture_storage +#define GL_TEXTURE_IMMUTABLE_FORMAT_EXT 0x912F +#define GL_ALPHA8_EXT 0x803C +#define GL_LUMINANCE8_EXT 0x8040 +#define GL_LUMINANCE8_ALPHA8_EXT 0x8045 +#define GL_RGBA32F_EXT 0x8814 +#define GL_RGB32F_EXT 0x8815 +#define GL_ALPHA32F_EXT 0x8816 +#define GL_LUMINANCE32F_EXT 0x8818 +#define GL_LUMINANCE_ALPHA32F_EXT 0x8819 +/* reuse GL_RGBA16F_EXT */ +/* reuse GL_RGB16F_EXT */ +#define GL_ALPHA16F_EXT 0x881C +#define GL_LUMINANCE16F_EXT 0x881E +#define GL_LUMINANCE_ALPHA16F_EXT 0x881F +#define GL_RGB10_A2_EXT 0x8059 +#define GL_RGB10_EXT 0x8052 +#define GL_BGRA8_EXT 0x93A1 +#define GL_R8_EXT 0x8229 +#define GL_RG8_EXT 0x822B +#define GL_R32F_EXT 0x822E +#define GL_RG32F_EXT 0x8230 +#define GL_R16F_EXT 0x822D +#define GL_RG16F_EXT 0x822F +#endif + +/* GL_EXT_texture_type_2_10_10_10_REV */ +#ifndef GL_EXT_texture_type_2_10_10_10_REV +#define GL_UNSIGNED_INT_2_10_10_10_REV_EXT 0x8368 +#endif + +/* GL_EXT_unpack_subimage */ +#ifndef GL_EXT_unpack_subimage +#define GL_UNPACK_ROW_LENGTH_EXT 0x0CF2 +#define GL_UNPACK_SKIP_ROWS_EXT 0x0CF3 +#define GL_UNPACK_SKIP_PIXELS_EXT 0x0CF4 +#endif + +/*------------------------------------------------------------------------* + * DMP extension tokens + *------------------------------------------------------------------------*/ + +/* GL_DMP_shader_binary */ +#ifndef GL_DMP_shader_binary +#define GL_SHADER_BINARY_DMP 0x9250 +#endif + +/*------------------------------------------------------------------------* + * FJ extension tokens + *------------------------------------------------------------------------*/ + +/* GL_FJ_shader_binary_GCCSO */ +#ifndef GL_FJ_shader_binary_GCCSO +#define GL_GCCSO_SHADER_BINARY_FJ 0x9260 +#endif + +/*------------------------------------------------------------------------* + * IMG extension tokens + *------------------------------------------------------------------------*/ + +/* GL_IMG_program_binary */ +#ifndef GL_IMG_program_binary +#define GL_SGX_PROGRAM_BINARY_IMG 0x9130 +#endif + +/* GL_IMG_read_format */ +#ifndef GL_IMG_read_format +#define GL_BGRA_IMG 0x80E1 +#define GL_UNSIGNED_SHORT_4_4_4_4_REV_IMG 0x8365 +#endif + +/* GL_IMG_shader_binary */ +#ifndef GL_IMG_shader_binary +#define GL_SGX_BINARY_IMG 0x8C0A +#endif + +/* GL_IMG_texture_compression_pvrtc */ +#ifndef GL_IMG_texture_compression_pvrtc +#define GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG 0x8C00 +#define GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG 0x8C01 +#define GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG 0x8C02 +#define GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG 0x8C03 +#endif + +/* GL_IMG_texture_compression_pvrtc2 */ +#ifndef GL_IMG_texture_compression_pvrtc2 +#define GL_COMPRESSED_RGBA_PVRTC_2BPPV2_IMG 0x9137 +#define GL_COMPRESSED_RGBA_PVRTC_4BPPV2_IMG 0x9138 +#endif + +/* GL_IMG_multisampled_render_to_texture */ +#ifndef GL_IMG_multisampled_render_to_texture +#define GL_RENDERBUFFER_SAMPLES_IMG 0x9133 +#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_IMG 0x9134 +#define GL_MAX_SAMPLES_IMG 0x9135 +#define GL_TEXTURE_SAMPLES_IMG 0x9136 +#endif + +/*------------------------------------------------------------------------* + * NV extension tokens + *------------------------------------------------------------------------*/ + +/* GL_NV_coverage_sample */ +#ifndef GL_NV_coverage_sample +#define GL_COVERAGE_COMPONENT_NV 0x8ED0 +#define GL_COVERAGE_COMPONENT4_NV 0x8ED1 +#define GL_COVERAGE_ATTACHMENT_NV 0x8ED2 +#define GL_COVERAGE_BUFFERS_NV 0x8ED3 +#define GL_COVERAGE_SAMPLES_NV 0x8ED4 +#define GL_COVERAGE_ALL_FRAGMENTS_NV 0x8ED5 +#define GL_COVERAGE_EDGE_FRAGMENTS_NV 0x8ED6 +#define GL_COVERAGE_AUTOMATIC_NV 0x8ED7 +#define GL_COVERAGE_BUFFER_BIT_NV 0x00008000 +#endif + +/* GL_NV_depth_nonlinear */ +#ifndef GL_NV_depth_nonlinear +#define GL_DEPTH_COMPONENT16_NONLINEAR_NV 0x8E2C +#endif + +/* GL_NV_draw_buffers */ +#ifndef GL_NV_draw_buffers +#define GL_MAX_DRAW_BUFFERS_NV 0x8824 +#define GL_DRAW_BUFFER0_NV 0x8825 +#define GL_DRAW_BUFFER1_NV 0x8826 +#define GL_DRAW_BUFFER2_NV 0x8827 +#define GL_DRAW_BUFFER3_NV 0x8828 +#define GL_DRAW_BUFFER4_NV 0x8829 +#define GL_DRAW_BUFFER5_NV 0x882A +#define GL_DRAW_BUFFER6_NV 0x882B +#define GL_DRAW_BUFFER7_NV 0x882C +#define GL_DRAW_BUFFER8_NV 0x882D +#define GL_DRAW_BUFFER9_NV 0x882E +#define GL_DRAW_BUFFER10_NV 0x882F +#define GL_DRAW_BUFFER11_NV 0x8830 +#define GL_DRAW_BUFFER12_NV 0x8831 +#define GL_DRAW_BUFFER13_NV 0x8832 +#define GL_DRAW_BUFFER14_NV 0x8833 +#define GL_DRAW_BUFFER15_NV 0x8834 +#define GL_COLOR_ATTACHMENT0_NV 0x8CE0 +#define GL_COLOR_ATTACHMENT1_NV 0x8CE1 +#define GL_COLOR_ATTACHMENT2_NV 0x8CE2 +#define GL_COLOR_ATTACHMENT3_NV 0x8CE3 +#define GL_COLOR_ATTACHMENT4_NV 0x8CE4 +#define GL_COLOR_ATTACHMENT5_NV 0x8CE5 +#define GL_COLOR_ATTACHMENT6_NV 0x8CE6 +#define GL_COLOR_ATTACHMENT7_NV 0x8CE7 +#define GL_COLOR_ATTACHMENT8_NV 0x8CE8 +#define GL_COLOR_ATTACHMENT9_NV 0x8CE9 +#define GL_COLOR_ATTACHMENT10_NV 0x8CEA +#define GL_COLOR_ATTACHMENT11_NV 0x8CEB +#define GL_COLOR_ATTACHMENT12_NV 0x8CEC +#define GL_COLOR_ATTACHMENT13_NV 0x8CED +#define GL_COLOR_ATTACHMENT14_NV 0x8CEE +#define GL_COLOR_ATTACHMENT15_NV 0x8CEF +#endif + +/* GL_NV_draw_instanced */ +/* No new tokens introduced by this extension. */ + +/* GL_NV_fbo_color_attachments */ +#ifndef GL_NV_fbo_color_attachments +#define GL_MAX_COLOR_ATTACHMENTS_NV 0x8CDF +/* GL_COLOR_ATTACHMENT{0-15}_NV defined in GL_NV_draw_buffers already. */ +#endif + +/* GL_NV_fence */ +#ifndef GL_NV_fence +#define GL_ALL_COMPLETED_NV 0x84F2 +#define GL_FENCE_STATUS_NV 0x84F3 +#define GL_FENCE_CONDITION_NV 0x84F4 +#endif + +/* GL_NV_framebuffer_blit */ +#ifndef GL_NV_framebuffer_blit +#define GL_READ_FRAMEBUFFER_NV 0x8CA8 +#define GL_DRAW_FRAMEBUFFER_NV 0x8CA9 +#define GL_DRAW_FRAMEBUFFER_BINDING_NV 0x8CA6 +#define GL_READ_FRAMEBUFFER_BINDING_NV 0x8CAA +#endif + +/* GL_NV_framebuffer_multisample */ +#ifndef GL_NV_framebuffer_multisample +#define GL_RENDERBUFFER_SAMPLES_NV 0x8CAB +#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_NV 0x8D56 +#define GL_MAX_SAMPLES_NV 0x8D57 +#endif + +/* GL_NV_generate_mipmap_sRGB */ +/* No new tokens introduced by this extension. */ + +/* GL_NV_instanced_arrays */ +#ifndef GL_NV_instanced_arrays +#define GL_VERTEX_ATTRIB_ARRAY_DIVISOR_NV 0x88FE +#endif + +/* GL_NV_read_buffer */ +#ifndef GL_NV_read_buffer +#define GL_READ_BUFFER_NV 0x0C02 +#endif + +/* GL_NV_read_buffer_front */ +/* No new tokens introduced by this extension. */ + +/* GL_NV_read_depth */ +/* No new tokens introduced by this extension. */ + +/* GL_NV_read_depth_stencil */ +/* No new tokens introduced by this extension. */ + +/* GL_NV_read_stencil */ +/* No new tokens introduced by this extension. */ + +/* GL_NV_shadow_samplers_array */ +#ifndef GL_NV_shadow_samplers_array +#define GL_SAMPLER_2D_ARRAY_SHADOW_NV 0x8DC4 +#endif + +/* GL_NV_shadow_samplers_cube */ +#ifndef GL_NV_shadow_samplers_cube +#define GL_SAMPLER_CUBE_SHADOW_NV 0x8DC5 +#endif + +/* GL_NV_sRGB_formats */ +#ifndef GL_NV_sRGB_formats +#define GL_SLUMINANCE_NV 0x8C46 +#define GL_SLUMINANCE_ALPHA_NV 0x8C44 +#define GL_SRGB8_NV 0x8C41 +#define GL_SLUMINANCE8_NV 0x8C47 +#define GL_SLUMINANCE8_ALPHA8_NV 0x8C45 +#define GL_COMPRESSED_SRGB_S3TC_DXT1_NV 0x8C4C +#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_NV 0x8C4D +#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_NV 0x8C4E +#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_NV 0x8C4F +#define GL_ETC1_SRGB8_NV 0x88EE +#endif + +/* GL_NV_texture_border_clamp */ +#ifndef GL_NV_texture_border_clamp +#define GL_TEXTURE_BORDER_COLOR_NV 0x1004 +#define GL_CLAMP_TO_BORDER_NV 0x812D +#endif + +/* GL_NV_texture_compression_s3tc_update */ +/* No new tokens introduced by this extension. */ + +/* GL_NV_texture_npot_2D_mipmap */ +/* No new tokens introduced by this extension. */ + +/*------------------------------------------------------------------------* + * QCOM extension tokens + *------------------------------------------------------------------------*/ + +/* GL_QCOM_alpha_test */ +#ifndef GL_QCOM_alpha_test +#define GL_ALPHA_TEST_QCOM 0x0BC0 +#define GL_ALPHA_TEST_FUNC_QCOM 0x0BC1 +#define GL_ALPHA_TEST_REF_QCOM 0x0BC2 +#endif + +/* GL_QCOM_binning_control */ +#ifndef GL_QCOM_binning_control +#define GL_BINNING_CONTROL_HINT_QCOM 0x8FB0 +#define GL_CPU_OPTIMIZED_QCOM 0x8FB1 +#define GL_GPU_OPTIMIZED_QCOM 0x8FB2 +#define GL_RENDER_DIRECT_TO_FRAMEBUFFER_QCOM 0x8FB3 +#endif + +/* GL_QCOM_driver_control */ +/* No new tokens introduced by this extension. */ + +/* GL_QCOM_extended_get */ +#ifndef GL_QCOM_extended_get +#define GL_TEXTURE_WIDTH_QCOM 0x8BD2 +#define GL_TEXTURE_HEIGHT_QCOM 0x8BD3 +#define GL_TEXTURE_DEPTH_QCOM 0x8BD4 +#define GL_TEXTURE_INTERNAL_FORMAT_QCOM 0x8BD5 +#define GL_TEXTURE_FORMAT_QCOM 0x8BD6 +#define GL_TEXTURE_TYPE_QCOM 0x8BD7 +#define GL_TEXTURE_IMAGE_VALID_QCOM 0x8BD8 +#define GL_TEXTURE_NUM_LEVELS_QCOM 0x8BD9 +#define GL_TEXTURE_TARGET_QCOM 0x8BDA +#define GL_TEXTURE_OBJECT_VALID_QCOM 0x8BDB +#define GL_STATE_RESTORE 0x8BDC +#endif + +/* GL_QCOM_extended_get2 */ +/* No new tokens introduced by this extension. */ + +/* GL_QCOM_perfmon_global_mode */ +#ifndef GL_QCOM_perfmon_global_mode +#define GL_PERFMON_GLOBAL_MODE_QCOM 0x8FA0 +#endif + +/* GL_QCOM_writeonly_rendering */ +#ifndef GL_QCOM_writeonly_rendering +#define GL_WRITEONLY_RENDERING_QCOM 0x8823 +#endif + +/* GL_QCOM_tiled_rendering */ +#ifndef GL_QCOM_tiled_rendering +#define GL_COLOR_BUFFER_BIT0_QCOM 0x00000001 +#define GL_COLOR_BUFFER_BIT1_QCOM 0x00000002 +#define GL_COLOR_BUFFER_BIT2_QCOM 0x00000004 +#define GL_COLOR_BUFFER_BIT3_QCOM 0x00000008 +#define GL_COLOR_BUFFER_BIT4_QCOM 0x00000010 +#define GL_COLOR_BUFFER_BIT5_QCOM 0x00000020 +#define GL_COLOR_BUFFER_BIT6_QCOM 0x00000040 +#define GL_COLOR_BUFFER_BIT7_QCOM 0x00000080 +#define GL_DEPTH_BUFFER_BIT0_QCOM 0x00000100 +#define GL_DEPTH_BUFFER_BIT1_QCOM 0x00000200 +#define GL_DEPTH_BUFFER_BIT2_QCOM 0x00000400 +#define GL_DEPTH_BUFFER_BIT3_QCOM 0x00000800 +#define GL_DEPTH_BUFFER_BIT4_QCOM 0x00001000 +#define GL_DEPTH_BUFFER_BIT5_QCOM 0x00002000 +#define GL_DEPTH_BUFFER_BIT6_QCOM 0x00004000 +#define GL_DEPTH_BUFFER_BIT7_QCOM 0x00008000 +#define GL_STENCIL_BUFFER_BIT0_QCOM 0x00010000 +#define GL_STENCIL_BUFFER_BIT1_QCOM 0x00020000 +#define GL_STENCIL_BUFFER_BIT2_QCOM 0x00040000 +#define GL_STENCIL_BUFFER_BIT3_QCOM 0x00080000 +#define GL_STENCIL_BUFFER_BIT4_QCOM 0x00100000 +#define GL_STENCIL_BUFFER_BIT5_QCOM 0x00200000 +#define GL_STENCIL_BUFFER_BIT6_QCOM 0x00400000 +#define GL_STENCIL_BUFFER_BIT7_QCOM 0x00800000 +#define GL_MULTISAMPLE_BUFFER_BIT0_QCOM 0x01000000 +#define GL_MULTISAMPLE_BUFFER_BIT1_QCOM 0x02000000 +#define GL_MULTISAMPLE_BUFFER_BIT2_QCOM 0x04000000 +#define GL_MULTISAMPLE_BUFFER_BIT3_QCOM 0x08000000 +#define GL_MULTISAMPLE_BUFFER_BIT4_QCOM 0x10000000 +#define GL_MULTISAMPLE_BUFFER_BIT5_QCOM 0x20000000 +#define GL_MULTISAMPLE_BUFFER_BIT6_QCOM 0x40000000 +#define GL_MULTISAMPLE_BUFFER_BIT7_QCOM 0x80000000 +#endif + +/*------------------------------------------------------------------------* + * VIV extension tokens + *------------------------------------------------------------------------*/ + +/* GL_VIV_shader_binary */ +#ifndef GL_VIV_shader_binary +#define GL_SHADER_BINARY_VIV 0x8FC4 +#endif + +/*------------------------------------------------------------------------* + * End of extension tokens, start of corresponding extension functions + *------------------------------------------------------------------------*/ + +/*------------------------------------------------------------------------* + * OES extension functions + *------------------------------------------------------------------------*/ + +/* GL_OES_compressed_ETC1_RGB8_texture */ +#ifndef GL_OES_compressed_ETC1_RGB8_texture +#define GL_OES_compressed_ETC1_RGB8_texture 1 +#endif + +/* GL_OES_compressed_paletted_texture */ +#ifndef GL_OES_compressed_paletted_texture +#define GL_OES_compressed_paletted_texture 1 +#endif + +/* GL_OES_depth24 */ +#ifndef GL_OES_depth24 +#define GL_OES_depth24 1 +#endif + +/* GL_OES_depth32 */ +#ifndef GL_OES_depth32 +#define GL_OES_depth32 1 +#endif + +/* GL_OES_depth_texture */ +#ifndef GL_OES_depth_texture +#define GL_OES_depth_texture 1 +#endif + +/* GL_OES_EGL_image */ +#ifndef GL_OES_EGL_image +#define GL_OES_EGL_image 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glEGLImageTargetTexture2DOES (GLenum target, GLeglImageOES image); +GL_APICALL void GL_APIENTRY glEGLImageTargetRenderbufferStorageOES (GLenum target, GLeglImageOES image); +#endif +typedef void (GL_APIENTRYP PFNGLEGLIMAGETARGETTEXTURE2DOESPROC) (GLenum target, GLeglImageOES image); +typedef void (GL_APIENTRYP PFNGLEGLIMAGETARGETRENDERBUFFERSTORAGEOESPROC) (GLenum target, GLeglImageOES image); +#endif + +/* GL_OES_EGL_image_external */ +#ifndef GL_OES_EGL_image_external +#define GL_OES_EGL_image_external 1 +/* glEGLImageTargetTexture2DOES defined in GL_OES_EGL_image already. */ +#endif + +/* GL_OES_element_index_uint */ +#ifndef GL_OES_element_index_uint +#define GL_OES_element_index_uint 1 +#endif + +/* GL_OES_fbo_render_mipmap */ +#ifndef GL_OES_fbo_render_mipmap +#define GL_OES_fbo_render_mipmap 1 +#endif + +/* GL_OES_fragment_precision_high */ +#ifndef GL_OES_fragment_precision_high +#define GL_OES_fragment_precision_high 1 +#endif + +/* GL_OES_get_program_binary */ +#ifndef GL_OES_get_program_binary +#define GL_OES_get_program_binary 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glGetProgramBinaryOES (GLuint program, GLsizei bufSize, GLsizei *length, GLenum *binaryFormat, GLvoid *binary); +GL_APICALL void GL_APIENTRY glProgramBinaryOES (GLuint program, GLenum binaryFormat, const GLvoid *binary, GLint length); +#endif +typedef void (GL_APIENTRYP PFNGLGETPROGRAMBINARYOESPROC) (GLuint program, GLsizei bufSize, GLsizei *length, GLenum *binaryFormat, GLvoid *binary); +typedef void (GL_APIENTRYP PFNGLPROGRAMBINARYOESPROC) (GLuint program, GLenum binaryFormat, const GLvoid *binary, GLint length); +#endif + +/* GL_OES_mapbuffer */ +#ifndef GL_OES_mapbuffer +#define GL_OES_mapbuffer 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void* GL_APIENTRY glMapBufferOES (GLenum target, GLenum access); +GL_APICALL GLboolean GL_APIENTRY glUnmapBufferOES (GLenum target); +GL_APICALL void GL_APIENTRY glGetBufferPointervOES (GLenum target, GLenum pname, GLvoid **params); +#endif +typedef void* (GL_APIENTRYP PFNGLMAPBUFFEROESPROC) (GLenum target, GLenum access); +typedef GLboolean (GL_APIENTRYP PFNGLUNMAPBUFFEROESPROC) (GLenum target); +typedef void (GL_APIENTRYP PFNGLGETBUFFERPOINTERVOESPROC) (GLenum target, GLenum pname, GLvoid **params); +#endif + +/* GL_OES_packed_depth_stencil */ +#ifndef GL_OES_packed_depth_stencil +#define GL_OES_packed_depth_stencil 1 +#endif + +/* GL_OES_required_internalformat */ +#ifndef GL_OES_required_internalformat +#define GL_OES_required_internalformat 1 +#endif + +/* GL_OES_rgb8_rgba8 */ +#ifndef GL_OES_rgb8_rgba8 +#define GL_OES_rgb8_rgba8 1 +#endif + +/* GL_OES_standard_derivatives */ +#ifndef GL_OES_standard_derivatives +#define GL_OES_standard_derivatives 1 +#endif + +/* GL_OES_stencil1 */ +#ifndef GL_OES_stencil1 +#define GL_OES_stencil1 1 +#endif + +/* GL_OES_stencil4 */ +#ifndef GL_OES_stencil4 +#define GL_OES_stencil4 1 +#endif + +#ifndef GL_OES_surfaceless_context +#define GL_OES_surfaceless_context 1 +#endif + +/* GL_OES_texture_3D */ +#ifndef GL_OES_texture_3D +#define GL_OES_texture_3D 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glTexImage3DOES (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid* pixels); +GL_APICALL void GL_APIENTRY glTexSubImage3DOES (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid* pixels); +GL_APICALL void GL_APIENTRY glCopyTexSubImage3DOES (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); +GL_APICALL void GL_APIENTRY glCompressedTexImage3DOES (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid* data); +GL_APICALL void GL_APIENTRY glCompressedTexSubImage3DOES (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid* data); +GL_APICALL void GL_APIENTRY glFramebufferTexture3DOES (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset); +#endif +typedef void (GL_APIENTRYP PFNGLTEXIMAGE3DOESPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid* pixels); +typedef void (GL_APIENTRYP PFNGLTEXSUBIMAGE3DOESPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid* pixels); +typedef void (GL_APIENTRYP PFNGLCOPYTEXSUBIMAGE3DOESPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); +typedef void (GL_APIENTRYP PFNGLCOMPRESSEDTEXIMAGE3DOESPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid* data); +typedef void (GL_APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE3DOESPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid* data); +typedef void (GL_APIENTRYP PFNGLFRAMEBUFFERTEXTURE3DOESPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset); +#endif + +/* GL_OES_texture_float */ +#ifndef GL_OES_texture_float +#define GL_OES_texture_float 1 +#endif + +/* GL_OES_texture_float_linear */ +#ifndef GL_OES_texture_float_linear +#define GL_OES_texture_float_linear 1 +#endif + +/* GL_OES_texture_half_float */ +#ifndef GL_OES_texture_half_float +#define GL_OES_texture_half_float 1 +#endif + +/* GL_OES_texture_half_float_linear */ +#ifndef GL_OES_texture_half_float_linear +#define GL_OES_texture_half_float_linear 1 +#endif + +/* GL_OES_texture_npot */ +#ifndef GL_OES_texture_npot +#define GL_OES_texture_npot 1 +#endif + +/* GL_OES_vertex_array_object */ +#ifndef GL_OES_vertex_array_object +#define GL_OES_vertex_array_object 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glBindVertexArrayOES (GLuint array); +GL_APICALL void GL_APIENTRY glDeleteVertexArraysOES (GLsizei n, const GLuint *arrays); +GL_APICALL void GL_APIENTRY glGenVertexArraysOES (GLsizei n, GLuint *arrays); +GL_APICALL GLboolean GL_APIENTRY glIsVertexArrayOES (GLuint array); +#endif +typedef void (GL_APIENTRYP PFNGLBINDVERTEXARRAYOESPROC) (GLuint array); +typedef void (GL_APIENTRYP PFNGLDELETEVERTEXARRAYSOESPROC) (GLsizei n, const GLuint *arrays); +typedef void (GL_APIENTRYP PFNGLGENVERTEXARRAYSOESPROC) (GLsizei n, GLuint *arrays); +typedef GLboolean (GL_APIENTRYP PFNGLISVERTEXARRAYOESPROC) (GLuint array); +#endif + +/* GL_OES_vertex_half_float */ +#ifndef GL_OES_vertex_half_float +#define GL_OES_vertex_half_float 1 +#endif + +/* GL_OES_vertex_type_10_10_10_2 */ +#ifndef GL_OES_vertex_type_10_10_10_2 +#define GL_OES_vertex_type_10_10_10_2 1 +#endif + +/*------------------------------------------------------------------------* + * KHR extension functions + *------------------------------------------------------------------------*/ + +#ifndef GL_KHR_debug +#define GL_KHR_debug 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glDebugMessageControlKHR (GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint *ids, GLboolean enabled); +GL_APICALL void GL_APIENTRY glDebugMessageInsertKHR (GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *buf); +GL_APICALL void GL_APIENTRY glDebugMessageCallbackKHR (GLDEBUGPROCKHR callback, const void *userParam); +GL_APICALL GLuint GL_APIENTRY glGetDebugMessageLogKHR (GLuint count, GLsizei bufsize, GLenum *sources, GLenum *types, GLuint *ids, GLenum *severities, GLsizei *lengths, GLchar *messageLog); +GL_APICALL void GL_APIENTRY glPushDebugGroupKHR (GLenum source, GLuint id, GLsizei length, const GLchar *message); +GL_APICALL void GL_APIENTRY glPopDebugGroupKHR (void); +GL_APICALL void GL_APIENTRY glObjectLabelKHR (GLenum identifier, GLuint name, GLsizei length, const GLchar *label); +GL_APICALL void GL_APIENTRY glGetObjectLabelKHR (GLenum identifier, GLuint name, GLsizei bufSize, GLsizei *length, GLchar *label); +GL_APICALL void GL_APIENTRY glObjectPtrLabelKHR (const void *ptr, GLsizei length, const GLchar *label); +GL_APICALL void GL_APIENTRY glGetObjectPtrLabelKHR (const void *ptr, GLsizei bufSize, GLsizei *length, GLchar *label); +GL_APICALL void GL_APIENTRY glGetPointervKHR (GLenum pname, GLvoid **params); +#endif +typedef void (GL_APIENTRYP PFNGLDEBUGMESSAGECONTROLKHRPROC) (GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint *ids, GLboolean enabled); +typedef void (GL_APIENTRYP PFNGLDEBUGMESSAGEINSERTKHRPROC) (GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *buf); +typedef void (GL_APIENTRYP PFNGLDEBUGMESSAGECALLBACKKHRPROC) (GLDEBUGPROCKHR callback, const void *userParam); +typedef GLuint (GL_APIENTRYP PFNGLGETDEBUGMESSAGELOGKHRPROC) (GLuint count, GLsizei bufsize, GLenum *sources, GLenum *types, GLuint *ids, GLenum *severities, GLsizei *lengths, GLchar *messageLog); +typedef void (GL_APIENTRYP PFNGLPUSHDEBUGGROUPKHRPROC) (GLenum source, GLuint id, GLsizei length, const GLchar *message); +typedef void (GL_APIENTRYP PFNGLPOPDEBUGGROUPKHRPROC) (void); +typedef void (GL_APIENTRYP PFNGLOBJECTLABELKHRPROC) (GLenum identifier, GLuint name, GLsizei length, const GLchar *label); +typedef void (GL_APIENTRYP PFNGLGETOBJECTLABELKHRPROC) (GLenum identifier, GLuint name, GLsizei bufSize, GLsizei *length, GLchar *label); +typedef void (GL_APIENTRYP PFNGLOBJECTPTRLABELKHRPROC) (const void *ptr, GLsizei length, const GLchar *label); +typedef void (GL_APIENTRYP PFNGLGETOBJECTPTRLABELKHRPROC) (const void *ptr, GLsizei bufSize, GLsizei *length, GLchar *label); +typedef void (GL_APIENTRYP PFNGLGETPOINTERVKHRPROC) (GLenum pname, GLvoid **params); +#endif + +#ifndef GL_KHR_texture_compression_astc_ldr +#define GL_KHR_texture_compression_astc_ldr 1 +#endif + + +/*------------------------------------------------------------------------* + * AMD extension functions + *------------------------------------------------------------------------*/ + +/* GL_AMD_compressed_3DC_texture */ +#ifndef GL_AMD_compressed_3DC_texture +#define GL_AMD_compressed_3DC_texture 1 +#endif + +/* GL_AMD_compressed_ATC_texture */ +#ifndef GL_AMD_compressed_ATC_texture +#define GL_AMD_compressed_ATC_texture 1 +#endif + +/* AMD_performance_monitor */ +#ifndef GL_AMD_performance_monitor +#define GL_AMD_performance_monitor 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glGetPerfMonitorGroupsAMD (GLint *numGroups, GLsizei groupsSize, GLuint *groups); +GL_APICALL void GL_APIENTRY glGetPerfMonitorCountersAMD (GLuint group, GLint *numCounters, GLint *maxActiveCounters, GLsizei counterSize, GLuint *counters); +GL_APICALL void GL_APIENTRY glGetPerfMonitorGroupStringAMD (GLuint group, GLsizei bufSize, GLsizei *length, GLchar *groupString); +GL_APICALL void GL_APIENTRY glGetPerfMonitorCounterStringAMD (GLuint group, GLuint counter, GLsizei bufSize, GLsizei *length, GLchar *counterString); +GL_APICALL void GL_APIENTRY glGetPerfMonitorCounterInfoAMD (GLuint group, GLuint counter, GLenum pname, GLvoid *data); +GL_APICALL void GL_APIENTRY glGenPerfMonitorsAMD (GLsizei n, GLuint *monitors); +GL_APICALL void GL_APIENTRY glDeletePerfMonitorsAMD (GLsizei n, GLuint *monitors); +GL_APICALL void GL_APIENTRY glSelectPerfMonitorCountersAMD (GLuint monitor, GLboolean enable, GLuint group, GLint numCounters, GLuint *countersList); +GL_APICALL void GL_APIENTRY glBeginPerfMonitorAMD (GLuint monitor); +GL_APICALL void GL_APIENTRY glEndPerfMonitorAMD (GLuint monitor); +GL_APICALL void GL_APIENTRY glGetPerfMonitorCounterDataAMD (GLuint monitor, GLenum pname, GLsizei dataSize, GLuint *data, GLint *bytesWritten); +#endif +typedef void (GL_APIENTRYP PFNGLGETPERFMONITORGROUPSAMDPROC) (GLint *numGroups, GLsizei groupsSize, GLuint *groups); +typedef void (GL_APIENTRYP PFNGLGETPERFMONITORCOUNTERSAMDPROC) (GLuint group, GLint *numCounters, GLint *maxActiveCounters, GLsizei counterSize, GLuint *counters); +typedef void (GL_APIENTRYP PFNGLGETPERFMONITORGROUPSTRINGAMDPROC) (GLuint group, GLsizei bufSize, GLsizei *length, GLchar *groupString); +typedef void (GL_APIENTRYP PFNGLGETPERFMONITORCOUNTERSTRINGAMDPROC) (GLuint group, GLuint counter, GLsizei bufSize, GLsizei *length, GLchar *counterString); +typedef void (GL_APIENTRYP PFNGLGETPERFMONITORCOUNTERINFOAMDPROC) (GLuint group, GLuint counter, GLenum pname, GLvoid *data); +typedef void (GL_APIENTRYP PFNGLGENPERFMONITORSAMDPROC) (GLsizei n, GLuint *monitors); +typedef void (GL_APIENTRYP PFNGLDELETEPERFMONITORSAMDPROC) (GLsizei n, GLuint *monitors); +typedef void (GL_APIENTRYP PFNGLSELECTPERFMONITORCOUNTERSAMDPROC) (GLuint monitor, GLboolean enable, GLuint group, GLint numCounters, GLuint *countersList); +typedef void (GL_APIENTRYP PFNGLBEGINPERFMONITORAMDPROC) (GLuint monitor); +typedef void (GL_APIENTRYP PFNGLENDPERFMONITORAMDPROC) (GLuint monitor); +typedef void (GL_APIENTRYP PFNGLGETPERFMONITORCOUNTERDATAAMDPROC) (GLuint monitor, GLenum pname, GLsizei dataSize, GLuint *data, GLint *bytesWritten); +#endif + +/* GL_AMD_program_binary_Z400 */ +#ifndef GL_AMD_program_binary_Z400 +#define GL_AMD_program_binary_Z400 1 +#endif + +/*------------------------------------------------------------------------* + * ANGLE extension functions + *------------------------------------------------------------------------*/ + +/* GL_ANGLE_depth_texture */ +#ifndef GL_ANGLE_depth_texture +#define GL_ANGLE_depth_texture 1 +#endif + +/* GL_ANGLE_framebuffer_blit */ +#ifndef GL_ANGLE_framebuffer_blit +#define GL_ANGLE_framebuffer_blit 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glBlitFramebufferANGLE (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); +#endif +typedef void (GL_APIENTRYP PFNGLBLITFRAMEBUFFERANGLEPROC) (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); +#endif + +/* GL_ANGLE_framebuffer_multisample */ +#ifndef GL_ANGLE_framebuffer_multisample +#define GL_ANGLE_framebuffer_multisample 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glRenderbufferStorageMultisampleANGLE (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); +#endif +typedef void (GL_APIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLEANGLEPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); +#endif + +#ifndef GL_ANGLE_instanced_arrays +#define GL_ANGLE_instanced_arrays 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glDrawArraysInstancedANGLE (GLenum mode, GLint first, GLsizei count, GLsizei primcount); +GL_APICALL void GL_APIENTRY glDrawElementsInstancedANGLE (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei primcount); +GL_APICALL void GL_APIENTRY glVertexAttribDivisorANGLE (GLuint index, GLuint divisor); +#endif +typedef void (GL_APIENTRYP PFNGLDRAWARRAYSINSTANCEDANGLEPROC) (GLenum mode, GLint first, GLsizei count, GLsizei primcount); +typedef void (GL_APIENTRYP PFNGLDRAWELEMENTSINSTANCEDANGLEPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei primcount); +typedef void (GL_APIENTRYP PFNGLVERTEXATTRIBDIVISORANGLEPROC) (GLuint index, GLuint divisor); +#endif + +/* GL_ANGLE_pack_reverse_row_order */ +#ifndef GL_ANGLE_pack_reverse_row_order +#define GL_ANGLE_pack_reverse_row_order 1 +#endif + +/* GL_ANGLE_program_binary */ +#ifndef GL_ANGLE_program_binary +#define GL_ANGLE_program_binary 1 +#endif + +/* GL_ANGLE_texture_compression_dxt3 */ +#ifndef GL_ANGLE_texture_compression_dxt3 +#define GL_ANGLE_texture_compression_dxt3 1 +#endif + +/* GL_ANGLE_texture_compression_dxt5 */ +#ifndef GL_ANGLE_texture_compression_dxt5 +#define GL_ANGLE_texture_compression_dxt5 1 +#endif + +/* GL_ANGLE_texture_usage */ +#ifndef GL_ANGLE_texture_usage +#define GL_ANGLE_texture_usage 1 +#endif + +#ifndef GL_ANGLE_translated_shader_source +#define GL_ANGLE_translated_shader_source 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glGetTranslatedShaderSourceANGLE (GLuint shader, GLsizei bufsize, GLsizei *length, GLchar *source); +#endif +typedef void (GL_APIENTRYP PFNGLGETTRANSLATEDSHADERSOURCEANGLEPROC) (GLuint shader, GLsizei bufsize, GLsizei *length, GLchar *source); +#endif + +/*------------------------------------------------------------------------* + * APPLE extension functions + *------------------------------------------------------------------------*/ + +/* GL_APPLE_copy_texture_levels */ +#ifndef GL_APPLE_copy_texture_levels +#define GL_APPLE_copy_texture_levels 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glCopyTextureLevelsAPPLE (GLuint destinationTexture, GLuint sourceTexture, GLint sourceBaseLevel, GLsizei sourceLevelCount); +#endif +typedef void (GL_APIENTRYP PFNGLCOPYTEXTURELEVELSAPPLEPROC) (GLuint destinationTexture, GLuint sourceTexture, GLint sourceBaseLevel, GLsizei sourceLevelCount); +#endif + +/* GL_APPLE_framebuffer_multisample */ +#ifndef GL_APPLE_framebuffer_multisample +#define GL_APPLE_framebuffer_multisample 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glRenderbufferStorageMultisampleAPPLE (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); +GL_APICALL void GL_APIENTRY glResolveMultisampleFramebufferAPPLE (void); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (GL_APIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLEAPPLEPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); +typedef void (GL_APIENTRYP PFNGLRESOLVEMULTISAMPLEFRAMEBUFFERAPPLEPROC) (void); +#endif + +/* GL_APPLE_rgb_422 */ +#ifndef GL_APPLE_rgb_422 +#define GL_APPLE_rgb_422 1 +#endif + +/* GL_APPLE_sync */ +#ifndef GL_APPLE_sync +#define GL_APPLE_sync 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL GLsync GL_APIENTRY glFenceSyncAPPLE (GLenum condition, GLbitfield flags); +GL_APICALL GLboolean GL_APIENTRY glIsSyncAPPLE (GLsync sync); +GL_APICALL void GL_APIENTRY glDeleteSyncAPPLE (GLsync sync); +GL_APICALL GLenum GL_APIENTRY glClientWaitSyncAPPLE (GLsync sync, GLbitfield flags, GLuint64 timeout); +GL_APICALL void GL_APIENTRY glWaitSyncAPPLE (GLsync sync, GLbitfield flags, GLuint64 timeout); +GL_APICALL void GL_APIENTRY glGetInteger64vAPPLE (GLenum pname, GLint64 *params); +GL_APICALL void GL_APIENTRY glGetSyncivAPPLE (GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values); +#endif +typedef GLsync (GL_APIENTRYP PFNGLFENCESYNCAPPLEPROC) (GLenum condition, GLbitfield flags); +typedef GLboolean (GL_APIENTRYP PFNGLISSYNCAPPLEPROC) (GLsync sync); +typedef void (GL_APIENTRYP PFNGLDELETESYNCAPPLEPROC) (GLsync sync); +typedef GLenum (GL_APIENTRYP PFNGLCLIENTWAITSYNCAPPLEPROC) (GLsync sync, GLbitfield flags, GLuint64 timeout); +typedef void (GL_APIENTRYP PFNGLWAITSYNCAPPLEPROC) (GLsync sync, GLbitfield flags, GLuint64 timeout); +typedef void (GL_APIENTRYP PFNGLGETINTEGER64VAPPLEPROC) (GLenum pname, GLint64 *params); +typedef void (GL_APIENTRYP PFNGLGETSYNCIVAPPLEPROC) (GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values); +#endif + +/* GL_APPLE_texture_format_BGRA8888 */ +#ifndef GL_APPLE_texture_format_BGRA8888 +#define GL_APPLE_texture_format_BGRA8888 1 +#endif + +/* GL_APPLE_texture_max_level */ +#ifndef GL_APPLE_texture_max_level +#define GL_APPLE_texture_max_level 1 +#endif + +/*------------------------------------------------------------------------* + * ARM extension functions + *------------------------------------------------------------------------*/ + +/* GL_ARM_mali_program_binary */ +#ifndef GL_ARM_mali_program_binary +#define GL_ARM_mali_program_binary 1 +#endif + +/* GL_ARM_mali_shader_binary */ +#ifndef GL_ARM_mali_shader_binary +#define GL_ARM_mali_shader_binary 1 +#endif + +/* GL_ARM_rgba8 */ +#ifndef GL_ARM_rgba8 +#define GL_ARM_rgba8 1 +#endif + +/*------------------------------------------------------------------------* + * EXT extension functions + *------------------------------------------------------------------------*/ + +/* GL_EXT_blend_minmax */ +#ifndef GL_EXT_blend_minmax +#define GL_EXT_blend_minmax 1 +#endif + +/* GL_EXT_color_buffer_half_float */ +#ifndef GL_EXT_color_buffer_half_float +#define GL_EXT_color_buffer_half_float 1 +#endif + +/* GL_EXT_debug_label */ +#ifndef GL_EXT_debug_label +#define GL_EXT_debug_label 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glLabelObjectEXT (GLenum type, GLuint object, GLsizei length, const GLchar *label); +GL_APICALL void GL_APIENTRY glGetObjectLabelEXT (GLenum type, GLuint object, GLsizei bufSize, GLsizei *length, GLchar *label); +#endif +typedef void (GL_APIENTRYP PFNGLLABELOBJECTEXTPROC) (GLenum type, GLuint object, GLsizei length, const GLchar *label); +typedef void (GL_APIENTRYP PFNGLGETOBJECTLABELEXTPROC) (GLenum type, GLuint object, GLsizei bufSize, GLsizei *length, GLchar *label); +#endif + +/* GL_EXT_debug_marker */ +#ifndef GL_EXT_debug_marker +#define GL_EXT_debug_marker 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glInsertEventMarkerEXT (GLsizei length, const GLchar *marker); +GL_APICALL void GL_APIENTRY glPushGroupMarkerEXT (GLsizei length, const GLchar *marker); +GL_APICALL void GL_APIENTRY glPopGroupMarkerEXT (void); +#endif +typedef void (GL_APIENTRYP PFNGLINSERTEVENTMARKEREXTPROC) (GLsizei length, const GLchar *marker); +typedef void (GL_APIENTRYP PFNGLPUSHGROUPMARKEREXTPROC) (GLsizei length, const GLchar *marker); +typedef void (GL_APIENTRYP PFNGLPOPGROUPMARKEREXTPROC) (void); +#endif + +/* GL_EXT_discard_framebuffer */ +#ifndef GL_EXT_discard_framebuffer +#define GL_EXT_discard_framebuffer 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glDiscardFramebufferEXT (GLenum target, GLsizei numAttachments, const GLenum *attachments); +#endif +typedef void (GL_APIENTRYP PFNGLDISCARDFRAMEBUFFEREXTPROC) (GLenum target, GLsizei numAttachments, const GLenum *attachments); +#endif + +#ifndef GL_EXT_disjoint_timer_query +#define GL_EXT_disjoint_timer_query 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glGenQueriesEXT (GLsizei n, GLuint *ids); +GL_APICALL void GL_APIENTRY glDeleteQueriesEXT (GLsizei n, const GLuint *ids); +GL_APICALL GLboolean GL_APIENTRY glIsQueryEXT (GLuint id); +GL_APICALL void GL_APIENTRY glBeginQueryEXT (GLenum target, GLuint id); +GL_APICALL void GL_APIENTRY glEndQueryEXT (GLenum target); +GL_APICALL void GL_APIENTRY glQueryCounterEXT (GLuint id, GLenum target); +GL_APICALL void GL_APIENTRY glGetQueryivEXT (GLenum target, GLenum pname, GLint *params); +GL_APICALL void GL_APIENTRY glGetQueryObjectivEXT (GLuint id, GLenum pname, GLint *params); +GL_APICALL void GL_APIENTRY glGetQueryObjectuivEXT (GLuint id, GLenum pname, GLuint *params); +GL_APICALL void GL_APIENTRY glGetQueryObjecti64vEXT (GLuint id, GLenum pname, GLint64 *params); +GL_APICALL void GL_APIENTRY glGetQueryObjectui64vEXT (GLuint id, GLenum pname, GLuint64 *params); +#endif +typedef void (GL_APIENTRYP PFNGLGENQUERIESEXTPROC) (GLsizei n, GLuint *ids); +typedef void (GL_APIENTRYP PFNGLDELETEQUERIESEXTPROC) (GLsizei n, const GLuint *ids); +typedef GLboolean (GL_APIENTRYP PFNGLISQUERYEXTPROC) (GLuint id); +typedef void (GL_APIENTRYP PFNGLBEGINQUERYEXTPROC) (GLenum target, GLuint id); +typedef void (GL_APIENTRYP PFNGLENDQUERYEXTPROC) (GLenum target); +typedef void (GL_APIENTRYP PFNGLQUERYCOUNTEREXTPROC) (GLuint id, GLenum target); +typedef void (GL_APIENTRYP PFNGLGETQUERYIVEXTPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (GL_APIENTRYP PFNGLGETQUERYOBJECTIVEXTPROC) (GLuint id, GLenum pname, GLint *params); +typedef void (GL_APIENTRYP PFNGLGETQUERYOBJECTUIVEXTPROC) (GLuint id, GLenum pname, GLuint *params); +typedef void (GL_APIENTRYP PFNGLGETQUERYOBJECTI64VEXTPROC) (GLuint id, GLenum pname, GLint64 *params); +typedef void (GL_APIENTRYP PFNGLGETQUERYOBJECTUI64VEXTPROC) (GLuint id, GLenum pname, GLuint64 *params); +#endif /* GL_EXT_disjoint_timer_query */ + +#ifndef GL_EXT_draw_buffers +#define GL_EXT_draw_buffers 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glDrawBuffersEXT (GLsizei n, const GLenum *bufs); +#endif +typedef void (GL_APIENTRYP PFNGLDRAWBUFFERSEXTPROC) (GLsizei n, const GLenum *bufs); +#endif /* GL_EXT_draw_buffers */ + +/* GL_EXT_map_buffer_range */ +#ifndef GL_EXT_map_buffer_range +#define GL_EXT_map_buffer_range 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void* GL_APIENTRY glMapBufferRangeEXT (GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access); +GL_APICALL void GL_APIENTRY glFlushMappedBufferRangeEXT (GLenum target, GLintptr offset, GLsizeiptr length); +#endif +typedef void* (GL_APIENTRYP PFNGLMAPBUFFERRANGEEXTPROC) (GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access); +typedef void (GL_APIENTRYP PFNGLFLUSHMAPPEDBUFFERRANGEEXTPROC) (GLenum target, GLintptr offset, GLsizeiptr length); +#endif + +/* GL_EXT_multisampled_render_to_texture */ +#ifndef GL_EXT_multisampled_render_to_texture +#define GL_EXT_multisampled_render_to_texture 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glRenderbufferStorageMultisampleEXT (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); +GL_APICALL void GL_APIENTRY glFramebufferTexture2DMultisampleEXT (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLsizei samples); +#endif +typedef void (GL_APIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); +typedef void (GL_APIENTRYP PFNGLFRAMEBUFFERTEXTURE2DMULTISAMPLEEXTPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLsizei samples); +#endif + +/* GL_EXT_multiview_draw_buffers */ +#ifndef GL_EXT_multiview_draw_buffers +#define GL_EXT_multiview_draw_buffers 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glReadBufferIndexedEXT (GLenum src, GLint index); +GL_APICALL void GL_APIENTRY glDrawBuffersIndexedEXT (GLint n, const GLenum *location, const GLint *indices); +GL_APICALL void GL_APIENTRY glGetIntegeri_vEXT (GLenum target, GLuint index, GLint *data); +#endif +typedef void (GL_APIENTRYP PFNGLREADBUFFERINDEXEDEXTPROC) (GLenum src, GLint index); +typedef void (GL_APIENTRYP PFNGLDRAWBUFFERSINDEXEDEXTPROC) (GLint n, const GLenum *location, const GLint *indices); +typedef void (GL_APIENTRYP PFNGLGETINTEGERI_VEXTPROC) (GLenum target, GLuint index, GLint *data); +#endif + +#ifndef GL_EXT_multi_draw_arrays +#define GL_EXT_multi_draw_arrays 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glMultiDrawArraysEXT (GLenum mode, const GLint *first, const GLsizei *count, GLsizei primcount); +GL_APICALL void GL_APIENTRY glMultiDrawElementsEXT (GLenum mode, const GLsizei *count, GLenum type, const GLvoid **indices, GLsizei primcount); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (GL_APIENTRYP PFNGLMULTIDRAWARRAYSEXTPROC) (GLenum mode, const GLint *first, const GLsizei *count, GLsizei primcount); +typedef void (GL_APIENTRYP PFNGLMULTIDRAWELEMENTSEXTPROC) (GLenum mode, const GLsizei *count, GLenum type, const GLvoid **indices, GLsizei primcount); +#endif + +/* GL_EXT_occlusion_query_boolean */ +#ifndef GL_EXT_occlusion_query_boolean +#define GL_EXT_occlusion_query_boolean 1 +/* All entry points also exist in GL_EXT_disjoint_timer_query */ +#endif + +/* GL_EXT_read_format_bgra */ +#ifndef GL_EXT_read_format_bgra +#define GL_EXT_read_format_bgra 1 +#endif + +/* GL_EXT_robustness */ +#ifndef GL_EXT_robustness +#define GL_EXT_robustness 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL GLenum GL_APIENTRY glGetGraphicsResetStatusEXT (void); +GL_APICALL void GL_APIENTRY glReadnPixelsEXT (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei bufSize, GLvoid *data); +GL_APICALL void GL_APIENTRY glGetnUniformfvEXT (GLuint program, GLint location, GLsizei bufSize, GLfloat *params); +GL_APICALL void GL_APIENTRY glGetnUniformivEXT (GLuint program, GLint location, GLsizei bufSize, GLint *params); +#endif +typedef GLenum (GL_APIENTRYP PFNGLGETGRAPHICSRESETSTATUSEXTPROC) (void); +typedef void (GL_APIENTRYP PFNGLREADNPIXELSEXTPROC) (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei bufSize, GLvoid *data); +typedef void (GL_APIENTRYP PFNGLGETNUNIFORMFVEXTPROC) (GLuint program, GLint location, GLsizei bufSize, GLfloat *params); +typedef void (GL_APIENTRYP PFNGLGETNUNIFORMIVEXTPROC) (GLuint program, GLint location, GLsizei bufSize, GLint *params); +#endif + +/* GL_EXT_separate_shader_objects */ +#ifndef GL_EXT_separate_shader_objects +#define GL_EXT_separate_shader_objects 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glUseProgramStagesEXT (GLuint pipeline, GLbitfield stages, GLuint program); +GL_APICALL void GL_APIENTRY glActiveShaderProgramEXT (GLuint pipeline, GLuint program); +GL_APICALL GLuint GL_APIENTRY glCreateShaderProgramvEXT (GLenum type, GLsizei count, const GLchar **strings); +GL_APICALL void GL_APIENTRY glBindProgramPipelineEXT (GLuint pipeline); +GL_APICALL void GL_APIENTRY glDeleteProgramPipelinesEXT (GLsizei n, const GLuint *pipelines); +GL_APICALL void GL_APIENTRY glGenProgramPipelinesEXT (GLsizei n, GLuint *pipelines); +GL_APICALL GLboolean GL_APIENTRY glIsProgramPipelineEXT (GLuint pipeline); +GL_APICALL void GL_APIENTRY glProgramParameteriEXT (GLuint program, GLenum pname, GLint value); +GL_APICALL void GL_APIENTRY glGetProgramPipelineivEXT (GLuint pipeline, GLenum pname, GLint *params); +GL_APICALL void GL_APIENTRY glProgramUniform1iEXT (GLuint program, GLint location, GLint x); +GL_APICALL void GL_APIENTRY glProgramUniform2iEXT (GLuint program, GLint location, GLint x, GLint y); +GL_APICALL void GL_APIENTRY glProgramUniform3iEXT (GLuint program, GLint location, GLint x, GLint y, GLint z); +GL_APICALL void GL_APIENTRY glProgramUniform4iEXT (GLuint program, GLint location, GLint x, GLint y, GLint z, GLint w); +GL_APICALL void GL_APIENTRY glProgramUniform1fEXT (GLuint program, GLint location, GLfloat x); +GL_APICALL void GL_APIENTRY glProgramUniform2fEXT (GLuint program, GLint location, GLfloat x, GLfloat y); +GL_APICALL void GL_APIENTRY glProgramUniform3fEXT (GLuint program, GLint location, GLfloat x, GLfloat y, GLfloat z); +GL_APICALL void GL_APIENTRY glProgramUniform4fEXT (GLuint program, GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +GL_APICALL void GL_APIENTRY glProgramUniform1ivEXT (GLuint program, GLint location, GLsizei count, const GLint *value); +GL_APICALL void GL_APIENTRY glProgramUniform2ivEXT (GLuint program, GLint location, GLsizei count, const GLint *value); +GL_APICALL void GL_APIENTRY glProgramUniform3ivEXT (GLuint program, GLint location, GLsizei count, const GLint *value); +GL_APICALL void GL_APIENTRY glProgramUniform4ivEXT (GLuint program, GLint location, GLsizei count, const GLint *value); +GL_APICALL void GL_APIENTRY glProgramUniform1fvEXT (GLuint program, GLint location, GLsizei count, const GLfloat *value); +GL_APICALL void GL_APIENTRY glProgramUniform2fvEXT (GLuint program, GLint location, GLsizei count, const GLfloat *value); +GL_APICALL void GL_APIENTRY glProgramUniform3fvEXT (GLuint program, GLint location, GLsizei count, const GLfloat *value); +GL_APICALL void GL_APIENTRY glProgramUniform4fvEXT (GLuint program, GLint location, GLsizei count, const GLfloat *value); +GL_APICALL void GL_APIENTRY glProgramUniformMatrix2fvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GL_APICALL void GL_APIENTRY glProgramUniformMatrix3fvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GL_APICALL void GL_APIENTRY glProgramUniformMatrix4fvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GL_APICALL void GL_APIENTRY glValidateProgramPipelineEXT (GLuint pipeline); +GL_APICALL void GL_APIENTRY glGetProgramPipelineInfoLogEXT (GLuint pipeline, GLsizei bufSize, GLsizei *length, GLchar *infoLog); +#endif +typedef void (GL_APIENTRYP PFNGLUSEPROGRAMSTAGESEXTPROC) (GLuint pipeline, GLbitfield stages, GLuint program); +typedef void (GL_APIENTRYP PFNGLACTIVESHADERPROGRAMEXTPROC) (GLuint pipeline, GLuint program); +typedef GLuint (GL_APIENTRYP PFNGLCREATESHADERPROGRAMVEXTPROC) (GLenum type, GLsizei count, const GLchar **strings); +typedef void (GL_APIENTRYP PFNGLBINDPROGRAMPIPELINEEXTPROC) (GLuint pipeline); +typedef void (GL_APIENTRYP PFNGLDELETEPROGRAMPIPELINESEXTPROC) (GLsizei n, const GLuint *pipelines); +typedef void (GL_APIENTRYP PFNGLGENPROGRAMPIPELINESEXTPROC) (GLsizei n, GLuint *pipelines); +typedef GLboolean (GL_APIENTRYP PFNGLISPROGRAMPIPELINEEXTPROC) (GLuint pipeline); +typedef void (GL_APIENTRYP PFNGLPROGRAMPARAMETERIEXTPROC) (GLuint program, GLenum pname, GLint value); +typedef void (GL_APIENTRYP PFNGLGETPROGRAMPIPELINEIVEXTPROC) (GLuint pipeline, GLenum pname, GLint *params); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM1IEXTPROC) (GLuint program, GLint location, GLint x); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM2IEXTPROC) (GLuint program, GLint location, GLint x, GLint y); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM3IEXTPROC) (GLuint program, GLint location, GLint x, GLint y, GLint z); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM4IEXTPROC) (GLuint program, GLint location, GLint x, GLint y, GLint z, GLint w); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM1FEXTPROC) (GLuint program, GLint location, GLfloat x); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM2FEXTPROC) (GLuint program, GLint location, GLfloat x, GLfloat y); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM3FEXTPROC) (GLuint program, GLint location, GLfloat x, GLfloat y, GLfloat z); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM4FEXTPROC) (GLuint program, GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM1IVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLint *value); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM2IVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLint *value); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM3IVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLint *value); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM4IVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLint *value); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM1FVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM2FVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM3FVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM4FVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (GL_APIENTRYP PFNGLVALIDATEPROGRAMPIPELINEEXTPROC) (GLuint pipeline); +typedef void (GL_APIENTRYP PFNGLGETPROGRAMPIPELINEINFOLOGEXTPROC) (GLuint pipeline, GLsizei bufSize, GLsizei *length, GLchar *infoLog); +#endif + +/* GL_EXT_shader_framebuffer_fetch */ +#ifndef GL_EXT_shader_framebuffer_fetch +#define GL_EXT_shader_framebuffer_fetch 1 +#endif + +/* GL_EXT_shader_texture_lod */ +#ifndef GL_EXT_shader_texture_lod +#define GL_EXT_shader_texture_lod 1 +#endif + +/* GL_EXT_shadow_samplers */ +#ifndef GL_EXT_shadow_samplers +#define GL_EXT_shadow_samplers 1 +#endif + +/* GL_EXT_sRGB */ +#ifndef GL_EXT_sRGB +#define GL_EXT_sRGB 1 +#endif + +/* GL_EXT_texture_compression_dxt1 */ +#ifndef GL_EXT_texture_compression_dxt1 +#define GL_EXT_texture_compression_dxt1 1 +#endif + +/* GL_EXT_texture_filter_anisotropic */ +#ifndef GL_EXT_texture_filter_anisotropic +#define GL_EXT_texture_filter_anisotropic 1 +#endif + +/* GL_EXT_texture_format_BGRA8888 */ +#ifndef GL_EXT_texture_format_BGRA8888 +#define GL_EXT_texture_format_BGRA8888 1 +#endif + +/* GL_EXT_texture_rg */ +#ifndef GL_EXT_texture_rg +#define GL_EXT_texture_rg 1 +#endif + +/* GL_EXT_texture_storage */ +#ifndef GL_EXT_texture_storage +#define GL_EXT_texture_storage 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glTexStorage1DEXT (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width); +GL_APICALL void GL_APIENTRY glTexStorage2DEXT (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height); +GL_APICALL void GL_APIENTRY glTexStorage3DEXT (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); +GL_APICALL void GL_APIENTRY glTextureStorage1DEXT (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width); +GL_APICALL void GL_APIENTRY glTextureStorage2DEXT (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height); +GL_APICALL void GL_APIENTRY glTextureStorage3DEXT (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); +#endif +typedef void (GL_APIENTRYP PFNGLTEXSTORAGE1DEXTPROC) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width); +typedef void (GL_APIENTRYP PFNGLTEXSTORAGE2DEXTPROC) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height); +typedef void (GL_APIENTRYP PFNGLTEXSTORAGE3DEXTPROC) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); +typedef void (GL_APIENTRYP PFNGLTEXTURESTORAGE1DEXTPROC) (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width); +typedef void (GL_APIENTRYP PFNGLTEXTURESTORAGE2DEXTPROC) (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height); +typedef void (GL_APIENTRYP PFNGLTEXTURESTORAGE3DEXTPROC) (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); +#endif + +/* GL_EXT_texture_type_2_10_10_10_REV */ +#ifndef GL_EXT_texture_type_2_10_10_10_REV +#define GL_EXT_texture_type_2_10_10_10_REV 1 +#endif + +/* GL_EXT_unpack_subimage */ +#ifndef GL_EXT_unpack_subimage +#define GL_EXT_unpack_subimage 1 +#endif + +/*------------------------------------------------------------------------* + * DMP extension functions + *------------------------------------------------------------------------*/ + +/* GL_DMP_shader_binary */ +#ifndef GL_DMP_shader_binary +#define GL_DMP_shader_binary 1 +#endif + +/*------------------------------------------------------------------------* + * FJ extension functions + *------------------------------------------------------------------------*/ + +/* GL_FJ_shader_binary_GCCSO */ +#ifndef GL_FJ_shader_binary_GCCSO +#define GL_FJ_shader_binary_GCCSO 1 +#endif + +/*------------------------------------------------------------------------* + * IMG extension functions + *------------------------------------------------------------------------*/ + +/* GL_IMG_program_binary */ +#ifndef GL_IMG_program_binary +#define GL_IMG_program_binary 1 +#endif + +/* GL_IMG_read_format */ +#ifndef GL_IMG_read_format +#define GL_IMG_read_format 1 +#endif + +/* GL_IMG_shader_binary */ +#ifndef GL_IMG_shader_binary +#define GL_IMG_shader_binary 1 +#endif + +/* GL_IMG_texture_compression_pvrtc */ +#ifndef GL_IMG_texture_compression_pvrtc +#define GL_IMG_texture_compression_pvrtc 1 +#endif + +/* GL_IMG_texture_compression_pvrtc2 */ +#ifndef GL_IMG_texture_compression_pvrtc2 +#define GL_IMG_texture_compression_pvrtc2 1 +#endif + +/* GL_IMG_multisampled_render_to_texture */ +#ifndef GL_IMG_multisampled_render_to_texture +#define GL_IMG_multisampled_render_to_texture 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glRenderbufferStorageMultisampleIMG (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); +GL_APICALL void GL_APIENTRY glFramebufferTexture2DMultisampleIMG (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLsizei samples); +#endif +typedef void (GL_APIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLEIMGPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); +typedef void (GL_APIENTRYP PFNGLFRAMEBUFFERTEXTURE2DMULTISAMPLEIMGPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLsizei samples); +#endif + +/*------------------------------------------------------------------------* + * NV extension functions + *------------------------------------------------------------------------*/ + +/* GL_NV_coverage_sample */ +#ifndef GL_NV_coverage_sample +#define GL_NV_coverage_sample 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glCoverageMaskNV (GLboolean mask); +GL_APICALL void GL_APIENTRY glCoverageOperationNV (GLenum operation); +#endif +typedef void (GL_APIENTRYP PFNGLCOVERAGEMASKNVPROC) (GLboolean mask); +typedef void (GL_APIENTRYP PFNGLCOVERAGEOPERATIONNVPROC) (GLenum operation); +#endif + +/* GL_NV_depth_nonlinear */ +#ifndef GL_NV_depth_nonlinear +#define GL_NV_depth_nonlinear 1 +#endif + +/* GL_NV_draw_buffers */ +#ifndef GL_NV_draw_buffers +#define GL_NV_draw_buffers 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glDrawBuffersNV (GLsizei n, const GLenum *bufs); +#endif +typedef void (GL_APIENTRYP PFNGLDRAWBUFFERSNVPROC) (GLsizei n, const GLenum *bufs); +#endif + +/* GL_NV_draw_instanced */ +#ifndef GL_NV_draw_instanced +#define GL_NV_draw_instanced 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glDrawArraysInstancedNV (GLenum mode, GLint first, GLsizei count, GLsizei primcount); +GL_APICALL void GL_APIENTRY glDrawElementsInstancedNV (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei primcount); +#endif +typedef void (GL_APIENTRYP PFNGLDRAWARRAYSINSTANCEDNVPROC) (GLenum mode, GLint first, GLsizei count, GLsizei primcount); +typedef void (GL_APIENTRYP PFNGLDRAWELEMENTSINSTANCEDNVPROC) (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei primcount); +#endif + +/* GL_NV_fbo_color_attachments */ +#ifndef GL_NV_fbo_color_attachments +#define GL_NV_fbo_color_attachments 1 +#endif + +/* GL_NV_fence */ +#ifndef GL_NV_fence +#define GL_NV_fence 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glDeleteFencesNV (GLsizei n, const GLuint *fences); +GL_APICALL void GL_APIENTRY glGenFencesNV (GLsizei n, GLuint *fences); +GL_APICALL GLboolean GL_APIENTRY glIsFenceNV (GLuint fence); +GL_APICALL GLboolean GL_APIENTRY glTestFenceNV (GLuint fence); +GL_APICALL void GL_APIENTRY glGetFenceivNV (GLuint fence, GLenum pname, GLint *params); +GL_APICALL void GL_APIENTRY glFinishFenceNV (GLuint fence); +GL_APICALL void GL_APIENTRY glSetFenceNV (GLuint fence, GLenum condition); +#endif +typedef void (GL_APIENTRYP PFNGLDELETEFENCESNVPROC) (GLsizei n, const GLuint *fences); +typedef void (GL_APIENTRYP PFNGLGENFENCESNVPROC) (GLsizei n, GLuint *fences); +typedef GLboolean (GL_APIENTRYP PFNGLISFENCENVPROC) (GLuint fence); +typedef GLboolean (GL_APIENTRYP PFNGLTESTFENCENVPROC) (GLuint fence); +typedef void (GL_APIENTRYP PFNGLGETFENCEIVNVPROC) (GLuint fence, GLenum pname, GLint *params); +typedef void (GL_APIENTRYP PFNGLFINISHFENCENVPROC) (GLuint fence); +typedef void (GL_APIENTRYP PFNGLSETFENCENVPROC) (GLuint fence, GLenum condition); +#endif + +/* GL_NV_framebuffer_blit */ +#ifndef GL_NV_framebuffer_blit +#define GL_NV_framebuffer_blit 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glBlitFramebufferNV (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); +#endif +typedef void (GL_APIENTRYP PFNGLBLITFRAMEBUFFERNVPROC) (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); +#endif + +/* GL_NV_framebuffer_multisample */ +#ifndef GL_NV_framebuffer_multisample +#define GL_NV_framebuffer_multisample 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glRenderbufferStorageMultisampleNV ( GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); +#endif +typedef void (GL_APIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLENVPROC) ( GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); +#endif + +/* GL_NV_generate_mipmap_sRGB */ +#ifndef GL_NV_generate_mipmap_sRGB +#define GL_NV_generate_mipmap_sRGB 1 +#endif + +/* GL_NV_instanced_arrays */ +#ifndef GL_NV_instanced_arrays +#define GL_NV_instanced_arrays 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glVertexAttribDivisorNV (GLuint index, GLuint divisor); +#endif +typedef void (GL_APIENTRYP PFNGLVERTEXATTRIBDIVISORNVPROC) (GLuint index, GLuint divisor); +#endif + +/* GL_NV_read_buffer */ +#ifndef GL_NV_read_buffer +#define GL_NV_read_buffer 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glReadBufferNV (GLenum mode); +#endif +typedef void (GL_APIENTRYP PFNGLREADBUFFERNVPROC) (GLenum mode); +#endif + +/* GL_NV_read_buffer_front */ +#ifndef GL_NV_read_buffer_front +#define GL_NV_read_buffer_front 1 +#endif + +/* GL_NV_read_depth */ +#ifndef GL_NV_read_depth +#define GL_NV_read_depth 1 +#endif + +/* GL_NV_read_depth_stencil */ +#ifndef GL_NV_read_depth_stencil +#define GL_NV_read_depth_stencil 1 +#endif + +/* GL_NV_read_stencil */ +#ifndef GL_NV_read_stencil +#define GL_NV_read_stencil 1 +#endif + +/* GL_NV_shadow_samplers_array */ +#ifndef GL_NV_shadow_samplers_array +#define GL_NV_shadow_samplers_array 1 +#endif + +/* GL_NV_shadow_samplers_cube */ +#ifndef GL_NV_shadow_samplers_cube +#define GL_NV_shadow_samplers_cube 1 +#endif + +/* GL_NV_sRGB_formats */ +#ifndef GL_NV_sRGB_formats +#define GL_NV_sRGB_formats 1 +#endif + +/* GL_NV_texture_border_clamp */ +#ifndef GL_NV_texture_border_clamp +#define GL_NV_texture_border_clamp 1 +#endif + +/* GL_NV_texture_compression_s3tc_update */ +#ifndef GL_NV_texture_compression_s3tc_update +#define GL_NV_texture_compression_s3tc_update 1 +#endif + +/* GL_NV_texture_npot_2D_mipmap */ +#ifndef GL_NV_texture_npot_2D_mipmap +#define GL_NV_texture_npot_2D_mipmap 1 +#endif + +/*------------------------------------------------------------------------* + * QCOM extension functions + *------------------------------------------------------------------------*/ + +/* GL_QCOM_alpha_test */ +#ifndef GL_QCOM_alpha_test +#define GL_QCOM_alpha_test 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glAlphaFuncQCOM (GLenum func, GLclampf ref); +#endif +typedef void (GL_APIENTRYP PFNGLALPHAFUNCQCOMPROC) (GLenum func, GLclampf ref); +#endif + +/* GL_QCOM_binning_control */ +#ifndef GL_QCOM_binning_control +#define GL_QCOM_binning_control 1 +#endif + +/* GL_QCOM_driver_control */ +#ifndef GL_QCOM_driver_control +#define GL_QCOM_driver_control 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glGetDriverControlsQCOM (GLint *num, GLsizei size, GLuint *driverControls); +GL_APICALL void GL_APIENTRY glGetDriverControlStringQCOM (GLuint driverControl, GLsizei bufSize, GLsizei *length, GLchar *driverControlString); +GL_APICALL void GL_APIENTRY glEnableDriverControlQCOM (GLuint driverControl); +GL_APICALL void GL_APIENTRY glDisableDriverControlQCOM (GLuint driverControl); +#endif +typedef void (GL_APIENTRYP PFNGLGETDRIVERCONTROLSQCOMPROC) (GLint *num, GLsizei size, GLuint *driverControls); +typedef void (GL_APIENTRYP PFNGLGETDRIVERCONTROLSTRINGQCOMPROC) (GLuint driverControl, GLsizei bufSize, GLsizei *length, GLchar *driverControlString); +typedef void (GL_APIENTRYP PFNGLENABLEDRIVERCONTROLQCOMPROC) (GLuint driverControl); +typedef void (GL_APIENTRYP PFNGLDISABLEDRIVERCONTROLQCOMPROC) (GLuint driverControl); +#endif + +/* GL_QCOM_extended_get */ +#ifndef GL_QCOM_extended_get +#define GL_QCOM_extended_get 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glExtGetTexturesQCOM (GLuint *textures, GLint maxTextures, GLint *numTextures); +GL_APICALL void GL_APIENTRY glExtGetBuffersQCOM (GLuint *buffers, GLint maxBuffers, GLint *numBuffers); +GL_APICALL void GL_APIENTRY glExtGetRenderbuffersQCOM (GLuint *renderbuffers, GLint maxRenderbuffers, GLint *numRenderbuffers); +GL_APICALL void GL_APIENTRY glExtGetFramebuffersQCOM (GLuint *framebuffers, GLint maxFramebuffers, GLint *numFramebuffers); +GL_APICALL void GL_APIENTRY glExtGetTexLevelParameterivQCOM (GLuint texture, GLenum face, GLint level, GLenum pname, GLint *params); +GL_APICALL void GL_APIENTRY glExtTexObjectStateOverrideiQCOM (GLenum target, GLenum pname, GLint param); +GL_APICALL void GL_APIENTRY glExtGetTexSubImageQCOM (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, GLvoid *texels); +GL_APICALL void GL_APIENTRY glExtGetBufferPointervQCOM (GLenum target, GLvoid **params); +#endif +typedef void (GL_APIENTRYP PFNGLEXTGETTEXTURESQCOMPROC) (GLuint *textures, GLint maxTextures, GLint *numTextures); +typedef void (GL_APIENTRYP PFNGLEXTGETBUFFERSQCOMPROC) (GLuint *buffers, GLint maxBuffers, GLint *numBuffers); +typedef void (GL_APIENTRYP PFNGLEXTGETRENDERBUFFERSQCOMPROC) (GLuint *renderbuffers, GLint maxRenderbuffers, GLint *numRenderbuffers); +typedef void (GL_APIENTRYP PFNGLEXTGETFRAMEBUFFERSQCOMPROC) (GLuint *framebuffers, GLint maxFramebuffers, GLint *numFramebuffers); +typedef void (GL_APIENTRYP PFNGLEXTGETTEXLEVELPARAMETERIVQCOMPROC) (GLuint texture, GLenum face, GLint level, GLenum pname, GLint *params); +typedef void (GL_APIENTRYP PFNGLEXTTEXOBJECTSTATEOVERRIDEIQCOMPROC) (GLenum target, GLenum pname, GLint param); +typedef void (GL_APIENTRYP PFNGLEXTGETTEXSUBIMAGEQCOMPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, GLvoid *texels); +typedef void (GL_APIENTRYP PFNGLEXTGETBUFFERPOINTERVQCOMPROC) (GLenum target, GLvoid **params); +#endif + +/* GL_QCOM_extended_get2 */ +#ifndef GL_QCOM_extended_get2 +#define GL_QCOM_extended_get2 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glExtGetShadersQCOM (GLuint *shaders, GLint maxShaders, GLint *numShaders); +GL_APICALL void GL_APIENTRY glExtGetProgramsQCOM (GLuint *programs, GLint maxPrograms, GLint *numPrograms); +GL_APICALL GLboolean GL_APIENTRY glExtIsProgramBinaryQCOM (GLuint program); +GL_APICALL void GL_APIENTRY glExtGetProgramBinarySourceQCOM (GLuint program, GLenum shadertype, GLchar *source, GLint *length); +#endif +typedef void (GL_APIENTRYP PFNGLEXTGETSHADERSQCOMPROC) (GLuint *shaders, GLint maxShaders, GLint *numShaders); +typedef void (GL_APIENTRYP PFNGLEXTGETPROGRAMSQCOMPROC) (GLuint *programs, GLint maxPrograms, GLint *numPrograms); +typedef GLboolean (GL_APIENTRYP PFNGLEXTISPROGRAMBINARYQCOMPROC) (GLuint program); +typedef void (GL_APIENTRYP PFNGLEXTGETPROGRAMBINARYSOURCEQCOMPROC) (GLuint program, GLenum shadertype, GLchar *source, GLint *length); +#endif + +/* GL_QCOM_perfmon_global_mode */ +#ifndef GL_QCOM_perfmon_global_mode +#define GL_QCOM_perfmon_global_mode 1 +#endif + +/* GL_QCOM_writeonly_rendering */ +#ifndef GL_QCOM_writeonly_rendering +#define GL_QCOM_writeonly_rendering 1 +#endif + +/* GL_QCOM_tiled_rendering */ +#ifndef GL_QCOM_tiled_rendering +#define GL_QCOM_tiled_rendering 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glStartTilingQCOM (GLuint x, GLuint y, GLuint width, GLuint height, GLbitfield preserveMask); +GL_APICALL void GL_APIENTRY glEndTilingQCOM (GLbitfield preserveMask); +#endif +typedef void (GL_APIENTRYP PFNGLSTARTTILINGQCOMPROC) (GLuint x, GLuint y, GLuint width, GLuint height, GLbitfield preserveMask); +typedef void (GL_APIENTRYP PFNGLENDTILINGQCOMPROC) (GLbitfield preserveMask); +#endif + +/*------------------------------------------------------------------------* + * VIV extension tokens + *------------------------------------------------------------------------*/ + +/* GL_VIV_shader_binary */ +#ifndef GL_VIV_shader_binary +#define GL_VIV_shader_binary 1 +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* __gl2ext_h_ */ diff --git a/engine/Windows/SDL2/include/SDL_opengles2_gl2platform.h b/engine/Windows/SDL2/include/SDL_opengles2_gl2platform.h new file mode 100644 index 0000000..c325686 --- /dev/null +++ b/engine/Windows/SDL2/include/SDL_opengles2_gl2platform.h @@ -0,0 +1,30 @@ +#ifndef __gl2platform_h_ +#define __gl2platform_h_ + +/* $Revision: 10602 $ on $Date:: 2010-03-04 22:35:34 -0800 #$ */ + +/* + * This document is licensed under the SGI Free Software B License Version + * 2.0. For details, see http://oss.sgi.com/projects/FreeB/ . + */ + +/* Platform-specific types and definitions for OpenGL ES 2.X gl2.h + * + * Adopters may modify khrplatform.h and this file to suit their platform. + * You are encouraged to submit all modifications to the Khronos group so that + * they can be included in future versions of this file. Please submit changes + * by sending them to the public Khronos Bugzilla (http://khronos.org/bugzilla) + * by filing a bug against product "OpenGL-ES" component "Registry". + */ + +/*#include */ + +#ifndef GL_APICALL +#define GL_APICALL KHRONOS_APICALL +#endif + +#ifndef GL_APIENTRY +#define GL_APIENTRY KHRONOS_APIENTRY +#endif + +#endif /* __gl2platform_h_ */ diff --git a/engine/Windows/SDL2/include/SDL_opengles2_khrplatform.h b/engine/Windows/SDL2/include/SDL_opengles2_khrplatform.h new file mode 100644 index 0000000..c9e6f17 --- /dev/null +++ b/engine/Windows/SDL2/include/SDL_opengles2_khrplatform.h @@ -0,0 +1,282 @@ +#ifndef __khrplatform_h_ +#define __khrplatform_h_ + +/* +** Copyright (c) 2008-2009 The Khronos Group Inc. +** +** Permission is hereby granted, free of charge, to any person obtaining a +** copy of this software and/or associated documentation files (the +** "Materials"), to deal in the Materials without restriction, including +** without limitation the rights to use, copy, modify, merge, publish, +** distribute, sublicense, and/or sell copies of the Materials, and to +** permit persons to whom the Materials are furnished to do so, subject to +** the following conditions: +** +** The above copyright notice and this permission notice shall be included +** in all copies or substantial portions of the Materials. +** +** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. +*/ + +/* Khronos platform-specific types and definitions. + * + * $Revision: 23298 $ on $Date: 2013-09-30 17:07:13 -0700 (Mon, 30 Sep 2013) $ + * + * Adopters may modify this file to suit their platform. Adopters are + * encouraged to submit platform specific modifications to the Khronos + * group so that they can be included in future versions of this file. + * Please submit changes by sending them to the public Khronos Bugzilla + * (http://khronos.org/bugzilla) by filing a bug against product + * "Khronos (general)" component "Registry". + * + * A predefined template which fills in some of the bug fields can be + * reached using http://tinyurl.com/khrplatform-h-bugreport, but you + * must create a Bugzilla login first. + * + * + * See the Implementer's Guidelines for information about where this file + * should be located on your system and for more details of its use: + * http://www.khronos.org/registry/implementers_guide.pdf + * + * This file should be included as + * #include + * by Khronos client API header files that use its types and defines. + * + * The types in khrplatform.h should only be used to define API-specific types. + * + * Types defined in khrplatform.h: + * khronos_int8_t signed 8 bit + * khronos_uint8_t unsigned 8 bit + * khronos_int16_t signed 16 bit + * khronos_uint16_t unsigned 16 bit + * khronos_int32_t signed 32 bit + * khronos_uint32_t unsigned 32 bit + * khronos_int64_t signed 64 bit + * khronos_uint64_t unsigned 64 bit + * khronos_intptr_t signed same number of bits as a pointer + * khronos_uintptr_t unsigned same number of bits as a pointer + * khronos_ssize_t signed size + * khronos_usize_t unsigned size + * khronos_float_t signed 32 bit floating point + * khronos_time_ns_t unsigned 64 bit time in nanoseconds + * khronos_utime_nanoseconds_t unsigned time interval or absolute time in + * nanoseconds + * khronos_stime_nanoseconds_t signed time interval in nanoseconds + * khronos_boolean_enum_t enumerated boolean type. This should + * only be used as a base type when a client API's boolean type is + * an enum. Client APIs which use an integer or other type for + * booleans cannot use this as the base type for their boolean. + * + * Tokens defined in khrplatform.h: + * + * KHRONOS_FALSE, KHRONOS_TRUE Enumerated boolean false/true values. + * + * KHRONOS_SUPPORT_INT64 is 1 if 64 bit integers are supported; otherwise 0. + * KHRONOS_SUPPORT_FLOAT is 1 if floats are supported; otherwise 0. + * + * Calling convention macros defined in this file: + * KHRONOS_APICALL + * KHRONOS_APIENTRY + * KHRONOS_APIATTRIBUTES + * + * These may be used in function prototypes as: + * + * KHRONOS_APICALL void KHRONOS_APIENTRY funcname( + * int arg1, + * int arg2) KHRONOS_APIATTRIBUTES; + */ + +/*------------------------------------------------------------------------- + * Definition of KHRONOS_APICALL + *------------------------------------------------------------------------- + * This precedes the return type of the function in the function prototype. + */ +#if defined(_WIN32) && !defined(__SCITECH_SNAP__) +# define KHRONOS_APICALL __declspec(dllimport) +#elif defined (__SYMBIAN32__) +# define KHRONOS_APICALL IMPORT_C +#else +# define KHRONOS_APICALL +#endif + +/*------------------------------------------------------------------------- + * Definition of KHRONOS_APIENTRY + *------------------------------------------------------------------------- + * This follows the return type of the function and precedes the function + * name in the function prototype. + */ +#if defined(_WIN32) && !defined(_WIN32_WCE) && !defined(__SCITECH_SNAP__) + /* Win32 but not WinCE */ +# define KHRONOS_APIENTRY __stdcall +#else +# define KHRONOS_APIENTRY +#endif + +/*------------------------------------------------------------------------- + * Definition of KHRONOS_APIATTRIBUTES + *------------------------------------------------------------------------- + * This follows the closing parenthesis of the function prototype arguments. + */ +#if defined (__ARMCC_2__) +#define KHRONOS_APIATTRIBUTES __softfp +#else +#define KHRONOS_APIATTRIBUTES +#endif + +/*------------------------------------------------------------------------- + * basic type definitions + *-----------------------------------------------------------------------*/ +#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || defined(__GNUC__) || defined(__SCO__) || defined(__USLC__) + + +/* + * Using + */ +#include +typedef int32_t khronos_int32_t; +typedef uint32_t khronos_uint32_t; +typedef int64_t khronos_int64_t; +typedef uint64_t khronos_uint64_t; +#define KHRONOS_SUPPORT_INT64 1 +#define KHRONOS_SUPPORT_FLOAT 1 + +#elif defined(__VMS ) || defined(__sgi) + +/* + * Using + */ +#include +typedef int32_t khronos_int32_t; +typedef uint32_t khronos_uint32_t; +typedef int64_t khronos_int64_t; +typedef uint64_t khronos_uint64_t; +#define KHRONOS_SUPPORT_INT64 1 +#define KHRONOS_SUPPORT_FLOAT 1 + +#elif defined(_WIN32) && !defined(__SCITECH_SNAP__) + +/* + * Win32 + */ +typedef __int32 khronos_int32_t; +typedef unsigned __int32 khronos_uint32_t; +typedef __int64 khronos_int64_t; +typedef unsigned __int64 khronos_uint64_t; +#define KHRONOS_SUPPORT_INT64 1 +#define KHRONOS_SUPPORT_FLOAT 1 + +#elif defined(__sun__) || defined(__digital__) + +/* + * Sun or Digital + */ +typedef int khronos_int32_t; +typedef unsigned int khronos_uint32_t; +#if defined(__arch64__) || defined(_LP64) +typedef long int khronos_int64_t; +typedef unsigned long int khronos_uint64_t; +#else +typedef long long int khronos_int64_t; +typedef unsigned long long int khronos_uint64_t; +#endif /* __arch64__ */ +#define KHRONOS_SUPPORT_INT64 1 +#define KHRONOS_SUPPORT_FLOAT 1 + +#elif 0 + +/* + * Hypothetical platform with no float or int64 support + */ +typedef int khronos_int32_t; +typedef unsigned int khronos_uint32_t; +#define KHRONOS_SUPPORT_INT64 0 +#define KHRONOS_SUPPORT_FLOAT 0 + +#else + +/* + * Generic fallback + */ +#include +typedef int32_t khronos_int32_t; +typedef uint32_t khronos_uint32_t; +typedef int64_t khronos_int64_t; +typedef uint64_t khronos_uint64_t; +#define KHRONOS_SUPPORT_INT64 1 +#define KHRONOS_SUPPORT_FLOAT 1 + +#endif + + +/* + * Types that are (so far) the same on all platforms + */ +typedef signed char khronos_int8_t; +typedef unsigned char khronos_uint8_t; +typedef signed short int khronos_int16_t; +typedef unsigned short int khronos_uint16_t; + +/* + * Types that differ between LLP64 and LP64 architectures - in LLP64, + * pointers are 64 bits, but 'long' is still 32 bits. Win64 appears + * to be the only LLP64 architecture in current use. + */ +#ifdef _WIN64 +typedef signed long long int khronos_intptr_t; +typedef unsigned long long int khronos_uintptr_t; +typedef signed long long int khronos_ssize_t; +typedef unsigned long long int khronos_usize_t; +#else +typedef signed long int khronos_intptr_t; +typedef unsigned long int khronos_uintptr_t; +typedef signed long int khronos_ssize_t; +typedef unsigned long int khronos_usize_t; +#endif + +#if KHRONOS_SUPPORT_FLOAT +/* + * Float type + */ +typedef float khronos_float_t; +#endif + +#if KHRONOS_SUPPORT_INT64 +/* Time types + * + * These types can be used to represent a time interval in nanoseconds or + * an absolute Unadjusted System Time. Unadjusted System Time is the number + * of nanoseconds since some arbitrary system event (e.g. since the last + * time the system booted). The Unadjusted System Time is an unsigned + * 64 bit value that wraps back to 0 every 584 years. Time intervals + * may be either signed or unsigned. + */ +typedef khronos_uint64_t khronos_utime_nanoseconds_t; +typedef khronos_int64_t khronos_stime_nanoseconds_t; +#endif + +/* + * Dummy value used to pad enum types to 32 bits. + */ +#ifndef KHRONOS_MAX_ENUM +#define KHRONOS_MAX_ENUM 0x7FFFFFFF +#endif + +/* + * Enumerated boolean type + * + * Values other than zero should be considered to be true. Therefore + * comparisons should not be made against KHRONOS_TRUE. + */ +typedef enum { + KHRONOS_FALSE = 0, + KHRONOS_TRUE = 1, + KHRONOS_BOOLEAN_ENUM_FORCE_SIZE = KHRONOS_MAX_ENUM +} khronos_boolean_enum_t; + +#endif /* __khrplatform_h_ */ diff --git a/engine/Windows/SDL2/include/SDL_pixels.h b/engine/Windows/SDL2/include/SDL_pixels.h new file mode 100644 index 0000000..2e2b05c --- /dev/null +++ b/engine/Windows/SDL2/include/SDL_pixels.h @@ -0,0 +1,470 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2019 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_pixels.h + * + * Header for the enumerated pixel format definitions. + */ + +#ifndef SDL_pixels_h_ +#define SDL_pixels_h_ + +#include "SDL_stdinc.h" +#include "SDL_endian.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \name Transparency definitions + * + * These define alpha as the opacity of a surface. + */ +/* @{ */ +#define SDL_ALPHA_OPAQUE 255 +#define SDL_ALPHA_TRANSPARENT 0 +/* @} */ + +/** Pixel type. */ +typedef enum +{ + SDL_PIXELTYPE_UNKNOWN, + SDL_PIXELTYPE_INDEX1, + SDL_PIXELTYPE_INDEX4, + SDL_PIXELTYPE_INDEX8, + SDL_PIXELTYPE_PACKED8, + SDL_PIXELTYPE_PACKED16, + SDL_PIXELTYPE_PACKED32, + SDL_PIXELTYPE_ARRAYU8, + SDL_PIXELTYPE_ARRAYU16, + SDL_PIXELTYPE_ARRAYU32, + SDL_PIXELTYPE_ARRAYF16, + SDL_PIXELTYPE_ARRAYF32 +} SDL_PixelType; + +/** Bitmap pixel order, high bit -> low bit. */ +typedef enum +{ + SDL_BITMAPORDER_NONE, + SDL_BITMAPORDER_4321, + SDL_BITMAPORDER_1234 +} SDL_BitmapOrder; + +/** Packed component order, high bit -> low bit. */ +typedef enum +{ + SDL_PACKEDORDER_NONE, + SDL_PACKEDORDER_XRGB, + SDL_PACKEDORDER_RGBX, + SDL_PACKEDORDER_ARGB, + SDL_PACKEDORDER_RGBA, + SDL_PACKEDORDER_XBGR, + SDL_PACKEDORDER_BGRX, + SDL_PACKEDORDER_ABGR, + SDL_PACKEDORDER_BGRA +} SDL_PackedOrder; + +/** Array component order, low byte -> high byte. */ +/* !!! FIXME: in 2.1, make these not overlap differently with + !!! FIXME: SDL_PACKEDORDER_*, so we can simplify SDL_ISPIXELFORMAT_ALPHA */ +typedef enum +{ + SDL_ARRAYORDER_NONE, + SDL_ARRAYORDER_RGB, + SDL_ARRAYORDER_RGBA, + SDL_ARRAYORDER_ARGB, + SDL_ARRAYORDER_BGR, + SDL_ARRAYORDER_BGRA, + SDL_ARRAYORDER_ABGR +} SDL_ArrayOrder; + +/** Packed component layout. */ +typedef enum +{ + SDL_PACKEDLAYOUT_NONE, + SDL_PACKEDLAYOUT_332, + SDL_PACKEDLAYOUT_4444, + SDL_PACKEDLAYOUT_1555, + SDL_PACKEDLAYOUT_5551, + SDL_PACKEDLAYOUT_565, + SDL_PACKEDLAYOUT_8888, + SDL_PACKEDLAYOUT_2101010, + SDL_PACKEDLAYOUT_1010102 +} SDL_PackedLayout; + +#define SDL_DEFINE_PIXELFOURCC(A, B, C, D) SDL_FOURCC(A, B, C, D) + +#define SDL_DEFINE_PIXELFORMAT(type, order, layout, bits, bytes) \ + ((1 << 28) | ((type) << 24) | ((order) << 20) | ((layout) << 16) | \ + ((bits) << 8) | ((bytes) << 0)) + +#define SDL_PIXELFLAG(X) (((X) >> 28) & 0x0F) +#define SDL_PIXELTYPE(X) (((X) >> 24) & 0x0F) +#define SDL_PIXELORDER(X) (((X) >> 20) & 0x0F) +#define SDL_PIXELLAYOUT(X) (((X) >> 16) & 0x0F) +#define SDL_BITSPERPIXEL(X) (((X) >> 8) & 0xFF) +#define SDL_BYTESPERPIXEL(X) \ + (SDL_ISPIXELFORMAT_FOURCC(X) ? \ + ((((X) == SDL_PIXELFORMAT_YUY2) || \ + ((X) == SDL_PIXELFORMAT_UYVY) || \ + ((X) == SDL_PIXELFORMAT_YVYU)) ? 2 : 1) : (((X) >> 0) & 0xFF)) + +#define SDL_ISPIXELFORMAT_INDEXED(format) \ + (!SDL_ISPIXELFORMAT_FOURCC(format) && \ + ((SDL_PIXELTYPE(format) == SDL_PIXELTYPE_INDEX1) || \ + (SDL_PIXELTYPE(format) == SDL_PIXELTYPE_INDEX4) || \ + (SDL_PIXELTYPE(format) == SDL_PIXELTYPE_INDEX8))) + +#define SDL_ISPIXELFORMAT_PACKED(format) \ + (!SDL_ISPIXELFORMAT_FOURCC(format) && \ + ((SDL_PIXELTYPE(format) == SDL_PIXELTYPE_PACKED8) || \ + (SDL_PIXELTYPE(format) == SDL_PIXELTYPE_PACKED16) || \ + (SDL_PIXELTYPE(format) == SDL_PIXELTYPE_PACKED32))) + +#define SDL_ISPIXELFORMAT_ARRAY(format) \ + (!SDL_ISPIXELFORMAT_FOURCC(format) && \ + ((SDL_PIXELTYPE(format) == SDL_PIXELTYPE_ARRAYU8) || \ + (SDL_PIXELTYPE(format) == SDL_PIXELTYPE_ARRAYU16) || \ + (SDL_PIXELTYPE(format) == SDL_PIXELTYPE_ARRAYU32) || \ + (SDL_PIXELTYPE(format) == SDL_PIXELTYPE_ARRAYF16) || \ + (SDL_PIXELTYPE(format) == SDL_PIXELTYPE_ARRAYF32))) + +#define SDL_ISPIXELFORMAT_ALPHA(format) \ + ((SDL_ISPIXELFORMAT_PACKED(format) && \ + ((SDL_PIXELORDER(format) == SDL_PACKEDORDER_ARGB) || \ + (SDL_PIXELORDER(format) == SDL_PACKEDORDER_RGBA) || \ + (SDL_PIXELORDER(format) == SDL_PACKEDORDER_ABGR) || \ + (SDL_PIXELORDER(format) == SDL_PACKEDORDER_BGRA))) || \ + (SDL_ISPIXELFORMAT_ARRAY(format) && \ + ((SDL_PIXELORDER(format) == SDL_ARRAYORDER_ARGB) || \ + (SDL_PIXELORDER(format) == SDL_ARRAYORDER_RGBA) || \ + (SDL_PIXELORDER(format) == SDL_ARRAYORDER_ABGR) || \ + (SDL_PIXELORDER(format) == SDL_ARRAYORDER_BGRA)))) + +/* The flag is set to 1 because 0x1? is not in the printable ASCII range */ +#define SDL_ISPIXELFORMAT_FOURCC(format) \ + ((format) && (SDL_PIXELFLAG(format) != 1)) + +/* Note: If you modify this list, update SDL_GetPixelFormatName() */ +typedef enum +{ + SDL_PIXELFORMAT_UNKNOWN, + SDL_PIXELFORMAT_INDEX1LSB = + SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_INDEX1, SDL_BITMAPORDER_4321, 0, + 1, 0), + SDL_PIXELFORMAT_INDEX1MSB = + SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_INDEX1, SDL_BITMAPORDER_1234, 0, + 1, 0), + SDL_PIXELFORMAT_INDEX4LSB = + SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_INDEX4, SDL_BITMAPORDER_4321, 0, + 4, 0), + SDL_PIXELFORMAT_INDEX4MSB = + SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_INDEX4, SDL_BITMAPORDER_1234, 0, + 4, 0), + SDL_PIXELFORMAT_INDEX8 = + SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_INDEX8, 0, 0, 8, 1), + SDL_PIXELFORMAT_RGB332 = + SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED8, SDL_PACKEDORDER_XRGB, + SDL_PACKEDLAYOUT_332, 8, 1), + SDL_PIXELFORMAT_RGB444 = + SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED16, SDL_PACKEDORDER_XRGB, + SDL_PACKEDLAYOUT_4444, 12, 2), + SDL_PIXELFORMAT_RGB555 = + SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED16, SDL_PACKEDORDER_XRGB, + SDL_PACKEDLAYOUT_1555, 15, 2), + SDL_PIXELFORMAT_BGR555 = + SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED16, SDL_PACKEDORDER_XBGR, + SDL_PACKEDLAYOUT_1555, 15, 2), + SDL_PIXELFORMAT_ARGB4444 = + SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED16, SDL_PACKEDORDER_ARGB, + SDL_PACKEDLAYOUT_4444, 16, 2), + SDL_PIXELFORMAT_RGBA4444 = + SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED16, SDL_PACKEDORDER_RGBA, + SDL_PACKEDLAYOUT_4444, 16, 2), + SDL_PIXELFORMAT_ABGR4444 = + SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED16, SDL_PACKEDORDER_ABGR, + SDL_PACKEDLAYOUT_4444, 16, 2), + SDL_PIXELFORMAT_BGRA4444 = + SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED16, SDL_PACKEDORDER_BGRA, + SDL_PACKEDLAYOUT_4444, 16, 2), + SDL_PIXELFORMAT_ARGB1555 = + SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED16, SDL_PACKEDORDER_ARGB, + SDL_PACKEDLAYOUT_1555, 16, 2), + SDL_PIXELFORMAT_RGBA5551 = + SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED16, SDL_PACKEDORDER_RGBA, + SDL_PACKEDLAYOUT_5551, 16, 2), + SDL_PIXELFORMAT_ABGR1555 = + SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED16, SDL_PACKEDORDER_ABGR, + SDL_PACKEDLAYOUT_1555, 16, 2), + SDL_PIXELFORMAT_BGRA5551 = + SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED16, SDL_PACKEDORDER_BGRA, + SDL_PACKEDLAYOUT_5551, 16, 2), + SDL_PIXELFORMAT_RGB565 = + SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED16, SDL_PACKEDORDER_XRGB, + SDL_PACKEDLAYOUT_565, 16, 2), + SDL_PIXELFORMAT_BGR565 = + SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED16, SDL_PACKEDORDER_XBGR, + SDL_PACKEDLAYOUT_565, 16, 2), + SDL_PIXELFORMAT_RGB24 = + SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_ARRAYU8, SDL_ARRAYORDER_RGB, 0, + 24, 3), + SDL_PIXELFORMAT_BGR24 = + SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_ARRAYU8, SDL_ARRAYORDER_BGR, 0, + 24, 3), + SDL_PIXELFORMAT_RGB888 = + SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED32, SDL_PACKEDORDER_XRGB, + SDL_PACKEDLAYOUT_8888, 24, 4), + SDL_PIXELFORMAT_RGBX8888 = + SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED32, SDL_PACKEDORDER_RGBX, + SDL_PACKEDLAYOUT_8888, 24, 4), + SDL_PIXELFORMAT_BGR888 = + SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED32, SDL_PACKEDORDER_XBGR, + SDL_PACKEDLAYOUT_8888, 24, 4), + SDL_PIXELFORMAT_BGRX8888 = + SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED32, SDL_PACKEDORDER_BGRX, + SDL_PACKEDLAYOUT_8888, 24, 4), + SDL_PIXELFORMAT_ARGB8888 = + SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED32, SDL_PACKEDORDER_ARGB, + SDL_PACKEDLAYOUT_8888, 32, 4), + SDL_PIXELFORMAT_RGBA8888 = + SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED32, SDL_PACKEDORDER_RGBA, + SDL_PACKEDLAYOUT_8888, 32, 4), + SDL_PIXELFORMAT_ABGR8888 = + SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED32, SDL_PACKEDORDER_ABGR, + SDL_PACKEDLAYOUT_8888, 32, 4), + SDL_PIXELFORMAT_BGRA8888 = + SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED32, SDL_PACKEDORDER_BGRA, + SDL_PACKEDLAYOUT_8888, 32, 4), + SDL_PIXELFORMAT_ARGB2101010 = + SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED32, SDL_PACKEDORDER_ARGB, + SDL_PACKEDLAYOUT_2101010, 32, 4), + + /* Aliases for RGBA byte arrays of color data, for the current platform */ +#if SDL_BYTEORDER == SDL_BIG_ENDIAN + SDL_PIXELFORMAT_RGBA32 = SDL_PIXELFORMAT_RGBA8888, + SDL_PIXELFORMAT_ARGB32 = SDL_PIXELFORMAT_ARGB8888, + SDL_PIXELFORMAT_BGRA32 = SDL_PIXELFORMAT_BGRA8888, + SDL_PIXELFORMAT_ABGR32 = SDL_PIXELFORMAT_ABGR8888, +#else + SDL_PIXELFORMAT_RGBA32 = SDL_PIXELFORMAT_ABGR8888, + SDL_PIXELFORMAT_ARGB32 = SDL_PIXELFORMAT_BGRA8888, + SDL_PIXELFORMAT_BGRA32 = SDL_PIXELFORMAT_ARGB8888, + SDL_PIXELFORMAT_ABGR32 = SDL_PIXELFORMAT_RGBA8888, +#endif + + SDL_PIXELFORMAT_YV12 = /**< Planar mode: Y + V + U (3 planes) */ + SDL_DEFINE_PIXELFOURCC('Y', 'V', '1', '2'), + SDL_PIXELFORMAT_IYUV = /**< Planar mode: Y + U + V (3 planes) */ + SDL_DEFINE_PIXELFOURCC('I', 'Y', 'U', 'V'), + SDL_PIXELFORMAT_YUY2 = /**< Packed mode: Y0+U0+Y1+V0 (1 plane) */ + SDL_DEFINE_PIXELFOURCC('Y', 'U', 'Y', '2'), + SDL_PIXELFORMAT_UYVY = /**< Packed mode: U0+Y0+V0+Y1 (1 plane) */ + SDL_DEFINE_PIXELFOURCC('U', 'Y', 'V', 'Y'), + SDL_PIXELFORMAT_YVYU = /**< Packed mode: Y0+V0+Y1+U0 (1 plane) */ + SDL_DEFINE_PIXELFOURCC('Y', 'V', 'Y', 'U'), + SDL_PIXELFORMAT_NV12 = /**< Planar mode: Y + U/V interleaved (2 planes) */ + SDL_DEFINE_PIXELFOURCC('N', 'V', '1', '2'), + SDL_PIXELFORMAT_NV21 = /**< Planar mode: Y + V/U interleaved (2 planes) */ + SDL_DEFINE_PIXELFOURCC('N', 'V', '2', '1'), + SDL_PIXELFORMAT_EXTERNAL_OES = /**< Android video texture format */ + SDL_DEFINE_PIXELFOURCC('O', 'E', 'S', ' ') +} SDL_PixelFormatEnum; + +typedef struct SDL_Color +{ + Uint8 r; + Uint8 g; + Uint8 b; + Uint8 a; +} SDL_Color; +#define SDL_Colour SDL_Color + +typedef struct SDL_Palette +{ + int ncolors; + SDL_Color *colors; + Uint32 version; + int refcount; +} SDL_Palette; + +/** + * \note Everything in the pixel format structure is read-only. + */ +typedef struct SDL_PixelFormat +{ + Uint32 format; + SDL_Palette *palette; + Uint8 BitsPerPixel; + Uint8 BytesPerPixel; + Uint8 padding[2]; + Uint32 Rmask; + Uint32 Gmask; + Uint32 Bmask; + Uint32 Amask; + Uint8 Rloss; + Uint8 Gloss; + Uint8 Bloss; + Uint8 Aloss; + Uint8 Rshift; + Uint8 Gshift; + Uint8 Bshift; + Uint8 Ashift; + int refcount; + struct SDL_PixelFormat *next; +} SDL_PixelFormat; + +/** + * \brief Get the human readable name of a pixel format + */ +extern DECLSPEC const char* SDLCALL SDL_GetPixelFormatName(Uint32 format); + +/** + * \brief Convert one of the enumerated pixel formats to a bpp and RGBA masks. + * + * \return SDL_TRUE, or SDL_FALSE if the conversion wasn't possible. + * + * \sa SDL_MasksToPixelFormatEnum() + */ +extern DECLSPEC SDL_bool SDLCALL SDL_PixelFormatEnumToMasks(Uint32 format, + int *bpp, + Uint32 * Rmask, + Uint32 * Gmask, + Uint32 * Bmask, + Uint32 * Amask); + +/** + * \brief Convert a bpp and RGBA masks to an enumerated pixel format. + * + * \return The pixel format, or ::SDL_PIXELFORMAT_UNKNOWN if the conversion + * wasn't possible. + * + * \sa SDL_PixelFormatEnumToMasks() + */ +extern DECLSPEC Uint32 SDLCALL SDL_MasksToPixelFormatEnum(int bpp, + Uint32 Rmask, + Uint32 Gmask, + Uint32 Bmask, + Uint32 Amask); + +/** + * \brief Create an SDL_PixelFormat structure from a pixel format enum. + */ +extern DECLSPEC SDL_PixelFormat * SDLCALL SDL_AllocFormat(Uint32 pixel_format); + +/** + * \brief Free an SDL_PixelFormat structure. + */ +extern DECLSPEC void SDLCALL SDL_FreeFormat(SDL_PixelFormat *format); + +/** + * \brief Create a palette structure with the specified number of color + * entries. + * + * \return A new palette, or NULL if there wasn't enough memory. + * + * \note The palette entries are initialized to white. + * + * \sa SDL_FreePalette() + */ +extern DECLSPEC SDL_Palette *SDLCALL SDL_AllocPalette(int ncolors); + +/** + * \brief Set the palette for a pixel format structure. + */ +extern DECLSPEC int SDLCALL SDL_SetPixelFormatPalette(SDL_PixelFormat * format, + SDL_Palette *palette); + +/** + * \brief Set a range of colors in a palette. + * + * \param palette The palette to modify. + * \param colors An array of colors to copy into the palette. + * \param firstcolor The index of the first palette entry to modify. + * \param ncolors The number of entries to modify. + * + * \return 0 on success, or -1 if not all of the colors could be set. + */ +extern DECLSPEC int SDLCALL SDL_SetPaletteColors(SDL_Palette * palette, + const SDL_Color * colors, + int firstcolor, int ncolors); + +/** + * \brief Free a palette created with SDL_AllocPalette(). + * + * \sa SDL_AllocPalette() + */ +extern DECLSPEC void SDLCALL SDL_FreePalette(SDL_Palette * palette); + +/** + * \brief Maps an RGB triple to an opaque pixel value for a given pixel format. + * + * \sa SDL_MapRGBA + */ +extern DECLSPEC Uint32 SDLCALL SDL_MapRGB(const SDL_PixelFormat * format, + Uint8 r, Uint8 g, Uint8 b); + +/** + * \brief Maps an RGBA quadruple to a pixel value for a given pixel format. + * + * \sa SDL_MapRGB + */ +extern DECLSPEC Uint32 SDLCALL SDL_MapRGBA(const SDL_PixelFormat * format, + Uint8 r, Uint8 g, Uint8 b, + Uint8 a); + +/** + * \brief Get the RGB components from a pixel of the specified format. + * + * \sa SDL_GetRGBA + */ +extern DECLSPEC void SDLCALL SDL_GetRGB(Uint32 pixel, + const SDL_PixelFormat * format, + Uint8 * r, Uint8 * g, Uint8 * b); + +/** + * \brief Get the RGBA components from a pixel of the specified format. + * + * \sa SDL_GetRGB + */ +extern DECLSPEC void SDLCALL SDL_GetRGBA(Uint32 pixel, + const SDL_PixelFormat * format, + Uint8 * r, Uint8 * g, Uint8 * b, + Uint8 * a); + +/** + * \brief Calculate a 256 entry gamma ramp for a gamma value. + */ +extern DECLSPEC void SDLCALL SDL_CalculateGammaRamp(float gamma, Uint16 * ramp); + + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_pixels_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/engine/Windows/SDL2/include/SDL_platform.h b/engine/Windows/SDL2/include/SDL_platform.h new file mode 100644 index 0000000..c2cbc6b --- /dev/null +++ b/engine/Windows/SDL2/include/SDL_platform.h @@ -0,0 +1,198 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2019 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_platform.h + * + * Try to get a standard set of platform defines. + */ + +#ifndef SDL_platform_h_ +#define SDL_platform_h_ + +#if defined(_AIX) +#undef __AIX__ +#define __AIX__ 1 +#endif +#if defined(__HAIKU__) +#undef __HAIKU__ +#define __HAIKU__ 1 +#endif +#if defined(bsdi) || defined(__bsdi) || defined(__bsdi__) +#undef __BSDI__ +#define __BSDI__ 1 +#endif +#if defined(_arch_dreamcast) +#undef __DREAMCAST__ +#define __DREAMCAST__ 1 +#endif +#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__) +#undef __FREEBSD__ +#define __FREEBSD__ 1 +#endif +#if defined(hpux) || defined(__hpux) || defined(__hpux__) +#undef __HPUX__ +#define __HPUX__ 1 +#endif +#if defined(sgi) || defined(__sgi) || defined(__sgi__) || defined(_SGI_SOURCE) +#undef __IRIX__ +#define __IRIX__ 1 +#endif +#if (defined(linux) || defined(__linux) || defined(__linux__)) +#undef __LINUX__ +#define __LINUX__ 1 +#endif +#if defined(ANDROID) || defined(__ANDROID__) +#undef __ANDROID__ +#undef __LINUX__ /* do we need to do this? */ +#define __ANDROID__ 1 +#endif + +#if defined(__APPLE__) +/* lets us know what version of Mac OS X we're compiling on */ +#include "AvailabilityMacros.h" +#include "TargetConditionals.h" +#if TARGET_OS_TV +#undef __TVOS__ +#define __TVOS__ 1 +#endif +#if TARGET_OS_IPHONE +/* if compiling for iOS */ +#undef __IPHONEOS__ +#define __IPHONEOS__ 1 +#undef __MACOSX__ +#else +/* if not compiling for iOS */ +#undef __MACOSX__ +#define __MACOSX__ 1 +#if MAC_OS_X_VERSION_MIN_REQUIRED < 1060 +# error SDL for Mac OS X only supports deploying on 10.6 and above. +#endif /* MAC_OS_X_VERSION_MIN_REQUIRED < 1060 */ +#endif /* TARGET_OS_IPHONE */ +#endif /* defined(__APPLE__) */ + +#if defined(__NetBSD__) +#undef __NETBSD__ +#define __NETBSD__ 1 +#endif +#if defined(__OpenBSD__) +#undef __OPENBSD__ +#define __OPENBSD__ 1 +#endif +#if defined(__OS2__) || defined(__EMX__) +#undef __OS2__ +#define __OS2__ 1 +#endif +#if defined(osf) || defined(__osf) || defined(__osf__) || defined(_OSF_SOURCE) +#undef __OSF__ +#define __OSF__ 1 +#endif +#if defined(__QNXNTO__) +#undef __QNXNTO__ +#define __QNXNTO__ 1 +#endif +#if defined(riscos) || defined(__riscos) || defined(__riscos__) +#undef __RISCOS__ +#define __RISCOS__ 1 +#endif +#if defined(__sun) && defined(__SVR4) +#undef __SOLARIS__ +#define __SOLARIS__ 1 +#endif + +#if defined(WIN32) || defined(_WIN32) || defined(__CYGWIN__) || defined(__MINGW32__) +/* Try to find out if we're compiling for WinRT or non-WinRT */ +#if defined(_MSC_VER) && defined(__has_include) +#if __has_include() +#define HAVE_WINAPIFAMILY_H 1 +#else +#define HAVE_WINAPIFAMILY_H 0 +#endif + +/* If _USING_V110_SDK71_ is defined it means we are using the Windows XP toolset. */ +#elif defined(_MSC_VER) && (_MSC_VER >= 1700 && !_USING_V110_SDK71_) /* _MSC_VER == 1700 for Visual Studio 2012 */ +#define HAVE_WINAPIFAMILY_H 1 +#else +#define HAVE_WINAPIFAMILY_H 0 +#endif + +#if HAVE_WINAPIFAMILY_H +#include +#define WINAPI_FAMILY_WINRT (!WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) && WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP)) +#else +#define WINAPI_FAMILY_WINRT 0 +#endif /* HAVE_WINAPIFAMILY_H */ + +#if WINAPI_FAMILY_WINRT +#undef __WINRT__ +#define __WINRT__ 1 +#else +#undef __WINDOWS__ +#define __WINDOWS__ 1 +#endif +#endif /* defined(WIN32) || defined(_WIN32) || defined(__CYGWIN__) */ + +#if defined(__WINDOWS__) +#undef __WIN32__ +#define __WIN32__ 1 +#endif +#if defined(__PSP__) +#undef __PSP__ +#define __PSP__ 1 +#endif + +/* The NACL compiler defines __native_client__ and __pnacl__ + * Ref: http://www.chromium.org/nativeclient/pnacl/stability-of-the-pnacl-bitcode-abi + */ +#if defined(__native_client__) +#undef __LINUX__ +#undef __NACL__ +#define __NACL__ 1 +#endif +#if defined(__pnacl__) +#undef __LINUX__ +#undef __PNACL__ +#define __PNACL__ 1 +/* PNACL with newlib supports static linking only */ +#define __SDL_NOGETPROCADDR__ +#endif + + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief Gets the name of the platform. + */ +extern DECLSPEC const char * SDLCALL SDL_GetPlatform (void); + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_platform_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/engine/Windows/SDL2/include/SDL_power.h b/engine/Windows/SDL2/include/SDL_power.h new file mode 100644 index 0000000..4831cb7 --- /dev/null +++ b/engine/Windows/SDL2/include/SDL_power.h @@ -0,0 +1,75 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2019 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef SDL_power_h_ +#define SDL_power_h_ + +/** + * \file SDL_power.h + * + * Header for the SDL power management routines. + */ + +#include "SDL_stdinc.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief The basic state for the system's power supply. + */ +typedef enum +{ + SDL_POWERSTATE_UNKNOWN, /**< cannot determine power status */ + SDL_POWERSTATE_ON_BATTERY, /**< Not plugged in, running on the battery */ + SDL_POWERSTATE_NO_BATTERY, /**< Plugged in, no battery available */ + SDL_POWERSTATE_CHARGING, /**< Plugged in, charging battery */ + SDL_POWERSTATE_CHARGED /**< Plugged in, battery charged */ +} SDL_PowerState; + + +/** + * \brief Get the current power supply details. + * + * \param secs Seconds of battery life left. You can pass a NULL here if + * you don't care. Will return -1 if we can't determine a + * value, or we're not running on a battery. + * + * \param pct Percentage of battery life left, between 0 and 100. You can + * pass a NULL here if you don't care. Will return -1 if we + * can't determine a value, or we're not running on a battery. + * + * \return The state of the battery (if any). + */ +extern DECLSPEC SDL_PowerState SDLCALL SDL_GetPowerInfo(int *secs, int *pct); + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_power_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/engine/Windows/SDL2/include/SDL_quit.h b/engine/Windows/SDL2/include/SDL_quit.h new file mode 100644 index 0000000..c979983 --- /dev/null +++ b/engine/Windows/SDL2/include/SDL_quit.h @@ -0,0 +1,58 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2019 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_quit.h + * + * Include file for SDL quit event handling. + */ + +#ifndef SDL_quit_h_ +#define SDL_quit_h_ + +#include "SDL_stdinc.h" +#include "SDL_error.h" + +/** + * \file SDL_quit.h + * + * An ::SDL_QUIT event is generated when the user tries to close the application + * window. If it is ignored or filtered out, the window will remain open. + * If it is not ignored or filtered, it is queued normally and the window + * is allowed to close. When the window is closed, screen updates will + * complete, but have no effect. + * + * SDL_Init() installs signal handlers for SIGINT (keyboard interrupt) + * and SIGTERM (system termination request), if handlers do not already + * exist, that generate ::SDL_QUIT events as well. There is no way + * to determine the cause of an ::SDL_QUIT event, but setting a signal + * handler in your application will override the default generation of + * quit events for that signal. + * + * \sa SDL_Quit() + */ + +/* There are no functions directly affecting the quit event */ + +#define SDL_QuitRequested() \ + (SDL_PumpEvents(), (SDL_PeepEvents(NULL,0,SDL_PEEKEVENT,SDL_QUIT,SDL_QUIT) > 0)) + +#endif /* SDL_quit_h_ */ diff --git a/engine/Windows/SDL2/include/SDL_rect.h b/engine/Windows/SDL2/include/SDL_rect.h new file mode 100644 index 0000000..71a4115 --- /dev/null +++ b/engine/Windows/SDL2/include/SDL_rect.h @@ -0,0 +1,174 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2019 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_rect.h + * + * Header file for SDL_rect definition and management functions. + */ + +#ifndef SDL_rect_h_ +#define SDL_rect_h_ + +#include "SDL_stdinc.h" +#include "SDL_error.h" +#include "SDL_pixels.h" +#include "SDL_rwops.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief The structure that defines a point (integer) + * + * \sa SDL_EnclosePoints + * \sa SDL_PointInRect + */ +typedef struct SDL_Point +{ + int x; + int y; +} SDL_Point; + +/** + * \brief The structure that defines a point (floating point) + * + * \sa SDL_EnclosePoints + * \sa SDL_PointInRect + */ +typedef struct SDL_FPoint +{ + float x; + float y; +} SDL_FPoint; + + +/** + * \brief A rectangle, with the origin at the upper left (integer). + * + * \sa SDL_RectEmpty + * \sa SDL_RectEquals + * \sa SDL_HasIntersection + * \sa SDL_IntersectRect + * \sa SDL_UnionRect + * \sa SDL_EnclosePoints + */ +typedef struct SDL_Rect +{ + int x, y; + int w, h; +} SDL_Rect; + + +/** + * \brief A rectangle, with the origin at the upper left (floating point). + */ +typedef struct SDL_FRect +{ + float x; + float y; + float w; + float h; +} SDL_FRect; + + +/** + * \brief Returns true if point resides inside a rectangle. + */ +SDL_FORCE_INLINE SDL_bool SDL_PointInRect(const SDL_Point *p, const SDL_Rect *r) +{ + return ( (p->x >= r->x) && (p->x < (r->x + r->w)) && + (p->y >= r->y) && (p->y < (r->y + r->h)) ) ? SDL_TRUE : SDL_FALSE; +} + +/** + * \brief Returns true if the rectangle has no area. + */ +SDL_FORCE_INLINE SDL_bool SDL_RectEmpty(const SDL_Rect *r) +{ + return ((!r) || (r->w <= 0) || (r->h <= 0)) ? SDL_TRUE : SDL_FALSE; +} + +/** + * \brief Returns true if the two rectangles are equal. + */ +SDL_FORCE_INLINE SDL_bool SDL_RectEquals(const SDL_Rect *a, const SDL_Rect *b) +{ + return (a && b && (a->x == b->x) && (a->y == b->y) && + (a->w == b->w) && (a->h == b->h)) ? SDL_TRUE : SDL_FALSE; +} + +/** + * \brief Determine whether two rectangles intersect. + * + * \return SDL_TRUE if there is an intersection, SDL_FALSE otherwise. + */ +extern DECLSPEC SDL_bool SDLCALL SDL_HasIntersection(const SDL_Rect * A, + const SDL_Rect * B); + +/** + * \brief Calculate the intersection of two rectangles. + * + * \return SDL_TRUE if there is an intersection, SDL_FALSE otherwise. + */ +extern DECLSPEC SDL_bool SDLCALL SDL_IntersectRect(const SDL_Rect * A, + const SDL_Rect * B, + SDL_Rect * result); + +/** + * \brief Calculate the union of two rectangles. + */ +extern DECLSPEC void SDLCALL SDL_UnionRect(const SDL_Rect * A, + const SDL_Rect * B, + SDL_Rect * result); + +/** + * \brief Calculate a minimal rectangle enclosing a set of points + * + * \return SDL_TRUE if any points were within the clipping rect + */ +extern DECLSPEC SDL_bool SDLCALL SDL_EnclosePoints(const SDL_Point * points, + int count, + const SDL_Rect * clip, + SDL_Rect * result); + +/** + * \brief Calculate the intersection of a rectangle and line segment. + * + * \return SDL_TRUE if there is an intersection, SDL_FALSE otherwise. + */ +extern DECLSPEC SDL_bool SDLCALL SDL_IntersectRectAndLine(const SDL_Rect * + rect, int *X1, + int *Y1, int *X2, + int *Y2); + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_rect_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/engine/Windows/SDL2/include/SDL_render.h b/engine/Windows/SDL2/include/SDL_render.h new file mode 100644 index 0000000..c2a995a --- /dev/null +++ b/engine/Windows/SDL2/include/SDL_render.h @@ -0,0 +1,1119 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2019 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_render.h + * + * Header file for SDL 2D rendering functions. + * + * This API supports the following features: + * * single pixel points + * * single pixel lines + * * filled rectangles + * * texture images + * + * The primitives may be drawn in opaque, blended, or additive modes. + * + * The texture images may be drawn in opaque, blended, or additive modes. + * They can have an additional color tint or alpha modulation applied to + * them, and may also be stretched with linear interpolation. + * + * This API is designed to accelerate simple 2D operations. You may + * want more functionality such as polygons and particle effects and + * in that case you should use SDL's OpenGL/Direct3D support or one + * of the many good 3D engines. + * + * These functions must be called from the main thread. + * See this bug for details: http://bugzilla.libsdl.org/show_bug.cgi?id=1995 + */ + +#ifndef SDL_render_h_ +#define SDL_render_h_ + +#include "SDL_stdinc.h" +#include "SDL_rect.h" +#include "SDL_video.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief Flags used when creating a rendering context + */ +typedef enum +{ + SDL_RENDERER_SOFTWARE = 0x00000001, /**< The renderer is a software fallback */ + SDL_RENDERER_ACCELERATED = 0x00000002, /**< The renderer uses hardware + acceleration */ + SDL_RENDERER_PRESENTVSYNC = 0x00000004, /**< Present is synchronized + with the refresh rate */ + SDL_RENDERER_TARGETTEXTURE = 0x00000008 /**< The renderer supports + rendering to texture */ +} SDL_RendererFlags; + +/** + * \brief Information on the capabilities of a render driver or context. + */ +typedef struct SDL_RendererInfo +{ + const char *name; /**< The name of the renderer */ + Uint32 flags; /**< Supported ::SDL_RendererFlags */ + Uint32 num_texture_formats; /**< The number of available texture formats */ + Uint32 texture_formats[16]; /**< The available texture formats */ + int max_texture_width; /**< The maximum texture width */ + int max_texture_height; /**< The maximum texture height */ +} SDL_RendererInfo; + +/** + * \brief The access pattern allowed for a texture. + */ +typedef enum +{ + SDL_TEXTUREACCESS_STATIC, /**< Changes rarely, not lockable */ + SDL_TEXTUREACCESS_STREAMING, /**< Changes frequently, lockable */ + SDL_TEXTUREACCESS_TARGET /**< Texture can be used as a render target */ +} SDL_TextureAccess; + +/** + * \brief The texture channel modulation used in SDL_RenderCopy(). + */ +typedef enum +{ + SDL_TEXTUREMODULATE_NONE = 0x00000000, /**< No modulation */ + SDL_TEXTUREMODULATE_COLOR = 0x00000001, /**< srcC = srcC * color */ + SDL_TEXTUREMODULATE_ALPHA = 0x00000002 /**< srcA = srcA * alpha */ +} SDL_TextureModulate; + +/** + * \brief Flip constants for SDL_RenderCopyEx + */ +typedef enum +{ + SDL_FLIP_NONE = 0x00000000, /**< Do not flip */ + SDL_FLIP_HORIZONTAL = 0x00000001, /**< flip horizontally */ + SDL_FLIP_VERTICAL = 0x00000002 /**< flip vertically */ +} SDL_RendererFlip; + +/** + * \brief A structure representing rendering state + */ +struct SDL_Renderer; +typedef struct SDL_Renderer SDL_Renderer; + +/** + * \brief An efficient driver-specific representation of pixel data + */ +struct SDL_Texture; +typedef struct SDL_Texture SDL_Texture; + + +/* Function prototypes */ + +/** + * \brief Get the number of 2D rendering drivers available for the current + * display. + * + * A render driver is a set of code that handles rendering and texture + * management on a particular display. Normally there is only one, but + * some drivers may have several available with different capabilities. + * + * \sa SDL_GetRenderDriverInfo() + * \sa SDL_CreateRenderer() + */ +extern DECLSPEC int SDLCALL SDL_GetNumRenderDrivers(void); + +/** + * \brief Get information about a specific 2D rendering driver for the current + * display. + * + * \param index The index of the driver to query information about. + * \param info A pointer to an SDL_RendererInfo struct to be filled with + * information on the rendering driver. + * + * \return 0 on success, -1 if the index was out of range. + * + * \sa SDL_CreateRenderer() + */ +extern DECLSPEC int SDLCALL SDL_GetRenderDriverInfo(int index, + SDL_RendererInfo * info); + +/** + * \brief Create a window and default renderer + * + * \param width The width of the window + * \param height The height of the window + * \param window_flags The flags used to create the window + * \param window A pointer filled with the window, or NULL on error + * \param renderer A pointer filled with the renderer, or NULL on error + * + * \return 0 on success, or -1 on error + */ +extern DECLSPEC int SDLCALL SDL_CreateWindowAndRenderer( + int width, int height, Uint32 window_flags, + SDL_Window **window, SDL_Renderer **renderer); + + +/** + * \brief Create a 2D rendering context for a window. + * + * \param window The window where rendering is displayed. + * \param index The index of the rendering driver to initialize, or -1 to + * initialize the first one supporting the requested flags. + * \param flags ::SDL_RendererFlags. + * + * \return A valid rendering context or NULL if there was an error. + * + * \sa SDL_CreateSoftwareRenderer() + * \sa SDL_GetRendererInfo() + * \sa SDL_DestroyRenderer() + */ +extern DECLSPEC SDL_Renderer * SDLCALL SDL_CreateRenderer(SDL_Window * window, + int index, Uint32 flags); + +/** + * \brief Create a 2D software rendering context for a surface. + * + * \param surface The surface where rendering is done. + * + * \return A valid rendering context or NULL if there was an error. + * + * \sa SDL_CreateRenderer() + * \sa SDL_DestroyRenderer() + */ +extern DECLSPEC SDL_Renderer * SDLCALL SDL_CreateSoftwareRenderer(SDL_Surface * surface); + +/** + * \brief Get the renderer associated with a window. + */ +extern DECLSPEC SDL_Renderer * SDLCALL SDL_GetRenderer(SDL_Window * window); + +/** + * \brief Get information about a rendering context. + */ +extern DECLSPEC int SDLCALL SDL_GetRendererInfo(SDL_Renderer * renderer, + SDL_RendererInfo * info); + +/** + * \brief Get the output size in pixels of a rendering context. + */ +extern DECLSPEC int SDLCALL SDL_GetRendererOutputSize(SDL_Renderer * renderer, + int *w, int *h); + +/** + * \brief Create a texture for a rendering context. + * + * \param renderer The renderer. + * \param format The format of the texture. + * \param access One of the enumerated values in ::SDL_TextureAccess. + * \param w The width of the texture in pixels. + * \param h The height of the texture in pixels. + * + * \return The created texture is returned, or NULL if no rendering context was + * active, the format was unsupported, or the width or height were out + * of range. + * + * \note The contents of the texture are not defined at creation. + * + * \sa SDL_QueryTexture() + * \sa SDL_UpdateTexture() + * \sa SDL_DestroyTexture() + */ +extern DECLSPEC SDL_Texture * SDLCALL SDL_CreateTexture(SDL_Renderer * renderer, + Uint32 format, + int access, int w, + int h); + +/** + * \brief Create a texture from an existing surface. + * + * \param renderer The renderer. + * \param surface The surface containing pixel data used to fill the texture. + * + * \return The created texture is returned, or NULL on error. + * + * \note The surface is not modified or freed by this function. + * + * \sa SDL_QueryTexture() + * \sa SDL_DestroyTexture() + */ +extern DECLSPEC SDL_Texture * SDLCALL SDL_CreateTextureFromSurface(SDL_Renderer * renderer, SDL_Surface * surface); + +/** + * \brief Query the attributes of a texture + * + * \param texture A texture to be queried. + * \param format A pointer filled in with the raw format of the texture. The + * actual format may differ, but pixel transfers will use this + * format. + * \param access A pointer filled in with the actual access to the texture. + * \param w A pointer filled in with the width of the texture in pixels. + * \param h A pointer filled in with the height of the texture in pixels. + * + * \return 0 on success, or -1 if the texture is not valid. + */ +extern DECLSPEC int SDLCALL SDL_QueryTexture(SDL_Texture * texture, + Uint32 * format, int *access, + int *w, int *h); + +/** + * \brief Set an additional color value used in render copy operations. + * + * \param texture The texture to update. + * \param r The red color value multiplied into copy operations. + * \param g The green color value multiplied into copy operations. + * \param b The blue color value multiplied into copy operations. + * + * \return 0 on success, or -1 if the texture is not valid or color modulation + * is not supported. + * + * \sa SDL_GetTextureColorMod() + */ +extern DECLSPEC int SDLCALL SDL_SetTextureColorMod(SDL_Texture * texture, + Uint8 r, Uint8 g, Uint8 b); + + +/** + * \brief Get the additional color value used in render copy operations. + * + * \param texture The texture to query. + * \param r A pointer filled in with the current red color value. + * \param g A pointer filled in with the current green color value. + * \param b A pointer filled in with the current blue color value. + * + * \return 0 on success, or -1 if the texture is not valid. + * + * \sa SDL_SetTextureColorMod() + */ +extern DECLSPEC int SDLCALL SDL_GetTextureColorMod(SDL_Texture * texture, + Uint8 * r, Uint8 * g, + Uint8 * b); + +/** + * \brief Set an additional alpha value used in render copy operations. + * + * \param texture The texture to update. + * \param alpha The alpha value multiplied into copy operations. + * + * \return 0 on success, or -1 if the texture is not valid or alpha modulation + * is not supported. + * + * \sa SDL_GetTextureAlphaMod() + */ +extern DECLSPEC int SDLCALL SDL_SetTextureAlphaMod(SDL_Texture * texture, + Uint8 alpha); + +/** + * \brief Get the additional alpha value used in render copy operations. + * + * \param texture The texture to query. + * \param alpha A pointer filled in with the current alpha value. + * + * \return 0 on success, or -1 if the texture is not valid. + * + * \sa SDL_SetTextureAlphaMod() + */ +extern DECLSPEC int SDLCALL SDL_GetTextureAlphaMod(SDL_Texture * texture, + Uint8 * alpha); + +/** + * \brief Set the blend mode used for texture copy operations. + * + * \param texture The texture to update. + * \param blendMode ::SDL_BlendMode to use for texture blending. + * + * \return 0 on success, or -1 if the texture is not valid or the blend mode is + * not supported. + * + * \note If the blend mode is not supported, the closest supported mode is + * chosen. + * + * \sa SDL_GetTextureBlendMode() + */ +extern DECLSPEC int SDLCALL SDL_SetTextureBlendMode(SDL_Texture * texture, + SDL_BlendMode blendMode); + +/** + * \brief Get the blend mode used for texture copy operations. + * + * \param texture The texture to query. + * \param blendMode A pointer filled in with the current blend mode. + * + * \return 0 on success, or -1 if the texture is not valid. + * + * \sa SDL_SetTextureBlendMode() + */ +extern DECLSPEC int SDLCALL SDL_GetTextureBlendMode(SDL_Texture * texture, + SDL_BlendMode *blendMode); + +/** + * \brief Update the given texture rectangle with new pixel data. + * + * \param texture The texture to update + * \param rect A pointer to the rectangle of pixels to update, or NULL to + * update the entire texture. + * \param pixels The raw pixel data in the format of the texture. + * \param pitch The number of bytes in a row of pixel data, including padding between lines. + * + * The pixel data must be in the format of the texture. The pixel format can be + * queried with SDL_QueryTexture. + * + * \return 0 on success, or -1 if the texture is not valid. + * + * \note This is a fairly slow function. + */ +extern DECLSPEC int SDLCALL SDL_UpdateTexture(SDL_Texture * texture, + const SDL_Rect * rect, + const void *pixels, int pitch); + +/** + * \brief Update a rectangle within a planar YV12 or IYUV texture with new pixel data. + * + * \param texture The texture to update + * \param rect A pointer to the rectangle of pixels to update, or NULL to + * update the entire texture. + * \param Yplane The raw pixel data for the Y plane. + * \param Ypitch The number of bytes between rows of pixel data for the Y plane. + * \param Uplane The raw pixel data for the U plane. + * \param Upitch The number of bytes between rows of pixel data for the U plane. + * \param Vplane The raw pixel data for the V plane. + * \param Vpitch The number of bytes between rows of pixel data for the V plane. + * + * \return 0 on success, or -1 if the texture is not valid. + * + * \note You can use SDL_UpdateTexture() as long as your pixel data is + * a contiguous block of Y and U/V planes in the proper order, but + * this function is available if your pixel data is not contiguous. + */ +extern DECLSPEC int SDLCALL SDL_UpdateYUVTexture(SDL_Texture * texture, + const SDL_Rect * rect, + const Uint8 *Yplane, int Ypitch, + const Uint8 *Uplane, int Upitch, + const Uint8 *Vplane, int Vpitch); + +/** + * \brief Lock a portion of the texture for write-only pixel access. + * + * \param texture The texture to lock for access, which was created with + * ::SDL_TEXTUREACCESS_STREAMING. + * \param rect A pointer to the rectangle to lock for access. If the rect + * is NULL, the entire texture will be locked. + * \param pixels This is filled in with a pointer to the locked pixels, + * appropriately offset by the locked area. + * \param pitch This is filled in with the pitch of the locked pixels. + * + * \return 0 on success, or -1 if the texture is not valid or was not created with ::SDL_TEXTUREACCESS_STREAMING. + * + * \sa SDL_UnlockTexture() + */ +extern DECLSPEC int SDLCALL SDL_LockTexture(SDL_Texture * texture, + const SDL_Rect * rect, + void **pixels, int *pitch); + +/** + * \brief Lock a portion of the texture for write-only pixel access. + * Expose it as a SDL surface. + * + * \param texture The texture to lock for access, which was created with + * ::SDL_TEXTUREACCESS_STREAMING. + * \param rect A pointer to the rectangle to lock for access. If the rect + * is NULL, the entire texture will be locked. + * \param surface This is filled in with a SDL surface representing the locked area + * Surface is freed internally after calling SDL_UnlockTexture or SDL_DestroyTexture. + * + * \return 0 on success, or -1 if the texture is not valid or was not created with ::SDL_TEXTUREACCESS_STREAMING. + * + * \sa SDL_UnlockTexture() + */ +extern DECLSPEC int SDLCALL SDL_LockTextureToSurface(SDL_Texture *texture, + const SDL_Rect *rect, + SDL_Surface **surface); + +/** + * \brief Unlock a texture, uploading the changes to video memory, if needed. + * If SDL_LockTextureToSurface() was called for locking, the SDL surface is freed. + * + * \sa SDL_LockTexture() + * \sa SDL_LockTextureToSurface() + */ +extern DECLSPEC void SDLCALL SDL_UnlockTexture(SDL_Texture * texture); + +/** + * \brief Determines whether a window supports the use of render targets + * + * \param renderer The renderer that will be checked + * + * \return SDL_TRUE if supported, SDL_FALSE if not. + */ +extern DECLSPEC SDL_bool SDLCALL SDL_RenderTargetSupported(SDL_Renderer *renderer); + +/** + * \brief Set a texture as the current rendering target. + * + * \param renderer The renderer. + * \param texture The targeted texture, which must be created with the SDL_TEXTUREACCESS_TARGET flag, or NULL for the default render target + * + * \return 0 on success, or -1 on error + * + * \sa SDL_GetRenderTarget() + */ +extern DECLSPEC int SDLCALL SDL_SetRenderTarget(SDL_Renderer *renderer, + SDL_Texture *texture); + +/** + * \brief Get the current render target or NULL for the default render target. + * + * \return The current render target + * + * \sa SDL_SetRenderTarget() + */ +extern DECLSPEC SDL_Texture * SDLCALL SDL_GetRenderTarget(SDL_Renderer *renderer); + +/** + * \brief Set device independent resolution for rendering + * + * \param renderer The renderer for which resolution should be set. + * \param w The width of the logical resolution + * \param h The height of the logical resolution + * + * This function uses the viewport and scaling functionality to allow a fixed logical + * resolution for rendering, regardless of the actual output resolution. If the actual + * output resolution doesn't have the same aspect ratio the output rendering will be + * centered within the output display. + * + * If the output display is a window, mouse events in the window will be filtered + * and scaled so they seem to arrive within the logical resolution. + * + * \note If this function results in scaling or subpixel drawing by the + * rendering backend, it will be handled using the appropriate + * quality hints. + * + * \sa SDL_RenderGetLogicalSize() + * \sa SDL_RenderSetScale() + * \sa SDL_RenderSetViewport() + */ +extern DECLSPEC int SDLCALL SDL_RenderSetLogicalSize(SDL_Renderer * renderer, int w, int h); + +/** + * \brief Get device independent resolution for rendering + * + * \param renderer The renderer from which resolution should be queried. + * \param w A pointer filled with the width of the logical resolution + * \param h A pointer filled with the height of the logical resolution + * + * \sa SDL_RenderSetLogicalSize() + */ +extern DECLSPEC void SDLCALL SDL_RenderGetLogicalSize(SDL_Renderer * renderer, int *w, int *h); + +/** + * \brief Set whether to force integer scales for resolution-independent rendering + * + * \param renderer The renderer for which integer scaling should be set. + * \param enable Enable or disable integer scaling + * + * This function restricts the logical viewport to integer values - that is, when + * a resolution is between two multiples of a logical size, the viewport size is + * rounded down to the lower multiple. + * + * \sa SDL_RenderSetLogicalSize() + */ +extern DECLSPEC int SDLCALL SDL_RenderSetIntegerScale(SDL_Renderer * renderer, + SDL_bool enable); + +/** + * \brief Get whether integer scales are forced for resolution-independent rendering + * + * \param renderer The renderer from which integer scaling should be queried. + * + * \sa SDL_RenderSetIntegerScale() + */ +extern DECLSPEC SDL_bool SDLCALL SDL_RenderGetIntegerScale(SDL_Renderer * renderer); + +/** + * \brief Set the drawing area for rendering on the current target. + * + * \param renderer The renderer for which the drawing area should be set. + * \param rect The rectangle representing the drawing area, or NULL to set the viewport to the entire target. + * + * The x,y of the viewport rect represents the origin for rendering. + * + * \return 0 on success, or -1 on error + * + * \note If the window associated with the renderer is resized, the viewport is automatically reset. + * + * \sa SDL_RenderGetViewport() + * \sa SDL_RenderSetLogicalSize() + */ +extern DECLSPEC int SDLCALL SDL_RenderSetViewport(SDL_Renderer * renderer, + const SDL_Rect * rect); + +/** + * \brief Get the drawing area for the current target. + * + * \sa SDL_RenderSetViewport() + */ +extern DECLSPEC void SDLCALL SDL_RenderGetViewport(SDL_Renderer * renderer, + SDL_Rect * rect); + +/** + * \brief Set the clip rectangle for the current target. + * + * \param renderer The renderer for which clip rectangle should be set. + * \param rect A pointer to the rectangle to set as the clip rectangle, or + * NULL to disable clipping. + * + * \return 0 on success, or -1 on error + * + * \sa SDL_RenderGetClipRect() + */ +extern DECLSPEC int SDLCALL SDL_RenderSetClipRect(SDL_Renderer * renderer, + const SDL_Rect * rect); + +/** + * \brief Get the clip rectangle for the current target. + * + * \param renderer The renderer from which clip rectangle should be queried. + * \param rect A pointer filled in with the current clip rectangle, or + * an empty rectangle if clipping is disabled. + * + * \sa SDL_RenderSetClipRect() + */ +extern DECLSPEC void SDLCALL SDL_RenderGetClipRect(SDL_Renderer * renderer, + SDL_Rect * rect); + +/** + * \brief Get whether clipping is enabled on the given renderer. + * + * \param renderer The renderer from which clip state should be queried. + * + * \sa SDL_RenderGetClipRect() + */ +extern DECLSPEC SDL_bool SDLCALL SDL_RenderIsClipEnabled(SDL_Renderer * renderer); + + +/** + * \brief Set the drawing scale for rendering on the current target. + * + * \param renderer The renderer for which the drawing scale should be set. + * \param scaleX The horizontal scaling factor + * \param scaleY The vertical scaling factor + * + * The drawing coordinates are scaled by the x/y scaling factors + * before they are used by the renderer. This allows resolution + * independent drawing with a single coordinate system. + * + * \note If this results in scaling or subpixel drawing by the + * rendering backend, it will be handled using the appropriate + * quality hints. For best results use integer scaling factors. + * + * \sa SDL_RenderGetScale() + * \sa SDL_RenderSetLogicalSize() + */ +extern DECLSPEC int SDLCALL SDL_RenderSetScale(SDL_Renderer * renderer, + float scaleX, float scaleY); + +/** + * \brief Get the drawing scale for the current target. + * + * \param renderer The renderer from which drawing scale should be queried. + * \param scaleX A pointer filled in with the horizontal scaling factor + * \param scaleY A pointer filled in with the vertical scaling factor + * + * \sa SDL_RenderSetScale() + */ +extern DECLSPEC void SDLCALL SDL_RenderGetScale(SDL_Renderer * renderer, + float *scaleX, float *scaleY); + +/** + * \brief Set the color used for drawing operations (Rect, Line and Clear). + * + * \param renderer The renderer for which drawing color should be set. + * \param r The red value used to draw on the rendering target. + * \param g The green value used to draw on the rendering target. + * \param b The blue value used to draw on the rendering target. + * \param a The alpha value used to draw on the rendering target, usually + * ::SDL_ALPHA_OPAQUE (255). + * + * \return 0 on success, or -1 on error + */ +extern DECLSPEC int SDLCALL SDL_SetRenderDrawColor(SDL_Renderer * renderer, + Uint8 r, Uint8 g, Uint8 b, + Uint8 a); + +/** + * \brief Get the color used for drawing operations (Rect, Line and Clear). + * + * \param renderer The renderer from which drawing color should be queried. + * \param r A pointer to the red value used to draw on the rendering target. + * \param g A pointer to the green value used to draw on the rendering target. + * \param b A pointer to the blue value used to draw on the rendering target. + * \param a A pointer to the alpha value used to draw on the rendering target, + * usually ::SDL_ALPHA_OPAQUE (255). + * + * \return 0 on success, or -1 on error + */ +extern DECLSPEC int SDLCALL SDL_GetRenderDrawColor(SDL_Renderer * renderer, + Uint8 * r, Uint8 * g, Uint8 * b, + Uint8 * a); + +/** + * \brief Set the blend mode used for drawing operations (Fill and Line). + * + * \param renderer The renderer for which blend mode should be set. + * \param blendMode ::SDL_BlendMode to use for blending. + * + * \return 0 on success, or -1 on error + * + * \note If the blend mode is not supported, the closest supported mode is + * chosen. + * + * \sa SDL_GetRenderDrawBlendMode() + */ +extern DECLSPEC int SDLCALL SDL_SetRenderDrawBlendMode(SDL_Renderer * renderer, + SDL_BlendMode blendMode); + +/** + * \brief Get the blend mode used for drawing operations. + * + * \param renderer The renderer from which blend mode should be queried. + * \param blendMode A pointer filled in with the current blend mode. + * + * \return 0 on success, or -1 on error + * + * \sa SDL_SetRenderDrawBlendMode() + */ +extern DECLSPEC int SDLCALL SDL_GetRenderDrawBlendMode(SDL_Renderer * renderer, + SDL_BlendMode *blendMode); + +/** + * \brief Clear the current rendering target with the drawing color + * + * This function clears the entire rendering target, ignoring the viewport and + * the clip rectangle. + * + * \return 0 on success, or -1 on error + */ +extern DECLSPEC int SDLCALL SDL_RenderClear(SDL_Renderer * renderer); + +/** + * \brief Draw a point on the current rendering target. + * + * \param renderer The renderer which should draw a point. + * \param x The x coordinate of the point. + * \param y The y coordinate of the point. + * + * \return 0 on success, or -1 on error + */ +extern DECLSPEC int SDLCALL SDL_RenderDrawPoint(SDL_Renderer * renderer, + int x, int y); + +/** + * \brief Draw multiple points on the current rendering target. + * + * \param renderer The renderer which should draw multiple points. + * \param points The points to draw + * \param count The number of points to draw + * + * \return 0 on success, or -1 on error + */ +extern DECLSPEC int SDLCALL SDL_RenderDrawPoints(SDL_Renderer * renderer, + const SDL_Point * points, + int count); + +/** + * \brief Draw a line on the current rendering target. + * + * \param renderer The renderer which should draw a line. + * \param x1 The x coordinate of the start point. + * \param y1 The y coordinate of the start point. + * \param x2 The x coordinate of the end point. + * \param y2 The y coordinate of the end point. + * + * \return 0 on success, or -1 on error + */ +extern DECLSPEC int SDLCALL SDL_RenderDrawLine(SDL_Renderer * renderer, + int x1, int y1, int x2, int y2); + +/** + * \brief Draw a series of connected lines on the current rendering target. + * + * \param renderer The renderer which should draw multiple lines. + * \param points The points along the lines + * \param count The number of points, drawing count-1 lines + * + * \return 0 on success, or -1 on error + */ +extern DECLSPEC int SDLCALL SDL_RenderDrawLines(SDL_Renderer * renderer, + const SDL_Point * points, + int count); + +/** + * \brief Draw a rectangle on the current rendering target. + * + * \param renderer The renderer which should draw a rectangle. + * \param rect A pointer to the destination rectangle, or NULL to outline the entire rendering target. + * + * \return 0 on success, or -1 on error + */ +extern DECLSPEC int SDLCALL SDL_RenderDrawRect(SDL_Renderer * renderer, + const SDL_Rect * rect); + +/** + * \brief Draw some number of rectangles on the current rendering target. + * + * \param renderer The renderer which should draw multiple rectangles. + * \param rects A pointer to an array of destination rectangles. + * \param count The number of rectangles. + * + * \return 0 on success, or -1 on error + */ +extern DECLSPEC int SDLCALL SDL_RenderDrawRects(SDL_Renderer * renderer, + const SDL_Rect * rects, + int count); + +/** + * \brief Fill a rectangle on the current rendering target with the drawing color. + * + * \param renderer The renderer which should fill a rectangle. + * \param rect A pointer to the destination rectangle, or NULL for the entire + * rendering target. + * + * \return 0 on success, or -1 on error + */ +extern DECLSPEC int SDLCALL SDL_RenderFillRect(SDL_Renderer * renderer, + const SDL_Rect * rect); + +/** + * \brief Fill some number of rectangles on the current rendering target with the drawing color. + * + * \param renderer The renderer which should fill multiple rectangles. + * \param rects A pointer to an array of destination rectangles. + * \param count The number of rectangles. + * + * \return 0 on success, or -1 on error + */ +extern DECLSPEC int SDLCALL SDL_RenderFillRects(SDL_Renderer * renderer, + const SDL_Rect * rects, + int count); + +/** + * \brief Copy a portion of the texture to the current rendering target. + * + * \param renderer The renderer which should copy parts of a texture. + * \param texture The source texture. + * \param srcrect A pointer to the source rectangle, or NULL for the entire + * texture. + * \param dstrect A pointer to the destination rectangle, or NULL for the + * entire rendering target. + * + * \return 0 on success, or -1 on error + */ +extern DECLSPEC int SDLCALL SDL_RenderCopy(SDL_Renderer * renderer, + SDL_Texture * texture, + const SDL_Rect * srcrect, + const SDL_Rect * dstrect); + +/** + * \brief Copy a portion of the source texture to the current rendering target, rotating it by angle around the given center + * + * \param renderer The renderer which should copy parts of a texture. + * \param texture The source texture. + * \param srcrect A pointer to the source rectangle, or NULL for the entire + * texture. + * \param dstrect A pointer to the destination rectangle, or NULL for the + * entire rendering target. + * \param angle An angle in degrees that indicates the rotation that will be applied to dstrect, rotating it in a clockwise direction + * \param center A pointer to a point indicating the point around which dstrect will be rotated (if NULL, rotation will be done around dstrect.w/2, dstrect.h/2). + * \param flip An SDL_RendererFlip value stating which flipping actions should be performed on the texture + * + * \return 0 on success, or -1 on error + */ +extern DECLSPEC int SDLCALL SDL_RenderCopyEx(SDL_Renderer * renderer, + SDL_Texture * texture, + const SDL_Rect * srcrect, + const SDL_Rect * dstrect, + const double angle, + const SDL_Point *center, + const SDL_RendererFlip flip); + + +/** + * \brief Draw a point on the current rendering target. + * + * \param renderer The renderer which should draw a point. + * \param x The x coordinate of the point. + * \param y The y coordinate of the point. + * + * \return 0 on success, or -1 on error + */ +extern DECLSPEC int SDLCALL SDL_RenderDrawPointF(SDL_Renderer * renderer, + float x, float y); + +/** + * \brief Draw multiple points on the current rendering target. + * + * \param renderer The renderer which should draw multiple points. + * \param points The points to draw + * \param count The number of points to draw + * + * \return 0 on success, or -1 on error + */ +extern DECLSPEC int SDLCALL SDL_RenderDrawPointsF(SDL_Renderer * renderer, + const SDL_FPoint * points, + int count); + +/** + * \brief Draw a line on the current rendering target. + * + * \param renderer The renderer which should draw a line. + * \param x1 The x coordinate of the start point. + * \param y1 The y coordinate of the start point. + * \param x2 The x coordinate of the end point. + * \param y2 The y coordinate of the end point. + * + * \return 0 on success, or -1 on error + */ +extern DECLSPEC int SDLCALL SDL_RenderDrawLineF(SDL_Renderer * renderer, + float x1, float y1, float x2, float y2); + +/** + * \brief Draw a series of connected lines on the current rendering target. + * + * \param renderer The renderer which should draw multiple lines. + * \param points The points along the lines + * \param count The number of points, drawing count-1 lines + * + * \return 0 on success, or -1 on error + */ +extern DECLSPEC int SDLCALL SDL_RenderDrawLinesF(SDL_Renderer * renderer, + const SDL_FPoint * points, + int count); + +/** + * \brief Draw a rectangle on the current rendering target. + * + * \param renderer The renderer which should draw a rectangle. + * \param rect A pointer to the destination rectangle, or NULL to outline the entire rendering target. + * + * \return 0 on success, or -1 on error + */ +extern DECLSPEC int SDLCALL SDL_RenderDrawRectF(SDL_Renderer * renderer, + const SDL_FRect * rect); + +/** + * \brief Draw some number of rectangles on the current rendering target. + * + * \param renderer The renderer which should draw multiple rectangles. + * \param rects A pointer to an array of destination rectangles. + * \param count The number of rectangles. + * + * \return 0 on success, or -1 on error + */ +extern DECLSPEC int SDLCALL SDL_RenderDrawRectsF(SDL_Renderer * renderer, + const SDL_FRect * rects, + int count); + +/** + * \brief Fill a rectangle on the current rendering target with the drawing color. + * + * \param renderer The renderer which should fill a rectangle. + * \param rect A pointer to the destination rectangle, or NULL for the entire + * rendering target. + * + * \return 0 on success, or -1 on error + */ +extern DECLSPEC int SDLCALL SDL_RenderFillRectF(SDL_Renderer * renderer, + const SDL_FRect * rect); + +/** + * \brief Fill some number of rectangles on the current rendering target with the drawing color. + * + * \param renderer The renderer which should fill multiple rectangles. + * \param rects A pointer to an array of destination rectangles. + * \param count The number of rectangles. + * + * \return 0 on success, or -1 on error + */ +extern DECLSPEC int SDLCALL SDL_RenderFillRectsF(SDL_Renderer * renderer, + const SDL_FRect * rects, + int count); + +/** + * \brief Copy a portion of the texture to the current rendering target. + * + * \param renderer The renderer which should copy parts of a texture. + * \param texture The source texture. + * \param srcrect A pointer to the source rectangle, or NULL for the entire + * texture. + * \param dstrect A pointer to the destination rectangle, or NULL for the + * entire rendering target. + * + * \return 0 on success, or -1 on error + */ +extern DECLSPEC int SDLCALL SDL_RenderCopyF(SDL_Renderer * renderer, + SDL_Texture * texture, + const SDL_Rect * srcrect, + const SDL_FRect * dstrect); + +/** + * \brief Copy a portion of the source texture to the current rendering target, rotating it by angle around the given center + * + * \param renderer The renderer which should copy parts of a texture. + * \param texture The source texture. + * \param srcrect A pointer to the source rectangle, or NULL for the entire + * texture. + * \param dstrect A pointer to the destination rectangle, or NULL for the + * entire rendering target. + * \param angle An angle in degrees that indicates the rotation that will be applied to dstrect, rotating it in a clockwise direction + * \param center A pointer to a point indicating the point around which dstrect will be rotated (if NULL, rotation will be done around dstrect.w/2, dstrect.h/2). + * \param flip An SDL_RendererFlip value stating which flipping actions should be performed on the texture + * + * \return 0 on success, or -1 on error + */ +extern DECLSPEC int SDLCALL SDL_RenderCopyExF(SDL_Renderer * renderer, + SDL_Texture * texture, + const SDL_Rect * srcrect, + const SDL_FRect * dstrect, + const double angle, + const SDL_FPoint *center, + const SDL_RendererFlip flip); + +/** + * \brief Read pixels from the current rendering target. + * + * \param renderer The renderer from which pixels should be read. + * \param rect A pointer to the rectangle to read, or NULL for the entire + * render target. + * \param format The desired format of the pixel data, or 0 to use the format + * of the rendering target + * \param pixels A pointer to be filled in with the pixel data + * \param pitch The pitch of the pixels parameter. + * + * \return 0 on success, or -1 if pixel reading is not supported. + * + * \warning This is a very slow operation, and should not be used frequently. + */ +extern DECLSPEC int SDLCALL SDL_RenderReadPixels(SDL_Renderer * renderer, + const SDL_Rect * rect, + Uint32 format, + void *pixels, int pitch); + +/** + * \brief Update the screen with rendering performed. + */ +extern DECLSPEC void SDLCALL SDL_RenderPresent(SDL_Renderer * renderer); + +/** + * \brief Destroy the specified texture. + * + * \sa SDL_CreateTexture() + * \sa SDL_CreateTextureFromSurface() + */ +extern DECLSPEC void SDLCALL SDL_DestroyTexture(SDL_Texture * texture); + +/** + * \brief Destroy the rendering context for a window and free associated + * textures. + * + * \sa SDL_CreateRenderer() + */ +extern DECLSPEC void SDLCALL SDL_DestroyRenderer(SDL_Renderer * renderer); + +/** + * \brief Force the rendering context to flush any pending commands to the + * underlying rendering API. + * + * You do not need to (and in fact, shouldn't) call this function unless + * you are planning to call into OpenGL/Direct3D/Metal/whatever directly + * in addition to using an SDL_Renderer. + * + * This is for a very-specific case: if you are using SDL's render API, + * you asked for a specific renderer backend (OpenGL, Direct3D, etc), + * you set SDL_HINT_RENDER_BATCHING to "1", and you plan to make + * OpenGL/D3D/whatever calls in addition to SDL render API calls. If all of + * this applies, you should call SDL_RenderFlush() between calls to SDL's + * render API and the low-level API you're using in cooperation. + * + * In all other cases, you can ignore this function. This is only here to + * get maximum performance out of a specific situation. In all other cases, + * SDL will do the right thing, perhaps at a performance loss. + * + * This function is first available in SDL 2.0.10, and is not needed in + * 2.0.9 and earlier, as earlier versions did not queue rendering commands + * at all, instead flushing them to the OS immediately. + */ +extern DECLSPEC int SDLCALL SDL_RenderFlush(SDL_Renderer * renderer); + + +/** + * \brief Bind the texture to the current OpenGL/ES/ES2 context for use with + * OpenGL instructions. + * + * \param texture The SDL texture to bind + * \param texw A pointer to a float that will be filled with the texture width + * \param texh A pointer to a float that will be filled with the texture height + * + * \return 0 on success, or -1 if the operation is not supported + */ +extern DECLSPEC int SDLCALL SDL_GL_BindTexture(SDL_Texture *texture, float *texw, float *texh); + +/** + * \brief Unbind a texture from the current OpenGL/ES/ES2 context. + * + * \param texture The SDL texture to unbind + * + * \return 0 on success, or -1 if the operation is not supported + */ +extern DECLSPEC int SDLCALL SDL_GL_UnbindTexture(SDL_Texture *texture); + +/** + * \brief Get the CAMetalLayer associated with the given Metal renderer + * + * \param renderer The renderer to query + * + * \return CAMetalLayer* on success, or NULL if the renderer isn't a Metal renderer + * + * \sa SDL_RenderGetMetalCommandEncoder() + */ +extern DECLSPEC void *SDLCALL SDL_RenderGetMetalLayer(SDL_Renderer * renderer); + +/** + * \brief Get the Metal command encoder for the current frame + * + * \param renderer The renderer to query + * + * \return id on success, or NULL if the renderer isn't a Metal renderer + * + * \sa SDL_RenderGetMetalLayer() + */ +extern DECLSPEC void *SDLCALL SDL_RenderGetMetalCommandEncoder(SDL_Renderer * renderer); + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_render_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/engine/Windows/SDL2/include/SDL_revision.h b/engine/Windows/SDL2/include/SDL_revision.h new file mode 100644 index 0000000..4b9565d --- /dev/null +++ b/engine/Windows/SDL2/include/SDL_revision.h @@ -0,0 +1,2 @@ +#define SDL_REVISION "hg-13229:0b98870c7f72" +#define SDL_REVISION_NUMBER 13229 diff --git a/engine/Windows/SDL2/include/SDL_rwops.h b/engine/Windows/SDL2/include/SDL_rwops.h new file mode 100644 index 0000000..f66119f --- /dev/null +++ b/engine/Windows/SDL2/include/SDL_rwops.h @@ -0,0 +1,291 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2019 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_rwops.h + * + * This file provides a general interface for SDL to read and write + * data streams. It can easily be extended to files, memory, etc. + */ + +#ifndef SDL_rwops_h_ +#define SDL_rwops_h_ + +#include "SDL_stdinc.h" +#include "SDL_error.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/* RWops Types */ +#define SDL_RWOPS_UNKNOWN 0U /**< Unknown stream type */ +#define SDL_RWOPS_WINFILE 1U /**< Win32 file */ +#define SDL_RWOPS_STDFILE 2U /**< Stdio file */ +#define SDL_RWOPS_JNIFILE 3U /**< Android asset */ +#define SDL_RWOPS_MEMORY 4U /**< Memory stream */ +#define SDL_RWOPS_MEMORY_RO 5U /**< Read-Only memory stream */ + +/** + * This is the read/write operation structure -- very basic. + */ +typedef struct SDL_RWops +{ + /** + * Return the size of the file in this rwops, or -1 if unknown + */ + Sint64 (SDLCALL * size) (struct SDL_RWops * context); + + /** + * Seek to \c offset relative to \c whence, one of stdio's whence values: + * RW_SEEK_SET, RW_SEEK_CUR, RW_SEEK_END + * + * \return the final offset in the data stream, or -1 on error. + */ + Sint64 (SDLCALL * seek) (struct SDL_RWops * context, Sint64 offset, + int whence); + + /** + * Read up to \c maxnum objects each of size \c size from the data + * stream to the area pointed at by \c ptr. + * + * \return the number of objects read, or 0 at error or end of file. + */ + size_t (SDLCALL * read) (struct SDL_RWops * context, void *ptr, + size_t size, size_t maxnum); + + /** + * Write exactly \c num objects each of size \c size from the area + * pointed at by \c ptr to data stream. + * + * \return the number of objects written, or 0 at error or end of file. + */ + size_t (SDLCALL * write) (struct SDL_RWops * context, const void *ptr, + size_t size, size_t num); + + /** + * Close and free an allocated SDL_RWops structure. + * + * \return 0 if successful or -1 on write error when flushing data. + */ + int (SDLCALL * close) (struct SDL_RWops * context); + + Uint32 type; + union + { +#if defined(__ANDROID__) + struct + { + void *fileNameRef; + void *inputStreamRef; + void *readableByteChannelRef; + void *readMethod; + void *assetFileDescriptorRef; + long position; + long size; + long offset; + int fd; + } androidio; +#elif defined(__WIN32__) + struct + { + SDL_bool append; + void *h; + struct + { + void *data; + size_t size; + size_t left; + } buffer; + } windowsio; +#endif + +#ifdef HAVE_STDIO_H + struct + { + SDL_bool autoclose; + FILE *fp; + } stdio; +#endif + struct + { + Uint8 *base; + Uint8 *here; + Uint8 *stop; + } mem; + struct + { + void *data1; + void *data2; + } unknown; + } hidden; + +} SDL_RWops; + + +/** + * \name RWFrom functions + * + * Functions to create SDL_RWops structures from various data streams. + */ +/* @{ */ + +extern DECLSPEC SDL_RWops *SDLCALL SDL_RWFromFile(const char *file, + const char *mode); + +#ifdef HAVE_STDIO_H +extern DECLSPEC SDL_RWops *SDLCALL SDL_RWFromFP(FILE * fp, + SDL_bool autoclose); +#else +extern DECLSPEC SDL_RWops *SDLCALL SDL_RWFromFP(void * fp, + SDL_bool autoclose); +#endif + +extern DECLSPEC SDL_RWops *SDLCALL SDL_RWFromMem(void *mem, int size); +extern DECLSPEC SDL_RWops *SDLCALL SDL_RWFromConstMem(const void *mem, + int size); + +/* @} *//* RWFrom functions */ + + +extern DECLSPEC SDL_RWops *SDLCALL SDL_AllocRW(void); +extern DECLSPEC void SDLCALL SDL_FreeRW(SDL_RWops * area); + +#define RW_SEEK_SET 0 /**< Seek from the beginning of data */ +#define RW_SEEK_CUR 1 /**< Seek relative to current read point */ +#define RW_SEEK_END 2 /**< Seek relative to the end of data */ + +/** + * Return the size of the file in this rwops, or -1 if unknown + */ +extern DECLSPEC Sint64 SDLCALL SDL_RWsize(SDL_RWops *context); + +/** + * Seek to \c offset relative to \c whence, one of stdio's whence values: + * RW_SEEK_SET, RW_SEEK_CUR, RW_SEEK_END + * + * \return the final offset in the data stream, or -1 on error. + */ +extern DECLSPEC Sint64 SDLCALL SDL_RWseek(SDL_RWops *context, + Sint64 offset, int whence); + +/** + * Return the current offset in the data stream, or -1 on error. + */ +extern DECLSPEC Sint64 SDLCALL SDL_RWtell(SDL_RWops *context); + +/** + * Read up to \c maxnum objects each of size \c size from the data + * stream to the area pointed at by \c ptr. + * + * \return the number of objects read, or 0 at error or end of file. + */ +extern DECLSPEC size_t SDLCALL SDL_RWread(SDL_RWops *context, + void *ptr, size_t size, size_t maxnum); + +/** + * Write exactly \c num objects each of size \c size from the area + * pointed at by \c ptr to data stream. + * + * \return the number of objects written, or 0 at error or end of file. + */ +extern DECLSPEC size_t SDLCALL SDL_RWwrite(SDL_RWops *context, + const void *ptr, size_t size, size_t num); + +/** + * Close and free an allocated SDL_RWops structure. + * + * \return 0 if successful or -1 on write error when flushing data. + */ +extern DECLSPEC int SDLCALL SDL_RWclose(SDL_RWops *context); + +/** + * Load all the data from an SDL data stream. + * + * The data is allocated with a zero byte at the end (null terminated) + * + * If \c datasize is not NULL, it is filled with the size of the data read. + * + * If \c freesrc is non-zero, the stream will be closed after being read. + * + * The data should be freed with SDL_free(). + * + * \return the data, or NULL if there was an error. + */ +extern DECLSPEC void *SDLCALL SDL_LoadFile_RW(SDL_RWops * src, size_t *datasize, + int freesrc); + +/** + * Load an entire file. + * + * The data is allocated with a zero byte at the end (null terminated) + * + * If \c datasize is not NULL, it is filled with the size of the data read. + * + * If \c freesrc is non-zero, the stream will be closed after being read. + * + * The data should be freed with SDL_free(). + * + * \return the data, or NULL if there was an error. + */ +extern DECLSPEC void *SDLCALL SDL_LoadFile(const char *file, size_t *datasize); + +/** + * \name Read endian functions + * + * Read an item of the specified endianness and return in native format. + */ +/* @{ */ +extern DECLSPEC Uint8 SDLCALL SDL_ReadU8(SDL_RWops * src); +extern DECLSPEC Uint16 SDLCALL SDL_ReadLE16(SDL_RWops * src); +extern DECLSPEC Uint16 SDLCALL SDL_ReadBE16(SDL_RWops * src); +extern DECLSPEC Uint32 SDLCALL SDL_ReadLE32(SDL_RWops * src); +extern DECLSPEC Uint32 SDLCALL SDL_ReadBE32(SDL_RWops * src); +extern DECLSPEC Uint64 SDLCALL SDL_ReadLE64(SDL_RWops * src); +extern DECLSPEC Uint64 SDLCALL SDL_ReadBE64(SDL_RWops * src); +/* @} *//* Read endian functions */ + +/** + * \name Write endian functions + * + * Write an item of native format to the specified endianness. + */ +/* @{ */ +extern DECLSPEC size_t SDLCALL SDL_WriteU8(SDL_RWops * dst, Uint8 value); +extern DECLSPEC size_t SDLCALL SDL_WriteLE16(SDL_RWops * dst, Uint16 value); +extern DECLSPEC size_t SDLCALL SDL_WriteBE16(SDL_RWops * dst, Uint16 value); +extern DECLSPEC size_t SDLCALL SDL_WriteLE32(SDL_RWops * dst, Uint32 value); +extern DECLSPEC size_t SDLCALL SDL_WriteBE32(SDL_RWops * dst, Uint32 value); +extern DECLSPEC size_t SDLCALL SDL_WriteLE64(SDL_RWops * dst, Uint64 value); +extern DECLSPEC size_t SDLCALL SDL_WriteBE64(SDL_RWops * dst, Uint64 value); +/* @} *//* Write endian functions */ + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_rwops_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/engine/Windows/SDL2/include/SDL_scancode.h b/engine/Windows/SDL2/include/SDL_scancode.h new file mode 100644 index 0000000..a50305f --- /dev/null +++ b/engine/Windows/SDL2/include/SDL_scancode.h @@ -0,0 +1,413 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2019 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_scancode.h + * + * Defines keyboard scancodes. + */ + +#ifndef SDL_scancode_h_ +#define SDL_scancode_h_ + +#include "SDL_stdinc.h" + +/** + * \brief The SDL keyboard scancode representation. + * + * Values of this type are used to represent keyboard keys, among other places + * in the \link SDL_Keysym::scancode key.keysym.scancode \endlink field of the + * SDL_Event structure. + * + * The values in this enumeration are based on the USB usage page standard: + * https://www.usb.org/sites/default/files/documents/hut1_12v2.pdf + */ +typedef enum +{ + SDL_SCANCODE_UNKNOWN = 0, + + /** + * \name Usage page 0x07 + * + * These values are from usage page 0x07 (USB keyboard page). + */ + /* @{ */ + + SDL_SCANCODE_A = 4, + SDL_SCANCODE_B = 5, + SDL_SCANCODE_C = 6, + SDL_SCANCODE_D = 7, + SDL_SCANCODE_E = 8, + SDL_SCANCODE_F = 9, + SDL_SCANCODE_G = 10, + SDL_SCANCODE_H = 11, + SDL_SCANCODE_I = 12, + SDL_SCANCODE_J = 13, + SDL_SCANCODE_K = 14, + SDL_SCANCODE_L = 15, + SDL_SCANCODE_M = 16, + SDL_SCANCODE_N = 17, + SDL_SCANCODE_O = 18, + SDL_SCANCODE_P = 19, + SDL_SCANCODE_Q = 20, + SDL_SCANCODE_R = 21, + SDL_SCANCODE_S = 22, + SDL_SCANCODE_T = 23, + SDL_SCANCODE_U = 24, + SDL_SCANCODE_V = 25, + SDL_SCANCODE_W = 26, + SDL_SCANCODE_X = 27, + SDL_SCANCODE_Y = 28, + SDL_SCANCODE_Z = 29, + + SDL_SCANCODE_1 = 30, + SDL_SCANCODE_2 = 31, + SDL_SCANCODE_3 = 32, + SDL_SCANCODE_4 = 33, + SDL_SCANCODE_5 = 34, + SDL_SCANCODE_6 = 35, + SDL_SCANCODE_7 = 36, + SDL_SCANCODE_8 = 37, + SDL_SCANCODE_9 = 38, + SDL_SCANCODE_0 = 39, + + SDL_SCANCODE_RETURN = 40, + SDL_SCANCODE_ESCAPE = 41, + SDL_SCANCODE_BACKSPACE = 42, + SDL_SCANCODE_TAB = 43, + SDL_SCANCODE_SPACE = 44, + + SDL_SCANCODE_MINUS = 45, + SDL_SCANCODE_EQUALS = 46, + SDL_SCANCODE_LEFTBRACKET = 47, + SDL_SCANCODE_RIGHTBRACKET = 48, + SDL_SCANCODE_BACKSLASH = 49, /**< Located at the lower left of the return + * key on ISO keyboards and at the right end + * of the QWERTY row on ANSI keyboards. + * Produces REVERSE SOLIDUS (backslash) and + * VERTICAL LINE in a US layout, REVERSE + * SOLIDUS and VERTICAL LINE in a UK Mac + * layout, NUMBER SIGN and TILDE in a UK + * Windows layout, DOLLAR SIGN and POUND SIGN + * in a Swiss German layout, NUMBER SIGN and + * APOSTROPHE in a German layout, GRAVE + * ACCENT and POUND SIGN in a French Mac + * layout, and ASTERISK and MICRO SIGN in a + * French Windows layout. + */ + SDL_SCANCODE_NONUSHASH = 50, /**< ISO USB keyboards actually use this code + * instead of 49 for the same key, but all + * OSes I've seen treat the two codes + * identically. So, as an implementor, unless + * your keyboard generates both of those + * codes and your OS treats them differently, + * you should generate SDL_SCANCODE_BACKSLASH + * instead of this code. As a user, you + * should not rely on this code because SDL + * will never generate it with most (all?) + * keyboards. + */ + SDL_SCANCODE_SEMICOLON = 51, + SDL_SCANCODE_APOSTROPHE = 52, + SDL_SCANCODE_GRAVE = 53, /**< Located in the top left corner (on both ANSI + * and ISO keyboards). Produces GRAVE ACCENT and + * TILDE in a US Windows layout and in US and UK + * Mac layouts on ANSI keyboards, GRAVE ACCENT + * and NOT SIGN in a UK Windows layout, SECTION + * SIGN and PLUS-MINUS SIGN in US and UK Mac + * layouts on ISO keyboards, SECTION SIGN and + * DEGREE SIGN in a Swiss German layout (Mac: + * only on ISO keyboards), CIRCUMFLEX ACCENT and + * DEGREE SIGN in a German layout (Mac: only on + * ISO keyboards), SUPERSCRIPT TWO and TILDE in a + * French Windows layout, COMMERCIAL AT and + * NUMBER SIGN in a French Mac layout on ISO + * keyboards, and LESS-THAN SIGN and GREATER-THAN + * SIGN in a Swiss German, German, or French Mac + * layout on ANSI keyboards. + */ + SDL_SCANCODE_COMMA = 54, + SDL_SCANCODE_PERIOD = 55, + SDL_SCANCODE_SLASH = 56, + + SDL_SCANCODE_CAPSLOCK = 57, + + SDL_SCANCODE_F1 = 58, + SDL_SCANCODE_F2 = 59, + SDL_SCANCODE_F3 = 60, + SDL_SCANCODE_F4 = 61, + SDL_SCANCODE_F5 = 62, + SDL_SCANCODE_F6 = 63, + SDL_SCANCODE_F7 = 64, + SDL_SCANCODE_F8 = 65, + SDL_SCANCODE_F9 = 66, + SDL_SCANCODE_F10 = 67, + SDL_SCANCODE_F11 = 68, + SDL_SCANCODE_F12 = 69, + + SDL_SCANCODE_PRINTSCREEN = 70, + SDL_SCANCODE_SCROLLLOCK = 71, + SDL_SCANCODE_PAUSE = 72, + SDL_SCANCODE_INSERT = 73, /**< insert on PC, help on some Mac keyboards (but + does send code 73, not 117) */ + SDL_SCANCODE_HOME = 74, + SDL_SCANCODE_PAGEUP = 75, + SDL_SCANCODE_DELETE = 76, + SDL_SCANCODE_END = 77, + SDL_SCANCODE_PAGEDOWN = 78, + SDL_SCANCODE_RIGHT = 79, + SDL_SCANCODE_LEFT = 80, + SDL_SCANCODE_DOWN = 81, + SDL_SCANCODE_UP = 82, + + SDL_SCANCODE_NUMLOCKCLEAR = 83, /**< num lock on PC, clear on Mac keyboards + */ + SDL_SCANCODE_KP_DIVIDE = 84, + SDL_SCANCODE_KP_MULTIPLY = 85, + SDL_SCANCODE_KP_MINUS = 86, + SDL_SCANCODE_KP_PLUS = 87, + SDL_SCANCODE_KP_ENTER = 88, + SDL_SCANCODE_KP_1 = 89, + SDL_SCANCODE_KP_2 = 90, + SDL_SCANCODE_KP_3 = 91, + SDL_SCANCODE_KP_4 = 92, + SDL_SCANCODE_KP_5 = 93, + SDL_SCANCODE_KP_6 = 94, + SDL_SCANCODE_KP_7 = 95, + SDL_SCANCODE_KP_8 = 96, + SDL_SCANCODE_KP_9 = 97, + SDL_SCANCODE_KP_0 = 98, + SDL_SCANCODE_KP_PERIOD = 99, + + SDL_SCANCODE_NONUSBACKSLASH = 100, /**< This is the additional key that ISO + * keyboards have over ANSI ones, + * located between left shift and Y. + * Produces GRAVE ACCENT and TILDE in a + * US or UK Mac layout, REVERSE SOLIDUS + * (backslash) and VERTICAL LINE in a + * US or UK Windows layout, and + * LESS-THAN SIGN and GREATER-THAN SIGN + * in a Swiss German, German, or French + * layout. */ + SDL_SCANCODE_APPLICATION = 101, /**< windows contextual menu, compose */ + SDL_SCANCODE_POWER = 102, /**< The USB document says this is a status flag, + * not a physical key - but some Mac keyboards + * do have a power key. */ + SDL_SCANCODE_KP_EQUALS = 103, + SDL_SCANCODE_F13 = 104, + SDL_SCANCODE_F14 = 105, + SDL_SCANCODE_F15 = 106, + SDL_SCANCODE_F16 = 107, + SDL_SCANCODE_F17 = 108, + SDL_SCANCODE_F18 = 109, + SDL_SCANCODE_F19 = 110, + SDL_SCANCODE_F20 = 111, + SDL_SCANCODE_F21 = 112, + SDL_SCANCODE_F22 = 113, + SDL_SCANCODE_F23 = 114, + SDL_SCANCODE_F24 = 115, + SDL_SCANCODE_EXECUTE = 116, + SDL_SCANCODE_HELP = 117, + SDL_SCANCODE_MENU = 118, + SDL_SCANCODE_SELECT = 119, + SDL_SCANCODE_STOP = 120, + SDL_SCANCODE_AGAIN = 121, /**< redo */ + SDL_SCANCODE_UNDO = 122, + SDL_SCANCODE_CUT = 123, + SDL_SCANCODE_COPY = 124, + SDL_SCANCODE_PASTE = 125, + SDL_SCANCODE_FIND = 126, + SDL_SCANCODE_MUTE = 127, + SDL_SCANCODE_VOLUMEUP = 128, + SDL_SCANCODE_VOLUMEDOWN = 129, +/* not sure whether there's a reason to enable these */ +/* SDL_SCANCODE_LOCKINGCAPSLOCK = 130, */ +/* SDL_SCANCODE_LOCKINGNUMLOCK = 131, */ +/* SDL_SCANCODE_LOCKINGSCROLLLOCK = 132, */ + SDL_SCANCODE_KP_COMMA = 133, + SDL_SCANCODE_KP_EQUALSAS400 = 134, + + SDL_SCANCODE_INTERNATIONAL1 = 135, /**< used on Asian keyboards, see + footnotes in USB doc */ + SDL_SCANCODE_INTERNATIONAL2 = 136, + SDL_SCANCODE_INTERNATIONAL3 = 137, /**< Yen */ + SDL_SCANCODE_INTERNATIONAL4 = 138, + SDL_SCANCODE_INTERNATIONAL5 = 139, + SDL_SCANCODE_INTERNATIONAL6 = 140, + SDL_SCANCODE_INTERNATIONAL7 = 141, + SDL_SCANCODE_INTERNATIONAL8 = 142, + SDL_SCANCODE_INTERNATIONAL9 = 143, + SDL_SCANCODE_LANG1 = 144, /**< Hangul/English toggle */ + SDL_SCANCODE_LANG2 = 145, /**< Hanja conversion */ + SDL_SCANCODE_LANG3 = 146, /**< Katakana */ + SDL_SCANCODE_LANG4 = 147, /**< Hiragana */ + SDL_SCANCODE_LANG5 = 148, /**< Zenkaku/Hankaku */ + SDL_SCANCODE_LANG6 = 149, /**< reserved */ + SDL_SCANCODE_LANG7 = 150, /**< reserved */ + SDL_SCANCODE_LANG8 = 151, /**< reserved */ + SDL_SCANCODE_LANG9 = 152, /**< reserved */ + + SDL_SCANCODE_ALTERASE = 153, /**< Erase-Eaze */ + SDL_SCANCODE_SYSREQ = 154, + SDL_SCANCODE_CANCEL = 155, + SDL_SCANCODE_CLEAR = 156, + SDL_SCANCODE_PRIOR = 157, + SDL_SCANCODE_RETURN2 = 158, + SDL_SCANCODE_SEPARATOR = 159, + SDL_SCANCODE_OUT = 160, + SDL_SCANCODE_OPER = 161, + SDL_SCANCODE_CLEARAGAIN = 162, + SDL_SCANCODE_CRSEL = 163, + SDL_SCANCODE_EXSEL = 164, + + SDL_SCANCODE_KP_00 = 176, + SDL_SCANCODE_KP_000 = 177, + SDL_SCANCODE_THOUSANDSSEPARATOR = 178, + SDL_SCANCODE_DECIMALSEPARATOR = 179, + SDL_SCANCODE_CURRENCYUNIT = 180, + SDL_SCANCODE_CURRENCYSUBUNIT = 181, + SDL_SCANCODE_KP_LEFTPAREN = 182, + SDL_SCANCODE_KP_RIGHTPAREN = 183, + SDL_SCANCODE_KP_LEFTBRACE = 184, + SDL_SCANCODE_KP_RIGHTBRACE = 185, + SDL_SCANCODE_KP_TAB = 186, + SDL_SCANCODE_KP_BACKSPACE = 187, + SDL_SCANCODE_KP_A = 188, + SDL_SCANCODE_KP_B = 189, + SDL_SCANCODE_KP_C = 190, + SDL_SCANCODE_KP_D = 191, + SDL_SCANCODE_KP_E = 192, + SDL_SCANCODE_KP_F = 193, + SDL_SCANCODE_KP_XOR = 194, + SDL_SCANCODE_KP_POWER = 195, + SDL_SCANCODE_KP_PERCENT = 196, + SDL_SCANCODE_KP_LESS = 197, + SDL_SCANCODE_KP_GREATER = 198, + SDL_SCANCODE_KP_AMPERSAND = 199, + SDL_SCANCODE_KP_DBLAMPERSAND = 200, + SDL_SCANCODE_KP_VERTICALBAR = 201, + SDL_SCANCODE_KP_DBLVERTICALBAR = 202, + SDL_SCANCODE_KP_COLON = 203, + SDL_SCANCODE_KP_HASH = 204, + SDL_SCANCODE_KP_SPACE = 205, + SDL_SCANCODE_KP_AT = 206, + SDL_SCANCODE_KP_EXCLAM = 207, + SDL_SCANCODE_KP_MEMSTORE = 208, + SDL_SCANCODE_KP_MEMRECALL = 209, + SDL_SCANCODE_KP_MEMCLEAR = 210, + SDL_SCANCODE_KP_MEMADD = 211, + SDL_SCANCODE_KP_MEMSUBTRACT = 212, + SDL_SCANCODE_KP_MEMMULTIPLY = 213, + SDL_SCANCODE_KP_MEMDIVIDE = 214, + SDL_SCANCODE_KP_PLUSMINUS = 215, + SDL_SCANCODE_KP_CLEAR = 216, + SDL_SCANCODE_KP_CLEARENTRY = 217, + SDL_SCANCODE_KP_BINARY = 218, + SDL_SCANCODE_KP_OCTAL = 219, + SDL_SCANCODE_KP_DECIMAL = 220, + SDL_SCANCODE_KP_HEXADECIMAL = 221, + + SDL_SCANCODE_LCTRL = 224, + SDL_SCANCODE_LSHIFT = 225, + SDL_SCANCODE_LALT = 226, /**< alt, option */ + SDL_SCANCODE_LGUI = 227, /**< windows, command (apple), meta */ + SDL_SCANCODE_RCTRL = 228, + SDL_SCANCODE_RSHIFT = 229, + SDL_SCANCODE_RALT = 230, /**< alt gr, option */ + SDL_SCANCODE_RGUI = 231, /**< windows, command (apple), meta */ + + SDL_SCANCODE_MODE = 257, /**< I'm not sure if this is really not covered + * by any of the above, but since there's a + * special KMOD_MODE for it I'm adding it here + */ + + /* @} *//* Usage page 0x07 */ + + /** + * \name Usage page 0x0C + * + * These values are mapped from usage page 0x0C (USB consumer page). + */ + /* @{ */ + + SDL_SCANCODE_AUDIONEXT = 258, + SDL_SCANCODE_AUDIOPREV = 259, + SDL_SCANCODE_AUDIOSTOP = 260, + SDL_SCANCODE_AUDIOPLAY = 261, + SDL_SCANCODE_AUDIOMUTE = 262, + SDL_SCANCODE_MEDIASELECT = 263, + SDL_SCANCODE_WWW = 264, + SDL_SCANCODE_MAIL = 265, + SDL_SCANCODE_CALCULATOR = 266, + SDL_SCANCODE_COMPUTER = 267, + SDL_SCANCODE_AC_SEARCH = 268, + SDL_SCANCODE_AC_HOME = 269, + SDL_SCANCODE_AC_BACK = 270, + SDL_SCANCODE_AC_FORWARD = 271, + SDL_SCANCODE_AC_STOP = 272, + SDL_SCANCODE_AC_REFRESH = 273, + SDL_SCANCODE_AC_BOOKMARKS = 274, + + /* @} *//* Usage page 0x0C */ + + /** + * \name Walther keys + * + * These are values that Christian Walther added (for mac keyboard?). + */ + /* @{ */ + + SDL_SCANCODE_BRIGHTNESSDOWN = 275, + SDL_SCANCODE_BRIGHTNESSUP = 276, + SDL_SCANCODE_DISPLAYSWITCH = 277, /**< display mirroring/dual display + switch, video mode switch */ + SDL_SCANCODE_KBDILLUMTOGGLE = 278, + SDL_SCANCODE_KBDILLUMDOWN = 279, + SDL_SCANCODE_KBDILLUMUP = 280, + SDL_SCANCODE_EJECT = 281, + SDL_SCANCODE_SLEEP = 282, + + SDL_SCANCODE_APP1 = 283, + SDL_SCANCODE_APP2 = 284, + + /* @} *//* Walther keys */ + + /** + * \name Usage page 0x0C (additional media keys) + * + * These values are mapped from usage page 0x0C (USB consumer page). + */ + /* @{ */ + + SDL_SCANCODE_AUDIOREWIND = 285, + SDL_SCANCODE_AUDIOFASTFORWARD = 286, + + /* @} *//* Usage page 0x0C (additional media keys) */ + + /* Add any other keys here. */ + + SDL_NUM_SCANCODES = 512 /**< not a key, just marks the number of scancodes + for array bounds */ +} SDL_Scancode; + +#endif /* SDL_scancode_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/engine/Windows/SDL2/include/SDL_sensor.h b/engine/Windows/SDL2/include/SDL_sensor.h new file mode 100644 index 0000000..966adbf --- /dev/null +++ b/engine/Windows/SDL2/include/SDL_sensor.h @@ -0,0 +1,251 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2019 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_sensor.h + * + * Include file for SDL sensor event handling + * + */ + +#ifndef SDL_sensor_h_ +#define SDL_sensor_h_ + +#include "SDL_stdinc.h" +#include "SDL_error.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +/* *INDENT-OFF* */ +extern "C" { +/* *INDENT-ON* */ +#endif + +/** + * \brief SDL_sensor.h + * + * In order to use these functions, SDL_Init() must have been called + * with the ::SDL_INIT_SENSOR flag. This causes SDL to scan the system + * for sensors, and load appropriate drivers. + */ + +struct _SDL_Sensor; +typedef struct _SDL_Sensor SDL_Sensor; + +/** + * This is a unique ID for a sensor for the time it is connected to the system, + * and is never reused for the lifetime of the application. + * + * The ID value starts at 0 and increments from there. The value -1 is an invalid ID. + */ +typedef Sint32 SDL_SensorID; + +/* The different sensors defined by SDL + * + * Additional sensors may be available, using platform dependent semantics. + * + * Hare are the additional Android sensors: + * https://developer.android.com/reference/android/hardware/SensorEvent.html#values + */ +typedef enum +{ + SDL_SENSOR_INVALID = -1, /**< Returned for an invalid sensor */ + SDL_SENSOR_UNKNOWN, /**< Unknown sensor type */ + SDL_SENSOR_ACCEL, /**< Accelerometer */ + SDL_SENSOR_GYRO /**< Gyroscope */ +} SDL_SensorType; + +/** + * Accelerometer sensor + * + * The accelerometer returns the current acceleration in SI meters per + * second squared. This includes gravity, so a device at rest will have + * an acceleration of SDL_STANDARD_GRAVITY straight down. + * + * values[0]: Acceleration on the x axis + * values[1]: Acceleration on the y axis + * values[2]: Acceleration on the z axis + * + * For phones held in portrait mode, the axes are defined as follows: + * -X ... +X : left ... right + * -Y ... +Y : bottom ... top + * -Z ... +Z : farther ... closer + * + * The axis data is not changed when the phone is rotated. + * + * \sa SDL_GetDisplayOrientation() + */ +#define SDL_STANDARD_GRAVITY 9.80665f + +/** + * Gyroscope sensor + * + * The gyroscope returns the current rate of rotation in radians per second. + * The rotation is positive in the counter-clockwise direction. That is, + * an observer looking from a positive location on one of the axes would + * see positive rotation on that axis when it appeared to be rotating + * counter-clockwise. + * + * values[0]: Angular speed around the x axis + * values[1]: Angular speed around the y axis + * values[2]: Angular speed around the z axis + * + * For phones held in portrait mode, the axes are defined as follows: + * -X ... +X : left ... right + * -Y ... +Y : bottom ... top + * -Z ... +Z : farther ... closer + * + * The axis data is not changed when the phone is rotated. + * + * \sa SDL_GetDisplayOrientation() + */ + +/* Function prototypes */ + +/** + * \brief Count the number of sensors attached to the system right now + */ +extern DECLSPEC int SDLCALL SDL_NumSensors(void); + +/** + * \brief Get the implementation dependent name of a sensor. + * + * This can be called before any sensors are opened. + * + * \return The sensor name, or NULL if device_index is out of range. + */ +extern DECLSPEC const char *SDLCALL SDL_SensorGetDeviceName(int device_index); + +/** + * \brief Get the type of a sensor. + * + * This can be called before any sensors are opened. + * + * \return The sensor type, or SDL_SENSOR_INVALID if device_index is out of range. + */ +extern DECLSPEC SDL_SensorType SDLCALL SDL_SensorGetDeviceType(int device_index); + +/** + * \brief Get the platform dependent type of a sensor. + * + * This can be called before any sensors are opened. + * + * \return The sensor platform dependent type, or -1 if device_index is out of range. + */ +extern DECLSPEC int SDLCALL SDL_SensorGetDeviceNonPortableType(int device_index); + +/** + * \brief Get the instance ID of a sensor. + * + * This can be called before any sensors are opened. + * + * \return The sensor instance ID, or -1 if device_index is out of range. + */ +extern DECLSPEC SDL_SensorID SDLCALL SDL_SensorGetDeviceInstanceID(int device_index); + +/** + * \brief Open a sensor for use. + * + * The index passed as an argument refers to the N'th sensor on the system. + * + * \return A sensor identifier, or NULL if an error occurred. + */ +extern DECLSPEC SDL_Sensor *SDLCALL SDL_SensorOpen(int device_index); + +/** + * Return the SDL_Sensor associated with an instance id. + */ +extern DECLSPEC SDL_Sensor *SDLCALL SDL_SensorFromInstanceID(SDL_SensorID instance_id); + +/** + * \brief Get the implementation dependent name of a sensor. + * + * \return The sensor name, or NULL if the sensor is NULL. + */ +extern DECLSPEC const char *SDLCALL SDL_SensorGetName(SDL_Sensor *sensor); + +/** + * \brief Get the type of a sensor. + * + * This can be called before any sensors are opened. + * + * \return The sensor type, or SDL_SENSOR_INVALID if the sensor is NULL. + */ +extern DECLSPEC SDL_SensorType SDLCALL SDL_SensorGetType(SDL_Sensor *sensor); + +/** + * \brief Get the platform dependent type of a sensor. + * + * This can be called before any sensors are opened. + * + * \return The sensor platform dependent type, or -1 if the sensor is NULL. + */ +extern DECLSPEC int SDLCALL SDL_SensorGetNonPortableType(SDL_Sensor *sensor); + +/** + * \brief Get the instance ID of a sensor. + * + * This can be called before any sensors are opened. + * + * \return The sensor instance ID, or -1 if the sensor is NULL. + */ +extern DECLSPEC SDL_SensorID SDLCALL SDL_SensorGetInstanceID(SDL_Sensor *sensor); + +/** + * Get the current state of an opened sensor. + * + * The number of values and interpretation of the data is sensor dependent. + * + * \param sensor The sensor to query + * \param data A pointer filled with the current sensor state + * \param num_values The number of values to write to data + * + * \return 0 or -1 if an error occurred. + */ +extern DECLSPEC int SDLCALL SDL_SensorGetData(SDL_Sensor * sensor, float *data, int num_values); + +/** + * Close a sensor previously opened with SDL_SensorOpen() + */ +extern DECLSPEC void SDLCALL SDL_SensorClose(SDL_Sensor * sensor); + +/** + * Update the current state of the open sensors. + * + * This is called automatically by the event loop if sensor events are enabled. + * + * This needs to be called from the thread that initialized the sensor subsystem. + */ +extern DECLSPEC void SDLCALL SDL_SensorUpdate(void); + + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +/* *INDENT-OFF* */ +} +/* *INDENT-ON* */ +#endif +#include "close_code.h" + +#endif /* SDL_sensor_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/engine/Windows/SDL2/include/SDL_shape.h b/engine/Windows/SDL2/include/SDL_shape.h new file mode 100644 index 0000000..2ab43fc --- /dev/null +++ b/engine/Windows/SDL2/include/SDL_shape.h @@ -0,0 +1,144 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2019 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef SDL_shape_h_ +#define SDL_shape_h_ + +#include "SDL_stdinc.h" +#include "SDL_pixels.h" +#include "SDL_rect.h" +#include "SDL_surface.h" +#include "SDL_video.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/** \file SDL_shape.h + * + * Header file for the shaped window API. + */ + +#define SDL_NONSHAPEABLE_WINDOW -1 +#define SDL_INVALID_SHAPE_ARGUMENT -2 +#define SDL_WINDOW_LACKS_SHAPE -3 + +/** + * \brief Create a window that can be shaped with the specified position, dimensions, and flags. + * + * \param title The title of the window, in UTF-8 encoding. + * \param x The x position of the window, ::SDL_WINDOWPOS_CENTERED, or + * ::SDL_WINDOWPOS_UNDEFINED. + * \param y The y position of the window, ::SDL_WINDOWPOS_CENTERED, or + * ::SDL_WINDOWPOS_UNDEFINED. + * \param w The width of the window. + * \param h The height of the window. + * \param flags The flags for the window, a mask of SDL_WINDOW_BORDERLESS with any of the following: + * ::SDL_WINDOW_OPENGL, ::SDL_WINDOW_INPUT_GRABBED, + * ::SDL_WINDOW_HIDDEN, ::SDL_WINDOW_RESIZABLE, + * ::SDL_WINDOW_MAXIMIZED, ::SDL_WINDOW_MINIMIZED, + * ::SDL_WINDOW_BORDERLESS is always set, and ::SDL_WINDOW_FULLSCREEN is always unset. + * + * \return The window created, or NULL if window creation failed. + * + * \sa SDL_DestroyWindow() + */ +extern DECLSPEC SDL_Window * SDLCALL SDL_CreateShapedWindow(const char *title,unsigned int x,unsigned int y,unsigned int w,unsigned int h,Uint32 flags); + +/** + * \brief Return whether the given window is a shaped window. + * + * \param window The window to query for being shaped. + * + * \return SDL_TRUE if the window is a window that can be shaped, SDL_FALSE if the window is unshaped or NULL. + * + * \sa SDL_CreateShapedWindow + */ +extern DECLSPEC SDL_bool SDLCALL SDL_IsShapedWindow(const SDL_Window *window); + +/** \brief An enum denoting the specific type of contents present in an SDL_WindowShapeParams union. */ +typedef enum { + /** \brief The default mode, a binarized alpha cutoff of 1. */ + ShapeModeDefault, + /** \brief A binarized alpha cutoff with a given integer value. */ + ShapeModeBinarizeAlpha, + /** \brief A binarized alpha cutoff with a given integer value, but with the opposite comparison. */ + ShapeModeReverseBinarizeAlpha, + /** \brief A color key is applied. */ + ShapeModeColorKey +} WindowShapeMode; + +#define SDL_SHAPEMODEALPHA(mode) (mode == ShapeModeDefault || mode == ShapeModeBinarizeAlpha || mode == ShapeModeReverseBinarizeAlpha) + +/** \brief A union containing parameters for shaped windows. */ +typedef union { + /** \brief A cutoff alpha value for binarization of the window shape's alpha channel. */ + Uint8 binarizationCutoff; + SDL_Color colorKey; +} SDL_WindowShapeParams; + +/** \brief A struct that tags the SDL_WindowShapeParams union with an enum describing the type of its contents. */ +typedef struct SDL_WindowShapeMode { + /** \brief The mode of these window-shape parameters. */ + WindowShapeMode mode; + /** \brief Window-shape parameters. */ + SDL_WindowShapeParams parameters; +} SDL_WindowShapeMode; + +/** + * \brief Set the shape and parameters of a shaped window. + * + * \param window The shaped window whose parameters should be set. + * \param shape A surface encoding the desired shape for the window. + * \param shape_mode The parameters to set for the shaped window. + * + * \return 0 on success, SDL_INVALID_SHAPE_ARGUMENT on an invalid shape argument, or SDL_NONSHAPEABLE_WINDOW + * if the SDL_Window given does not reference a valid shaped window. + * + * \sa SDL_WindowShapeMode + * \sa SDL_GetShapedWindowMode. + */ +extern DECLSPEC int SDLCALL SDL_SetWindowShape(SDL_Window *window,SDL_Surface *shape,SDL_WindowShapeMode *shape_mode); + +/** + * \brief Get the shape parameters of a shaped window. + * + * \param window The shaped window whose parameters should be retrieved. + * \param shape_mode An empty shape-mode structure to fill, or NULL to check whether the window has a shape. + * + * \return 0 if the window has a shape and, provided shape_mode was not NULL, shape_mode has been filled with the mode + * data, SDL_NONSHAPEABLE_WINDOW if the SDL_Window given is not a shaped window, or SDL_WINDOW_LACKS_SHAPE if + * the SDL_Window given is a shapeable window currently lacking a shape. + * + * \sa SDL_WindowShapeMode + * \sa SDL_SetWindowShape + */ +extern DECLSPEC int SDLCALL SDL_GetShapedWindowMode(SDL_Window *window,SDL_WindowShapeMode *shape_mode); + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_shape_h_ */ diff --git a/engine/Windows/SDL2/include/SDL_stdinc.h b/engine/Windows/SDL2/include/SDL_stdinc.h new file mode 100644 index 0000000..a95700a --- /dev/null +++ b/engine/Windows/SDL2/include/SDL_stdinc.h @@ -0,0 +1,610 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2019 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_stdinc.h + * + * This is a general header that includes C language support. + */ + +#ifndef SDL_stdinc_h_ +#define SDL_stdinc_h_ + +#include "SDL_config.h" + +#ifdef HAVE_SYS_TYPES_H +#include +#endif +#ifdef HAVE_STDIO_H +#include +#endif +#if defined(STDC_HEADERS) +# include +# include +# include +#else +# if defined(HAVE_STDLIB_H) +# include +# elif defined(HAVE_MALLOC_H) +# include +# endif +# if defined(HAVE_STDDEF_H) +# include +# endif +# if defined(HAVE_STDARG_H) +# include +# endif +#endif +#ifdef HAVE_STRING_H +# if !defined(STDC_HEADERS) && defined(HAVE_MEMORY_H) +# include +# endif +# include +#endif +#ifdef HAVE_STRINGS_H +# include +#endif +#ifdef HAVE_WCHAR_H +# include +#endif +#if defined(HAVE_INTTYPES_H) +# include +#elif defined(HAVE_STDINT_H) +# include +#endif +#ifdef HAVE_CTYPE_H +# include +#endif +#ifdef HAVE_MATH_H +# if defined(__WINRT__) +/* Defining _USE_MATH_DEFINES is required to get M_PI to be defined on + WinRT. See http://msdn.microsoft.com/en-us/library/4hwaceh6.aspx + for more information. +*/ +# define _USE_MATH_DEFINES +# endif +# include +#endif +#ifdef HAVE_FLOAT_H +# include +#endif +#if defined(HAVE_ALLOCA) && !defined(alloca) +# if defined(HAVE_ALLOCA_H) +# include +# elif defined(__GNUC__) +# define alloca __builtin_alloca +# elif defined(_MSC_VER) +# include +# define alloca _alloca +# elif defined(__WATCOMC__) +# include +# elif defined(__BORLANDC__) +# include +# elif defined(__DMC__) +# include +# elif defined(__AIX__) +#pragma alloca +# elif defined(__MRC__) +void *alloca(unsigned); +# else +char *alloca(); +# endif +#endif + +/** + * The number of elements in an array. + */ +#define SDL_arraysize(array) (sizeof(array)/sizeof(array[0])) +#define SDL_TABLESIZE(table) SDL_arraysize(table) + +/** + * Macro useful for building other macros with strings in them + * + * e.g. #define LOG_ERROR(X) OutputDebugString(SDL_STRINGIFY_ARG(__FUNCTION__) ": " X "\n") + */ +#define SDL_STRINGIFY_ARG(arg) #arg + +/** + * \name Cast operators + * + * Use proper C++ casts when compiled as C++ to be compatible with the option + * -Wold-style-cast of GCC (and -Werror=old-style-cast in GCC 4.2 and above). + */ +/* @{ */ +#ifdef __cplusplus +#define SDL_reinterpret_cast(type, expression) reinterpret_cast(expression) +#define SDL_static_cast(type, expression) static_cast(expression) +#define SDL_const_cast(type, expression) const_cast(expression) +#else +#define SDL_reinterpret_cast(type, expression) ((type)(expression)) +#define SDL_static_cast(type, expression) ((type)(expression)) +#define SDL_const_cast(type, expression) ((type)(expression)) +#endif +/* @} *//* Cast operators */ + +/* Define a four character code as a Uint32 */ +#define SDL_FOURCC(A, B, C, D) \ + ((SDL_static_cast(Uint32, SDL_static_cast(Uint8, (A))) << 0) | \ + (SDL_static_cast(Uint32, SDL_static_cast(Uint8, (B))) << 8) | \ + (SDL_static_cast(Uint32, SDL_static_cast(Uint8, (C))) << 16) | \ + (SDL_static_cast(Uint32, SDL_static_cast(Uint8, (D))) << 24)) + +/** + * \name Basic data types + */ +/* @{ */ + +#ifdef __CC_ARM +/* ARM's compiler throws warnings if we use an enum: like "SDL_bool x = a < b;" */ +#define SDL_FALSE 0 +#define SDL_TRUE 1 +typedef int SDL_bool; +#else +typedef enum +{ + SDL_FALSE = 0, + SDL_TRUE = 1 +} SDL_bool; +#endif + +/** + * \brief A signed 8-bit integer type. + */ +#define SDL_MAX_SINT8 ((Sint8)0x7F) /* 127 */ +#define SDL_MIN_SINT8 ((Sint8)(~0x7F)) /* -128 */ +typedef int8_t Sint8; +/** + * \brief An unsigned 8-bit integer type. + */ +#define SDL_MAX_UINT8 ((Uint8)0xFF) /* 255 */ +#define SDL_MIN_UINT8 ((Uint8)0x00) /* 0 */ +typedef uint8_t Uint8; +/** + * \brief A signed 16-bit integer type. + */ +#define SDL_MAX_SINT16 ((Sint16)0x7FFF) /* 32767 */ +#define SDL_MIN_SINT16 ((Sint16)(~0x7FFF)) /* -32768 */ +typedef int16_t Sint16; +/** + * \brief An unsigned 16-bit integer type. + */ +#define SDL_MAX_UINT16 ((Uint16)0xFFFF) /* 65535 */ +#define SDL_MIN_UINT16 ((Uint16)0x0000) /* 0 */ +typedef uint16_t Uint16; +/** + * \brief A signed 32-bit integer type. + */ +#define SDL_MAX_SINT32 ((Sint32)0x7FFFFFFF) /* 2147483647 */ +#define SDL_MIN_SINT32 ((Sint32)(~0x7FFFFFFF)) /* -2147483648 */ +typedef int32_t Sint32; +/** + * \brief An unsigned 32-bit integer type. + */ +#define SDL_MAX_UINT32 ((Uint32)0xFFFFFFFFu) /* 4294967295 */ +#define SDL_MIN_UINT32 ((Uint32)0x00000000) /* 0 */ +typedef uint32_t Uint32; + +/** + * \brief A signed 64-bit integer type. + */ +#define SDL_MAX_SINT64 ((Sint64)0x7FFFFFFFFFFFFFFFll) /* 9223372036854775807 */ +#define SDL_MIN_SINT64 ((Sint64)(~0x7FFFFFFFFFFFFFFFll)) /* -9223372036854775808 */ +typedef int64_t Sint64; +/** + * \brief An unsigned 64-bit integer type. + */ +#define SDL_MAX_UINT64 ((Uint64)0xFFFFFFFFFFFFFFFFull) /* 18446744073709551615 */ +#define SDL_MIN_UINT64 ((Uint64)(0x0000000000000000ull)) /* 0 */ +typedef uint64_t Uint64; + +/* @} *//* Basic data types */ + +/* Make sure we have macros for printing 64 bit values. + * should define these but this is not true all platforms. + * (for example win32) */ +#ifndef SDL_PRIs64 +#ifdef PRIs64 +#define SDL_PRIs64 PRIs64 +#elif defined(__WIN32__) +#define SDL_PRIs64 "I64d" +#elif defined(__LINUX__) && defined(__LP64__) +#define SDL_PRIs64 "ld" +#else +#define SDL_PRIs64 "lld" +#endif +#endif +#ifndef SDL_PRIu64 +#ifdef PRIu64 +#define SDL_PRIu64 PRIu64 +#elif defined(__WIN32__) +#define SDL_PRIu64 "I64u" +#elif defined(__LINUX__) && defined(__LP64__) +#define SDL_PRIu64 "lu" +#else +#define SDL_PRIu64 "llu" +#endif +#endif +#ifndef SDL_PRIx64 +#ifdef PRIx64 +#define SDL_PRIx64 PRIx64 +#elif defined(__WIN32__) +#define SDL_PRIx64 "I64x" +#elif defined(__LINUX__) && defined(__LP64__) +#define SDL_PRIx64 "lx" +#else +#define SDL_PRIx64 "llx" +#endif +#endif +#ifndef SDL_PRIX64 +#ifdef PRIX64 +#define SDL_PRIX64 PRIX64 +#elif defined(__WIN32__) +#define SDL_PRIX64 "I64X" +#elif defined(__LINUX__) && defined(__LP64__) +#define SDL_PRIX64 "lX" +#else +#define SDL_PRIX64 "llX" +#endif +#endif + +/* Annotations to help code analysis tools */ +#ifdef SDL_DISABLE_ANALYZE_MACROS +#define SDL_IN_BYTECAP(x) +#define SDL_INOUT_Z_CAP(x) +#define SDL_OUT_Z_CAP(x) +#define SDL_OUT_CAP(x) +#define SDL_OUT_BYTECAP(x) +#define SDL_OUT_Z_BYTECAP(x) +#define SDL_PRINTF_FORMAT_STRING +#define SDL_SCANF_FORMAT_STRING +#define SDL_PRINTF_VARARG_FUNC( fmtargnumber ) +#define SDL_SCANF_VARARG_FUNC( fmtargnumber ) +#else +#if defined(_MSC_VER) && (_MSC_VER >= 1600) /* VS 2010 and above */ +#include + +#define SDL_IN_BYTECAP(x) _In_bytecount_(x) +#define SDL_INOUT_Z_CAP(x) _Inout_z_cap_(x) +#define SDL_OUT_Z_CAP(x) _Out_z_cap_(x) +#define SDL_OUT_CAP(x) _Out_cap_(x) +#define SDL_OUT_BYTECAP(x) _Out_bytecap_(x) +#define SDL_OUT_Z_BYTECAP(x) _Out_z_bytecap_(x) + +#define SDL_PRINTF_FORMAT_STRING _Printf_format_string_ +#define SDL_SCANF_FORMAT_STRING _Scanf_format_string_impl_ +#else +#define SDL_IN_BYTECAP(x) +#define SDL_INOUT_Z_CAP(x) +#define SDL_OUT_Z_CAP(x) +#define SDL_OUT_CAP(x) +#define SDL_OUT_BYTECAP(x) +#define SDL_OUT_Z_BYTECAP(x) +#define SDL_PRINTF_FORMAT_STRING +#define SDL_SCANF_FORMAT_STRING +#endif +#if defined(__GNUC__) +#define SDL_PRINTF_VARARG_FUNC( fmtargnumber ) __attribute__ (( format( __printf__, fmtargnumber, fmtargnumber+1 ))) +#define SDL_SCANF_VARARG_FUNC( fmtargnumber ) __attribute__ (( format( __scanf__, fmtargnumber, fmtargnumber+1 ))) +#else +#define SDL_PRINTF_VARARG_FUNC( fmtargnumber ) +#define SDL_SCANF_VARARG_FUNC( fmtargnumber ) +#endif +#endif /* SDL_DISABLE_ANALYZE_MACROS */ + +#define SDL_COMPILE_TIME_ASSERT(name, x) \ + typedef int SDL_compile_time_assert_ ## name[(x) * 2 - 1] +/** \cond */ +#ifndef DOXYGEN_SHOULD_IGNORE_THIS +SDL_COMPILE_TIME_ASSERT(uint8, sizeof(Uint8) == 1); +SDL_COMPILE_TIME_ASSERT(sint8, sizeof(Sint8) == 1); +SDL_COMPILE_TIME_ASSERT(uint16, sizeof(Uint16) == 2); +SDL_COMPILE_TIME_ASSERT(sint16, sizeof(Sint16) == 2); +SDL_COMPILE_TIME_ASSERT(uint32, sizeof(Uint32) == 4); +SDL_COMPILE_TIME_ASSERT(sint32, sizeof(Sint32) == 4); +SDL_COMPILE_TIME_ASSERT(uint64, sizeof(Uint64) == 8); +SDL_COMPILE_TIME_ASSERT(sint64, sizeof(Sint64) == 8); +#endif /* DOXYGEN_SHOULD_IGNORE_THIS */ +/** \endcond */ + +/* Check to make sure enums are the size of ints, for structure packing. + For both Watcom C/C++ and Borland C/C++ the compiler option that makes + enums having the size of an int must be enabled. + This is "-b" for Borland C/C++ and "-ei" for Watcom C/C++ (v11). +*/ + +/** \cond */ +#ifndef DOXYGEN_SHOULD_IGNORE_THIS +#if !defined(__ANDROID__) + /* TODO: include/SDL_stdinc.h:174: error: size of array 'SDL_dummy_enum' is negative */ +typedef enum +{ + DUMMY_ENUM_VALUE +} SDL_DUMMY_ENUM; + +SDL_COMPILE_TIME_ASSERT(enum, sizeof(SDL_DUMMY_ENUM) == sizeof(int)); +#endif +#endif /* DOXYGEN_SHOULD_IGNORE_THIS */ +/** \endcond */ + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef HAVE_ALLOCA +#define SDL_stack_alloc(type, count) (type*)alloca(sizeof(type)*(count)) +#define SDL_stack_free(data) +#else +#define SDL_stack_alloc(type, count) (type*)SDL_malloc(sizeof(type)*(count)) +#define SDL_stack_free(data) SDL_free(data) +#endif + +extern DECLSPEC void *SDLCALL SDL_malloc(size_t size); +extern DECLSPEC void *SDLCALL SDL_calloc(size_t nmemb, size_t size); +extern DECLSPEC void *SDLCALL SDL_realloc(void *mem, size_t size); +extern DECLSPEC void SDLCALL SDL_free(void *mem); + +typedef void *(SDLCALL *SDL_malloc_func)(size_t size); +typedef void *(SDLCALL *SDL_calloc_func)(size_t nmemb, size_t size); +typedef void *(SDLCALL *SDL_realloc_func)(void *mem, size_t size); +typedef void (SDLCALL *SDL_free_func)(void *mem); + +/** + * \brief Get the current set of SDL memory functions + */ +extern DECLSPEC void SDLCALL SDL_GetMemoryFunctions(SDL_malloc_func *malloc_func, + SDL_calloc_func *calloc_func, + SDL_realloc_func *realloc_func, + SDL_free_func *free_func); + +/** + * \brief Replace SDL's memory allocation functions with a custom set + * + * \note If you are replacing SDL's memory functions, you should call + * SDL_GetNumAllocations() and be very careful if it returns non-zero. + * That means that your free function will be called with memory + * allocated by the previous memory allocation functions. + */ +extern DECLSPEC int SDLCALL SDL_SetMemoryFunctions(SDL_malloc_func malloc_func, + SDL_calloc_func calloc_func, + SDL_realloc_func realloc_func, + SDL_free_func free_func); + +/** + * \brief Get the number of outstanding (unfreed) allocations + */ +extern DECLSPEC int SDLCALL SDL_GetNumAllocations(void); + +extern DECLSPEC char *SDLCALL SDL_getenv(const char *name); +extern DECLSPEC int SDLCALL SDL_setenv(const char *name, const char *value, int overwrite); + +extern DECLSPEC void SDLCALL SDL_qsort(void *base, size_t nmemb, size_t size, int (*compare) (const void *, const void *)); + +extern DECLSPEC int SDLCALL SDL_abs(int x); + +/* !!! FIXME: these have side effects. You probably shouldn't use them. */ +/* !!! FIXME: Maybe we do forceinline functions of SDL_mini, SDL_minf, etc? */ +#define SDL_min(x, y) (((x) < (y)) ? (x) : (y)) +#define SDL_max(x, y) (((x) > (y)) ? (x) : (y)) + +extern DECLSPEC int SDLCALL SDL_isdigit(int x); +extern DECLSPEC int SDLCALL SDL_isspace(int x); +extern DECLSPEC int SDLCALL SDL_toupper(int x); +extern DECLSPEC int SDLCALL SDL_tolower(int x); + +extern DECLSPEC void *SDLCALL SDL_memset(SDL_OUT_BYTECAP(len) void *dst, int c, size_t len); + +#define SDL_zero(x) SDL_memset(&(x), 0, sizeof((x))) +#define SDL_zerop(x) SDL_memset((x), 0, sizeof(*(x))) +#define SDL_zeroa(x) SDL_memset((x), 0, sizeof((x))) + +/* Note that memset() is a byte assignment and this is a 32-bit assignment, so they're not directly equivalent. */ +SDL_FORCE_INLINE void SDL_memset4(void *dst, Uint32 val, size_t dwords) +{ +#ifdef __APPLE__ + memset_pattern4(dst, &val, dwords * 4); +#elif defined(__GNUC__) && defined(i386) + int u0, u1, u2; + __asm__ __volatile__ ( + "cld \n\t" + "rep ; stosl \n\t" + : "=&D" (u0), "=&a" (u1), "=&c" (u2) + : "0" (dst), "1" (val), "2" (SDL_static_cast(Uint32, dwords)) + : "memory" + ); +#else + size_t _n = (dwords + 3) / 4; + Uint32 *_p = SDL_static_cast(Uint32 *, dst); + Uint32 _val = (val); + if (dwords == 0) + return; + switch (dwords % 4) + { + case 0: do { *_p++ = _val; /* fallthrough */ + case 3: *_p++ = _val; /* fallthrough */ + case 2: *_p++ = _val; /* fallthrough */ + case 1: *_p++ = _val; /* fallthrough */ + } while ( --_n ); + } +#endif +} + +extern DECLSPEC void *SDLCALL SDL_memcpy(SDL_OUT_BYTECAP(len) void *dst, SDL_IN_BYTECAP(len) const void *src, size_t len); + +extern DECLSPEC void *SDLCALL SDL_memmove(SDL_OUT_BYTECAP(len) void *dst, SDL_IN_BYTECAP(len) const void *src, size_t len); +extern DECLSPEC int SDLCALL SDL_memcmp(const void *s1, const void *s2, size_t len); + +extern DECLSPEC wchar_t *SDLCALL SDL_wcsdup(const wchar_t *wstr); +extern DECLSPEC size_t SDLCALL SDL_wcslen(const wchar_t *wstr); +extern DECLSPEC size_t SDLCALL SDL_wcslcpy(SDL_OUT_Z_CAP(maxlen) wchar_t *dst, const wchar_t *src, size_t maxlen); +extern DECLSPEC size_t SDLCALL SDL_wcslcat(SDL_INOUT_Z_CAP(maxlen) wchar_t *dst, const wchar_t *src, size_t maxlen); +extern DECLSPEC int SDLCALL SDL_wcscmp(const wchar_t *str1, const wchar_t *str2); + +extern DECLSPEC size_t SDLCALL SDL_strlen(const char *str); +extern DECLSPEC size_t SDLCALL SDL_strlcpy(SDL_OUT_Z_CAP(maxlen) char *dst, const char *src, size_t maxlen); +extern DECLSPEC size_t SDLCALL SDL_utf8strlcpy(SDL_OUT_Z_CAP(dst_bytes) char *dst, const char *src, size_t dst_bytes); +extern DECLSPEC size_t SDLCALL SDL_strlcat(SDL_INOUT_Z_CAP(maxlen) char *dst, const char *src, size_t maxlen); +extern DECLSPEC char *SDLCALL SDL_strdup(const char *str); +extern DECLSPEC char *SDLCALL SDL_strrev(char *str); +extern DECLSPEC char *SDLCALL SDL_strupr(char *str); +extern DECLSPEC char *SDLCALL SDL_strlwr(char *str); +extern DECLSPEC char *SDLCALL SDL_strchr(const char *str, int c); +extern DECLSPEC char *SDLCALL SDL_strrchr(const char *str, int c); +extern DECLSPEC char *SDLCALL SDL_strstr(const char *haystack, const char *needle); +extern DECLSPEC size_t SDLCALL SDL_utf8strlen(const char *str); + +extern DECLSPEC char *SDLCALL SDL_itoa(int value, char *str, int radix); +extern DECLSPEC char *SDLCALL SDL_uitoa(unsigned int value, char *str, int radix); +extern DECLSPEC char *SDLCALL SDL_ltoa(long value, char *str, int radix); +extern DECLSPEC char *SDLCALL SDL_ultoa(unsigned long value, char *str, int radix); +extern DECLSPEC char *SDLCALL SDL_lltoa(Sint64 value, char *str, int radix); +extern DECLSPEC char *SDLCALL SDL_ulltoa(Uint64 value, char *str, int radix); + +extern DECLSPEC int SDLCALL SDL_atoi(const char *str); +extern DECLSPEC double SDLCALL SDL_atof(const char *str); +extern DECLSPEC long SDLCALL SDL_strtol(const char *str, char **endp, int base); +extern DECLSPEC unsigned long SDLCALL SDL_strtoul(const char *str, char **endp, int base); +extern DECLSPEC Sint64 SDLCALL SDL_strtoll(const char *str, char **endp, int base); +extern DECLSPEC Uint64 SDLCALL SDL_strtoull(const char *str, char **endp, int base); +extern DECLSPEC double SDLCALL SDL_strtod(const char *str, char **endp); + +extern DECLSPEC int SDLCALL SDL_strcmp(const char *str1, const char *str2); +extern DECLSPEC int SDLCALL SDL_strncmp(const char *str1, const char *str2, size_t maxlen); +extern DECLSPEC int SDLCALL SDL_strcasecmp(const char *str1, const char *str2); +extern DECLSPEC int SDLCALL SDL_strncasecmp(const char *str1, const char *str2, size_t len); + +extern DECLSPEC int SDLCALL SDL_sscanf(const char *text, SDL_SCANF_FORMAT_STRING const char *fmt, ...) SDL_SCANF_VARARG_FUNC(2); +extern DECLSPEC int SDLCALL SDL_vsscanf(const char *text, const char *fmt, va_list ap); +extern DECLSPEC int SDLCALL SDL_snprintf(SDL_OUT_Z_CAP(maxlen) char *text, size_t maxlen, SDL_PRINTF_FORMAT_STRING const char *fmt, ... ) SDL_PRINTF_VARARG_FUNC(3); +extern DECLSPEC int SDLCALL SDL_vsnprintf(SDL_OUT_Z_CAP(maxlen) char *text, size_t maxlen, const char *fmt, va_list ap); + +#ifndef HAVE_M_PI +#ifndef M_PI +#define M_PI 3.14159265358979323846264338327950288 /**< pi */ +#endif +#endif + +extern DECLSPEC double SDLCALL SDL_acos(double x); +extern DECLSPEC float SDLCALL SDL_acosf(float x); +extern DECLSPEC double SDLCALL SDL_asin(double x); +extern DECLSPEC float SDLCALL SDL_asinf(float x); +extern DECLSPEC double SDLCALL SDL_atan(double x); +extern DECLSPEC float SDLCALL SDL_atanf(float x); +extern DECLSPEC double SDLCALL SDL_atan2(double x, double y); +extern DECLSPEC float SDLCALL SDL_atan2f(float x, float y); +extern DECLSPEC double SDLCALL SDL_ceil(double x); +extern DECLSPEC float SDLCALL SDL_ceilf(float x); +extern DECLSPEC double SDLCALL SDL_copysign(double x, double y); +extern DECLSPEC float SDLCALL SDL_copysignf(float x, float y); +extern DECLSPEC double SDLCALL SDL_cos(double x); +extern DECLSPEC float SDLCALL SDL_cosf(float x); +extern DECLSPEC double SDLCALL SDL_exp(double x); +extern DECLSPEC float SDLCALL SDL_expf(float x); +extern DECLSPEC double SDLCALL SDL_fabs(double x); +extern DECLSPEC float SDLCALL SDL_fabsf(float x); +extern DECLSPEC double SDLCALL SDL_floor(double x); +extern DECLSPEC float SDLCALL SDL_floorf(float x); +extern DECLSPEC double SDLCALL SDL_fmod(double x, double y); +extern DECLSPEC float SDLCALL SDL_fmodf(float x, float y); +extern DECLSPEC double SDLCALL SDL_log(double x); +extern DECLSPEC float SDLCALL SDL_logf(float x); +extern DECLSPEC double SDLCALL SDL_log10(double x); +extern DECLSPEC float SDLCALL SDL_log10f(float x); +extern DECLSPEC double SDLCALL SDL_pow(double x, double y); +extern DECLSPEC float SDLCALL SDL_powf(float x, float y); +extern DECLSPEC double SDLCALL SDL_scalbn(double x, int n); +extern DECLSPEC float SDLCALL SDL_scalbnf(float x, int n); +extern DECLSPEC double SDLCALL SDL_sin(double x); +extern DECLSPEC float SDLCALL SDL_sinf(float x); +extern DECLSPEC double SDLCALL SDL_sqrt(double x); +extern DECLSPEC float SDLCALL SDL_sqrtf(float x); +extern DECLSPEC double SDLCALL SDL_tan(double x); +extern DECLSPEC float SDLCALL SDL_tanf(float x); + +/* The SDL implementation of iconv() returns these error codes */ +#define SDL_ICONV_ERROR (size_t)-1 +#define SDL_ICONV_E2BIG (size_t)-2 +#define SDL_ICONV_EILSEQ (size_t)-3 +#define SDL_ICONV_EINVAL (size_t)-4 + +/* SDL_iconv_* are now always real symbols/types, not macros or inlined. */ +typedef struct _SDL_iconv_t *SDL_iconv_t; +extern DECLSPEC SDL_iconv_t SDLCALL SDL_iconv_open(const char *tocode, + const char *fromcode); +extern DECLSPEC int SDLCALL SDL_iconv_close(SDL_iconv_t cd); +extern DECLSPEC size_t SDLCALL SDL_iconv(SDL_iconv_t cd, const char **inbuf, + size_t * inbytesleft, char **outbuf, + size_t * outbytesleft); +/** + * This function converts a string between encodings in one pass, returning a + * string that must be freed with SDL_free() or NULL on error. + */ +extern DECLSPEC char *SDLCALL SDL_iconv_string(const char *tocode, + const char *fromcode, + const char *inbuf, + size_t inbytesleft); +#define SDL_iconv_utf8_locale(S) SDL_iconv_string("", "UTF-8", S, SDL_strlen(S)+1) +#define SDL_iconv_utf8_ucs2(S) (Uint16 *)SDL_iconv_string("UCS-2-INTERNAL", "UTF-8", S, SDL_strlen(S)+1) +#define SDL_iconv_utf8_ucs4(S) (Uint32 *)SDL_iconv_string("UCS-4-INTERNAL", "UTF-8", S, SDL_strlen(S)+1) + +/* force builds using Clang's static analysis tools to use literal C runtime + here, since there are possibly tests that are ineffective otherwise. */ +#if defined(__clang_analyzer__) && !defined(SDL_DISABLE_ANALYZE_MACROS) +#define SDL_malloc malloc +#define SDL_calloc calloc +#define SDL_realloc realloc +#define SDL_free free +#define SDL_memset memset +#define SDL_memcpy memcpy +#define SDL_memmove memmove +#define SDL_memcmp memcmp +#define SDL_strlen strlen +#define SDL_strlcpy strlcpy +#define SDL_strlcat strlcat +#define SDL_strdup strdup +#define SDL_strchr strchr +#define SDL_strrchr strrchr +#define SDL_strstr strstr +#define SDL_strcmp strcmp +#define SDL_strncmp strncmp +#define SDL_strcasecmp strcasecmp +#define SDL_strncasecmp strncasecmp +#define SDL_sscanf sscanf +#define SDL_vsscanf vsscanf +#define SDL_snprintf snprintf +#define SDL_vsnprintf vsnprintf +#endif + +SDL_FORCE_INLINE void *SDL_memcpy4(SDL_OUT_BYTECAP(dwords*4) void *dst, SDL_IN_BYTECAP(dwords*4) const void *src, size_t dwords) +{ + return SDL_memcpy(dst, src, dwords * 4); +} + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_stdinc_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/engine/Windows/SDL2/include/SDL_surface.h b/engine/Windows/SDL2/include/SDL_surface.h new file mode 100644 index 0000000..51a1283 --- /dev/null +++ b/engine/Windows/SDL2/include/SDL_surface.h @@ -0,0 +1,554 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2019 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_surface.h + * + * Header file for ::SDL_Surface definition and management functions. + */ + +#ifndef SDL_surface_h_ +#define SDL_surface_h_ + +#include "SDL_stdinc.h" +#include "SDL_pixels.h" +#include "SDL_rect.h" +#include "SDL_blendmode.h" +#include "SDL_rwops.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \name Surface flags + * + * These are the currently supported flags for the ::SDL_Surface. + * + * \internal + * Used internally (read-only). + */ +/* @{ */ +#define SDL_SWSURFACE 0 /**< Just here for compatibility */ +#define SDL_PREALLOC 0x00000001 /**< Surface uses preallocated memory */ +#define SDL_RLEACCEL 0x00000002 /**< Surface is RLE encoded */ +#define SDL_DONTFREE 0x00000004 /**< Surface is referenced internally */ +#define SDL_SIMD_ALIGNED 0x00000008 /**< Surface uses aligned memory */ +/* @} *//* Surface flags */ + +/** + * Evaluates to true if the surface needs to be locked before access. + */ +#define SDL_MUSTLOCK(S) (((S)->flags & SDL_RLEACCEL) != 0) + +/** + * \brief A collection of pixels used in software blitting. + * + * \note This structure should be treated as read-only, except for \c pixels, + * which, if not NULL, contains the raw pixel data for the surface. + */ +typedef struct SDL_Surface +{ + Uint32 flags; /**< Read-only */ + SDL_PixelFormat *format; /**< Read-only */ + int w, h; /**< Read-only */ + int pitch; /**< Read-only */ + void *pixels; /**< Read-write */ + + /** Application data associated with the surface */ + void *userdata; /**< Read-write */ + + /** information needed for surfaces requiring locks */ + int locked; /**< Read-only */ + void *lock_data; /**< Read-only */ + + /** clipping information */ + SDL_Rect clip_rect; /**< Read-only */ + + /** info for fast blit mapping to other surfaces */ + struct SDL_BlitMap *map; /**< Private */ + + /** Reference count -- used when freeing surface */ + int refcount; /**< Read-mostly */ +} SDL_Surface; + +/** + * \brief The type of function used for surface blitting functions. + */ +typedef int (SDLCALL *SDL_blit) (struct SDL_Surface * src, SDL_Rect * srcrect, + struct SDL_Surface * dst, SDL_Rect * dstrect); + +/** + * \brief The formula used for converting between YUV and RGB + */ +typedef enum +{ + SDL_YUV_CONVERSION_JPEG, /**< Full range JPEG */ + SDL_YUV_CONVERSION_BT601, /**< BT.601 (the default) */ + SDL_YUV_CONVERSION_BT709, /**< BT.709 */ + SDL_YUV_CONVERSION_AUTOMATIC /**< BT.601 for SD content, BT.709 for HD content */ +} SDL_YUV_CONVERSION_MODE; + +/** + * Allocate and free an RGB surface. + * + * 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. + * + * \param flags The \c flags are obsolete and should be set to 0. + * \param width The width in pixels of the surface to create. + * \param height The height in pixels of the surface to create. + * \param depth The depth in bits of the surface to create. + * \param Rmask The red mask of the surface to create. + * \param Gmask The green mask of the surface to create. + * \param Bmask The blue mask of the surface to create. + * \param Amask The alpha mask of the surface to create. + */ +extern DECLSPEC SDL_Surface *SDLCALL SDL_CreateRGBSurface + (Uint32 flags, int width, int height, int depth, + Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask); + +/* !!! FIXME for 2.1: why does this ask for depth? Format provides that. */ +extern DECLSPEC SDL_Surface *SDLCALL SDL_CreateRGBSurfaceWithFormat + (Uint32 flags, int width, int height, int depth, Uint32 format); + +extern DECLSPEC SDL_Surface *SDLCALL SDL_CreateRGBSurfaceFrom(void *pixels, + int width, + int height, + int depth, + int pitch, + Uint32 Rmask, + Uint32 Gmask, + Uint32 Bmask, + Uint32 Amask); +extern DECLSPEC SDL_Surface *SDLCALL SDL_CreateRGBSurfaceWithFormatFrom + (void *pixels, int width, int height, int depth, int pitch, Uint32 format); +extern DECLSPEC void SDLCALL SDL_FreeSurface(SDL_Surface * surface); + +/** + * \brief Set the palette used by a surface. + * + * \return 0, or -1 if the surface format doesn't use a palette. + * + * \note A single palette can be shared with many surfaces. + */ +extern DECLSPEC int SDLCALL SDL_SetSurfacePalette(SDL_Surface * surface, + SDL_Palette * palette); + +/** + * \brief Sets up a surface for directly accessing the pixels. + * + * Between calls to SDL_LockSurface() / SDL_UnlockSurface(), you can write + * to and read from \c surface->pixels, using the pixel format stored in + * \c 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. + * + * 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. + * + * \sa SDL_UnlockSurface() + */ +extern DECLSPEC int SDLCALL SDL_LockSurface(SDL_Surface * surface); +/** \sa SDL_LockSurface() */ +extern DECLSPEC void SDLCALL SDL_UnlockSurface(SDL_Surface * surface); + +/** + * Load a surface from a seekable SDL data stream (memory or file). + * + * If \c freesrc is non-zero, the stream will be closed after being read. + * + * The new surface should be freed with SDL_FreeSurface(). + * + * \return the new surface, or NULL if there was an error. + */ +extern DECLSPEC SDL_Surface *SDLCALL SDL_LoadBMP_RW(SDL_RWops * src, + int freesrc); + +/** + * Load a surface from a file. + * + * Convenience macro. + */ +#define SDL_LoadBMP(file) SDL_LoadBMP_RW(SDL_RWFromFile(file, "rb"), 1) + +/** + * Save a surface to a seekable SDL data stream (memory or file). + * + * Surfaces with a 24-bit, 32-bit and paletted 8-bit format get saved in the + * BMP directly. Other RGB formats with 8-bit or higher get converted to a + * 24-bit surface or, if they have an alpha mask or a colorkey, to a 32-bit + * surface before they are saved. YUV and paletted 1-bit and 4-bit formats are + * not supported. + * + * If \c freedst is non-zero, the stream will be closed after being written. + * + * \return 0 if successful or -1 if there was an error. + */ +extern DECLSPEC int SDLCALL SDL_SaveBMP_RW + (SDL_Surface * surface, SDL_RWops * dst, int freedst); + +/** + * Save a surface to a file. + * + * Convenience macro. + */ +#define SDL_SaveBMP(surface, file) \ + SDL_SaveBMP_RW(surface, SDL_RWFromFile(file, "wb"), 1) + +/** + * \brief Sets the RLE acceleration hint for a surface. + * + * \return 0 on success, or -1 if the surface is not valid + * + * \note If RLE is enabled, colorkey and alpha blending blits are much faster, + * but the surface must be locked before directly accessing the pixels. + */ +extern DECLSPEC int SDLCALL SDL_SetSurfaceRLE(SDL_Surface * surface, + int flag); + +/** + * \brief Sets the color key (transparent pixel) in a blittable surface. + * + * \param surface The surface to update + * \param flag Non-zero to enable colorkey and 0 to disable colorkey + * \param key The transparent pixel in the native surface format + * + * \return 0 on success, or -1 if the surface is not valid + * + * You can pass SDL_RLEACCEL to enable RLE accelerated blits. + */ +extern DECLSPEC int SDLCALL SDL_SetColorKey(SDL_Surface * surface, + int flag, Uint32 key); + +/** + * \brief Returns whether the surface has a color key + * + * \return SDL_TRUE if the surface has a color key, or SDL_FALSE if the surface is NULL or has no color key + */ +extern DECLSPEC SDL_bool SDLCALL SDL_HasColorKey(SDL_Surface * surface); + +/** + * \brief Gets the color key (transparent pixel) in a blittable surface. + * + * \param surface The surface to update + * \param key A pointer filled in with the transparent pixel in the native + * surface format + * + * \return 0 on success, or -1 if the surface is not valid or colorkey is not + * enabled. + */ +extern DECLSPEC int SDLCALL SDL_GetColorKey(SDL_Surface * surface, + Uint32 * key); + +/** + * \brief Set an additional color value used in blit operations. + * + * \param surface The surface to update. + * \param r The red color value multiplied into blit operations. + * \param g The green color value multiplied into blit operations. + * \param b The blue color value multiplied into blit operations. + * + * \return 0 on success, or -1 if the surface is not valid. + * + * \sa SDL_GetSurfaceColorMod() + */ +extern DECLSPEC int SDLCALL SDL_SetSurfaceColorMod(SDL_Surface * surface, + Uint8 r, Uint8 g, Uint8 b); + + +/** + * \brief Get the additional color value used in blit operations. + * + * \param surface The surface to query. + * \param r A pointer filled in with the current red color value. + * \param g A pointer filled in with the current green color value. + * \param b A pointer filled in with the current blue color value. + * + * \return 0 on success, or -1 if the surface is not valid. + * + * \sa SDL_SetSurfaceColorMod() + */ +extern DECLSPEC int SDLCALL SDL_GetSurfaceColorMod(SDL_Surface * surface, + Uint8 * r, Uint8 * g, + Uint8 * b); + +/** + * \brief Set an additional alpha value used in blit operations. + * + * \param surface The surface to update. + * \param alpha The alpha value multiplied into blit operations. + * + * \return 0 on success, or -1 if the surface is not valid. + * + * \sa SDL_GetSurfaceAlphaMod() + */ +extern DECLSPEC int SDLCALL SDL_SetSurfaceAlphaMod(SDL_Surface * surface, + Uint8 alpha); + +/** + * \brief Get the additional alpha value used in blit operations. + * + * \param surface The surface to query. + * \param alpha A pointer filled in with the current alpha value. + * + * \return 0 on success, or -1 if the surface is not valid. + * + * \sa SDL_SetSurfaceAlphaMod() + */ +extern DECLSPEC int SDLCALL SDL_GetSurfaceAlphaMod(SDL_Surface * surface, + Uint8 * alpha); + +/** + * \brief Set the blend mode used for blit operations. + * + * \param surface The surface to update. + * \param blendMode ::SDL_BlendMode to use for blit blending. + * + * \return 0 on success, or -1 if the parameters are not valid. + * + * \sa SDL_GetSurfaceBlendMode() + */ +extern DECLSPEC int SDLCALL SDL_SetSurfaceBlendMode(SDL_Surface * surface, + SDL_BlendMode blendMode); + +/** + * \brief Get the blend mode used for blit operations. + * + * \param surface The surface to query. + * \param blendMode A pointer filled in with the current blend mode. + * + * \return 0 on success, or -1 if the surface is not valid. + * + * \sa SDL_SetSurfaceBlendMode() + */ +extern DECLSPEC int SDLCALL SDL_GetSurfaceBlendMode(SDL_Surface * surface, + SDL_BlendMode *blendMode); + +/** + * 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. + */ +extern DECLSPEC SDL_bool SDLCALL SDL_SetClipRect(SDL_Surface * surface, + const SDL_Rect * rect); + +/** + * Gets the clipping rectangle for the destination surface in a blit. + * + * \c rect must be a pointer to a valid rectangle which will be filled + * with the correct values. + */ +extern DECLSPEC void SDLCALL SDL_GetClipRect(SDL_Surface * surface, + SDL_Rect * rect); + +/* + * Creates a new surface identical to the existing surface + */ +extern DECLSPEC SDL_Surface *SDLCALL SDL_DuplicateSurface(SDL_Surface * surface); + +/** + * 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 \c 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. + */ +extern DECLSPEC SDL_Surface *SDLCALL SDL_ConvertSurface + (SDL_Surface * src, const SDL_PixelFormat * fmt, Uint32 flags); +extern DECLSPEC SDL_Surface *SDLCALL SDL_ConvertSurfaceFormat + (SDL_Surface * src, Uint32 pixel_format, Uint32 flags); + +/** + * \brief Copy a block of pixels of one format to another format + * + * \return 0 on success, or -1 if there was an error + */ +extern DECLSPEC int SDLCALL SDL_ConvertPixels(int width, int height, + Uint32 src_format, + const void * src, int src_pitch, + Uint32 dst_format, + void * dst, int dst_pitch); + +/** + * Performs a fast fill of the given rectangle with \c color. + * + * If \c rect is NULL, the whole surface will be filled with \c color. + * + * The color should be a pixel of the format used by the surface, and + * can be generated by the SDL_MapRGB() function. + * + * \return 0 on success, or -1 on error. + */ +extern DECLSPEC int SDLCALL SDL_FillRect + (SDL_Surface * dst, const SDL_Rect * rect, Uint32 color); +extern DECLSPEC int SDLCALL SDL_FillRects + (SDL_Surface * dst, const SDL_Rect * rects, int count, Uint32 color); + +/** + * Performs a fast blit from the source surface to the destination surface. + * + * This assumes that the source and destination rectangles are + * the same size. If either \c srcrect or \c dstrect are NULL, the entire + * surface (\c src or \c dst) is copied. The final blit rectangles are saved + * in \c srcrect and \c dstrect after all clipping is performed. + * + * \return 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 blending and colorkey + * are defined as follows: + * \verbatim + RGBA->RGB: + Source surface blend mode set to SDL_BLENDMODE_BLEND: + alpha-blend (using the source alpha-channel and per-surface alpha) + SDL_SRCCOLORKEY ignored. + Source surface blend mode set to SDL_BLENDMODE_NONE: + copy RGB. + if SDL_SRCCOLORKEY set, only copy the pixels matching the + RGB values of the source color key, ignoring alpha in the + comparison. + + RGB->RGBA: + Source surface blend mode set to SDL_BLENDMODE_BLEND: + alpha-blend (using the source per-surface alpha) + Source surface blend mode set to SDL_BLENDMODE_NONE: + copy RGB, set destination alpha to source per-surface alpha value. + both: + if SDL_SRCCOLORKEY set, only copy the pixels matching the + source color key. + + RGBA->RGBA: + Source surface blend mode set to SDL_BLENDMODE_BLEND: + alpha-blend (using the source alpha-channel and per-surface alpha) + SDL_SRCCOLORKEY ignored. + Source surface blend mode set to SDL_BLENDMODE_NONE: + copy all of RGBA to the destination. + if SDL_SRCCOLORKEY set, only copy the pixels matching the + RGB values of the source color key, ignoring alpha in the + comparison. + + RGB->RGB: + Source surface blend mode set to SDL_BLENDMODE_BLEND: + alpha-blend (using the source per-surface alpha) + Source surface blend mode set to SDL_BLENDMODE_NONE: + copy RGB. + both: + if SDL_SRCCOLORKEY set, only copy the pixels matching the + source color key. + \endverbatim + * + * You should call SDL_BlitSurface() unless you know exactly how SDL + * blitting works internally and how to use the other blit functions. + */ +#define SDL_BlitSurface SDL_UpperBlit + +/** + * This is the public blit function, SDL_BlitSurface(), and it performs + * rectangle validation and clipping before passing it to SDL_LowerBlit() + */ +extern DECLSPEC int SDLCALL SDL_UpperBlit + (SDL_Surface * src, const SDL_Rect * srcrect, + SDL_Surface * dst, SDL_Rect * dstrect); + +/** + * This is a semi-private blit function and it performs low-level surface + * blitting only. + */ +extern DECLSPEC int SDLCALL SDL_LowerBlit + (SDL_Surface * src, SDL_Rect * srcrect, + SDL_Surface * dst, SDL_Rect * dstrect); + +/** + * \brief Perform a fast, low quality, stretch blit between two surfaces of the + * same pixel format. + * + * \note This function uses a static buffer, and is not thread-safe. + */ +extern DECLSPEC int SDLCALL SDL_SoftStretch(SDL_Surface * src, + const SDL_Rect * srcrect, + SDL_Surface * dst, + const SDL_Rect * dstrect); + +#define SDL_BlitScaled SDL_UpperBlitScaled + +/** + * This is the public scaled blit function, SDL_BlitScaled(), and it performs + * rectangle validation and clipping before passing it to SDL_LowerBlitScaled() + */ +extern DECLSPEC int SDLCALL SDL_UpperBlitScaled + (SDL_Surface * src, const SDL_Rect * srcrect, + SDL_Surface * dst, SDL_Rect * dstrect); + +/** + * This is a semi-private blit function and it performs low-level surface + * scaled blitting only. + */ +extern DECLSPEC int SDLCALL SDL_LowerBlitScaled + (SDL_Surface * src, SDL_Rect * srcrect, + SDL_Surface * dst, SDL_Rect * dstrect); + +/** + * \brief Set the YUV conversion mode + */ +extern DECLSPEC void SDLCALL SDL_SetYUVConversionMode(SDL_YUV_CONVERSION_MODE mode); + +/** + * \brief Get the YUV conversion mode + */ +extern DECLSPEC SDL_YUV_CONVERSION_MODE SDLCALL SDL_GetYUVConversionMode(void); + +/** + * \brief Get the YUV conversion mode, returning the correct mode for the resolution when the current conversion mode is SDL_YUV_CONVERSION_AUTOMATIC + */ +extern DECLSPEC SDL_YUV_CONVERSION_MODE SDLCALL SDL_GetYUVConversionModeForResolution(int width, int height); + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_surface_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/engine/Windows/SDL2/include/SDL_system.h b/engine/Windows/SDL2/include/SDL_system.h new file mode 100644 index 0000000..3b08407 --- /dev/null +++ b/engine/Windows/SDL2/include/SDL_system.h @@ -0,0 +1,279 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2019 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_system.h + * + * Include file for platform specific SDL API functions + */ + +#ifndef SDL_system_h_ +#define SDL_system_h_ + +#include "SDL_stdinc.h" +#include "SDL_keyboard.h" +#include "SDL_render.h" +#include "SDL_video.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + + +/* Platform specific functions for Windows */ +#ifdef __WIN32__ + +/** + \brief Set a function that is called for every windows message, before TranslateMessage() +*/ +typedef void (SDLCALL * SDL_WindowsMessageHook)(void *userdata, void *hWnd, unsigned int message, Uint64 wParam, Sint64 lParam); +extern DECLSPEC void SDLCALL SDL_SetWindowsMessageHook(SDL_WindowsMessageHook callback, void *userdata); + +/** + \brief Returns the D3D9 adapter index that matches the specified display index. + + This adapter index can be passed to IDirect3D9::CreateDevice and controls + on which monitor a full screen application will appear. +*/ +extern DECLSPEC int SDLCALL SDL_Direct3D9GetAdapterIndex( int displayIndex ); + +typedef struct IDirect3DDevice9 IDirect3DDevice9; +/** + \brief Returns the D3D device associated with a renderer, or NULL if it's not a D3D renderer. + + Once you are done using the device, you should release it to avoid a resource leak. + */ +extern DECLSPEC IDirect3DDevice9* SDLCALL SDL_RenderGetD3D9Device(SDL_Renderer * renderer); + +/** + \brief Returns the DXGI Adapter and Output indices for the specified display index. + + These can be passed to EnumAdapters and EnumOutputs respectively to get the objects + required to create a DX10 or DX11 device and swap chain. + */ +extern DECLSPEC SDL_bool SDLCALL SDL_DXGIGetOutputInfo( int displayIndex, int *adapterIndex, int *outputIndex ); + +#endif /* __WIN32__ */ + + +/* Platform specific functions for Linux */ +#ifdef __LINUX__ + +/** + \brief Sets the UNIX nice value for a thread, using setpriority() if possible, and RealtimeKit if available. + + \return 0 on success, or -1 on error. + */ +extern DECLSPEC int SDLCALL SDL_LinuxSetThreadPriority(Sint64 threadID, int priority); + +#endif /* __LINUX__ */ + +/* Platform specific functions for iOS */ +#if defined(__IPHONEOS__) && __IPHONEOS__ + +#define SDL_iOSSetAnimationCallback(window, interval, callback, callbackParam) SDL_iPhoneSetAnimationCallback(window, interval, callback, callbackParam) +extern DECLSPEC int SDLCALL SDL_iPhoneSetAnimationCallback(SDL_Window * window, int interval, void (*callback)(void*), void *callbackParam); + +#define SDL_iOSSetEventPump(enabled) SDL_iPhoneSetEventPump(enabled) +extern DECLSPEC void SDLCALL SDL_iPhoneSetEventPump(SDL_bool enabled); + +#endif /* __IPHONEOS__ */ + + +/* Platform specific functions for Android */ +#if defined(__ANDROID__) && __ANDROID__ + +/** + \brief Get the JNI environment for the current thread + + This returns JNIEnv*, but the prototype is void* so we don't need jni.h + */ +extern DECLSPEC void * SDLCALL SDL_AndroidGetJNIEnv(void); + +/** + \brief Get the SDL Activity object for the application + + This returns jobject, but the prototype is void* so we don't need jni.h + The jobject returned by SDL_AndroidGetActivity is a local reference. + It is the caller's responsibility to properly release it + (using env->Push/PopLocalFrame or manually with env->DeleteLocalRef) + */ +extern DECLSPEC void * SDLCALL SDL_AndroidGetActivity(void); + +/** + \brief Return true if the application is running on Android TV + */ +extern DECLSPEC SDL_bool SDLCALL SDL_IsAndroidTV(void); + +/** + \brief Return true if the application is running on a Chromebook + */ +extern DECLSPEC SDL_bool SDLCALL SDL_IsChromebook(void); + +/** + \brief Return true is the application is running on a Samsung DeX docking station + */ +extern DECLSPEC SDL_bool SDLCALL SDL_IsDeXMode(void); + +/** + \brief Trigger the Android system back button behavior. + */ +extern DECLSPEC void SDLCALL SDL_AndroidBackButton(void); + +/** + See the official Android developer guide for more information: + http://developer.android.com/guide/topics/data/data-storage.html +*/ +#define SDL_ANDROID_EXTERNAL_STORAGE_READ 0x01 +#define SDL_ANDROID_EXTERNAL_STORAGE_WRITE 0x02 + +/** + \brief Get the path used for internal storage for this application. + + This path is unique to your application and cannot be written to + by other applications. + */ +extern DECLSPEC const char * SDLCALL SDL_AndroidGetInternalStoragePath(void); + +/** + \brief Get the current state of external storage, a bitmask of these values: + SDL_ANDROID_EXTERNAL_STORAGE_READ + SDL_ANDROID_EXTERNAL_STORAGE_WRITE + + If external storage is currently unavailable, this will return 0. +*/ +extern DECLSPEC int SDLCALL SDL_AndroidGetExternalStorageState(void); + +/** + \brief Get the path used for external storage for this application. + + This path is unique to your application, but is public and can be + written to by other applications. + */ +extern DECLSPEC const char * SDLCALL SDL_AndroidGetExternalStoragePath(void); + +#endif /* __ANDROID__ */ + +/* Platform specific functions for WinRT */ +#if defined(__WINRT__) && __WINRT__ + +/** + * \brief WinRT / Windows Phone path types + */ +typedef enum +{ + /** \brief The installed app's root directory. + Files here are likely to be read-only. */ + SDL_WINRT_PATH_INSTALLED_LOCATION, + + /** \brief The app's local data store. Files may be written here */ + SDL_WINRT_PATH_LOCAL_FOLDER, + + /** \brief The app's roaming data store. Unsupported on Windows Phone. + Files written here may be copied to other machines via a network + connection. + */ + SDL_WINRT_PATH_ROAMING_FOLDER, + + /** \brief The app's temporary data store. Unsupported on Windows Phone. + Files written here may be deleted at any time. */ + SDL_WINRT_PATH_TEMP_FOLDER +} SDL_WinRT_Path; + + +/** + * \brief WinRT Device Family + */ +typedef enum +{ + /** \brief Unknown family */ + SDL_WINRT_DEVICEFAMILY_UNKNOWN, + + /** \brief Desktop family*/ + SDL_WINRT_DEVICEFAMILY_DESKTOP, + + /** \brief Mobile family (for example smartphone) */ + SDL_WINRT_DEVICEFAMILY_MOBILE, + + /** \brief XBox family */ + SDL_WINRT_DEVICEFAMILY_XBOX, +} SDL_WinRT_DeviceFamily; + + +/** + * \brief Retrieves a WinRT defined path on the local file system + * + * \note Documentation on most app-specific path types on WinRT + * can be found on MSDN, at the URL: + * http://msdn.microsoft.com/en-us/library/windows/apps/hh464917.aspx + * + * \param pathType The type of path to retrieve. + * \return A UCS-2 string (16-bit, wide-char) containing the path, or NULL + * if the path is not available for any reason. Not all paths are + * available on all versions of Windows. This is especially true on + * Windows Phone. Check the documentation for the given + * SDL_WinRT_Path for more information on which path types are + * supported where. + */ +extern DECLSPEC const wchar_t * SDLCALL SDL_WinRTGetFSPathUNICODE(SDL_WinRT_Path pathType); + +/** + * \brief Retrieves a WinRT defined path on the local file system + * + * \note Documentation on most app-specific path types on WinRT + * can be found on MSDN, at the URL: + * http://msdn.microsoft.com/en-us/library/windows/apps/hh464917.aspx + * + * \param pathType The type of path to retrieve. + * \return A UTF-8 string (8-bit, multi-byte) containing the path, or NULL + * if the path is not available for any reason. Not all paths are + * available on all versions of Windows. This is especially true on + * Windows Phone. Check the documentation for the given + * SDL_WinRT_Path for more information on which path types are + * supported where. + */ +extern DECLSPEC const char * SDLCALL SDL_WinRTGetFSPathUTF8(SDL_WinRT_Path pathType); + +/** + * \brief Detects the device family of WinRT plattform on runtime + * + * \return Device family + */ +extern DECLSPEC SDL_WinRT_DeviceFamily SDLCALL SDL_WinRTGetDeviceFamily(); + +#endif /* __WINRT__ */ + +/** + \brief Return true if the current device is a tablet. + */ +extern DECLSPEC SDL_bool SDLCALL SDL_IsTablet(void); + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_system_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/engine/Windows/SDL2/include/SDL_syswm.h b/engine/Windows/SDL2/include/SDL_syswm.h new file mode 100644 index 0000000..1469b23 --- /dev/null +++ b/engine/Windows/SDL2/include/SDL_syswm.h @@ -0,0 +1,330 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2019 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_syswm.h + * + * Include file for SDL custom system window manager hooks. + */ + +#ifndef SDL_syswm_h_ +#define SDL_syswm_h_ + +#include "SDL_stdinc.h" +#include "SDL_error.h" +#include "SDL_video.h" +#include "SDL_version.h" + +/** + * \brief SDL_syswm.h + * + * Your application has access to a special type of event ::SDL_SYSWMEVENT, + * which contains window-manager specific information and arrives whenever + * an unhandled window event occurs. This event is ignored by default, but + * you can enable it with SDL_EventState(). + */ +struct SDL_SysWMinfo; + +#if !defined(SDL_PROTOTYPES_ONLY) + +#if defined(SDL_VIDEO_DRIVER_WINDOWS) +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN +#endif +#ifndef NOMINMAX /* don't define min() and max(). */ +#define NOMINMAX +#endif +#include +#endif + +#if defined(SDL_VIDEO_DRIVER_WINRT) +#include +#endif + +/* This is the structure for custom window manager events */ +#if defined(SDL_VIDEO_DRIVER_X11) +#if defined(__APPLE__) && defined(__MACH__) +/* conflicts with Quickdraw.h */ +#define Cursor X11Cursor +#endif + +#include +#include + +#if defined(__APPLE__) && defined(__MACH__) +/* matches the re-define above */ +#undef Cursor +#endif + +#endif /* defined(SDL_VIDEO_DRIVER_X11) */ + +#if defined(SDL_VIDEO_DRIVER_DIRECTFB) +#include +#endif + +#if defined(SDL_VIDEO_DRIVER_COCOA) +#ifdef __OBJC__ +@class NSWindow; +#else +typedef struct _NSWindow NSWindow; +#endif +#endif + +#if defined(SDL_VIDEO_DRIVER_UIKIT) +#ifdef __OBJC__ +#include +#else +typedef struct _UIWindow UIWindow; +typedef struct _UIViewController UIViewController; +#endif +typedef Uint32 GLuint; +#endif + +#if defined(SDL_VIDEO_DRIVER_ANDROID) +typedef struct ANativeWindow ANativeWindow; +typedef void *EGLSurface; +#endif + +#if defined(SDL_VIDEO_DRIVER_VIVANTE) +#include "SDL_egl.h" +#endif +#endif /* SDL_PROTOTYPES_ONLY */ + + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +#if !defined(SDL_PROTOTYPES_ONLY) +/** + * These are the various supported windowing subsystems + */ +typedef enum +{ + SDL_SYSWM_UNKNOWN, + SDL_SYSWM_WINDOWS, + SDL_SYSWM_X11, + SDL_SYSWM_DIRECTFB, + SDL_SYSWM_COCOA, + SDL_SYSWM_UIKIT, + SDL_SYSWM_WAYLAND, + SDL_SYSWM_MIR, /* no longer available, left for API/ABI compatibility. Remove in 2.1! */ + SDL_SYSWM_WINRT, + SDL_SYSWM_ANDROID, + SDL_SYSWM_VIVANTE, + SDL_SYSWM_OS2 +} SDL_SYSWM_TYPE; + +/** + * The custom event structure. + */ +struct SDL_SysWMmsg +{ + SDL_version version; + SDL_SYSWM_TYPE subsystem; + union + { +#if defined(SDL_VIDEO_DRIVER_WINDOWS) + struct { + HWND hwnd; /**< The window for the message */ + UINT msg; /**< The type of message */ + WPARAM wParam; /**< WORD message parameter */ + LPARAM lParam; /**< LONG message parameter */ + } win; +#endif +#if defined(SDL_VIDEO_DRIVER_X11) + struct { + XEvent event; + } x11; +#endif +#if defined(SDL_VIDEO_DRIVER_DIRECTFB) + struct { + DFBEvent event; + } dfb; +#endif +#if defined(SDL_VIDEO_DRIVER_COCOA) + struct + { + /* Latest version of Xcode clang complains about empty structs in C v. C++: + error: empty struct has size 0 in C, size 1 in C++ + */ + int dummy; + /* No Cocoa window events yet */ + } cocoa; +#endif +#if defined(SDL_VIDEO_DRIVER_UIKIT) + struct + { + int dummy; + /* No UIKit window events yet */ + } uikit; +#endif +#if defined(SDL_VIDEO_DRIVER_VIVANTE) + struct + { + int dummy; + /* No Vivante window events yet */ + } vivante; +#endif + /* Can't have an empty union */ + int dummy; + } msg; +}; + +/** + * The custom window manager information structure. + * + * When this structure is returned, it holds information about which + * low level system it is using, and will be one of SDL_SYSWM_TYPE. + */ +struct SDL_SysWMinfo +{ + SDL_version version; + SDL_SYSWM_TYPE subsystem; + union + { +#if defined(SDL_VIDEO_DRIVER_WINDOWS) + struct + { + HWND window; /**< The window handle */ + HDC hdc; /**< The window device context */ + HINSTANCE hinstance; /**< The instance handle */ + } win; +#endif +#if defined(SDL_VIDEO_DRIVER_WINRT) + struct + { + IInspectable * window; /**< The WinRT CoreWindow */ + } winrt; +#endif +#if defined(SDL_VIDEO_DRIVER_X11) + struct + { + Display *display; /**< The X11 display */ + Window window; /**< The X11 window */ + } x11; +#endif +#if defined(SDL_VIDEO_DRIVER_DIRECTFB) + struct + { + IDirectFB *dfb; /**< The directfb main interface */ + IDirectFBWindow *window; /**< The directfb window handle */ + IDirectFBSurface *surface; /**< The directfb client surface */ + } dfb; +#endif +#if defined(SDL_VIDEO_DRIVER_COCOA) + struct + { +#if defined(__OBJC__) && defined(__has_feature) && __has_feature(objc_arc) + NSWindow __unsafe_unretained *window; /**< The Cocoa window */ +#else + NSWindow *window; /**< The Cocoa window */ +#endif + } cocoa; +#endif +#if defined(SDL_VIDEO_DRIVER_UIKIT) + struct + { +#if defined(__OBJC__) && defined(__has_feature) && __has_feature(objc_arc) + UIWindow __unsafe_unretained *window; /**< The UIKit window */ +#else + UIWindow *window; /**< The UIKit window */ +#endif + GLuint framebuffer; /**< The GL view's Framebuffer Object. It must be bound when rendering to the screen using GL. */ + GLuint colorbuffer; /**< The GL view's color Renderbuffer Object. It must be bound when SDL_GL_SwapWindow is called. */ + GLuint resolveFramebuffer; /**< The Framebuffer Object which holds the resolve color Renderbuffer, when MSAA is used. */ + } uikit; +#endif +#if defined(SDL_VIDEO_DRIVER_WAYLAND) + struct + { + struct wl_display *display; /**< Wayland display */ + struct wl_surface *surface; /**< Wayland surface */ + struct wl_shell_surface *shell_surface; /**< Wayland shell_surface (window manager handle) */ + } wl; +#endif +#if defined(SDL_VIDEO_DRIVER_MIR) /* no longer available, left for API/ABI compatibility. Remove in 2.1! */ + struct + { + void *connection; /**< Mir display server connection */ + void *surface; /**< Mir surface */ + } mir; +#endif + +#if defined(SDL_VIDEO_DRIVER_ANDROID) + struct + { + ANativeWindow *window; + EGLSurface surface; + } android; +#endif + +#if defined(SDL_VIDEO_DRIVER_VIVANTE) + struct + { + EGLNativeDisplayType display; + EGLNativeWindowType window; + } vivante; +#endif + + /* Make sure this union is always 64 bytes (8 64-bit pointers). */ + /* Be careful not to overflow this if you add a new target! */ + Uint8 dummy[64]; + } info; +}; + +#endif /* SDL_PROTOTYPES_ONLY */ + +typedef struct SDL_SysWMinfo SDL_SysWMinfo; + +/* Function prototypes */ +/** + * \brief This function allows access to driver-dependent window information. + * + * \param window The window about which information is being requested + * \param info This structure must be initialized with the SDL version, and is + * then filled in with information about the given window. + * + * \return SDL_TRUE if the function is implemented and the version member of + * the \c info struct is valid, SDL_FALSE otherwise. + * + * You typically use this function like this: + * \code + * SDL_SysWMinfo info; + * SDL_VERSION(&info.version); + * if ( SDL_GetWindowWMInfo(window, &info) ) { ... } + * \endcode + */ +extern DECLSPEC SDL_bool SDLCALL SDL_GetWindowWMInfo(SDL_Window * window, + SDL_SysWMinfo * info); + + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_syswm_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/engine/Windows/SDL2/include/SDL_thread.h b/engine/Windows/SDL2/include/SDL_thread.h new file mode 100644 index 0000000..f78b114 --- /dev/null +++ b/engine/Windows/SDL2/include/SDL_thread.h @@ -0,0 +1,343 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2019 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef SDL_thread_h_ +#define SDL_thread_h_ + +/** + * \file SDL_thread.h + * + * Header for the SDL thread management routines. + */ + +#include "SDL_stdinc.h" +#include "SDL_error.h" + +/* Thread synchronization primitives */ +#include "SDL_atomic.h" +#include "SDL_mutex.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/* The SDL thread structure, defined in SDL_thread.c */ +struct SDL_Thread; +typedef struct SDL_Thread SDL_Thread; + +/* The SDL thread ID */ +typedef unsigned long SDL_threadID; + +/* Thread local storage ID, 0 is the invalid ID */ +typedef unsigned int SDL_TLSID; + +/** + * The SDL thread priority. + * + * \note On many systems you require special privileges to set high or time critical priority. + */ +typedef enum { + SDL_THREAD_PRIORITY_LOW, + SDL_THREAD_PRIORITY_NORMAL, + SDL_THREAD_PRIORITY_HIGH, + SDL_THREAD_PRIORITY_TIME_CRITICAL +} SDL_ThreadPriority; + +/** + * The function passed to SDL_CreateThread(). + * It is passed a void* user context parameter and returns an int. + */ +typedef int (SDLCALL * SDL_ThreadFunction) (void *data); + +#if defined(__WIN32__) && !defined(HAVE_LIBC) +/** + * \file SDL_thread.h + * + * We compile SDL into a DLL. This means, that it's the DLL which + * creates a new thread for the calling process with the SDL_CreateThread() + * API. There is a problem with this, that only the RTL of the SDL2.DLL will + * be initialized for those threads, and not the RTL of the calling + * application! + * + * To solve this, we make a little hack here. + * + * We'll always use the caller's _beginthread() and _endthread() APIs to + * start a new thread. This way, if it's the SDL2.DLL which uses this API, + * then the RTL of SDL2.DLL will be used to create the new thread, and if it's + * the application, then the RTL of the application will be used. + * + * So, in short: + * Always use the _beginthread() and _endthread() of the calling runtime + * library! + */ +#define SDL_PASSED_BEGINTHREAD_ENDTHREAD +#include /* _beginthreadex() and _endthreadex() */ + +typedef uintptr_t(__cdecl * pfnSDL_CurrentBeginThread) + (void *, unsigned, unsigned (__stdcall *func)(void *), + void * /*arg*/, unsigned, unsigned * /* threadID */); +typedef void (__cdecl * pfnSDL_CurrentEndThread) (unsigned code); + +/** + * Create a thread. + */ +extern DECLSPEC SDL_Thread *SDLCALL +SDL_CreateThread(SDL_ThreadFunction fn, const char *name, void *data, + pfnSDL_CurrentBeginThread pfnBeginThread, + pfnSDL_CurrentEndThread pfnEndThread); + +extern DECLSPEC SDL_Thread *SDLCALL +SDL_CreateThreadWithStackSize(int (SDLCALL * fn) (void *), + const char *name, const size_t stacksize, void *data, + pfnSDL_CurrentBeginThread pfnBeginThread, + pfnSDL_CurrentEndThread pfnEndThread); + + +/** + * Create a thread. + */ +#if defined(SDL_CreateThread) && SDL_DYNAMIC_API +#undef SDL_CreateThread +#define SDL_CreateThread(fn, name, data) SDL_CreateThread_REAL(fn, name, data, (pfnSDL_CurrentBeginThread)_beginthreadex, (pfnSDL_CurrentEndThread)_endthreadex) +#undef SDL_CreateThreadWithStackSize +#define SDL_CreateThreadWithStackSize(fn, name, stacksize, data) SDL_CreateThreadWithStackSize_REAL(fn, name, stacksize, data, (pfnSDL_CurrentBeginThread)_beginthreadex, (pfnSDL_CurrentEndThread)_endthreadex) +#else +#define SDL_CreateThread(fn, name, data) SDL_CreateThread(fn, name, data, (pfnSDL_CurrentBeginThread)_beginthreadex, (pfnSDL_CurrentEndThread)_endthreadex) +#define SDL_CreateThreadWithStackSize(fn, name, stacksize, data) SDL_CreateThreadWithStackSize(fn, name, data, (pfnSDL_CurrentBeginThread)_beginthreadex, (pfnSDL_CurrentEndThread)_endthreadex) +#endif + +#elif defined(__OS2__) +/* + * just like the windows case above: We compile SDL2 + * into a dll with Watcom's runtime statically linked. + */ +#define SDL_PASSED_BEGINTHREAD_ENDTHREAD +#ifndef __EMX__ +#include +#else +#include +#endif +typedef int (*pfnSDL_CurrentBeginThread)(void (*func)(void *), void *, unsigned, void * /*arg*/); +typedef void (*pfnSDL_CurrentEndThread)(void); +extern DECLSPEC SDL_Thread *SDLCALL +SDL_CreateThread(SDL_ThreadFunction fn, const char *name, void *data, + pfnSDL_CurrentBeginThread pfnBeginThread, + pfnSDL_CurrentEndThread pfnEndThread); +extern DECLSPEC SDL_Thread *SDLCALL +SDL_CreateThreadWithStackSize(SDL_ThreadFunction fn, const char *name, const size_t stacksize, void *data, + pfnSDL_CurrentBeginThread pfnBeginThread, + pfnSDL_CurrentEndThread pfnEndThread); +#if defined(SDL_CreateThread) && SDL_DYNAMIC_API +#undef SDL_CreateThread +#define SDL_CreateThread(fn, name, data) SDL_CreateThread_REAL(fn, name, data, (pfnSDL_CurrentBeginThread)_beginthread, (pfnSDL_CurrentEndThread)_endthread) +#undef SDL_CreateThreadWithStackSize +#define SDL_CreateThreadWithStackSize(fn, name, stacksize, data) SDL_CreateThreadWithStackSize_REAL(fn, name, data, (pfnSDL_CurrentBeginThread)_beginthread, (pfnSDL_CurrentEndThread)_endthread) +#else +#define SDL_CreateThread(fn, name, data) SDL_CreateThread(fn, name, data, (pfnSDL_CurrentBeginThread)_beginthread, (pfnSDL_CurrentEndThread)_endthread) +#define SDL_CreateThreadWithStackSize(fn, name, stacksize, data) SDL_CreateThreadWithStackSize(fn, name, stacksize, data, (pfnSDL_CurrentBeginThread)_beginthread, (pfnSDL_CurrentEndThread)_endthread) +#endif + +#else + +/** + * Create a thread with a default stack size. + * + * This is equivalent to calling: + * SDL_CreateThreadWithStackSize(fn, name, 0, data); + */ +extern DECLSPEC SDL_Thread *SDLCALL +SDL_CreateThread(SDL_ThreadFunction fn, const char *name, void *data); + +/** + * Create a thread. + * + * Thread naming is a little complicated: Most systems have very small + * limits for the string length (Haiku has 32 bytes, Linux currently has 16, + * Visual C++ 6.0 has nine!), and possibly other arbitrary rules. You'll + * have to see what happens with your system's debugger. The name should be + * UTF-8 (but using the naming limits of C identifiers is a better bet). + * There are no requirements for thread naming conventions, so long as the + * string is null-terminated UTF-8, but these guidelines are helpful in + * choosing a name: + * + * http://stackoverflow.com/questions/149932/naming-conventions-for-threads + * + * If a system imposes requirements, SDL will try to munge the string for + * it (truncate, etc), but the original string contents will be available + * from SDL_GetThreadName(). + * + * The size (in bytes) of the new stack can be specified. Zero means "use + * the system default" which might be wildly different between platforms + * (x86 Linux generally defaults to eight megabytes, an embedded device + * might be a few kilobytes instead). + * + * In SDL 2.1, stacksize will be folded into the original SDL_CreateThread + * function. + */ +extern DECLSPEC SDL_Thread *SDLCALL +SDL_CreateThreadWithStackSize(SDL_ThreadFunction fn, const char *name, const size_t stacksize, void *data); + +#endif + +/** + * Get the thread name, as it was specified in SDL_CreateThread(). + * This function returns a pointer to a UTF-8 string that names the + * specified thread, or NULL if it doesn't have a name. This is internal + * memory, not to be free()'d by the caller, and remains valid until the + * specified thread is cleaned up by SDL_WaitThread(). + */ +extern DECLSPEC const char *SDLCALL SDL_GetThreadName(SDL_Thread *thread); + +/** + * Get the thread identifier for the current thread. + */ +extern DECLSPEC SDL_threadID SDLCALL SDL_ThreadID(void); + +/** + * Get the thread identifier for the specified thread. + * + * Equivalent to SDL_ThreadID() if the specified thread is NULL. + */ +extern DECLSPEC SDL_threadID SDLCALL SDL_GetThreadID(SDL_Thread * thread); + +/** + * Set the priority for the current thread + */ +extern DECLSPEC int SDLCALL SDL_SetThreadPriority(SDL_ThreadPriority priority); + +/** + * Wait for a thread to finish. Threads that haven't been detached will + * remain (as a "zombie") until this function cleans them up. Not doing so + * is a resource leak. + * + * Once a thread has been cleaned up through this function, the SDL_Thread + * that references it becomes invalid and should not be referenced again. + * As such, only one thread may call SDL_WaitThread() on another. + * + * The return code for the thread function is placed in the area + * pointed to by \c status, if \c status is not NULL. + * + * You may not wait on a thread that has been used in a call to + * SDL_DetachThread(). Use either that function or this one, but not + * both, or behavior is undefined. + * + * It is safe to pass NULL to this function; it is a no-op. + */ +extern DECLSPEC void SDLCALL SDL_WaitThread(SDL_Thread * thread, int *status); + +/** + * A thread may be "detached" to signify that it should not remain until + * another thread has called SDL_WaitThread() on it. Detaching a thread + * is useful for long-running threads that nothing needs to synchronize + * with or further manage. When a detached thread is done, it simply + * goes away. + * + * There is no way to recover the return code of a detached thread. If you + * need this, don't detach the thread and instead use SDL_WaitThread(). + * + * Once a thread is detached, you should usually assume the SDL_Thread isn't + * safe to reference again, as it will become invalid immediately upon + * the detached thread's exit, instead of remaining until someone has called + * SDL_WaitThread() to finally clean it up. As such, don't detach the same + * thread more than once. + * + * If a thread has already exited when passed to SDL_DetachThread(), it will + * stop waiting for a call to SDL_WaitThread() and clean up immediately. + * It is not safe to detach a thread that might be used with SDL_WaitThread(). + * + * You may not call SDL_WaitThread() on a thread that has been detached. + * Use either that function or this one, but not both, or behavior is + * undefined. + * + * It is safe to pass NULL to this function; it is a no-op. + */ +extern DECLSPEC void SDLCALL SDL_DetachThread(SDL_Thread * thread); + +/** + * \brief Create an identifier that is globally visible to all threads but refers to data that is thread-specific. + * + * \return The newly created thread local storage identifier, or 0 on error + * + * \code + * static SDL_SpinLock tls_lock; + * static SDL_TLSID thread_local_storage; + * + * void SetMyThreadData(void *value) + * { + * if (!thread_local_storage) { + * SDL_AtomicLock(&tls_lock); + * if (!thread_local_storage) { + * thread_local_storage = SDL_TLSCreate(); + * } + * SDL_AtomicUnlock(&tls_lock); + * } + * SDL_TLSSet(thread_local_storage, value, 0); + * } + * + * void *GetMyThreadData(void) + * { + * return SDL_TLSGet(thread_local_storage); + * } + * \endcode + * + * \sa SDL_TLSGet() + * \sa SDL_TLSSet() + */ +extern DECLSPEC SDL_TLSID SDLCALL SDL_TLSCreate(void); + +/** + * \brief Get the value associated with a thread local storage ID for the current thread. + * + * \param id The thread local storage ID + * + * \return The value associated with the ID for the current thread, or NULL if no value has been set. + * + * \sa SDL_TLSCreate() + * \sa SDL_TLSSet() + */ +extern DECLSPEC void * SDLCALL SDL_TLSGet(SDL_TLSID id); + +/** + * \brief Set the value associated with a thread local storage ID for the current thread. + * + * \param id The thread local storage ID + * \param value The value to associate with the ID for the current thread + * \param destructor A function called when the thread exits, to free the value. + * + * \return 0 on success, -1 on error + * + * \sa SDL_TLSCreate() + * \sa SDL_TLSGet() + */ +extern DECLSPEC int SDLCALL SDL_TLSSet(SDL_TLSID id, const void *value, void (SDLCALL *destructor)(void*)); + + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_thread_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/engine/Windows/SDL2/include/SDL_timer.h b/engine/Windows/SDL2/include/SDL_timer.h new file mode 100644 index 0000000..2a47b04 --- /dev/null +++ b/engine/Windows/SDL2/include/SDL_timer.h @@ -0,0 +1,115 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2019 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef SDL_timer_h_ +#define SDL_timer_h_ + +/** + * \file SDL_timer.h + * + * Header for the SDL time management routines. + */ + +#include "SDL_stdinc.h" +#include "SDL_error.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief Get the number of milliseconds since the SDL library initialization. + * + * \note This value wraps if the program runs for more than ~49 days. + */ +extern DECLSPEC Uint32 SDLCALL SDL_GetTicks(void); + +/** + * \brief Compare SDL ticks values, and return true if A has passed B + * + * e.g. if you want to wait 100 ms, you could do this: + * Uint32 timeout = SDL_GetTicks() + 100; + * while (!SDL_TICKS_PASSED(SDL_GetTicks(), timeout)) { + * ... do work until timeout has elapsed + * } + */ +#define SDL_TICKS_PASSED(A, B) ((Sint32)((B) - (A)) <= 0) + +/** + * \brief Get the current value of the high resolution counter + */ +extern DECLSPEC Uint64 SDLCALL SDL_GetPerformanceCounter(void); + +/** + * \brief Get the count per second of the high resolution counter + */ +extern DECLSPEC Uint64 SDLCALL SDL_GetPerformanceFrequency(void); + +/** + * \brief Wait a specified number of milliseconds before returning. + */ +extern DECLSPEC void SDLCALL SDL_Delay(Uint32 ms); + +/** + * Function prototype for the 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. + */ +typedef Uint32 (SDLCALL * SDL_TimerCallback) (Uint32 interval, void *param); + +/** + * Definition of the timer ID type. + */ +typedef int SDL_TimerID; + +/** + * \brief Add a new timer to the pool of timers already running. + * + * \return A timer ID, or 0 when an error occurs. + */ +extern DECLSPEC SDL_TimerID SDLCALL SDL_AddTimer(Uint32 interval, + SDL_TimerCallback callback, + void *param); + +/** + * \brief Remove a timer knowing its ID. + * + * \return A boolean value indicating success or failure. + * + * \warning It is not safe to remove a timer multiple times. + */ +extern DECLSPEC SDL_bool SDLCALL SDL_RemoveTimer(SDL_TimerID id); + + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_timer_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/engine/Windows/SDL2/include/SDL_touch.h b/engine/Windows/SDL2/include/SDL_touch.h new file mode 100644 index 0000000..99dbcb8 --- /dev/null +++ b/engine/Windows/SDL2/include/SDL_touch.h @@ -0,0 +1,102 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2019 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_touch.h + * + * Include file for SDL touch event handling. + */ + +#ifndef SDL_touch_h_ +#define SDL_touch_h_ + +#include "SDL_stdinc.h" +#include "SDL_error.h" +#include "SDL_video.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +typedef Sint64 SDL_TouchID; +typedef Sint64 SDL_FingerID; + +typedef enum +{ + SDL_TOUCH_DEVICE_INVALID = -1, + SDL_TOUCH_DEVICE_DIRECT, /* touch screen with window-relative coordinates */ + SDL_TOUCH_DEVICE_INDIRECT_ABSOLUTE, /* trackpad with absolute device coordinates */ + SDL_TOUCH_DEVICE_INDIRECT_RELATIVE /* trackpad with screen cursor-relative coordinates */ +} SDL_TouchDeviceType; + +typedef struct SDL_Finger +{ + SDL_FingerID id; + float x; + float y; + float pressure; +} SDL_Finger; + +/* Used as the device ID for mouse events simulated with touch input */ +#define SDL_TOUCH_MOUSEID ((Uint32)-1) + +/* Used as the SDL_TouchID for touch events simulated with mouse input */ +#define SDL_MOUSE_TOUCHID ((Sint64)-1) + + +/* Function prototypes */ + +/** + * \brief Get the number of registered touch devices. + */ +extern DECLSPEC int SDLCALL SDL_GetNumTouchDevices(void); + +/** + * \brief Get the touch ID with the given index, or 0 if the index is invalid. + */ +extern DECLSPEC SDL_TouchID SDLCALL SDL_GetTouchDevice(int index); + +/** + * \brief Get the type of the given touch device. + */ +extern DECLSPEC SDL_TouchDeviceType SDLCALL SDL_GetTouchDeviceType(SDL_TouchID touchID); + +/** + * \brief Get the number of active fingers for a given touch device. + */ +extern DECLSPEC int SDLCALL SDL_GetNumTouchFingers(SDL_TouchID touchID); + +/** + * \brief Get the finger object of the given touch, with the given index. + */ +extern DECLSPEC SDL_Finger * SDLCALL SDL_GetTouchFinger(SDL_TouchID touchID, int index); + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_touch_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/engine/Windows/SDL2/include/SDL_types.h b/engine/Windows/SDL2/include/SDL_types.h new file mode 100644 index 0000000..9c3e989 --- /dev/null +++ b/engine/Windows/SDL2/include/SDL_types.h @@ -0,0 +1,29 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2019 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_types.h + * + * \deprecated + */ + +/* DEPRECATED */ +#include "SDL_stdinc.h" diff --git a/engine/Windows/SDL2/include/SDL_version.h b/engine/Windows/SDL2/include/SDL_version.h new file mode 100644 index 0000000..69b0270 --- /dev/null +++ b/engine/Windows/SDL2/include/SDL_version.h @@ -0,0 +1,162 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2019 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_version.h + * + * This header defines the current SDL version. + */ + +#ifndef SDL_version_h_ +#define SDL_version_h_ + +#include "SDL_stdinc.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief Information the version of SDL in use. + * + * Represents the library's version as three levels: major revision + * (increments with massive changes, additions, and enhancements), + * minor revision (increments with backwards-compatible changes to the + * major revision), and patchlevel (increments with fixes to the minor + * revision). + * + * \sa SDL_VERSION + * \sa SDL_GetVersion + */ +typedef struct SDL_version +{ + Uint8 major; /**< major version */ + Uint8 minor; /**< minor version */ + Uint8 patch; /**< update version */ +} SDL_version; + +/* Printable format: "%d.%d.%d", MAJOR, MINOR, PATCHLEVEL +*/ +#define SDL_MAJOR_VERSION 2 +#define SDL_MINOR_VERSION 0 +#define SDL_PATCHLEVEL 11 + +/** + * \brief Macro to determine SDL version program was compiled against. + * + * This macro fills in a SDL_version structure with the version of the + * library you compiled against. This is determined by what header the + * compiler uses. Note that if you dynamically linked the library, you might + * have a slightly newer or older version at runtime. That version can be + * determined with SDL_GetVersion(), which, unlike SDL_VERSION(), + * is not a macro. + * + * \param x A pointer to a SDL_version struct to initialize. + * + * \sa SDL_version + * \sa SDL_GetVersion + */ +#define SDL_VERSION(x) \ +{ \ + (x)->major = SDL_MAJOR_VERSION; \ + (x)->minor = SDL_MINOR_VERSION; \ + (x)->patch = SDL_PATCHLEVEL; \ +} + +/** + * This macro turns the version numbers into a numeric value: + * \verbatim + (1,2,3) -> (1203) + \endverbatim + * + * This assumes that there will never be more than 100 patchlevels. + */ +#define SDL_VERSIONNUM(X, Y, Z) \ + ((X)*1000 + (Y)*100 + (Z)) + +/** + * This is the version number macro for the current SDL version. + */ +#define SDL_COMPILEDVERSION \ + SDL_VERSIONNUM(SDL_MAJOR_VERSION, SDL_MINOR_VERSION, SDL_PATCHLEVEL) + +/** + * This macro will evaluate to true if compiled with SDL at least X.Y.Z. + */ +#define SDL_VERSION_ATLEAST(X, Y, Z) \ + (SDL_COMPILEDVERSION >= SDL_VERSIONNUM(X, Y, Z)) + +/** + * \brief Get the version of SDL that is linked against your program. + * + * If you are linking to SDL dynamically, then it is possible that the + * current version will be different than the version you compiled against. + * This function returns the current version, while SDL_VERSION() is a + * macro that tells you what version you compiled with. + * + * \code + * SDL_version compiled; + * SDL_version linked; + * + * SDL_VERSION(&compiled); + * SDL_GetVersion(&linked); + * printf("We compiled against SDL version %d.%d.%d ...\n", + * compiled.major, compiled.minor, compiled.patch); + * printf("But we linked against SDL version %d.%d.%d.\n", + * linked.major, linked.minor, linked.patch); + * \endcode + * + * This function may be called safely at any time, even before SDL_Init(). + * + * \sa SDL_VERSION + */ +extern DECLSPEC void SDLCALL SDL_GetVersion(SDL_version * ver); + +/** + * \brief Get the code revision of SDL that is linked against your program. + * + * Returns an arbitrary string (a hash value) uniquely identifying the + * exact revision of the SDL library in use, and is only useful in comparing + * against other revisions. It is NOT an incrementing number. + */ +extern DECLSPEC const char *SDLCALL SDL_GetRevision(void); + +/** + * \brief Get the revision number of SDL that is linked against your program. + * + * Returns a number uniquely identifying the exact revision of the SDL + * library in use. It is an incrementing number based on commits to + * hg.libsdl.org. + */ +extern DECLSPEC int SDLCALL SDL_GetRevisionNumber(void); + + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_version_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/engine/Windows/SDL2/include/SDL_video.h b/engine/Windows/SDL2/include/SDL_video.h new file mode 100644 index 0000000..c1bb752 --- /dev/null +++ b/engine/Windows/SDL2/include/SDL_video.h @@ -0,0 +1,1275 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2019 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_video.h + * + * Header file for SDL video functions. + */ + +#ifndef SDL_video_h_ +#define SDL_video_h_ + +#include "SDL_stdinc.h" +#include "SDL_pixels.h" +#include "SDL_rect.h" +#include "SDL_surface.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief The structure that defines a display mode + * + * \sa SDL_GetNumDisplayModes() + * \sa SDL_GetDisplayMode() + * \sa SDL_GetDesktopDisplayMode() + * \sa SDL_GetCurrentDisplayMode() + * \sa SDL_GetClosestDisplayMode() + * \sa SDL_SetWindowDisplayMode() + * \sa SDL_GetWindowDisplayMode() + */ +typedef struct +{ + Uint32 format; /**< pixel format */ + int w; /**< width, in screen coordinates */ + int h; /**< height, in screen coordinates */ + int refresh_rate; /**< refresh rate (or zero for unspecified) */ + void *driverdata; /**< driver-specific data, initialize to 0 */ +} SDL_DisplayMode; + +/** + * \brief The type used to identify a window + * + * \sa SDL_CreateWindow() + * \sa SDL_CreateWindowFrom() + * \sa SDL_DestroyWindow() + * \sa SDL_GetWindowData() + * \sa SDL_GetWindowFlags() + * \sa SDL_GetWindowGrab() + * \sa SDL_GetWindowPosition() + * \sa SDL_GetWindowSize() + * \sa SDL_GetWindowTitle() + * \sa SDL_HideWindow() + * \sa SDL_MaximizeWindow() + * \sa SDL_MinimizeWindow() + * \sa SDL_RaiseWindow() + * \sa SDL_RestoreWindow() + * \sa SDL_SetWindowData() + * \sa SDL_SetWindowFullscreen() + * \sa SDL_SetWindowGrab() + * \sa SDL_SetWindowIcon() + * \sa SDL_SetWindowPosition() + * \sa SDL_SetWindowSize() + * \sa SDL_SetWindowBordered() + * \sa SDL_SetWindowResizable() + * \sa SDL_SetWindowTitle() + * \sa SDL_ShowWindow() + */ +typedef struct SDL_Window SDL_Window; + +/** + * \brief The flags on a window + * + * \sa SDL_GetWindowFlags() + */ +typedef enum +{ + SDL_WINDOW_FULLSCREEN = 0x00000001, /**< fullscreen window */ + SDL_WINDOW_OPENGL = 0x00000002, /**< window usable with OpenGL context */ + SDL_WINDOW_SHOWN = 0x00000004, /**< window is visible */ + SDL_WINDOW_HIDDEN = 0x00000008, /**< window is not visible */ + SDL_WINDOW_BORDERLESS = 0x00000010, /**< no window decoration */ + SDL_WINDOW_RESIZABLE = 0x00000020, /**< window can be resized */ + SDL_WINDOW_MINIMIZED = 0x00000040, /**< window is minimized */ + SDL_WINDOW_MAXIMIZED = 0x00000080, /**< window is maximized */ + SDL_WINDOW_INPUT_GRABBED = 0x00000100, /**< window has grabbed input focus */ + SDL_WINDOW_INPUT_FOCUS = 0x00000200, /**< window has input focus */ + SDL_WINDOW_MOUSE_FOCUS = 0x00000400, /**< window has mouse focus */ + SDL_WINDOW_FULLSCREEN_DESKTOP = ( SDL_WINDOW_FULLSCREEN | 0x00001000 ), + SDL_WINDOW_FOREIGN = 0x00000800, /**< window not created by SDL */ + SDL_WINDOW_ALLOW_HIGHDPI = 0x00002000, /**< window should be created in high-DPI mode if supported. + On macOS NSHighResolutionCapable must be set true in the + application's Info.plist for this to have any effect. */ + SDL_WINDOW_MOUSE_CAPTURE = 0x00004000, /**< window has mouse captured (unrelated to INPUT_GRABBED) */ + SDL_WINDOW_ALWAYS_ON_TOP = 0x00008000, /**< window should always be above others */ + SDL_WINDOW_SKIP_TASKBAR = 0x00010000, /**< window should not be added to the taskbar */ + SDL_WINDOW_UTILITY = 0x00020000, /**< window should be treated as a utility window */ + SDL_WINDOW_TOOLTIP = 0x00040000, /**< window should be treated as a tooltip */ + SDL_WINDOW_POPUP_MENU = 0x00080000, /**< window should be treated as a popup menu */ + SDL_WINDOW_VULKAN = 0x10000000 /**< window usable for Vulkan surface */ +} SDL_WindowFlags; + +/** + * \brief Used to indicate that you don't care what the window position is. + */ +#define SDL_WINDOWPOS_UNDEFINED_MASK 0x1FFF0000u +#define SDL_WINDOWPOS_UNDEFINED_DISPLAY(X) (SDL_WINDOWPOS_UNDEFINED_MASK|(X)) +#define SDL_WINDOWPOS_UNDEFINED SDL_WINDOWPOS_UNDEFINED_DISPLAY(0) +#define SDL_WINDOWPOS_ISUNDEFINED(X) \ + (((X)&0xFFFF0000) == SDL_WINDOWPOS_UNDEFINED_MASK) + +/** + * \brief Used to indicate that the window position should be centered. + */ +#define SDL_WINDOWPOS_CENTERED_MASK 0x2FFF0000u +#define SDL_WINDOWPOS_CENTERED_DISPLAY(X) (SDL_WINDOWPOS_CENTERED_MASK|(X)) +#define SDL_WINDOWPOS_CENTERED SDL_WINDOWPOS_CENTERED_DISPLAY(0) +#define SDL_WINDOWPOS_ISCENTERED(X) \ + (((X)&0xFFFF0000) == SDL_WINDOWPOS_CENTERED_MASK) + +/** + * \brief Event subtype for window events + */ +typedef enum +{ + SDL_WINDOWEVENT_NONE, /**< Never used */ + SDL_WINDOWEVENT_SHOWN, /**< Window has been shown */ + SDL_WINDOWEVENT_HIDDEN, /**< Window has been hidden */ + SDL_WINDOWEVENT_EXPOSED, /**< Window has been exposed and should be + redrawn */ + SDL_WINDOWEVENT_MOVED, /**< Window has been moved to data1, data2 + */ + SDL_WINDOWEVENT_RESIZED, /**< Window has been resized to data1xdata2 */ + SDL_WINDOWEVENT_SIZE_CHANGED, /**< The window size has changed, either as + a result of an API call or through the + system or user changing the window size. */ + SDL_WINDOWEVENT_MINIMIZED, /**< Window has been minimized */ + SDL_WINDOWEVENT_MAXIMIZED, /**< Window has been maximized */ + SDL_WINDOWEVENT_RESTORED, /**< Window has been restored to normal size + and position */ + SDL_WINDOWEVENT_ENTER, /**< Window has gained mouse focus */ + SDL_WINDOWEVENT_LEAVE, /**< Window has lost mouse focus */ + SDL_WINDOWEVENT_FOCUS_GAINED, /**< Window has gained keyboard focus */ + SDL_WINDOWEVENT_FOCUS_LOST, /**< Window has lost keyboard focus */ + SDL_WINDOWEVENT_CLOSE, /**< The window manager requests that the window be closed */ + SDL_WINDOWEVENT_TAKE_FOCUS, /**< Window is being offered a focus (should SetWindowInputFocus() on itself or a subwindow, or ignore) */ + SDL_WINDOWEVENT_HIT_TEST /**< Window had a hit test that wasn't SDL_HITTEST_NORMAL. */ +} SDL_WindowEventID; + +/** + * \brief Event subtype for display events + */ +typedef enum +{ + SDL_DISPLAYEVENT_NONE, /**< Never used */ + SDL_DISPLAYEVENT_ORIENTATION /**< Display orientation has changed to data1 */ +} SDL_DisplayEventID; + +typedef enum +{ + SDL_ORIENTATION_UNKNOWN, /**< The display orientation can't be determined */ + SDL_ORIENTATION_LANDSCAPE, /**< The display is in landscape mode, with the right side up, relative to portrait mode */ + SDL_ORIENTATION_LANDSCAPE_FLIPPED, /**< The display is in landscape mode, with the left side up, relative to portrait mode */ + SDL_ORIENTATION_PORTRAIT, /**< The display is in portrait mode */ + SDL_ORIENTATION_PORTRAIT_FLIPPED /**< The display is in portrait mode, upside down */ +} SDL_DisplayOrientation; + +/** + * \brief An opaque handle to an OpenGL context. + */ +typedef void *SDL_GLContext; + +/** + * \brief OpenGL configuration attributes + */ +typedef enum +{ + 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_RETAINED_BACKING, + SDL_GL_CONTEXT_MAJOR_VERSION, + SDL_GL_CONTEXT_MINOR_VERSION, + SDL_GL_CONTEXT_EGL, + SDL_GL_CONTEXT_FLAGS, + SDL_GL_CONTEXT_PROFILE_MASK, + SDL_GL_SHARE_WITH_CURRENT_CONTEXT, + SDL_GL_FRAMEBUFFER_SRGB_CAPABLE, + SDL_GL_CONTEXT_RELEASE_BEHAVIOR, + SDL_GL_CONTEXT_RESET_NOTIFICATION, + SDL_GL_CONTEXT_NO_ERROR +} SDL_GLattr; + +typedef enum +{ + SDL_GL_CONTEXT_PROFILE_CORE = 0x0001, + SDL_GL_CONTEXT_PROFILE_COMPATIBILITY = 0x0002, + SDL_GL_CONTEXT_PROFILE_ES = 0x0004 /**< GLX_CONTEXT_ES2_PROFILE_BIT_EXT */ +} SDL_GLprofile; + +typedef enum +{ + SDL_GL_CONTEXT_DEBUG_FLAG = 0x0001, + SDL_GL_CONTEXT_FORWARD_COMPATIBLE_FLAG = 0x0002, + SDL_GL_CONTEXT_ROBUST_ACCESS_FLAG = 0x0004, + SDL_GL_CONTEXT_RESET_ISOLATION_FLAG = 0x0008 +} SDL_GLcontextFlag; + +typedef enum +{ + SDL_GL_CONTEXT_RELEASE_BEHAVIOR_NONE = 0x0000, + SDL_GL_CONTEXT_RELEASE_BEHAVIOR_FLUSH = 0x0001 +} SDL_GLcontextReleaseFlag; + +typedef enum +{ + SDL_GL_CONTEXT_RESET_NO_NOTIFICATION = 0x0000, + SDL_GL_CONTEXT_RESET_LOSE_CONTEXT = 0x0001 +} SDL_GLContextResetNotification; + +/* Function prototypes */ + +/** + * \brief Get the number of video drivers compiled into SDL + * + * \sa SDL_GetVideoDriver() + */ +extern DECLSPEC int SDLCALL SDL_GetNumVideoDrivers(void); + +/** + * \brief Get the name of a built in video driver. + * + * \note The video drivers are presented in the order in which they are + * normally checked during initialization. + * + * \sa SDL_GetNumVideoDrivers() + */ +extern DECLSPEC const char *SDLCALL SDL_GetVideoDriver(int index); + +/** + * \brief Initialize the video subsystem, optionally specifying a video driver. + * + * \param driver_name Initialize a specific driver by name, or NULL for the + * default video driver. + * + * \return 0 on success, -1 on error + * + * This function initializes the video subsystem; setting up a connection + * to the window manager, etc, and determines the available display modes + * and pixel formats, but does not initialize a window or graphics mode. + * + * \sa SDL_VideoQuit() + */ +extern DECLSPEC int SDLCALL SDL_VideoInit(const char *driver_name); + +/** + * \brief Shuts down the video subsystem. + * + * This function closes all windows, and restores the original video mode. + * + * \sa SDL_VideoInit() + */ +extern DECLSPEC void SDLCALL SDL_VideoQuit(void); + +/** + * \brief Returns the name of the currently initialized video driver. + * + * \return The name of the current video driver or NULL if no driver + * has been initialized + * + * \sa SDL_GetNumVideoDrivers() + * \sa SDL_GetVideoDriver() + */ +extern DECLSPEC const char *SDLCALL SDL_GetCurrentVideoDriver(void); + +/** + * \brief Returns the number of available video displays. + * + * \sa SDL_GetDisplayBounds() + */ +extern DECLSPEC int SDLCALL SDL_GetNumVideoDisplays(void); + +/** + * \brief Get the name of a display in UTF-8 encoding + * + * \return The name of a display, or NULL for an invalid display index. + * + * \sa SDL_GetNumVideoDisplays() + */ +extern DECLSPEC const char * SDLCALL SDL_GetDisplayName(int displayIndex); + +/** + * \brief Get the desktop area represented by a display, with the primary + * display located at 0,0 + * + * \return 0 on success, or -1 if the index is out of range. + * + * \sa SDL_GetNumVideoDisplays() + */ +extern DECLSPEC int SDLCALL SDL_GetDisplayBounds(int displayIndex, SDL_Rect * rect); + +/** + * \brief Get the usable desktop area represented by a display, with the + * primary display located at 0,0 + * + * This is the same area as SDL_GetDisplayBounds() reports, but with portions + * reserved by the system removed. For example, on Mac OS X, this subtracts + * the area occupied by the menu bar and dock. + * + * Setting a window to be fullscreen generally bypasses these unusable areas, + * so these are good guidelines for the maximum space available to a + * non-fullscreen window. + * + * \return 0 on success, or -1 if the index is out of range. + * + * \sa SDL_GetDisplayBounds() + * \sa SDL_GetNumVideoDisplays() + */ +extern DECLSPEC int SDLCALL SDL_GetDisplayUsableBounds(int displayIndex, SDL_Rect * rect); + +/** + * \brief Get the dots/pixels-per-inch for a display + * + * \note Diagonal, horizontal and vertical DPI can all be optionally + * returned if the parameter is non-NULL. + * + * \return 0 on success, or -1 if no DPI information is available or the index is out of range. + * + * \sa SDL_GetNumVideoDisplays() + */ +extern DECLSPEC int SDLCALL SDL_GetDisplayDPI(int displayIndex, float * ddpi, float * hdpi, float * vdpi); + +/** + * \brief Get the orientation of a display + * + * \return The orientation of the display, or SDL_ORIENTATION_UNKNOWN if it isn't available. + * + * \sa SDL_GetNumVideoDisplays() + */ +extern DECLSPEC SDL_DisplayOrientation SDLCALL SDL_GetDisplayOrientation(int displayIndex); + +/** + * \brief Returns the number of available display modes. + * + * \sa SDL_GetDisplayMode() + */ +extern DECLSPEC int SDLCALL SDL_GetNumDisplayModes(int displayIndex); + +/** + * \brief Fill in information about a specific display mode. + * + * \note The display modes are sorted in this priority: + * \li bits per pixel -> more colors to fewer colors + * \li width -> largest to smallest + * \li height -> largest to smallest + * \li refresh rate -> highest to lowest + * + * \sa SDL_GetNumDisplayModes() + */ +extern DECLSPEC int SDLCALL SDL_GetDisplayMode(int displayIndex, int modeIndex, + SDL_DisplayMode * mode); + +/** + * \brief Fill in information about the desktop display mode. + */ +extern DECLSPEC int SDLCALL SDL_GetDesktopDisplayMode(int displayIndex, SDL_DisplayMode * mode); + +/** + * \brief Fill in information about the current display mode. + */ +extern DECLSPEC int SDLCALL SDL_GetCurrentDisplayMode(int displayIndex, SDL_DisplayMode * mode); + + +/** + * \brief Get the closest match to the requested display mode. + * + * \param displayIndex The index of display from which mode should be queried. + * \param mode The desired display mode + * \param closest A pointer to a display mode to be filled in with the closest + * match of the available display modes. + * + * \return The passed in value \c closest, or NULL if no matching video mode + * was available. + * + * The available display modes are scanned, and \c closest is filled in with the + * closest mode matching the requested mode and returned. The mode format and + * refresh_rate default to the desktop mode if they are 0. The modes are + * scanned with size being first priority, format being second priority, and + * finally checking the refresh_rate. If all the available modes are too + * small, then NULL is returned. + * + * \sa SDL_GetNumDisplayModes() + * \sa SDL_GetDisplayMode() + */ +extern DECLSPEC SDL_DisplayMode * SDLCALL SDL_GetClosestDisplayMode(int displayIndex, const SDL_DisplayMode * mode, SDL_DisplayMode * closest); + +/** + * \brief Get the display index associated with a window. + * + * \return the display index of the display containing the center of the + * window, or -1 on error. + */ +extern DECLSPEC int SDLCALL SDL_GetWindowDisplayIndex(SDL_Window * window); + +/** + * \brief Set the display mode used when a fullscreen window is visible. + * + * By default the window's dimensions and the desktop format and refresh rate + * are used. + * + * \param window The window for which the display mode should be set. + * \param mode The mode to use, or NULL for the default mode. + * + * \return 0 on success, or -1 if setting the display mode failed. + * + * \sa SDL_GetWindowDisplayMode() + * \sa SDL_SetWindowFullscreen() + */ +extern DECLSPEC int SDLCALL SDL_SetWindowDisplayMode(SDL_Window * window, + const SDL_DisplayMode + * mode); + +/** + * \brief Fill in information about the display mode used when a fullscreen + * window is visible. + * + * \sa SDL_SetWindowDisplayMode() + * \sa SDL_SetWindowFullscreen() + */ +extern DECLSPEC int SDLCALL SDL_GetWindowDisplayMode(SDL_Window * window, + SDL_DisplayMode * mode); + +/** + * \brief Get the pixel format associated with the window. + */ +extern DECLSPEC Uint32 SDLCALL SDL_GetWindowPixelFormat(SDL_Window * window); + +/** + * \brief Create a window with the specified position, dimensions, and flags. + * + * \param title The title of the window, in UTF-8 encoding. + * \param x The x position of the window, ::SDL_WINDOWPOS_CENTERED, or + * ::SDL_WINDOWPOS_UNDEFINED. + * \param y The y position of the window, ::SDL_WINDOWPOS_CENTERED, or + * ::SDL_WINDOWPOS_UNDEFINED. + * \param w The width of the window, in screen coordinates. + * \param h The height of the window, in screen coordinates. + * \param flags The flags for the window, a mask of any of the following: + * ::SDL_WINDOW_FULLSCREEN, ::SDL_WINDOW_OPENGL, + * ::SDL_WINDOW_HIDDEN, ::SDL_WINDOW_BORDERLESS, + * ::SDL_WINDOW_RESIZABLE, ::SDL_WINDOW_MAXIMIZED, + * ::SDL_WINDOW_MINIMIZED, ::SDL_WINDOW_INPUT_GRABBED, + * ::SDL_WINDOW_ALLOW_HIGHDPI, ::SDL_WINDOW_VULKAN. + * + * \return The created window, or NULL if window creation failed. + * + * If the window is created with the SDL_WINDOW_ALLOW_HIGHDPI flag, its size + * in pixels may differ from its size in screen coordinates on platforms with + * high-DPI support (e.g. iOS and Mac OS X). Use SDL_GetWindowSize() to query + * the client area's size in screen coordinates, and SDL_GL_GetDrawableSize(), + * SDL_Vulkan_GetDrawableSize(), or SDL_GetRendererOutputSize() to query the + * drawable size in pixels. + * + * If the window is created with any of the SDL_WINDOW_OPENGL or + * SDL_WINDOW_VULKAN flags, then the corresponding LoadLibrary function + * (SDL_GL_LoadLibrary or SDL_Vulkan_LoadLibrary) is called and the + * corresponding UnloadLibrary function is called by SDL_DestroyWindow(). + * + * If SDL_WINDOW_VULKAN is specified and there isn't a working Vulkan driver, + * SDL_CreateWindow() will fail because SDL_Vulkan_LoadLibrary() will fail. + * + * \note On non-Apple devices, SDL requires you to either not link to the + * Vulkan loader or link to a dynamic library version. This limitation + * may be removed in a future version of SDL. + * + * \sa SDL_DestroyWindow() + * \sa SDL_GL_LoadLibrary() + * \sa SDL_Vulkan_LoadLibrary() + */ +extern DECLSPEC SDL_Window * SDLCALL SDL_CreateWindow(const char *title, + int x, int y, int w, + int h, Uint32 flags); + +/** + * \brief Create an SDL window from an existing native window. + * + * \param data A pointer to driver-dependent window creation data + * + * \return The created window, or NULL if window creation failed. + * + * \sa SDL_DestroyWindow() + */ +extern DECLSPEC SDL_Window * SDLCALL SDL_CreateWindowFrom(const void *data); + +/** + * \brief Get the numeric ID of a window, for logging purposes. + */ +extern DECLSPEC Uint32 SDLCALL SDL_GetWindowID(SDL_Window * window); + +/** + * \brief Get a window from a stored ID, or NULL if it doesn't exist. + */ +extern DECLSPEC SDL_Window * SDLCALL SDL_GetWindowFromID(Uint32 id); + +/** + * \brief Get the window flags. + */ +extern DECLSPEC Uint32 SDLCALL SDL_GetWindowFlags(SDL_Window * window); + +/** + * \brief Set the title of a window, in UTF-8 format. + * + * \sa SDL_GetWindowTitle() + */ +extern DECLSPEC void SDLCALL SDL_SetWindowTitle(SDL_Window * window, + const char *title); + +/** + * \brief Get the title of a window, in UTF-8 format. + * + * \sa SDL_SetWindowTitle() + */ +extern DECLSPEC const char *SDLCALL SDL_GetWindowTitle(SDL_Window * window); + +/** + * \brief Set the icon for a window. + * + * \param window The window for which the icon should be set. + * \param icon The icon for the window. + */ +extern DECLSPEC void SDLCALL SDL_SetWindowIcon(SDL_Window * window, + SDL_Surface * icon); + +/** + * \brief Associate an arbitrary named pointer with a window. + * + * \param window The window to associate with the pointer. + * \param name The name of the pointer. + * \param userdata The associated pointer. + * + * \return The previous value associated with 'name' + * + * \note The name is case-sensitive. + * + * \sa SDL_GetWindowData() + */ +extern DECLSPEC void* SDLCALL SDL_SetWindowData(SDL_Window * window, + const char *name, + void *userdata); + +/** + * \brief Retrieve the data pointer associated with a window. + * + * \param window The window to query. + * \param name The name of the pointer. + * + * \return The value associated with 'name' + * + * \sa SDL_SetWindowData() + */ +extern DECLSPEC void *SDLCALL SDL_GetWindowData(SDL_Window * window, + const char *name); + +/** + * \brief Set the position of a window. + * + * \param window The window to reposition. + * \param x The x coordinate of the window in screen coordinates, or + * ::SDL_WINDOWPOS_CENTERED or ::SDL_WINDOWPOS_UNDEFINED. + * \param y The y coordinate of the window in screen coordinates, or + * ::SDL_WINDOWPOS_CENTERED or ::SDL_WINDOWPOS_UNDEFINED. + * + * \note The window coordinate origin is the upper left of the display. + * + * \sa SDL_GetWindowPosition() + */ +extern DECLSPEC void SDLCALL SDL_SetWindowPosition(SDL_Window * window, + int x, int y); + +/** + * \brief Get the position of a window. + * + * \param window The window to query. + * \param x Pointer to variable for storing the x position, in screen + * coordinates. May be NULL. + * \param y Pointer to variable for storing the y position, in screen + * coordinates. May be NULL. + * + * \sa SDL_SetWindowPosition() + */ +extern DECLSPEC void SDLCALL SDL_GetWindowPosition(SDL_Window * window, + int *x, int *y); + +/** + * \brief Set the size of a window's client area. + * + * \param window The window to resize. + * \param w The width of the window, in screen coordinates. Must be >0. + * \param h The height of the window, in screen coordinates. Must be >0. + * + * \note Fullscreen windows automatically match the size of the display mode, + * and you should use SDL_SetWindowDisplayMode() to change their size. + * + * The window size in screen coordinates may differ from the size in pixels, if + * the window was created with SDL_WINDOW_ALLOW_HIGHDPI on a platform with + * high-dpi support (e.g. iOS or OS X). Use SDL_GL_GetDrawableSize() or + * SDL_GetRendererOutputSize() to get the real client area size in pixels. + * + * \sa SDL_GetWindowSize() + * \sa SDL_SetWindowDisplayMode() + */ +extern DECLSPEC void SDLCALL SDL_SetWindowSize(SDL_Window * window, int w, + int h); + +/** + * \brief Get the size of a window's client area. + * + * \param window The window to query. + * \param w Pointer to variable for storing the width, in screen + * coordinates. May be NULL. + * \param h Pointer to variable for storing the height, in screen + * coordinates. May be NULL. + * + * The window size in screen coordinates may differ from the size in pixels, if + * the window was created with SDL_WINDOW_ALLOW_HIGHDPI on a platform with + * high-dpi support (e.g. iOS or OS X). Use SDL_GL_GetDrawableSize() or + * SDL_GetRendererOutputSize() to get the real client area size in pixels. + * + * \sa SDL_SetWindowSize() + */ +extern DECLSPEC void SDLCALL SDL_GetWindowSize(SDL_Window * window, int *w, + int *h); + +/** + * \brief Get the size of a window's borders (decorations) around the client area. + * + * \param window The window to query. + * \param top Pointer to variable for storing the size of the top border. NULL is permitted. + * \param left Pointer to variable for storing the size of the left border. NULL is permitted. + * \param bottom Pointer to variable for storing the size of the bottom border. NULL is permitted. + * \param right Pointer to variable for storing the size of the right border. NULL is permitted. + * + * \return 0 on success, or -1 if getting this information is not supported. + * + * \note if this function fails (returns -1), the size values will be + * initialized to 0, 0, 0, 0 (if a non-NULL pointer is provided), as + * if the window in question was borderless. + */ +extern DECLSPEC int SDLCALL SDL_GetWindowBordersSize(SDL_Window * window, + int *top, int *left, + int *bottom, int *right); + +/** + * \brief Set the minimum size of a window's client area. + * + * \param window The window to set a new minimum size. + * \param min_w The minimum width of the window, must be >0 + * \param min_h The minimum height of the window, must be >0 + * + * \note You can't change the minimum size of a fullscreen window, it + * automatically matches the size of the display mode. + * + * \sa SDL_GetWindowMinimumSize() + * \sa SDL_SetWindowMaximumSize() + */ +extern DECLSPEC void SDLCALL SDL_SetWindowMinimumSize(SDL_Window * window, + int min_w, int min_h); + +/** + * \brief Get the minimum size of a window's client area. + * + * \param window The window to query. + * \param w Pointer to variable for storing the minimum width, may be NULL + * \param h Pointer to variable for storing the minimum height, may be NULL + * + * \sa SDL_GetWindowMaximumSize() + * \sa SDL_SetWindowMinimumSize() + */ +extern DECLSPEC void SDLCALL SDL_GetWindowMinimumSize(SDL_Window * window, + int *w, int *h); + +/** + * \brief Set the maximum size of a window's client area. + * + * \param window The window to set a new maximum size. + * \param max_w The maximum width of the window, must be >0 + * \param max_h The maximum height of the window, must be >0 + * + * \note You can't change the maximum size of a fullscreen window, it + * automatically matches the size of the display mode. + * + * \sa SDL_GetWindowMaximumSize() + * \sa SDL_SetWindowMinimumSize() + */ +extern DECLSPEC void SDLCALL SDL_SetWindowMaximumSize(SDL_Window * window, + int max_w, int max_h); + +/** + * \brief Get the maximum size of a window's client area. + * + * \param window The window to query. + * \param w Pointer to variable for storing the maximum width, may be NULL + * \param h Pointer to variable for storing the maximum height, may be NULL + * + * \sa SDL_GetWindowMinimumSize() + * \sa SDL_SetWindowMaximumSize() + */ +extern DECLSPEC void SDLCALL SDL_GetWindowMaximumSize(SDL_Window * window, + int *w, int *h); + +/** + * \brief Set the border state of a window. + * + * This will add or remove the window's SDL_WINDOW_BORDERLESS flag and + * add or remove the border from the actual window. This is a no-op if the + * window's border already matches the requested state. + * + * \param window The window of which to change the border state. + * \param bordered SDL_FALSE to remove border, SDL_TRUE to add border. + * + * \note You can't change the border state of a fullscreen window. + * + * \sa SDL_GetWindowFlags() + */ +extern DECLSPEC void SDLCALL SDL_SetWindowBordered(SDL_Window * window, + SDL_bool bordered); + +/** + * \brief Set the user-resizable state of a window. + * + * This will add or remove the window's SDL_WINDOW_RESIZABLE flag and + * allow/disallow user resizing of the window. This is a no-op if the + * window's resizable state already matches the requested state. + * + * \param window The window of which to change the resizable state. + * \param resizable SDL_TRUE to allow resizing, SDL_FALSE to disallow. + * + * \note You can't change the resizable state of a fullscreen window. + * + * \sa SDL_GetWindowFlags() + */ +extern DECLSPEC void SDLCALL SDL_SetWindowResizable(SDL_Window * window, + SDL_bool resizable); + +/** + * \brief Show a window. + * + * \sa SDL_HideWindow() + */ +extern DECLSPEC void SDLCALL SDL_ShowWindow(SDL_Window * window); + +/** + * \brief Hide a window. + * + * \sa SDL_ShowWindow() + */ +extern DECLSPEC void SDLCALL SDL_HideWindow(SDL_Window * window); + +/** + * \brief Raise a window above other windows and set the input focus. + */ +extern DECLSPEC void SDLCALL SDL_RaiseWindow(SDL_Window * window); + +/** + * \brief Make a window as large as possible. + * + * \sa SDL_RestoreWindow() + */ +extern DECLSPEC void SDLCALL SDL_MaximizeWindow(SDL_Window * window); + +/** + * \brief Minimize a window to an iconic representation. + * + * \sa SDL_RestoreWindow() + */ +extern DECLSPEC void SDLCALL SDL_MinimizeWindow(SDL_Window * window); + +/** + * \brief Restore the size and position of a minimized or maximized window. + * + * \sa SDL_MaximizeWindow() + * \sa SDL_MinimizeWindow() + */ +extern DECLSPEC void SDLCALL SDL_RestoreWindow(SDL_Window * window); + +/** + * \brief Set a window's fullscreen state. + * + * \return 0 on success, or -1 if setting the display mode failed. + * + * \sa SDL_SetWindowDisplayMode() + * \sa SDL_GetWindowDisplayMode() + */ +extern DECLSPEC int SDLCALL SDL_SetWindowFullscreen(SDL_Window * window, + Uint32 flags); + +/** + * \brief Get the SDL surface associated with the window. + * + * \return The window's framebuffer surface, or NULL on error. + * + * A new surface will be created with the optimal format for the window, + * if necessary. This surface will be freed when the window is destroyed. + * + * \note You may not combine this with 3D or the rendering API on this window. + * + * \sa SDL_UpdateWindowSurface() + * \sa SDL_UpdateWindowSurfaceRects() + */ +extern DECLSPEC SDL_Surface * SDLCALL SDL_GetWindowSurface(SDL_Window * window); + +/** + * \brief Copy the window surface to the screen. + * + * \return 0 on success, or -1 on error. + * + * \sa SDL_GetWindowSurface() + * \sa SDL_UpdateWindowSurfaceRects() + */ +extern DECLSPEC int SDLCALL SDL_UpdateWindowSurface(SDL_Window * window); + +/** + * \brief Copy a number of rectangles on the window surface to the screen. + * + * \return 0 on success, or -1 on error. + * + * \sa SDL_GetWindowSurface() + * \sa SDL_UpdateWindowSurface() + */ +extern DECLSPEC int SDLCALL SDL_UpdateWindowSurfaceRects(SDL_Window * window, + const SDL_Rect * rects, + int numrects); + +/** + * \brief Set a window's input grab mode. + * + * \param window The window for which the input grab mode should be set. + * \param grabbed This is SDL_TRUE to grab input, and SDL_FALSE to release input. + * + * If the caller enables a grab while another window is currently grabbed, + * the other window loses its grab in favor of the caller's window. + * + * \sa SDL_GetWindowGrab() + */ +extern DECLSPEC void SDLCALL SDL_SetWindowGrab(SDL_Window * window, + SDL_bool grabbed); + +/** + * \brief Get a window's input grab mode. + * + * \return This returns SDL_TRUE if input is grabbed, and SDL_FALSE otherwise. + * + * \sa SDL_SetWindowGrab() + */ +extern DECLSPEC SDL_bool SDLCALL SDL_GetWindowGrab(SDL_Window * window); + +/** + * \brief Get the window that currently has an input grab enabled. + * + * \return This returns the window if input is grabbed, and NULL otherwise. + * + * \sa SDL_SetWindowGrab() + */ +extern DECLSPEC SDL_Window * SDLCALL SDL_GetGrabbedWindow(void); + +/** + * \brief Set the brightness (gamma correction) for a window. + * + * \return 0 on success, or -1 if setting the brightness isn't supported. + * + * \sa SDL_GetWindowBrightness() + * \sa SDL_SetWindowGammaRamp() + */ +extern DECLSPEC int SDLCALL SDL_SetWindowBrightness(SDL_Window * window, float brightness); + +/** + * \brief Get the brightness (gamma correction) for a window. + * + * \return The last brightness value passed to SDL_SetWindowBrightness() + * + * \sa SDL_SetWindowBrightness() + */ +extern DECLSPEC float SDLCALL SDL_GetWindowBrightness(SDL_Window * window); + +/** + * \brief Set the opacity for a window + * + * \param window The window which will be made transparent or opaque + * \param opacity Opacity (0.0f - transparent, 1.0f - opaque) This will be + * clamped internally between 0.0f and 1.0f. + * + * \return 0 on success, or -1 if setting the opacity isn't supported. + * + * \sa SDL_GetWindowOpacity() + */ +extern DECLSPEC int SDLCALL SDL_SetWindowOpacity(SDL_Window * window, float opacity); + +/** + * \brief Get the opacity of a window. + * + * If transparency isn't supported on this platform, opacity will be reported + * as 1.0f without error. + * + * \param window The window in question. + * \param out_opacity Opacity (0.0f - transparent, 1.0f - opaque) + * + * \return 0 on success, or -1 on error (invalid window, etc). + * + * \sa SDL_SetWindowOpacity() + */ +extern DECLSPEC int SDLCALL SDL_GetWindowOpacity(SDL_Window * window, float * out_opacity); + +/** + * \brief Sets the window as a modal for another window (TODO: reconsider this function and/or its name) + * + * \param modal_window The window that should be modal + * \param parent_window The parent window + * + * \return 0 on success, or -1 otherwise. + */ +extern DECLSPEC int SDLCALL SDL_SetWindowModalFor(SDL_Window * modal_window, SDL_Window * parent_window); + +/** + * \brief Explicitly sets input focus to the window. + * + * You almost certainly want SDL_RaiseWindow() instead of this function. Use + * this with caution, as you might give focus to a window that's completely + * obscured by other windows. + * + * \param window The window that should get the input focus + * + * \return 0 on success, or -1 otherwise. + * \sa SDL_RaiseWindow() + */ +extern DECLSPEC int SDLCALL SDL_SetWindowInputFocus(SDL_Window * window); + +/** + * \brief Set the gamma ramp for a window. + * + * \param window The window for which the gamma ramp should be set. + * \param red The translation table for the red channel, or NULL. + * \param green The translation table for the green channel, or NULL. + * \param blue The translation table for the blue channel, or NULL. + * + * \return 0 on success, or -1 if gamma ramps are unsupported. + * + * 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. + * + * \sa SDL_GetWindowGammaRamp() + */ +extern DECLSPEC int SDLCALL SDL_SetWindowGammaRamp(SDL_Window * window, + const Uint16 * red, + const Uint16 * green, + const Uint16 * blue); + +/** + * \brief Get the gamma ramp for a window. + * + * \param window The window from which the gamma ramp should be queried. + * \param red A pointer to a 256 element array of 16-bit quantities to hold + * the translation table for the red channel, or NULL. + * \param green A pointer to a 256 element array of 16-bit quantities to hold + * the translation table for the green channel, or NULL. + * \param blue A pointer to a 256 element array of 16-bit quantities to hold + * the translation table for the blue channel, or NULL. + * + * \return 0 on success, or -1 if gamma ramps are unsupported. + * + * \sa SDL_SetWindowGammaRamp() + */ +extern DECLSPEC int SDLCALL SDL_GetWindowGammaRamp(SDL_Window * window, + Uint16 * red, + Uint16 * green, + Uint16 * blue); + +/** + * \brief Possible return values from the SDL_HitTest callback. + * + * \sa SDL_HitTest + */ +typedef enum +{ + SDL_HITTEST_NORMAL, /**< Region is normal. No special properties. */ + SDL_HITTEST_DRAGGABLE, /**< Region can drag entire window. */ + SDL_HITTEST_RESIZE_TOPLEFT, + SDL_HITTEST_RESIZE_TOP, + SDL_HITTEST_RESIZE_TOPRIGHT, + SDL_HITTEST_RESIZE_RIGHT, + SDL_HITTEST_RESIZE_BOTTOMRIGHT, + SDL_HITTEST_RESIZE_BOTTOM, + SDL_HITTEST_RESIZE_BOTTOMLEFT, + SDL_HITTEST_RESIZE_LEFT +} SDL_HitTestResult; + +/** + * \brief Callback used for hit-testing. + * + * \sa SDL_SetWindowHitTest + */ +typedef SDL_HitTestResult (SDLCALL *SDL_HitTest)(SDL_Window *win, + const SDL_Point *area, + void *data); + +/** + * \brief Provide a callback that decides if a window region has special properties. + * + * Normally windows are dragged and resized by decorations provided by the + * system window manager (a title bar, borders, etc), but for some apps, it + * makes sense to drag them from somewhere else inside the window itself; for + * example, one might have a borderless window that wants to be draggable + * from any part, or simulate its own title bar, etc. + * + * This function lets the app provide a callback that designates pieces of + * a given window as special. This callback is run during event processing + * if we need to tell the OS to treat a region of the window specially; the + * use of this callback is known as "hit testing." + * + * Mouse input may not be delivered to your application if it is within + * a special area; the OS will often apply that input to moving the window or + * resizing the window and not deliver it to the application. + * + * Specifying NULL for a callback disables hit-testing. Hit-testing is + * disabled by default. + * + * Platforms that don't support this functionality will return -1 + * unconditionally, even if you're attempting to disable hit-testing. + * + * Your callback may fire at any time, and its firing does not indicate any + * specific behavior (for example, on Windows, this certainly might fire + * when the OS is deciding whether to drag your window, but it fires for lots + * of other reasons, too, some unrelated to anything you probably care about + * _and when the mouse isn't actually at the location it is testing_). + * Since this can fire at any time, you should try to keep your callback + * efficient, devoid of allocations, etc. + * + * \param window The window to set hit-testing on. + * \param callback The callback to call when doing a hit-test. + * \param callback_data An app-defined void pointer passed to the callback. + * \return 0 on success, -1 on error (including unsupported). + */ +extern DECLSPEC int SDLCALL SDL_SetWindowHitTest(SDL_Window * window, + SDL_HitTest callback, + void *callback_data); + +/** + * \brief Destroy a window. + */ +extern DECLSPEC void SDLCALL SDL_DestroyWindow(SDL_Window * window); + + +/** + * \brief Returns whether the screensaver is currently enabled (default off). + * + * \sa SDL_EnableScreenSaver() + * \sa SDL_DisableScreenSaver() + */ +extern DECLSPEC SDL_bool SDLCALL SDL_IsScreenSaverEnabled(void); + +/** + * \brief Allow the screen to be blanked by a screensaver + * + * \sa SDL_IsScreenSaverEnabled() + * \sa SDL_DisableScreenSaver() + */ +extern DECLSPEC void SDLCALL SDL_EnableScreenSaver(void); + +/** + * \brief Prevent the screen from being blanked by a screensaver + * + * \sa SDL_IsScreenSaverEnabled() + * \sa SDL_EnableScreenSaver() + */ +extern DECLSPEC void SDLCALL SDL_DisableScreenSaver(void); + + +/** + * \name OpenGL support functions + */ +/* @{ */ + +/** + * \brief Dynamically load an OpenGL library. + * + * \param path The platform dependent OpenGL library name, or NULL to open the + * default OpenGL library. + * + * \return 0 on success, or -1 if the library couldn't be loaded. + * + * This should be done after initializing the video driver, but before + * creating any OpenGL windows. If no OpenGL library is loaded, the default + * library will be loaded upon creation of the first OpenGL window. + * + * \note 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(). + * + * \sa SDL_GL_GetProcAddress() + * \sa SDL_GL_UnloadLibrary() + */ +extern DECLSPEC int SDLCALL SDL_GL_LoadLibrary(const char *path); + +/** + * \brief Get the address of an OpenGL function. + */ +extern DECLSPEC void *SDLCALL SDL_GL_GetProcAddress(const char *proc); + +/** + * \brief Unload the OpenGL library previously loaded by SDL_GL_LoadLibrary(). + * + * \sa SDL_GL_LoadLibrary() + */ +extern DECLSPEC void SDLCALL SDL_GL_UnloadLibrary(void); + +/** + * \brief Return true if an OpenGL extension is supported for the current + * context. + */ +extern DECLSPEC SDL_bool SDLCALL SDL_GL_ExtensionSupported(const char + *extension); + +/** + * \brief Reset all previously set OpenGL context attributes to their default values + */ +extern DECLSPEC void SDLCALL SDL_GL_ResetAttributes(void); + +/** + * \brief Set an OpenGL window attribute before window creation. + * + * \return 0 on success, or -1 if the attribute could not be set. + */ +extern DECLSPEC int SDLCALL SDL_GL_SetAttribute(SDL_GLattr attr, int value); + +/** + * \brief Get the actual value for an attribute from the current context. + * + * \return 0 on success, or -1 if the attribute could not be retrieved. + * The integer at \c value will be modified in either case. + */ +extern DECLSPEC int SDLCALL SDL_GL_GetAttribute(SDL_GLattr attr, int *value); + +/** + * \brief Create an OpenGL context for use with an OpenGL window, and make it + * current. + * + * \sa SDL_GL_DeleteContext() + */ +extern DECLSPEC SDL_GLContext SDLCALL SDL_GL_CreateContext(SDL_Window * + window); + +/** + * \brief Set up an OpenGL context for rendering into an OpenGL window. + * + * \note The context must have been created with a compatible window. + */ +extern DECLSPEC int SDLCALL SDL_GL_MakeCurrent(SDL_Window * window, + SDL_GLContext context); + +/** + * \brief Get the currently active OpenGL window. + */ +extern DECLSPEC SDL_Window* SDLCALL SDL_GL_GetCurrentWindow(void); + +/** + * \brief Get the currently active OpenGL context. + */ +extern DECLSPEC SDL_GLContext SDLCALL SDL_GL_GetCurrentContext(void); + +/** + * \brief Get the size of a window's underlying drawable in pixels (for use + * with glViewport). + * + * \param window Window from which the drawable size should be queried + * \param w Pointer to variable for storing the width in pixels, may be NULL + * \param h Pointer to variable for storing the height in pixels, may be NULL + * + * This may differ from SDL_GetWindowSize() if we're rendering to a high-DPI + * drawable, i.e. the window was created with SDL_WINDOW_ALLOW_HIGHDPI on a + * platform with high-DPI support (Apple calls this "Retina"), and not disabled + * by the SDL_HINT_VIDEO_HIGHDPI_DISABLED hint. + * + * \sa SDL_GetWindowSize() + * \sa SDL_CreateWindow() + */ +extern DECLSPEC void SDLCALL SDL_GL_GetDrawableSize(SDL_Window * window, int *w, + int *h); + +/** + * \brief Set the swap interval for the current OpenGL context. + * + * \param interval 0 for immediate updates, 1 for updates synchronized with the + * vertical retrace. If the system supports it, you may + * specify -1 to allow late swaps to happen immediately + * instead of waiting for the next retrace. + * + * \return 0 on success, or -1 if setting the swap interval is not supported. + * + * \sa SDL_GL_GetSwapInterval() + */ +extern DECLSPEC int SDLCALL SDL_GL_SetSwapInterval(int interval); + +/** + * \brief Get the swap interval for the current OpenGL context. + * + * \return 0 if there is no vertical retrace synchronization, 1 if the buffer + * swap is synchronized with the vertical retrace, and -1 if late + * swaps happen immediately instead of waiting for the next retrace. + * If the system can't determine the swap interval, or there isn't a + * valid current context, this will return 0 as a safe default. + * + * \sa SDL_GL_SetSwapInterval() + */ +extern DECLSPEC int SDLCALL SDL_GL_GetSwapInterval(void); + +/** + * \brief Swap the OpenGL buffers for a window, if double-buffering is + * supported. + */ +extern DECLSPEC void SDLCALL SDL_GL_SwapWindow(SDL_Window * window); + +/** + * \brief Delete an OpenGL context. + * + * \sa SDL_GL_CreateContext() + */ +extern DECLSPEC void SDLCALL SDL_GL_DeleteContext(SDL_GLContext context); + +/* @} *//* OpenGL support functions */ + + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_video_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/engine/Windows/SDL2/include/SDL_vulkan.h b/engine/Windows/SDL2/include/SDL_vulkan.h new file mode 100644 index 0000000..d69a436 --- /dev/null +++ b/engine/Windows/SDL2/include/SDL_vulkan.h @@ -0,0 +1,278 @@ +/* + Simple DirectMedia Layer + Copyright (C) 2017, Mark Callow + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_vulkan.h + * + * Header file for functions to creating Vulkan surfaces on SDL windows. + */ + +#ifndef SDL_vulkan_h_ +#define SDL_vulkan_h_ + +#include "SDL_video.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/* Avoid including vulkan.h, don't define VkInstance if it's already included */ +#ifdef VULKAN_H_ +#define NO_SDL_VULKAN_TYPEDEFS +#endif +#ifndef NO_SDL_VULKAN_TYPEDEFS +#define VK_DEFINE_HANDLE(object) typedef struct object##_T* object; + +#if defined(__LP64__) || defined(_WIN64) || defined(__x86_64__) || defined(_M_X64) || defined(__ia64) || defined (_M_IA64) || defined(__aarch64__) || defined(__powerpc64__) +#define VK_DEFINE_NON_DISPATCHABLE_HANDLE(object) typedef struct object##_T *object; +#else +#define VK_DEFINE_NON_DISPATCHABLE_HANDLE(object) typedef uint64_t object; +#endif + +VK_DEFINE_HANDLE(VkInstance) +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkSurfaceKHR) + +#endif /* !NO_SDL_VULKAN_TYPEDEFS */ + +typedef VkInstance SDL_vulkanInstance; +typedef VkSurfaceKHR SDL_vulkanSurface; /* for compatibility with Tizen */ + +/** + * \name Vulkan support functions + * + * \note SDL_Vulkan_GetInstanceExtensions & SDL_Vulkan_CreateSurface API + * is compatable with Tizen's implementation of Vulkan in SDL. + */ +/* @{ */ + +/** + * \brief Dynamically load a Vulkan loader library. + * + * \param [in] path The platform dependent Vulkan loader library name, or + * \c NULL. + * + * \return \c 0 on success, or \c -1 if the library couldn't be loaded. + * + * If \a path is NULL SDL will use the value of the environment variable + * \c SDL_VULKAN_LIBRARY, if set, otherwise it loads the default Vulkan + * loader library. + * + * This should be called after initializing the video driver, but before + * creating any Vulkan windows. If no Vulkan loader library is loaded, the + * default library will be loaded upon creation of the first Vulkan window. + * + * \note It is fairly common for Vulkan applications to link with \a libvulkan + * instead of explicitly loading it at run time. This will work with + * SDL provided the application links to a dynamic library and both it + * and SDL use the same search path. + * + * \note If you specify a non-NULL \c path, an application should retrieve all + * of the Vulkan functions it uses from the dynamic library using + * \c SDL_Vulkan_GetVkGetInstanceProcAddr() unless you can guarantee + * \c path points to the same vulkan loader library the application + * linked to. + * + * \note On Apple devices, if \a path is NULL, SDL will attempt to find + * the vkGetInstanceProcAddr address within all the mach-o images of + * the current process. This is because it is fairly common for Vulkan + * applications to link with libvulkan (and historically MoltenVK was + * provided as a static library). If it is not found then, on macOS, SDL + * will attempt to load \c vulkan.framework/vulkan, \c libvulkan.1.dylib, + * followed by \c libvulkan.dylib, in that order. + * On iOS SDL will attempt to load \c libvulkan.dylib only. Applications + * using a dynamic framework or .dylib must ensure it is included in its + * application bundle. + * + * \note On non-Apple devices, application linking with a static libvulkan is + * not supported. Either do not link to the Vulkan loader or link to a + * dynamic library version. + * + * \note This function will fail if there are no working Vulkan drivers + * installed. + * + * \sa SDL_Vulkan_GetVkGetInstanceProcAddr() + * \sa SDL_Vulkan_UnloadLibrary() + */ +extern DECLSPEC int SDLCALL SDL_Vulkan_LoadLibrary(const char *path); + +/** + * \brief Get the address of the \c vkGetInstanceProcAddr function. + * + * \note This should be called after either calling SDL_Vulkan_LoadLibrary + * or creating an SDL_Window with the SDL_WINDOW_VULKAN flag. + */ +extern DECLSPEC void *SDLCALL SDL_Vulkan_GetVkGetInstanceProcAddr(void); + +/** + * \brief Unload the Vulkan loader library previously loaded by + * \c SDL_Vulkan_LoadLibrary(). + * + * \sa SDL_Vulkan_LoadLibrary() + */ +extern DECLSPEC void SDLCALL SDL_Vulkan_UnloadLibrary(void); + +/** + * \brief Get the names of the Vulkan instance extensions needed to create + * a surface with \c SDL_Vulkan_CreateSurface(). + * + * \param [in] \c NULL or window Window for which the required Vulkan instance + * extensions should be retrieved + * \param [in,out] pCount pointer to an \c unsigned related to the number of + * required Vulkan instance extensions + * \param [out] pNames \c NULL or a pointer to an array to be filled with the + * required Vulkan instance extensions + * + * \return \c SDL_TRUE on success, \c SDL_FALSE on error. + * + * If \a pNames is \c NULL, then the number of required Vulkan instance + * extensions is returned in pCount. Otherwise, \a pCount must point to a + * variable set to the number of elements in the \a pNames array, and on + * return the variable is overwritten with the number of names actually + * written to \a pNames. If \a pCount is less than the number of required + * extensions, at most \a pCount structures will be written. If \a pCount + * is smaller than the number of required extensions, \c SDL_FALSE will be + * returned instead of \c SDL_TRUE, to indicate that not all the required + * extensions were returned. + * + * \note If \c window is not NULL, it will be checked against its creation + * flags to ensure that the Vulkan flag is present. This parameter + * will be removed in a future major release. + * + * \note The returned list of extensions will contain \c VK_KHR_surface + * and zero or more platform specific extensions + * + * \note The extension names queried here must be enabled when calling + * VkCreateInstance, otherwise surface creation will fail. + * + * \note \c window should have been created with the \c SDL_WINDOW_VULKAN flag + * or be \c NULL + * + * \code + * unsigned int count; + * // get count of required extensions + * if(!SDL_Vulkan_GetInstanceExtensions(NULL, &count, NULL)) + * handle_error(); + * + * static const char *const additionalExtensions[] = + * { + * VK_EXT_DEBUG_REPORT_EXTENSION_NAME, // example additional extension + * }; + * size_t additionalExtensionsCount = sizeof(additionalExtensions) / sizeof(additionalExtensions[0]); + * size_t extensionCount = count + additionalExtensionsCount; + * const char **names = malloc(sizeof(const char *) * extensionCount); + * if(!names) + * handle_error(); + * + * // get names of required extensions + * if(!SDL_Vulkan_GetInstanceExtensions(NULL, &count, names)) + * handle_error(); + * + * // copy additional extensions after required extensions + * for(size_t i = 0; i < additionalExtensionsCount; i++) + * names[i + count] = additionalExtensions[i]; + * + * VkInstanceCreateInfo instanceCreateInfo = {}; + * instanceCreateInfo.enabledExtensionCount = extensionCount; + * instanceCreateInfo.ppEnabledExtensionNames = names; + * // fill in rest of instanceCreateInfo + * + * VkInstance instance; + * // create the Vulkan instance + * VkResult result = vkCreateInstance(&instanceCreateInfo, NULL, &instance); + * free(names); + * \endcode + * + * \sa SDL_Vulkan_CreateSurface() + */ +extern DECLSPEC SDL_bool SDLCALL SDL_Vulkan_GetInstanceExtensions( + SDL_Window *window, + unsigned int *pCount, + const char **pNames); + +/** + * \brief Create a Vulkan rendering surface for a window. + * + * \param [in] window SDL_Window to which to attach the rendering surface. + * \param [in] instance handle to the Vulkan instance to use. + * \param [out] surface pointer to a VkSurfaceKHR handle to receive the + * handle of the newly created surface. + * + * \return \c SDL_TRUE on success, \c SDL_FALSE on error. + * + * \code + * VkInstance instance; + * SDL_Window *window; + * + * // create instance and window + * + * // create the Vulkan surface + * VkSurfaceKHR surface; + * if(!SDL_Vulkan_CreateSurface(window, instance, &surface)) + * handle_error(); + * \endcode + * + * \note \a window should have been created with the \c SDL_WINDOW_VULKAN flag. + * + * \note \a instance should have been created with the extensions returned + * by \c SDL_Vulkan_CreateSurface() enabled. + * + * \sa SDL_Vulkan_GetInstanceExtensions() + */ +extern DECLSPEC SDL_bool SDLCALL SDL_Vulkan_CreateSurface( + SDL_Window *window, + VkInstance instance, + VkSurfaceKHR* surface); + +/** + * \brief Get the size of a window's underlying drawable in pixels (for use + * with setting viewport, scissor & etc). + * + * \param window SDL_Window from which the drawable size should be queried + * \param w Pointer to variable for storing the width in pixels, + * may be NULL + * \param h Pointer to variable for storing the height in pixels, + * may be NULL + * + * This may differ from SDL_GetWindowSize() if we're rendering to a high-DPI + * drawable, i.e. the window was created with SDL_WINDOW_ALLOW_HIGHDPI on a + * platform with high-DPI support (Apple calls this "Retina"), and not disabled + * by the \c SDL_HINT_VIDEO_HIGHDPI_DISABLED hint. + * + * \note On macOS high-DPI support must be enabled for an application by + * setting NSHighResolutionCapable to true in its Info.plist. + * + * \sa SDL_GetWindowSize() + * \sa SDL_CreateWindow() + */ +extern DECLSPEC void SDLCALL SDL_Vulkan_GetDrawableSize(SDL_Window * window, + int *w, int *h); + +/* @} *//* Vulkan support functions */ + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_vulkan_h_ */ diff --git a/engine/Windows/SDL2/include/begin_code.h b/engine/Windows/SDL2/include/begin_code.h new file mode 100644 index 0000000..22c997c --- /dev/null +++ b/engine/Windows/SDL2/include/begin_code.h @@ -0,0 +1,170 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2019 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file begin_code.h + * + * This file sets things up for C dynamic library function definitions, + * static inlined functions, and structures aligned at 4-byte alignment. + * If you don't like ugly C preprocessor code, don't look at this file. :) + */ + +/* This shouldn't be nested -- included it around code only. */ +#ifdef _begin_code_h +#error Nested inclusion of begin_code.h +#endif +#define _begin_code_h + +#ifndef SDL_DEPRECATED +# if (__GNUC__ >= 4) /* technically, this arrived in gcc 3.1, but oh well. */ +# define SDL_DEPRECATED __attribute__((deprecated)) +# else +# define SDL_DEPRECATED +# endif +#endif + +#ifndef SDL_UNUSED +# ifdef __GNUC__ +# define SDL_UNUSED __attribute__((unused)) +# else +# define SDL_UNUSED +# endif +#endif + +/* Some compilers use a special export keyword */ +#ifndef DECLSPEC +# if defined(__WIN32__) || defined(__WINRT__) +# ifdef __BORLANDC__ +# ifdef BUILD_SDL +# define DECLSPEC +# else +# define DECLSPEC __declspec(dllimport) +# endif +# else +# define DECLSPEC __declspec(dllexport) +# endif +# elif defined(__OS2__) +# ifdef BUILD_SDL +# define DECLSPEC __declspec(dllexport) +# else +# define DECLSPEC +# endif +# else +# if defined(__GNUC__) && __GNUC__ >= 4 +# define DECLSPEC __attribute__ ((visibility("default"))) +# else +# define DECLSPEC +# endif +# endif +#endif + +/* By default SDL uses the C calling convention */ +#ifndef SDLCALL +#if (defined(__WIN32__) || defined(__WINRT__)) && !defined(__GNUC__) +#define SDLCALL __cdecl +#elif defined(__OS2__) || defined(__EMX__) +#define SDLCALL _System +# if defined (__GNUC__) && !defined(_System) +# define _System /* for old EMX/GCC compat. */ +# endif +#else +#define SDLCALL +#endif +#endif /* SDLCALL */ + +/* Removed DECLSPEC on Symbian OS because SDL cannot be a DLL in EPOC */ +#ifdef __SYMBIAN32__ +#undef DECLSPEC +#define DECLSPEC +#endif /* __SYMBIAN32__ */ + +/* Force structure packing at 4 byte alignment. + This is necessary if the header is included in code which has structure + packing set to an alternate value, say for loading structures from disk. + The packing is reset to the previous value in close_code.h + */ +#if defined(_MSC_VER) || defined(__MWERKS__) || defined(__BORLANDC__) +#ifdef _MSC_VER +#pragma warning(disable: 4103) +#endif +#ifdef __clang__ +#pragma clang diagnostic ignored "-Wpragma-pack" +#endif +#ifdef __BORLANDC__ +#pragma nopackwarning +#endif +#ifdef _M_X64 +/* Use 8-byte alignment on 64-bit architectures, so pointers are aligned */ +#pragma pack(push,8) +#else +#pragma pack(push,4) +#endif +#endif /* Compiler needs structure packing set */ + +#ifndef SDL_INLINE +#if defined(__GNUC__) +#define SDL_INLINE __inline__ +#elif defined(_MSC_VER) || defined(__BORLANDC__) || \ + defined(__DMC__) || defined(__SC__) || \ + defined(__WATCOMC__) || defined(__LCC__) || \ + defined(__DECC) || defined(__CC_ARM) +#define SDL_INLINE __inline +#ifndef __inline__ +#define __inline__ __inline +#endif +#else +#define SDL_INLINE inline +#ifndef __inline__ +#define __inline__ inline +#endif +#endif +#endif /* SDL_INLINE not defined */ + +#ifndef SDL_FORCE_INLINE +#if defined(_MSC_VER) +#define SDL_FORCE_INLINE __forceinline +#elif ( (defined(__GNUC__) && (__GNUC__ >= 4)) || defined(__clang__) ) +#define SDL_FORCE_INLINE __attribute__((always_inline)) static __inline__ +#else +#define SDL_FORCE_INLINE static SDL_INLINE +#endif +#endif /* SDL_FORCE_INLINE not defined */ + +#ifndef SDL_NORETURN +#if defined(__GNUC__) +#define SDL_NORETURN __attribute__((noreturn)) +#elif defined(_MSC_VER) +#define SDL_NORETURN __declspec(noreturn) +#else +#define SDL_NORETURN +#endif +#endif /* SDL_NORETURN not defined */ + +/* Apparently this is needed by several Windows compilers */ +#if !defined(__MACH__) +#ifndef NULL +#ifdef __cplusplus +#define NULL 0 +#else +#define NULL ((void *)0) +#endif +#endif /* NULL */ +#endif /* ! Mac OS X - breaks precompiled headers */ diff --git a/engine/Windows/SDL2/include/close_code.h b/engine/Windows/SDL2/include/close_code.h new file mode 100644 index 0000000..8e4cac3 --- /dev/null +++ b/engine/Windows/SDL2/include/close_code.h @@ -0,0 +1,40 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2019 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file close_code.h + * + * This file reverses the effects of begin_code.h and should be included + * after you finish any function and structure declarations in your headers + */ + +#ifndef _begin_code_h +#error close_code.h included without matching begin_code.h +#endif +#undef _begin_code_h + +/* Reset structure packing at previous byte alignment */ +#if defined(_MSC_VER) || defined(__MWERKS__) || defined(__BORLANDC__) +#ifdef __BORLANDC__ +#pragma nopackwarning +#endif +#pragma pack(pop) +#endif /* Compiler needs structure packing set */ diff --git a/engine/Windows/SDL2/lib/libSDL2.dll.a b/engine/Windows/SDL2/lib/libSDL2.dll.a new file mode 100644 index 0000000..d12ccb4 Binary files /dev/null and b/engine/Windows/SDL2/lib/libSDL2.dll.a differ diff --git a/engine/Windows/SDL2/lib/libSDL2main.a b/engine/Windows/SDL2/lib/libSDL2main.a new file mode 100644 index 0000000..b3a3e8e Binary files /dev/null and b/engine/Windows/SDL2/lib/libSDL2main.a differ diff --git a/engine/Windows/SDL2/lib64/libSDL2.dll.a b/engine/Windows/SDL2/lib64/libSDL2.dll.a new file mode 100644 index 0000000..f916437 Binary files /dev/null and b/engine/Windows/SDL2/lib64/libSDL2.dll.a differ diff --git a/engine/Windows/SDL2/lib64/libSDL2main.a b/engine/Windows/SDL2/lib64/libSDL2main.a new file mode 100644 index 0000000..5a9e00c Binary files /dev/null and b/engine/Windows/SDL2/lib64/libSDL2main.a differ diff --git a/engine/Windows/SDL2/main/SDL_windows.h b/engine/Windows/SDL2/main/SDL_windows.h new file mode 100644 index 0000000..3217026 --- /dev/null +++ b/engine/Windows/SDL2/main/SDL_windows.h @@ -0,0 +1,75 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2019 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/* This is an include file for windows.h with the SDL build settings */ + +#ifndef _INCLUDED_WINDOWS_H +#define _INCLUDED_WINDOWS_H + +#if defined(__WIN32__) +#define WIN32_LEAN_AND_MEAN +#define STRICT +#ifndef UNICODE +#define UNICODE 1 +#endif +#undef _WIN32_WINNT +#define _WIN32_WINNT 0x501 /* Need 0x410 for AlphaBlend() and 0x500 for EnumDisplayDevices(), 0x501 for raw input */ +#endif + +#include +#include /* for REFIID with broken mingw.org headers */ + +/* Routines to convert from UTF8 to native Windows text */ +#if UNICODE +#define WIN_StringToUTF8(S) SDL_iconv_string("UTF-8", "UTF-16LE", (char *)(S), (SDL_wcslen(S)+1)*sizeof(WCHAR)) +#define WIN_UTF8ToString(S) (WCHAR *)SDL_iconv_string("UTF-16LE", "UTF-8", (char *)(S), SDL_strlen(S)+1) +#else +/* !!! FIXME: UTF8ToString() can just be a SDL_strdup() here. */ +#define WIN_StringToUTF8(S) SDL_iconv_string("UTF-8", "ASCII", (char *)(S), (SDL_strlen(S)+1)) +#define WIN_UTF8ToString(S) SDL_iconv_string("ASCII", "UTF-8", (char *)(S), SDL_strlen(S)+1) +#endif + +/* Sets an error message based on a given HRESULT */ +extern int WIN_SetErrorFromHRESULT(const char *prefix, HRESULT hr); + +/* Sets an error message based on GetLastError(). Always return -1. */ +extern int WIN_SetError(const char *prefix); + +/* Wrap up the oddities of CoInitialize() into a common function. */ +extern HRESULT WIN_CoInitialize(void); +extern void WIN_CoUninitialize(void); + +/* Returns SDL_TRUE if we're running on Windows Vista and newer */ +extern BOOL WIN_IsWindowsVistaOrGreater(void); + +/* Returns SDL_TRUE if we're running on Windows 7 and newer */ +extern BOOL WIN_IsWindows7OrGreater(void); + +/* You need to SDL_free() the result of this call. */ +extern char *WIN_LookupAudioDeviceName(const WCHAR *name, const GUID *guid); + +/* Checks to see if two GUID are the same. */ +extern BOOL WIN_IsEqualGUID(const GUID * a, const GUID * b); +extern BOOL WIN_IsEqualIID(REFIID a, REFIID b); + +#endif /* _INCLUDED_WINDOWS_H */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/engine/Windows/SDL2/main/SDL_windows_main.c b/engine/Windows/SDL2/main/SDL_windows_main.c new file mode 100644 index 0000000..e862be9 --- /dev/null +++ b/engine/Windows/SDL2/main/SDL_windows_main.c @@ -0,0 +1,108 @@ +/* + SDL_windows_main.c, placed in the public domain by Sam Lantinga 4/13/98 + + The WinMain function -- calls your program's main() function +*/ +#include "SDL_config.h" + +#ifdef __WIN32__ + +/* Include this so we define UNICODE properly */ +#include "SDL_windows.h" /* copied here from the SDL2 source tree */ +#include /* CommandLineToArgvW() */ + +/* Include the SDL main definition header */ +#include "SDL.h" +#include "SDL_main.h" + +#ifdef main +# undef main +#endif /* main */ + +#define WIN_WStringToUTF8(S) SDL_iconv_string("UTF-8", "UTF-16LE", (char *)(S), (SDL_wcslen(S)+1)*sizeof(WCHAR)) + +/* Pop up an out of memory message, returns to Windows */ +static BOOL +OutOfMemory(void) +{ + SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Fatal Error", "Out of memory - aborting", NULL); + return FALSE; +} + +#if defined(_MSC_VER) +/* The VC++ compiler needs main/wmain defined */ +# define console_ansi_main main +# if UNICODE +# define console_wmain wmain +# endif +#endif + +/* Gets the arguments with GetCommandLine, converts them to argc and argv + and calls SDL_main */ +static int +main_getcmdline(void) +{ + LPWSTR *argvw; + char **argv; + int i, argc, result; + + argvw = CommandLineToArgvW(GetCommandLineW(), &argc); + if (argvw == NULL) { + return OutOfMemory(); + } + + /* Parse it into argv and argc */ + argv = (char **)SDL_calloc(argc + 1, sizeof(*argv)); + if (!argv) { + return OutOfMemory(); + } + for (i = 0; i < argc; ++i) { + argv[i] = WIN_WStringToUTF8(argvw[i]); + if (!argv[i]) { + return OutOfMemory(); + } + } + argv[i] = NULL; + LocalFree(argvw); + + SDL_SetMainReady(); + + /* Run the application main() code */ + result = SDL_main(argc, argv); + + /* Free argv, to avoid memory leak */ + for (i = 0; i < argc; ++i) { + SDL_free(argv[i]); + } + SDL_free(argv); + + return result; +} + +/* This is where execution begins [console apps, ansi] */ +int +console_ansi_main(int argc, char *argv[]) +{ + return main_getcmdline(); +} + + +#if UNICODE +/* This is where execution begins [console apps, unicode] */ +int +console_wmain(int argc, wchar_t *wargv[], wchar_t *wenvp) +{ + return main_getcmdline(); +} +#endif + +/* This is where execution begins [windowed apps] */ +int WINAPI +WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR szCmdLine, int sw) +{ + return main_getcmdline(); +} + +#endif /* __WIN32__ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/engine/Windows/SDL2/watcom/SDL2.def b/engine/Windows/SDL2/watcom/SDL2.def new file mode 100644 index 0000000..23b13bc --- /dev/null +++ b/engine/Windows/SDL2/watcom/SDL2.def @@ -0,0 +1,685 @@ +; lib /def:SDL2.def /out:SDL2.lib /machine:x86 +LIBRARY SDL2.dll +EXPORTS +SDL_AddEventWatch +SDL_AddHintCallback +SDL_AddTimer +SDL_AllocFormat +SDL_AllocPalette +SDL_AllocRW +SDL_AtomicAdd +SDL_AtomicCAS +SDL_AtomicCASPtr +SDL_AtomicGet +SDL_AtomicGetPtr +SDL_AtomicLock +SDL_AtomicSet +SDL_AtomicSetPtr +SDL_AtomicTryLock +SDL_AtomicUnlock +SDL_AudioInit +SDL_AudioQuit +SDL_AudioStreamAvailable +SDL_AudioStreamClear +SDL_AudioStreamFlush +SDL_AudioStreamGet +SDL_AudioStreamPut +SDL_BuildAudioCVT +SDL_CalculateGammaRamp +SDL_CaptureMouse +SDL_ClearError +SDL_ClearHints +SDL_ClearQueuedAudio +SDL_CloseAudio +SDL_CloseAudioDevice +SDL_ComposeCustomBlendMode +SDL_CondBroadcast +SDL_CondSignal +SDL_CondWait +SDL_CondWaitTimeout +SDL_ConvertAudio +SDL_ConvertPixels +SDL_ConvertSurface +SDL_ConvertSurfaceFormat +SDL_CreateColorCursor +SDL_CreateCond +SDL_CreateCursor +SDL_CreateMutex +SDL_CreateRGBSurface +SDL_CreateRGBSurfaceFrom +SDL_CreateRGBSurfaceWithFormat +SDL_CreateRGBSurfaceWithFormatFrom +SDL_CreateRenderer +SDL_CreateSemaphore +SDL_CreateShapedWindow +SDL_CreateSoftwareRenderer +SDL_CreateSystemCursor +SDL_CreateTexture +SDL_CreateTextureFromSurface +SDL_CreateThread +SDL_CreateThreadWithStackSize +SDL_CreateWindow +SDL_CreateWindowAndRenderer +SDL_CreateWindowFrom +SDL_DXGIGetOutputInfo +SDL_DYNAPI_entry +SDL_DelEventWatch +SDL_DelHintCallback +SDL_Delay +SDL_DequeueAudio +SDL_DestroyCond +SDL_DestroyMutex +SDL_DestroyRenderer +SDL_DestroySemaphore +SDL_DestroyTexture +SDL_DestroyWindow +SDL_DetachThread +SDL_Direct3D9GetAdapterIndex +SDL_DisableScreenSaver +SDL_DuplicateSurface +SDL_EnableScreenSaver +SDL_EnclosePoints +SDL_Error +SDL_EventState +SDL_FillRect +SDL_FillRects +SDL_FilterEvents +SDL_FlushEvent +SDL_FlushEvents +SDL_FreeAudioStream +SDL_FreeCursor +SDL_FreeFormat +SDL_FreePalette +SDL_FreeRW +SDL_FreeSurface +SDL_FreeWAV +SDL_GL_BindTexture +SDL_GL_CreateContext +SDL_GL_DeleteContext +SDL_GL_ExtensionSupported +SDL_GL_GetAttribute +SDL_GL_GetCurrentContext +SDL_GL_GetCurrentWindow +SDL_GL_GetDrawableSize +SDL_GL_GetProcAddress +SDL_GL_GetSwapInterval +SDL_GL_LoadLibrary +SDL_GL_MakeCurrent +SDL_GL_ResetAttributes +SDL_GL_SetAttribute +SDL_GL_SetSwapInterval +SDL_GL_SwapWindow +SDL_GL_UnbindTexture +SDL_GL_UnloadLibrary +SDL_GameControllerAddMapping +SDL_GameControllerAddMappingsFromRW +SDL_GameControllerClose +SDL_GameControllerEventState +SDL_GameControllerFromInstanceID +SDL_GameControllerGetAttached +SDL_GameControllerGetAxis +SDL_GameControllerGetAxisFromString +SDL_GameControllerGetBindForAxis +SDL_GameControllerGetBindForButton +SDL_GameControllerGetButton +SDL_GameControllerGetButtonFromString +SDL_GameControllerGetJoystick +SDL_GameControllerGetPlayerIndex +SDL_GameControllerGetProduct +SDL_GameControllerGetProductVersion +SDL_GameControllerGetStringForAxis +SDL_GameControllerGetStringForButton +SDL_GameControllerGetVendor +SDL_GameControllerMapping +SDL_GameControllerMappingForDeviceIndex +SDL_GameControllerMappingForGUID +SDL_GameControllerMappingForIndex +SDL_GameControllerName +SDL_GameControllerNameForIndex +SDL_GameControllerNumMappings +SDL_GameControllerOpen +SDL_GameControllerRumble +SDL_GameControllerUpdate +SDL_GetAssertionHandler +SDL_GetAssertionReport +SDL_GetAudioDeviceName +SDL_GetAudioDeviceStatus +SDL_GetAudioDriver +SDL_GetAudioStatus +SDL_GetBasePath +SDL_GetCPUCacheLineSize +SDL_GetCPUCount +SDL_GetClipRect +SDL_GetClipboardText +SDL_GetClosestDisplayMode +SDL_GetColorKey +SDL_GetCurrentAudioDriver +SDL_GetCurrentDisplayMode +SDL_GetCurrentVideoDriver +SDL_GetCursor +SDL_GetDefaultAssertionHandler +SDL_GetDefaultCursor +SDL_GetDesktopDisplayMode +SDL_GetDisplayBounds +SDL_GetDisplayDPI +SDL_GetDisplayMode +SDL_GetDisplayName +SDL_GetDisplayOrientation +SDL_GetDisplayUsableBounds +SDL_GetError +SDL_GetEventFilter +SDL_GetGlobalMouseState +SDL_GetGrabbedWindow +SDL_GetHint +SDL_GetHintBoolean +SDL_GetKeyFromName +SDL_GetKeyFromScancode +SDL_GetKeyName +SDL_GetKeyboardFocus +SDL_GetKeyboardState +SDL_GetMemoryFunctions +SDL_GetModState +SDL_GetMouseFocus +SDL_GetMouseState +SDL_GetNumAllocations +SDL_GetNumAudioDevices +SDL_GetNumAudioDrivers +SDL_GetNumDisplayModes +SDL_GetNumRenderDrivers +SDL_GetNumTouchDevices +SDL_GetNumTouchFingers +SDL_GetNumVideoDisplays +SDL_GetNumVideoDrivers +SDL_GetPerformanceCounter +SDL_GetPerformanceFrequency +SDL_GetPixelFormatName +SDL_GetPlatform +SDL_GetPowerInfo +SDL_GetPrefPath +SDL_GetQueuedAudioSize +SDL_GetRGB +SDL_GetRGBA +SDL_GetRelativeMouseMode +SDL_GetRelativeMouseState +SDL_GetRenderDrawBlendMode +SDL_GetRenderDrawColor +SDL_GetRenderDriverInfo +SDL_GetRenderTarget +SDL_GetRenderer +SDL_GetRendererInfo +SDL_GetRendererOutputSize +SDL_GetRevision +SDL_GetRevisionNumber +SDL_GetScancodeFromKey +SDL_GetScancodeFromName +SDL_GetScancodeName +SDL_GetShapedWindowMode +SDL_GetSurfaceAlphaMod +SDL_GetSurfaceBlendMode +SDL_GetSurfaceColorMod +SDL_GetSystemRAM +SDL_GetTextureAlphaMod +SDL_GetTextureBlendMode +SDL_GetTextureColorMod +SDL_GetThreadID +SDL_GetThreadName +SDL_GetTicks +SDL_GetTouchDevice +SDL_GetTouchDeviceType +SDL_GetTouchFinger +SDL_GetVersion +SDL_GetVideoDriver +SDL_GetWindowBordersSize +SDL_GetWindowBrightness +SDL_GetWindowData +SDL_GetWindowDisplayIndex +SDL_GetWindowDisplayMode +SDL_GetWindowFlags +SDL_GetWindowFromID +SDL_GetWindowGammaRamp +SDL_GetWindowGrab +SDL_GetWindowID +SDL_GetWindowMaximumSize +SDL_GetWindowMinimumSize +SDL_GetWindowOpacity +SDL_GetWindowPixelFormat +SDL_GetWindowPosition +SDL_GetWindowSize +SDL_GetWindowSurface +SDL_GetWindowTitle +SDL_GetWindowWMInfo +SDL_GetYUVConversionMode +SDL_GetYUVConversionModeForResolution +SDL_HapticClose +SDL_HapticDestroyEffect +SDL_HapticEffectSupported +SDL_HapticGetEffectStatus +SDL_HapticIndex +SDL_HapticName +SDL_HapticNewEffect +SDL_HapticNumAxes +SDL_HapticNumEffects +SDL_HapticNumEffectsPlaying +SDL_HapticOpen +SDL_HapticOpenFromJoystick +SDL_HapticOpenFromMouse +SDL_HapticOpened +SDL_HapticPause +SDL_HapticQuery +SDL_HapticRumbleInit +SDL_HapticRumblePlay +SDL_HapticRumbleStop +SDL_HapticRumbleSupported +SDL_HapticRunEffect +SDL_HapticSetAutocenter +SDL_HapticSetGain +SDL_HapticStopAll +SDL_HapticStopEffect +SDL_HapticUnpause +SDL_HapticUpdateEffect +SDL_Has3DNow +SDL_HasARMSIMD +SDL_HasAVX +SDL_HasAVX2 +SDL_HasAVX512F +SDL_HasAltiVec +SDL_HasClipboardText +SDL_HasColorKey +SDL_HasEvent +SDL_HasEvents +SDL_HasIntersection +SDL_HasMMX +SDL_HasNEON +SDL_HasRDTSC +SDL_HasSSE +SDL_HasSSE2 +SDL_HasSSE3 +SDL_HasSSE41 +SDL_HasSSE42 +SDL_HasScreenKeyboardSupport +SDL_HideWindow +SDL_Init +SDL_InitSubSystem +SDL_IntersectRect +SDL_IntersectRectAndLine +SDL_IsGameController +SDL_IsScreenKeyboardShown +SDL_IsScreenSaverEnabled +SDL_IsShapedWindow +SDL_IsTablet +SDL_IsTextInputActive +SDL_JoystickClose +SDL_JoystickCurrentPowerLevel +SDL_JoystickEventState +SDL_JoystickFromInstanceID +SDL_JoystickGetAttached +SDL_JoystickGetAxis +SDL_JoystickGetAxisInitialState +SDL_JoystickGetBall +SDL_JoystickGetButton +SDL_JoystickGetDeviceGUID +SDL_JoystickGetDeviceInstanceID +SDL_JoystickGetDevicePlayerIndex +SDL_JoystickGetDeviceProduct +SDL_JoystickGetDeviceProductVersion +SDL_JoystickGetDeviceType +SDL_JoystickGetDeviceVendor +SDL_JoystickGetGUID +SDL_JoystickGetGUIDFromString +SDL_JoystickGetGUIDString +SDL_JoystickGetHat +SDL_JoystickGetPlayerIndex +SDL_JoystickGetProduct +SDL_JoystickGetProductVersion +SDL_JoystickGetType +SDL_JoystickGetVendor +SDL_JoystickInstanceID +SDL_JoystickIsHaptic +SDL_JoystickName +SDL_JoystickNameForIndex +SDL_JoystickNumAxes +SDL_JoystickNumBalls +SDL_JoystickNumButtons +SDL_JoystickNumHats +SDL_JoystickOpen +SDL_JoystickRumble +SDL_JoystickUpdate +SDL_LoadBMP_RW +SDL_LoadDollarTemplates +SDL_LoadFile +SDL_LoadFile_RW +SDL_LoadFunction +SDL_LoadObject +SDL_LoadWAV_RW +SDL_LockAudio +SDL_LockAudioDevice +SDL_LockJoysticks +SDL_LockMutex +SDL_LockSurface +SDL_LockTexture +SDL_LockTextureToSurface +SDL_Log +SDL_LogCritical +SDL_LogDebug +SDL_LogError +SDL_LogGetOutputFunction +SDL_LogGetPriority +SDL_LogInfo +SDL_LogMessage +SDL_LogMessageV +SDL_LogResetPriorities +SDL_LogSetAllPriority +SDL_LogSetOutputFunction +SDL_LogSetPriority +SDL_LogVerbose +SDL_LogWarn +SDL_LowerBlit +SDL_LowerBlitScaled +SDL_MapRGB +SDL_MapRGBA +SDL_MasksToPixelFormatEnum +SDL_MaximizeWindow +SDL_MemoryBarrierAcquireFunction +SDL_MemoryBarrierReleaseFunction +SDL_Metal_CreateView +SDL_Metal_DestroyView +SDL_MinimizeWindow +SDL_MixAudio +SDL_MixAudioFormat +SDL_MouseIsHaptic +SDL_NewAudioStream +SDL_NumHaptics +SDL_NumJoysticks +SDL_NumSensors +SDL_OpenAudio +SDL_OpenAudioDevice +SDL_PauseAudio +SDL_PauseAudioDevice +SDL_PeepEvents +SDL_PixelFormatEnumToMasks +SDL_PollEvent +SDL_PumpEvents +SDL_PushEvent +SDL_QueryTexture +SDL_QueueAudio +SDL_Quit +SDL_QuitSubSystem +SDL_RWFromConstMem +SDL_RWFromFP +SDL_RWFromFile +SDL_RWFromMem +SDL_RWclose +SDL_RWread +SDL_RWseek +SDL_RWsize +SDL_RWtell +SDL_RWwrite +SDL_RaiseWindow +SDL_ReadBE16 +SDL_ReadBE32 +SDL_ReadBE64 +SDL_ReadLE16 +SDL_ReadLE32 +SDL_ReadLE64 +SDL_ReadU8 +SDL_RecordGesture +SDL_RegisterApp +SDL_RegisterEvents +SDL_RemoveTimer +SDL_RenderClear +SDL_RenderCopy +SDL_RenderCopyEx +SDL_RenderCopyExF +SDL_RenderCopyF +SDL_RenderDrawLine +SDL_RenderDrawLineF +SDL_RenderDrawLines +SDL_RenderDrawLinesF +SDL_RenderDrawPoint +SDL_RenderDrawPointF +SDL_RenderDrawPoints +SDL_RenderDrawPointsF +SDL_RenderDrawRect +SDL_RenderDrawRectF +SDL_RenderDrawRects +SDL_RenderDrawRectsF +SDL_RenderFillRect +SDL_RenderFillRectF +SDL_RenderFillRects +SDL_RenderFillRectsF +SDL_RenderFlush +SDL_RenderGetClipRect +SDL_RenderGetD3D9Device +SDL_RenderGetIntegerScale +SDL_RenderGetLogicalSize +SDL_RenderGetMetalCommandEncoder +SDL_RenderGetMetalLayer +SDL_RenderGetScale +SDL_RenderGetViewport +SDL_RenderIsClipEnabled +SDL_RenderPresent +SDL_RenderReadPixels +SDL_RenderSetClipRect +SDL_RenderSetIntegerScale +SDL_RenderSetLogicalSize +SDL_RenderSetScale +SDL_RenderSetViewport +SDL_RenderTargetSupported +SDL_ReportAssertion +SDL_ResetAssertionReport +SDL_RestoreWindow +SDL_SIMDAlloc +SDL_SIMDFree +SDL_SIMDGetAlignment +SDL_SaveAllDollarTemplates +SDL_SaveBMP_RW +SDL_SaveDollarTemplate +SDL_SemPost +SDL_SemTryWait +SDL_SemValue +SDL_SemWait +SDL_SemWaitTimeout +SDL_SensorClose +SDL_SensorFromInstanceID +SDL_SensorGetData +SDL_SensorGetDeviceInstanceID +SDL_SensorGetDeviceName +SDL_SensorGetDeviceNonPortableType +SDL_SensorGetDeviceType +SDL_SensorGetInstanceID +SDL_SensorGetName +SDL_SensorGetNonPortableType +SDL_SensorGetType +SDL_SensorOpen +SDL_SensorUpdate +SDL_SetAssertionHandler +SDL_SetClipRect +SDL_SetClipboardText +SDL_SetColorKey +SDL_SetCursor +SDL_SetError +SDL_SetEventFilter +SDL_SetHint +SDL_SetHintWithPriority +SDL_SetMainReady +SDL_SetMemoryFunctions +SDL_SetModState +SDL_SetPaletteColors +SDL_SetPixelFormatPalette +SDL_SetRelativeMouseMode +SDL_SetRenderDrawBlendMode +SDL_SetRenderDrawColor +SDL_SetRenderTarget +SDL_SetSurfaceAlphaMod +SDL_SetSurfaceBlendMode +SDL_SetSurfaceColorMod +SDL_SetSurfacePalette +SDL_SetSurfaceRLE +SDL_SetTextInputRect +SDL_SetTextureAlphaMod +SDL_SetTextureBlendMode +SDL_SetTextureColorMod +SDL_SetThreadPriority +SDL_SetWindowBordered +SDL_SetWindowBrightness +SDL_SetWindowData +SDL_SetWindowDisplayMode +SDL_SetWindowFullscreen +SDL_SetWindowGammaRamp +SDL_SetWindowGrab +SDL_SetWindowHitTest +SDL_SetWindowIcon +SDL_SetWindowInputFocus +SDL_SetWindowMaximumSize +SDL_SetWindowMinimumSize +SDL_SetWindowModalFor +SDL_SetWindowOpacity +SDL_SetWindowPosition +SDL_SetWindowResizable +SDL_SetWindowShape +SDL_SetWindowSize +SDL_SetWindowTitle +SDL_SetWindowsMessageHook +SDL_SetYUVConversionMode +SDL_ShowCursor +SDL_ShowMessageBox +SDL_ShowSimpleMessageBox +SDL_ShowWindow +SDL_SoftStretch +SDL_StartTextInput +SDL_StopTextInput +SDL_TLSCreate +SDL_TLSGet +SDL_TLSSet +SDL_ThreadID +SDL_TryLockMutex +SDL_UnionRect +SDL_UnloadObject +SDL_UnlockAudio +SDL_UnlockAudioDevice +SDL_UnlockJoysticks +SDL_UnlockMutex +SDL_UnlockSurface +SDL_UnlockTexture +SDL_UnregisterApp +SDL_UpdateTexture +SDL_UpdateWindowSurface +SDL_UpdateWindowSurfaceRects +SDL_UpdateYUVTexture +SDL_UpperBlit +SDL_UpperBlitScaled +SDL_VideoInit +SDL_VideoQuit +SDL_Vulkan_CreateSurface +SDL_Vulkan_GetDrawableSize +SDL_Vulkan_GetInstanceExtensions +SDL_Vulkan_GetVkGetInstanceProcAddr +SDL_Vulkan_LoadLibrary +SDL_Vulkan_UnloadLibrary +SDL_WaitEvent +SDL_WaitEventTimeout +SDL_WaitThread +SDL_WarpMouseGlobal +SDL_WarpMouseInWindow +SDL_WasInit +SDL_WriteBE16 +SDL_WriteBE32 +SDL_WriteBE64 +SDL_WriteLE16 +SDL_WriteLE32 +SDL_WriteLE64 +SDL_WriteU8 +SDL_abs +SDL_acos +SDL_acosf +SDL_asin +SDL_asinf +SDL_atan +SDL_atan2 +SDL_atan2f +SDL_atanf +SDL_atof +SDL_atoi +SDL_calloc +SDL_ceil +SDL_ceilf +SDL_copysign +SDL_copysignf +SDL_cos +SDL_cosf +SDL_exp +SDL_expf +SDL_fabs +SDL_fabsf +SDL_floor +SDL_floorf +SDL_fmod +SDL_fmodf +SDL_free +SDL_getenv +SDL_iconv +SDL_iconv_close +SDL_iconv_open +SDL_iconv_string +SDL_isdigit +SDL_isspace +SDL_itoa +SDL_lltoa +SDL_log +SDL_log10 +SDL_log10f +SDL_logf +SDL_ltoa +SDL_malloc +SDL_memcmp +SDL_memcpy +SDL_memmove +SDL_memset +SDL_pow +SDL_powf +SDL_qsort +SDL_realloc +SDL_scalbn +SDL_scalbnf +SDL_setenv +SDL_sin +SDL_sinf +SDL_snprintf +SDL_sqrt +SDL_sqrtf +SDL_sscanf +SDL_strcasecmp +SDL_strchr +SDL_strcmp +SDL_strdup +SDL_strlcat +SDL_strlcpy +SDL_strlen +SDL_strlwr +SDL_strncasecmp +SDL_strncmp +SDL_strrchr +SDL_strrev +SDL_strstr +SDL_strtod +SDL_strtol +SDL_strtoll +SDL_strtoul +SDL_strtoull +SDL_strupr +SDL_tan +SDL_tanf +SDL_tolower +SDL_toupper +SDL_uitoa +SDL_ulltoa +SDL_ultoa +SDL_utf8strlcpy +SDL_utf8strlen +SDL_vsnprintf +SDL_vsscanf +SDL_wcscmp +SDL_wcsdup +SDL_wcslcat +SDL_wcslcpy +SDL_wcslen diff --git a/engine/Windows/SDL2/watcom/SDL2.exp b/engine/Windows/SDL2/watcom/SDL2.exp new file mode 100644 index 0000000..56bda35 --- /dev/null +++ b/engine/Windows/SDL2/watcom/SDL2.exp @@ -0,0 +1,682 @@ +++'_SDL_AddEventWatch'.'SDL2.DLL'..'SDL_AddEventWatch' +++'_SDL_AddHintCallback'.'SDL2.DLL'..'SDL_AddHintCallback' +++'_SDL_AddTimer'.'SDL2.DLL'..'SDL_AddTimer' +++'_SDL_AllocFormat'.'SDL2.DLL'..'SDL_AllocFormat' +++'_SDL_AllocPalette'.'SDL2.DLL'..'SDL_AllocPalette' +++'_SDL_AllocRW'.'SDL2.DLL'..'SDL_AllocRW' +++'_SDL_AtomicAdd'.'SDL2.DLL'..'SDL_AtomicAdd' +++'_SDL_AtomicCAS'.'SDL2.DLL'..'SDL_AtomicCAS' +++'_SDL_AtomicCASPtr'.'SDL2.DLL'..'SDL_AtomicCASPtr' +++'_SDL_AtomicGet'.'SDL2.DLL'..'SDL_AtomicGet' +++'_SDL_AtomicGetPtr'.'SDL2.DLL'..'SDL_AtomicGetPtr' +++'_SDL_AtomicLock'.'SDL2.DLL'..'SDL_AtomicLock' +++'_SDL_AtomicSet'.'SDL2.DLL'..'SDL_AtomicSet' +++'_SDL_AtomicSetPtr'.'SDL2.DLL'..'SDL_AtomicSetPtr' +++'_SDL_AtomicTryLock'.'SDL2.DLL'..'SDL_AtomicTryLock' +++'_SDL_AtomicUnlock'.'SDL2.DLL'..'SDL_AtomicUnlock' +++'_SDL_AudioInit'.'SDL2.DLL'..'SDL_AudioInit' +++'_SDL_AudioQuit'.'SDL2.DLL'..'SDL_AudioQuit' +++'_SDL_AudioStreamAvailable'.'SDL2.DLL'..'SDL_AudioStreamAvailable' +++'_SDL_AudioStreamClear'.'SDL2.DLL'..'SDL_AudioStreamClear' +++'_SDL_AudioStreamFlush'.'SDL2.DLL'..'SDL_AudioStreamFlush' +++'_SDL_AudioStreamGet'.'SDL2.DLL'..'SDL_AudioStreamGet' +++'_SDL_AudioStreamPut'.'SDL2.DLL'..'SDL_AudioStreamPut' +++'_SDL_BuildAudioCVT'.'SDL2.DLL'..'SDL_BuildAudioCVT' +++'_SDL_CalculateGammaRamp'.'SDL2.DLL'..'SDL_CalculateGammaRamp' +++'_SDL_CaptureMouse'.'SDL2.DLL'..'SDL_CaptureMouse' +++'_SDL_ClearError'.'SDL2.DLL'..'SDL_ClearError' +++'_SDL_ClearHints'.'SDL2.DLL'..'SDL_ClearHints' +++'_SDL_ClearQueuedAudio'.'SDL2.DLL'..'SDL_ClearQueuedAudio' +++'_SDL_CloseAudio'.'SDL2.DLL'..'SDL_CloseAudio' +++'_SDL_CloseAudioDevice'.'SDL2.DLL'..'SDL_CloseAudioDevice' +++'_SDL_ComposeCustomBlendMode'.'SDL2.DLL'..'SDL_ComposeCustomBlendMode' +++'_SDL_CondBroadcast'.'SDL2.DLL'..'SDL_CondBroadcast' +++'_SDL_CondSignal'.'SDL2.DLL'..'SDL_CondSignal' +++'_SDL_CondWait'.'SDL2.DLL'..'SDL_CondWait' +++'_SDL_CondWaitTimeout'.'SDL2.DLL'..'SDL_CondWaitTimeout' +++'_SDL_ConvertAudio'.'SDL2.DLL'..'SDL_ConvertAudio' +++'_SDL_ConvertPixels'.'SDL2.DLL'..'SDL_ConvertPixels' +++'_SDL_ConvertSurface'.'SDL2.DLL'..'SDL_ConvertSurface' +++'_SDL_ConvertSurfaceFormat'.'SDL2.DLL'..'SDL_ConvertSurfaceFormat' +++'_SDL_CreateColorCursor'.'SDL2.DLL'..'SDL_CreateColorCursor' +++'_SDL_CreateCond'.'SDL2.DLL'..'SDL_CreateCond' +++'_SDL_CreateCursor'.'SDL2.DLL'..'SDL_CreateCursor' +++'_SDL_CreateMutex'.'SDL2.DLL'..'SDL_CreateMutex' +++'_SDL_CreateRGBSurface'.'SDL2.DLL'..'SDL_CreateRGBSurface' +++'_SDL_CreateRGBSurfaceFrom'.'SDL2.DLL'..'SDL_CreateRGBSurfaceFrom' +++'_SDL_CreateRGBSurfaceWithFormat'.'SDL2.DLL'..'SDL_CreateRGBSurfaceWithFormat' +++'_SDL_CreateRGBSurfaceWithFormatFrom'.'SDL2.DLL'..'SDL_CreateRGBSurfaceWithFormatFrom' +++'_SDL_CreateRenderer'.'SDL2.DLL'..'SDL_CreateRenderer' +++'_SDL_CreateSemaphore'.'SDL2.DLL'..'SDL_CreateSemaphore' +++'_SDL_CreateShapedWindow'.'SDL2.DLL'..'SDL_CreateShapedWindow' +++'_SDL_CreateSoftwareRenderer'.'SDL2.DLL'..'SDL_CreateSoftwareRenderer' +++'_SDL_CreateSystemCursor'.'SDL2.DLL'..'SDL_CreateSystemCursor' +++'_SDL_CreateTexture'.'SDL2.DLL'..'SDL_CreateTexture' +++'_SDL_CreateTextureFromSurface'.'SDL2.DLL'..'SDL_CreateTextureFromSurface' +++'_SDL_CreateThread'.'SDL2.DLL'..'SDL_CreateThread' +++'_SDL_CreateThreadWithStackSize'.'SDL2.DLL'..'SDL_CreateThreadWithStackSize' +++'_SDL_CreateWindow'.'SDL2.DLL'..'SDL_CreateWindow' +++'_SDL_CreateWindowAndRenderer'.'SDL2.DLL'..'SDL_CreateWindowAndRenderer' +++'_SDL_CreateWindowFrom'.'SDL2.DLL'..'SDL_CreateWindowFrom' +++'_SDL_DXGIGetOutputInfo'.'SDL2.DLL'..'SDL_DXGIGetOutputInfo' +++'_SDL_DYNAPI_entry'.'SDL2.DLL'..'SDL_DYNAPI_entry' +++'_SDL_DelEventWatch'.'SDL2.DLL'..'SDL_DelEventWatch' +++'_SDL_DelHintCallback'.'SDL2.DLL'..'SDL_DelHintCallback' +++'_SDL_Delay'.'SDL2.DLL'..'SDL_Delay' +++'_SDL_DequeueAudio'.'SDL2.DLL'..'SDL_DequeueAudio' +++'_SDL_DestroyCond'.'SDL2.DLL'..'SDL_DestroyCond' +++'_SDL_DestroyMutex'.'SDL2.DLL'..'SDL_DestroyMutex' +++'_SDL_DestroyRenderer'.'SDL2.DLL'..'SDL_DestroyRenderer' +++'_SDL_DestroySemaphore'.'SDL2.DLL'..'SDL_DestroySemaphore' +++'_SDL_DestroyTexture'.'SDL2.DLL'..'SDL_DestroyTexture' +++'_SDL_DestroyWindow'.'SDL2.DLL'..'SDL_DestroyWindow' +++'_SDL_DetachThread'.'SDL2.DLL'..'SDL_DetachThread' +++'_SDL_Direct3D9GetAdapterIndex'.'SDL2.DLL'..'SDL_Direct3D9GetAdapterIndex' +++'_SDL_DisableScreenSaver'.'SDL2.DLL'..'SDL_DisableScreenSaver' +++'_SDL_DuplicateSurface'.'SDL2.DLL'..'SDL_DuplicateSurface' +++'_SDL_EnableScreenSaver'.'SDL2.DLL'..'SDL_EnableScreenSaver' +++'_SDL_EnclosePoints'.'SDL2.DLL'..'SDL_EnclosePoints' +++'_SDL_Error'.'SDL2.DLL'..'SDL_Error' +++'_SDL_EventState'.'SDL2.DLL'..'SDL_EventState' +++'_SDL_FillRect'.'SDL2.DLL'..'SDL_FillRect' +++'_SDL_FillRects'.'SDL2.DLL'..'SDL_FillRects' +++'_SDL_FilterEvents'.'SDL2.DLL'..'SDL_FilterEvents' +++'_SDL_FlushEvent'.'SDL2.DLL'..'SDL_FlushEvent' +++'_SDL_FlushEvents'.'SDL2.DLL'..'SDL_FlushEvents' +++'_SDL_FreeAudioStream'.'SDL2.DLL'..'SDL_FreeAudioStream' +++'_SDL_FreeCursor'.'SDL2.DLL'..'SDL_FreeCursor' +++'_SDL_FreeFormat'.'SDL2.DLL'..'SDL_FreeFormat' +++'_SDL_FreePalette'.'SDL2.DLL'..'SDL_FreePalette' +++'_SDL_FreeRW'.'SDL2.DLL'..'SDL_FreeRW' +++'_SDL_FreeSurface'.'SDL2.DLL'..'SDL_FreeSurface' +++'_SDL_FreeWAV'.'SDL2.DLL'..'SDL_FreeWAV' +++'_SDL_GL_BindTexture'.'SDL2.DLL'..'SDL_GL_BindTexture' +++'_SDL_GL_CreateContext'.'SDL2.DLL'..'SDL_GL_CreateContext' +++'_SDL_GL_DeleteContext'.'SDL2.DLL'..'SDL_GL_DeleteContext' +++'_SDL_GL_ExtensionSupported'.'SDL2.DLL'..'SDL_GL_ExtensionSupported' +++'_SDL_GL_GetAttribute'.'SDL2.DLL'..'SDL_GL_GetAttribute' +++'_SDL_GL_GetCurrentContext'.'SDL2.DLL'..'SDL_GL_GetCurrentContext' +++'_SDL_GL_GetCurrentWindow'.'SDL2.DLL'..'SDL_GL_GetCurrentWindow' +++'_SDL_GL_GetDrawableSize'.'SDL2.DLL'..'SDL_GL_GetDrawableSize' +++'_SDL_GL_GetProcAddress'.'SDL2.DLL'..'SDL_GL_GetProcAddress' +++'_SDL_GL_GetSwapInterval'.'SDL2.DLL'..'SDL_GL_GetSwapInterval' +++'_SDL_GL_LoadLibrary'.'SDL2.DLL'..'SDL_GL_LoadLibrary' +++'_SDL_GL_MakeCurrent'.'SDL2.DLL'..'SDL_GL_MakeCurrent' +++'_SDL_GL_ResetAttributes'.'SDL2.DLL'..'SDL_GL_ResetAttributes' +++'_SDL_GL_SetAttribute'.'SDL2.DLL'..'SDL_GL_SetAttribute' +++'_SDL_GL_SetSwapInterval'.'SDL2.DLL'..'SDL_GL_SetSwapInterval' +++'_SDL_GL_SwapWindow'.'SDL2.DLL'..'SDL_GL_SwapWindow' +++'_SDL_GL_UnbindTexture'.'SDL2.DLL'..'SDL_GL_UnbindTexture' +++'_SDL_GL_UnloadLibrary'.'SDL2.DLL'..'SDL_GL_UnloadLibrary' +++'_SDL_GameControllerAddMapping'.'SDL2.DLL'..'SDL_GameControllerAddMapping' +++'_SDL_GameControllerAddMappingsFromRW'.'SDL2.DLL'..'SDL_GameControllerAddMappingsFromRW' +++'_SDL_GameControllerClose'.'SDL2.DLL'..'SDL_GameControllerClose' +++'_SDL_GameControllerEventState'.'SDL2.DLL'..'SDL_GameControllerEventState' +++'_SDL_GameControllerFromInstanceID'.'SDL2.DLL'..'SDL_GameControllerFromInstanceID' +++'_SDL_GameControllerGetAttached'.'SDL2.DLL'..'SDL_GameControllerGetAttached' +++'_SDL_GameControllerGetAxis'.'SDL2.DLL'..'SDL_GameControllerGetAxis' +++'_SDL_GameControllerGetAxisFromString'.'SDL2.DLL'..'SDL_GameControllerGetAxisFromString' +++'_SDL_GameControllerGetBindForAxis'.'SDL2.DLL'..'SDL_GameControllerGetBindForAxis' +++'_SDL_GameControllerGetBindForButton'.'SDL2.DLL'..'SDL_GameControllerGetBindForButton' +++'_SDL_GameControllerGetButton'.'SDL2.DLL'..'SDL_GameControllerGetButton' +++'_SDL_GameControllerGetButtonFromString'.'SDL2.DLL'..'SDL_GameControllerGetButtonFromString' +++'_SDL_GameControllerGetJoystick'.'SDL2.DLL'..'SDL_GameControllerGetJoystick' +++'_SDL_GameControllerGetPlayerIndex'.'SDL2.DLL'..'SDL_GameControllerGetPlayerIndex' +++'_SDL_GameControllerGetProduct'.'SDL2.DLL'..'SDL_GameControllerGetProduct' +++'_SDL_GameControllerGetProductVersion'.'SDL2.DLL'..'SDL_GameControllerGetProductVersion' +++'_SDL_GameControllerGetStringForAxis'.'SDL2.DLL'..'SDL_GameControllerGetStringForAxis' +++'_SDL_GameControllerGetStringForButton'.'SDL2.DLL'..'SDL_GameControllerGetStringForButton' +++'_SDL_GameControllerGetVendor'.'SDL2.DLL'..'SDL_GameControllerGetVendor' +++'_SDL_GameControllerMapping'.'SDL2.DLL'..'SDL_GameControllerMapping' +++'_SDL_GameControllerMappingForDeviceIndex'.'SDL2.DLL'..'SDL_GameControllerMappingForDeviceIndex' +++'_SDL_GameControllerMappingForGUID'.'SDL2.DLL'..'SDL_GameControllerMappingForGUID' +++'_SDL_GameControllerMappingForIndex'.'SDL2.DLL'..'SDL_GameControllerMappingForIndex' +++'_SDL_GameControllerName'.'SDL2.DLL'..'SDL_GameControllerName' +++'_SDL_GameControllerNameForIndex'.'SDL2.DLL'..'SDL_GameControllerNameForIndex' +++'_SDL_GameControllerNumMappings'.'SDL2.DLL'..'SDL_GameControllerNumMappings' +++'_SDL_GameControllerOpen'.'SDL2.DLL'..'SDL_GameControllerOpen' +++'_SDL_GameControllerRumble'.'SDL2.DLL'..'SDL_GameControllerRumble' +++'_SDL_GameControllerUpdate'.'SDL2.DLL'..'SDL_GameControllerUpdate' +++'_SDL_GetAssertionHandler'.'SDL2.DLL'..'SDL_GetAssertionHandler' +++'_SDL_GetAssertionReport'.'SDL2.DLL'..'SDL_GetAssertionReport' +++'_SDL_GetAudioDeviceName'.'SDL2.DLL'..'SDL_GetAudioDeviceName' +++'_SDL_GetAudioDeviceStatus'.'SDL2.DLL'..'SDL_GetAudioDeviceStatus' +++'_SDL_GetAudioDriver'.'SDL2.DLL'..'SDL_GetAudioDriver' +++'_SDL_GetAudioStatus'.'SDL2.DLL'..'SDL_GetAudioStatus' +++'_SDL_GetBasePath'.'SDL2.DLL'..'SDL_GetBasePath' +++'_SDL_GetCPUCacheLineSize'.'SDL2.DLL'..'SDL_GetCPUCacheLineSize' +++'_SDL_GetCPUCount'.'SDL2.DLL'..'SDL_GetCPUCount' +++'_SDL_GetClipRect'.'SDL2.DLL'..'SDL_GetClipRect' +++'_SDL_GetClipboardText'.'SDL2.DLL'..'SDL_GetClipboardText' +++'_SDL_GetClosestDisplayMode'.'SDL2.DLL'..'SDL_GetClosestDisplayMode' +++'_SDL_GetColorKey'.'SDL2.DLL'..'SDL_GetColorKey' +++'_SDL_GetCurrentAudioDriver'.'SDL2.DLL'..'SDL_GetCurrentAudioDriver' +++'_SDL_GetCurrentDisplayMode'.'SDL2.DLL'..'SDL_GetCurrentDisplayMode' +++'_SDL_GetCurrentVideoDriver'.'SDL2.DLL'..'SDL_GetCurrentVideoDriver' +++'_SDL_GetCursor'.'SDL2.DLL'..'SDL_GetCursor' +++'_SDL_GetDefaultAssertionHandler'.'SDL2.DLL'..'SDL_GetDefaultAssertionHandler' +++'_SDL_GetDefaultCursor'.'SDL2.DLL'..'SDL_GetDefaultCursor' +++'_SDL_GetDesktopDisplayMode'.'SDL2.DLL'..'SDL_GetDesktopDisplayMode' +++'_SDL_GetDisplayBounds'.'SDL2.DLL'..'SDL_GetDisplayBounds' +++'_SDL_GetDisplayDPI'.'SDL2.DLL'..'SDL_GetDisplayDPI' +++'_SDL_GetDisplayMode'.'SDL2.DLL'..'SDL_GetDisplayMode' +++'_SDL_GetDisplayName'.'SDL2.DLL'..'SDL_GetDisplayName' +++'_SDL_GetDisplayOrientation'.'SDL2.DLL'..'SDL_GetDisplayOrientation' +++'_SDL_GetDisplayUsableBounds'.'SDL2.DLL'..'SDL_GetDisplayUsableBounds' +++'_SDL_GetError'.'SDL2.DLL'..'SDL_GetError' +++'_SDL_GetEventFilter'.'SDL2.DLL'..'SDL_GetEventFilter' +++'_SDL_GetGlobalMouseState'.'SDL2.DLL'..'SDL_GetGlobalMouseState' +++'_SDL_GetGrabbedWindow'.'SDL2.DLL'..'SDL_GetGrabbedWindow' +++'_SDL_GetHint'.'SDL2.DLL'..'SDL_GetHint' +++'_SDL_GetHintBoolean'.'SDL2.DLL'..'SDL_GetHintBoolean' +++'_SDL_GetKeyFromName'.'SDL2.DLL'..'SDL_GetKeyFromName' +++'_SDL_GetKeyFromScancode'.'SDL2.DLL'..'SDL_GetKeyFromScancode' +++'_SDL_GetKeyName'.'SDL2.DLL'..'SDL_GetKeyName' +++'_SDL_GetKeyboardFocus'.'SDL2.DLL'..'SDL_GetKeyboardFocus' +++'_SDL_GetKeyboardState'.'SDL2.DLL'..'SDL_GetKeyboardState' +++'_SDL_GetMemoryFunctions'.'SDL2.DLL'..'SDL_GetMemoryFunctions' +++'_SDL_GetModState'.'SDL2.DLL'..'SDL_GetModState' +++'_SDL_GetMouseFocus'.'SDL2.DLL'..'SDL_GetMouseFocus' +++'_SDL_GetMouseState'.'SDL2.DLL'..'SDL_GetMouseState' +++'_SDL_GetNumAllocations'.'SDL2.DLL'..'SDL_GetNumAllocations' +++'_SDL_GetNumAudioDevices'.'SDL2.DLL'..'SDL_GetNumAudioDevices' +++'_SDL_GetNumAudioDrivers'.'SDL2.DLL'..'SDL_GetNumAudioDrivers' +++'_SDL_GetNumDisplayModes'.'SDL2.DLL'..'SDL_GetNumDisplayModes' +++'_SDL_GetNumRenderDrivers'.'SDL2.DLL'..'SDL_GetNumRenderDrivers' +++'_SDL_GetNumTouchDevices'.'SDL2.DLL'..'SDL_GetNumTouchDevices' +++'_SDL_GetNumTouchFingers'.'SDL2.DLL'..'SDL_GetNumTouchFingers' +++'_SDL_GetNumVideoDisplays'.'SDL2.DLL'..'SDL_GetNumVideoDisplays' +++'_SDL_GetNumVideoDrivers'.'SDL2.DLL'..'SDL_GetNumVideoDrivers' +++'_SDL_GetPerformanceCounter'.'SDL2.DLL'..'SDL_GetPerformanceCounter' +++'_SDL_GetPerformanceFrequency'.'SDL2.DLL'..'SDL_GetPerformanceFrequency' +++'_SDL_GetPixelFormatName'.'SDL2.DLL'..'SDL_GetPixelFormatName' +++'_SDL_GetPlatform'.'SDL2.DLL'..'SDL_GetPlatform' +++'_SDL_GetPowerInfo'.'SDL2.DLL'..'SDL_GetPowerInfo' +++'_SDL_GetPrefPath'.'SDL2.DLL'..'SDL_GetPrefPath' +++'_SDL_GetQueuedAudioSize'.'SDL2.DLL'..'SDL_GetQueuedAudioSize' +++'_SDL_GetRGB'.'SDL2.DLL'..'SDL_GetRGB' +++'_SDL_GetRGBA'.'SDL2.DLL'..'SDL_GetRGBA' +++'_SDL_GetRelativeMouseMode'.'SDL2.DLL'..'SDL_GetRelativeMouseMode' +++'_SDL_GetRelativeMouseState'.'SDL2.DLL'..'SDL_GetRelativeMouseState' +++'_SDL_GetRenderDrawBlendMode'.'SDL2.DLL'..'SDL_GetRenderDrawBlendMode' +++'_SDL_GetRenderDrawColor'.'SDL2.DLL'..'SDL_GetRenderDrawColor' +++'_SDL_GetRenderDriverInfo'.'SDL2.DLL'..'SDL_GetRenderDriverInfo' +++'_SDL_GetRenderTarget'.'SDL2.DLL'..'SDL_GetRenderTarget' +++'_SDL_GetRenderer'.'SDL2.DLL'..'SDL_GetRenderer' +++'_SDL_GetRendererInfo'.'SDL2.DLL'..'SDL_GetRendererInfo' +++'_SDL_GetRendererOutputSize'.'SDL2.DLL'..'SDL_GetRendererOutputSize' +++'_SDL_GetRevision'.'SDL2.DLL'..'SDL_GetRevision' +++'_SDL_GetRevisionNumber'.'SDL2.DLL'..'SDL_GetRevisionNumber' +++'_SDL_GetScancodeFromKey'.'SDL2.DLL'..'SDL_GetScancodeFromKey' +++'_SDL_GetScancodeFromName'.'SDL2.DLL'..'SDL_GetScancodeFromName' +++'_SDL_GetScancodeName'.'SDL2.DLL'..'SDL_GetScancodeName' +++'_SDL_GetShapedWindowMode'.'SDL2.DLL'..'SDL_GetShapedWindowMode' +++'_SDL_GetSurfaceAlphaMod'.'SDL2.DLL'..'SDL_GetSurfaceAlphaMod' +++'_SDL_GetSurfaceBlendMode'.'SDL2.DLL'..'SDL_GetSurfaceBlendMode' +++'_SDL_GetSurfaceColorMod'.'SDL2.DLL'..'SDL_GetSurfaceColorMod' +++'_SDL_GetSystemRAM'.'SDL2.DLL'..'SDL_GetSystemRAM' +++'_SDL_GetTextureAlphaMod'.'SDL2.DLL'..'SDL_GetTextureAlphaMod' +++'_SDL_GetTextureBlendMode'.'SDL2.DLL'..'SDL_GetTextureBlendMode' +++'_SDL_GetTextureColorMod'.'SDL2.DLL'..'SDL_GetTextureColorMod' +++'_SDL_GetThreadID'.'SDL2.DLL'..'SDL_GetThreadID' +++'_SDL_GetThreadName'.'SDL2.DLL'..'SDL_GetThreadName' +++'_SDL_GetTicks'.'SDL2.DLL'..'SDL_GetTicks' +++'_SDL_GetTouchDevice'.'SDL2.DLL'..'SDL_GetTouchDevice' +++'_SDL_GetTouchDeviceType'.'SDL2.DLL'..'SDL_GetTouchDeviceType' +++'_SDL_GetTouchFinger'.'SDL2.DLL'..'SDL_GetTouchFinger' +++'_SDL_GetVersion'.'SDL2.DLL'..'SDL_GetVersion' +++'_SDL_GetVideoDriver'.'SDL2.DLL'..'SDL_GetVideoDriver' +++'_SDL_GetWindowBordersSize'.'SDL2.DLL'..'SDL_GetWindowBordersSize' +++'_SDL_GetWindowBrightness'.'SDL2.DLL'..'SDL_GetWindowBrightness' +++'_SDL_GetWindowData'.'SDL2.DLL'..'SDL_GetWindowData' +++'_SDL_GetWindowDisplayIndex'.'SDL2.DLL'..'SDL_GetWindowDisplayIndex' +++'_SDL_GetWindowDisplayMode'.'SDL2.DLL'..'SDL_GetWindowDisplayMode' +++'_SDL_GetWindowFlags'.'SDL2.DLL'..'SDL_GetWindowFlags' +++'_SDL_GetWindowFromID'.'SDL2.DLL'..'SDL_GetWindowFromID' +++'_SDL_GetWindowGammaRamp'.'SDL2.DLL'..'SDL_GetWindowGammaRamp' +++'_SDL_GetWindowGrab'.'SDL2.DLL'..'SDL_GetWindowGrab' +++'_SDL_GetWindowID'.'SDL2.DLL'..'SDL_GetWindowID' +++'_SDL_GetWindowMaximumSize'.'SDL2.DLL'..'SDL_GetWindowMaximumSize' +++'_SDL_GetWindowMinimumSize'.'SDL2.DLL'..'SDL_GetWindowMinimumSize' +++'_SDL_GetWindowOpacity'.'SDL2.DLL'..'SDL_GetWindowOpacity' +++'_SDL_GetWindowPixelFormat'.'SDL2.DLL'..'SDL_GetWindowPixelFormat' +++'_SDL_GetWindowPosition'.'SDL2.DLL'..'SDL_GetWindowPosition' +++'_SDL_GetWindowSize'.'SDL2.DLL'..'SDL_GetWindowSize' +++'_SDL_GetWindowSurface'.'SDL2.DLL'..'SDL_GetWindowSurface' +++'_SDL_GetWindowTitle'.'SDL2.DLL'..'SDL_GetWindowTitle' +++'_SDL_GetWindowWMInfo'.'SDL2.DLL'..'SDL_GetWindowWMInfo' +++'_SDL_GetYUVConversionMode'.'SDL2.DLL'..'SDL_GetYUVConversionMode' +++'_SDL_GetYUVConversionModeForResolution'.'SDL2.DLL'..'SDL_GetYUVConversionModeForResolution' +++'_SDL_HapticClose'.'SDL2.DLL'..'SDL_HapticClose' +++'_SDL_HapticDestroyEffect'.'SDL2.DLL'..'SDL_HapticDestroyEffect' +++'_SDL_HapticEffectSupported'.'SDL2.DLL'..'SDL_HapticEffectSupported' +++'_SDL_HapticGetEffectStatus'.'SDL2.DLL'..'SDL_HapticGetEffectStatus' +++'_SDL_HapticIndex'.'SDL2.DLL'..'SDL_HapticIndex' +++'_SDL_HapticName'.'SDL2.DLL'..'SDL_HapticName' +++'_SDL_HapticNewEffect'.'SDL2.DLL'..'SDL_HapticNewEffect' +++'_SDL_HapticNumAxes'.'SDL2.DLL'..'SDL_HapticNumAxes' +++'_SDL_HapticNumEffects'.'SDL2.DLL'..'SDL_HapticNumEffects' +++'_SDL_HapticNumEffectsPlaying'.'SDL2.DLL'..'SDL_HapticNumEffectsPlaying' +++'_SDL_HapticOpen'.'SDL2.DLL'..'SDL_HapticOpen' +++'_SDL_HapticOpenFromJoystick'.'SDL2.DLL'..'SDL_HapticOpenFromJoystick' +++'_SDL_HapticOpenFromMouse'.'SDL2.DLL'..'SDL_HapticOpenFromMouse' +++'_SDL_HapticOpened'.'SDL2.DLL'..'SDL_HapticOpened' +++'_SDL_HapticPause'.'SDL2.DLL'..'SDL_HapticPause' +++'_SDL_HapticQuery'.'SDL2.DLL'..'SDL_HapticQuery' +++'_SDL_HapticRumbleInit'.'SDL2.DLL'..'SDL_HapticRumbleInit' +++'_SDL_HapticRumblePlay'.'SDL2.DLL'..'SDL_HapticRumblePlay' +++'_SDL_HapticRumbleStop'.'SDL2.DLL'..'SDL_HapticRumbleStop' +++'_SDL_HapticRumbleSupported'.'SDL2.DLL'..'SDL_HapticRumbleSupported' +++'_SDL_HapticRunEffect'.'SDL2.DLL'..'SDL_HapticRunEffect' +++'_SDL_HapticSetAutocenter'.'SDL2.DLL'..'SDL_HapticSetAutocenter' +++'_SDL_HapticSetGain'.'SDL2.DLL'..'SDL_HapticSetGain' +++'_SDL_HapticStopAll'.'SDL2.DLL'..'SDL_HapticStopAll' +++'_SDL_HapticStopEffect'.'SDL2.DLL'..'SDL_HapticStopEffect' +++'_SDL_HapticUnpause'.'SDL2.DLL'..'SDL_HapticUnpause' +++'_SDL_HapticUpdateEffect'.'SDL2.DLL'..'SDL_HapticUpdateEffect' +++'_SDL_Has3DNow'.'SDL2.DLL'..'SDL_Has3DNow' +++'_SDL_HasARMSIMD'.'SDL2.DLL'..'SDL_HasARMSIMD' +++'_SDL_HasAVX'.'SDL2.DLL'..'SDL_HasAVX' +++'_SDL_HasAVX2'.'SDL2.DLL'..'SDL_HasAVX2' +++'_SDL_HasAVX512F'.'SDL2.DLL'..'SDL_HasAVX512F' +++'_SDL_HasAltiVec'.'SDL2.DLL'..'SDL_HasAltiVec' +++'_SDL_HasClipboardText'.'SDL2.DLL'..'SDL_HasClipboardText' +++'_SDL_HasColorKey'.'SDL2.DLL'..'SDL_HasColorKey' +++'_SDL_HasEvent'.'SDL2.DLL'..'SDL_HasEvent' +++'_SDL_HasEvents'.'SDL2.DLL'..'SDL_HasEvents' +++'_SDL_HasIntersection'.'SDL2.DLL'..'SDL_HasIntersection' +++'_SDL_HasMMX'.'SDL2.DLL'..'SDL_HasMMX' +++'_SDL_HasNEON'.'SDL2.DLL'..'SDL_HasNEON' +++'_SDL_HasRDTSC'.'SDL2.DLL'..'SDL_HasRDTSC' +++'_SDL_HasSSE'.'SDL2.DLL'..'SDL_HasSSE' +++'_SDL_HasSSE2'.'SDL2.DLL'..'SDL_HasSSE2' +++'_SDL_HasSSE3'.'SDL2.DLL'..'SDL_HasSSE3' +++'_SDL_HasSSE41'.'SDL2.DLL'..'SDL_HasSSE41' +++'_SDL_HasSSE42'.'SDL2.DLL'..'SDL_HasSSE42' +++'_SDL_HasScreenKeyboardSupport'.'SDL2.DLL'..'SDL_HasScreenKeyboardSupport' +++'_SDL_HideWindow'.'SDL2.DLL'..'SDL_HideWindow' +++'_SDL_Init'.'SDL2.DLL'..'SDL_Init' +++'_SDL_InitSubSystem'.'SDL2.DLL'..'SDL_InitSubSystem' +++'_SDL_IntersectRect'.'SDL2.DLL'..'SDL_IntersectRect' +++'_SDL_IntersectRectAndLine'.'SDL2.DLL'..'SDL_IntersectRectAndLine' +++'_SDL_IsGameController'.'SDL2.DLL'..'SDL_IsGameController' +++'_SDL_IsScreenKeyboardShown'.'SDL2.DLL'..'SDL_IsScreenKeyboardShown' +++'_SDL_IsScreenSaverEnabled'.'SDL2.DLL'..'SDL_IsScreenSaverEnabled' +++'_SDL_IsShapedWindow'.'SDL2.DLL'..'SDL_IsShapedWindow' +++'_SDL_IsTablet'.'SDL2.DLL'..'SDL_IsTablet' +++'_SDL_IsTextInputActive'.'SDL2.DLL'..'SDL_IsTextInputActive' +++'_SDL_JoystickClose'.'SDL2.DLL'..'SDL_JoystickClose' +++'_SDL_JoystickCurrentPowerLevel'.'SDL2.DLL'..'SDL_JoystickCurrentPowerLevel' +++'_SDL_JoystickEventState'.'SDL2.DLL'..'SDL_JoystickEventState' +++'_SDL_JoystickFromInstanceID'.'SDL2.DLL'..'SDL_JoystickFromInstanceID' +++'_SDL_JoystickGetAttached'.'SDL2.DLL'..'SDL_JoystickGetAttached' +++'_SDL_JoystickGetAxis'.'SDL2.DLL'..'SDL_JoystickGetAxis' +++'_SDL_JoystickGetAxisInitialState'.'SDL2.DLL'..'SDL_JoystickGetAxisInitialState' +++'_SDL_JoystickGetBall'.'SDL2.DLL'..'SDL_JoystickGetBall' +++'_SDL_JoystickGetButton'.'SDL2.DLL'..'SDL_JoystickGetButton' +++'_SDL_JoystickGetDeviceGUID'.'SDL2.DLL'..'SDL_JoystickGetDeviceGUID' +++'_SDL_JoystickGetDeviceInstanceID'.'SDL2.DLL'..'SDL_JoystickGetDeviceInstanceID' +++'_SDL_JoystickGetDevicePlayerIndex'.'SDL2.DLL'..'SDL_JoystickGetDevicePlayerIndex' +++'_SDL_JoystickGetDeviceProduct'.'SDL2.DLL'..'SDL_JoystickGetDeviceProduct' +++'_SDL_JoystickGetDeviceProductVersion'.'SDL2.DLL'..'SDL_JoystickGetDeviceProductVersion' +++'_SDL_JoystickGetDeviceType'.'SDL2.DLL'..'SDL_JoystickGetDeviceType' +++'_SDL_JoystickGetDeviceVendor'.'SDL2.DLL'..'SDL_JoystickGetDeviceVendor' +++'_SDL_JoystickGetGUID'.'SDL2.DLL'..'SDL_JoystickGetGUID' +++'_SDL_JoystickGetGUIDFromString'.'SDL2.DLL'..'SDL_JoystickGetGUIDFromString' +++'_SDL_JoystickGetGUIDString'.'SDL2.DLL'..'SDL_JoystickGetGUIDString' +++'_SDL_JoystickGetHat'.'SDL2.DLL'..'SDL_JoystickGetHat' +++'_SDL_JoystickGetPlayerIndex'.'SDL2.DLL'..'SDL_JoystickGetPlayerIndex' +++'_SDL_JoystickGetProduct'.'SDL2.DLL'..'SDL_JoystickGetProduct' +++'_SDL_JoystickGetProductVersion'.'SDL2.DLL'..'SDL_JoystickGetProductVersion' +++'_SDL_JoystickGetType'.'SDL2.DLL'..'SDL_JoystickGetType' +++'_SDL_JoystickGetVendor'.'SDL2.DLL'..'SDL_JoystickGetVendor' +++'_SDL_JoystickInstanceID'.'SDL2.DLL'..'SDL_JoystickInstanceID' +++'_SDL_JoystickIsHaptic'.'SDL2.DLL'..'SDL_JoystickIsHaptic' +++'_SDL_JoystickName'.'SDL2.DLL'..'SDL_JoystickName' +++'_SDL_JoystickNameForIndex'.'SDL2.DLL'..'SDL_JoystickNameForIndex' +++'_SDL_JoystickNumAxes'.'SDL2.DLL'..'SDL_JoystickNumAxes' +++'_SDL_JoystickNumBalls'.'SDL2.DLL'..'SDL_JoystickNumBalls' +++'_SDL_JoystickNumButtons'.'SDL2.DLL'..'SDL_JoystickNumButtons' +++'_SDL_JoystickNumHats'.'SDL2.DLL'..'SDL_JoystickNumHats' +++'_SDL_JoystickOpen'.'SDL2.DLL'..'SDL_JoystickOpen' +++'_SDL_JoystickRumble'.'SDL2.DLL'..'SDL_JoystickRumble' +++'_SDL_JoystickUpdate'.'SDL2.DLL'..'SDL_JoystickUpdate' +++'_SDL_LoadBMP_RW'.'SDL2.DLL'..'SDL_LoadBMP_RW' +++'_SDL_LoadDollarTemplates'.'SDL2.DLL'..'SDL_LoadDollarTemplates' +++'_SDL_LoadFile'.'SDL2.DLL'..'SDL_LoadFile' +++'_SDL_LoadFile_RW'.'SDL2.DLL'..'SDL_LoadFile_RW' +++'_SDL_LoadFunction'.'SDL2.DLL'..'SDL_LoadFunction' +++'_SDL_LoadObject'.'SDL2.DLL'..'SDL_LoadObject' +++'_SDL_LoadWAV_RW'.'SDL2.DLL'..'SDL_LoadWAV_RW' +++'_SDL_LockAudio'.'SDL2.DLL'..'SDL_LockAudio' +++'_SDL_LockAudioDevice'.'SDL2.DLL'..'SDL_LockAudioDevice' +++'_SDL_LockJoysticks'.'SDL2.DLL'..'SDL_LockJoysticks' +++'_SDL_LockMutex'.'SDL2.DLL'..'SDL_LockMutex' +++'_SDL_LockSurface'.'SDL2.DLL'..'SDL_LockSurface' +++'_SDL_LockTexture'.'SDL2.DLL'..'SDL_LockTexture' +++'_SDL_LockTextureToSurface'.'SDL2.DLL'..'SDL_LockTextureToSurface' +++'_SDL_Log'.'SDL2.DLL'..'SDL_Log' +++'_SDL_LogCritical'.'SDL2.DLL'..'SDL_LogCritical' +++'_SDL_LogDebug'.'SDL2.DLL'..'SDL_LogDebug' +++'_SDL_LogError'.'SDL2.DLL'..'SDL_LogError' +++'_SDL_LogGetOutputFunction'.'SDL2.DLL'..'SDL_LogGetOutputFunction' +++'_SDL_LogGetPriority'.'SDL2.DLL'..'SDL_LogGetPriority' +++'_SDL_LogInfo'.'SDL2.DLL'..'SDL_LogInfo' +++'_SDL_LogMessage'.'SDL2.DLL'..'SDL_LogMessage' +++'_SDL_LogMessageV'.'SDL2.DLL'..'SDL_LogMessageV' +++'_SDL_LogResetPriorities'.'SDL2.DLL'..'SDL_LogResetPriorities' +++'_SDL_LogSetAllPriority'.'SDL2.DLL'..'SDL_LogSetAllPriority' +++'_SDL_LogSetOutputFunction'.'SDL2.DLL'..'SDL_LogSetOutputFunction' +++'_SDL_LogSetPriority'.'SDL2.DLL'..'SDL_LogSetPriority' +++'_SDL_LogVerbose'.'SDL2.DLL'..'SDL_LogVerbose' +++'_SDL_LogWarn'.'SDL2.DLL'..'SDL_LogWarn' +++'_SDL_LowerBlit'.'SDL2.DLL'..'SDL_LowerBlit' +++'_SDL_LowerBlitScaled'.'SDL2.DLL'..'SDL_LowerBlitScaled' +++'_SDL_MapRGB'.'SDL2.DLL'..'SDL_MapRGB' +++'_SDL_MapRGBA'.'SDL2.DLL'..'SDL_MapRGBA' +++'_SDL_MasksToPixelFormatEnum'.'SDL2.DLL'..'SDL_MasksToPixelFormatEnum' +++'_SDL_MaximizeWindow'.'SDL2.DLL'..'SDL_MaximizeWindow' +++'_SDL_MemoryBarrierAcquireFunction'.'SDL2.DLL'..'SDL_MemoryBarrierAcquireFunction' +++'_SDL_MemoryBarrierReleaseFunction'.'SDL2.DLL'..'SDL_MemoryBarrierReleaseFunction' +++'_SDL_Metal_CreateView'.'SDL2.DLL'..'SDL_Metal_CreateView' +++'_SDL_Metal_DestroyView'.'SDL2.DLL'..'SDL_Metal_DestroyView' +++'_SDL_MinimizeWindow'.'SDL2.DLL'..'SDL_MinimizeWindow' +++'_SDL_MixAudio'.'SDL2.DLL'..'SDL_MixAudio' +++'_SDL_MixAudioFormat'.'SDL2.DLL'..'SDL_MixAudioFormat' +++'_SDL_MouseIsHaptic'.'SDL2.DLL'..'SDL_MouseIsHaptic' +++'_SDL_NewAudioStream'.'SDL2.DLL'..'SDL_NewAudioStream' +++'_SDL_NumHaptics'.'SDL2.DLL'..'SDL_NumHaptics' +++'_SDL_NumJoysticks'.'SDL2.DLL'..'SDL_NumJoysticks' +++'_SDL_NumSensors'.'SDL2.DLL'..'SDL_NumSensors' +++'_SDL_OpenAudio'.'SDL2.DLL'..'SDL_OpenAudio' +++'_SDL_OpenAudioDevice'.'SDL2.DLL'..'SDL_OpenAudioDevice' +++'_SDL_PauseAudio'.'SDL2.DLL'..'SDL_PauseAudio' +++'_SDL_PauseAudioDevice'.'SDL2.DLL'..'SDL_PauseAudioDevice' +++'_SDL_PeepEvents'.'SDL2.DLL'..'SDL_PeepEvents' +++'_SDL_PixelFormatEnumToMasks'.'SDL2.DLL'..'SDL_PixelFormatEnumToMasks' +++'_SDL_PollEvent'.'SDL2.DLL'..'SDL_PollEvent' +++'_SDL_PumpEvents'.'SDL2.DLL'..'SDL_PumpEvents' +++'_SDL_PushEvent'.'SDL2.DLL'..'SDL_PushEvent' +++'_SDL_QueryTexture'.'SDL2.DLL'..'SDL_QueryTexture' +++'_SDL_QueueAudio'.'SDL2.DLL'..'SDL_QueueAudio' +++'_SDL_Quit'.'SDL2.DLL'..'SDL_Quit' +++'_SDL_QuitSubSystem'.'SDL2.DLL'..'SDL_QuitSubSystem' +++'_SDL_RWFromConstMem'.'SDL2.DLL'..'SDL_RWFromConstMem' +++'_SDL_RWFromFP'.'SDL2.DLL'..'SDL_RWFromFP' +++'_SDL_RWFromFile'.'SDL2.DLL'..'SDL_RWFromFile' +++'_SDL_RWFromMem'.'SDL2.DLL'..'SDL_RWFromMem' +++'_SDL_RWclose'.'SDL2.DLL'..'SDL_RWclose' +++'_SDL_RWread'.'SDL2.DLL'..'SDL_RWread' +++'_SDL_RWseek'.'SDL2.DLL'..'SDL_RWseek' +++'_SDL_RWsize'.'SDL2.DLL'..'SDL_RWsize' +++'_SDL_RWtell'.'SDL2.DLL'..'SDL_RWtell' +++'_SDL_RWwrite'.'SDL2.DLL'..'SDL_RWwrite' +++'_SDL_RaiseWindow'.'SDL2.DLL'..'SDL_RaiseWindow' +++'_SDL_ReadBE16'.'SDL2.DLL'..'SDL_ReadBE16' +++'_SDL_ReadBE32'.'SDL2.DLL'..'SDL_ReadBE32' +++'_SDL_ReadBE64'.'SDL2.DLL'..'SDL_ReadBE64' +++'_SDL_ReadLE16'.'SDL2.DLL'..'SDL_ReadLE16' +++'_SDL_ReadLE32'.'SDL2.DLL'..'SDL_ReadLE32' +++'_SDL_ReadLE64'.'SDL2.DLL'..'SDL_ReadLE64' +++'_SDL_ReadU8'.'SDL2.DLL'..'SDL_ReadU8' +++'_SDL_RecordGesture'.'SDL2.DLL'..'SDL_RecordGesture' +++'_SDL_RegisterApp'.'SDL2.DLL'..'SDL_RegisterApp' +++'_SDL_RegisterEvents'.'SDL2.DLL'..'SDL_RegisterEvents' +++'_SDL_RemoveTimer'.'SDL2.DLL'..'SDL_RemoveTimer' +++'_SDL_RenderClear'.'SDL2.DLL'..'SDL_RenderClear' +++'_SDL_RenderCopy'.'SDL2.DLL'..'SDL_RenderCopy' +++'_SDL_RenderCopyEx'.'SDL2.DLL'..'SDL_RenderCopyEx' +++'_SDL_RenderCopyExF'.'SDL2.DLL'..'SDL_RenderCopyExF' +++'_SDL_RenderCopyF'.'SDL2.DLL'..'SDL_RenderCopyF' +++'_SDL_RenderDrawLine'.'SDL2.DLL'..'SDL_RenderDrawLine' +++'_SDL_RenderDrawLineF'.'SDL2.DLL'..'SDL_RenderDrawLineF' +++'_SDL_RenderDrawLines'.'SDL2.DLL'..'SDL_RenderDrawLines' +++'_SDL_RenderDrawLinesF'.'SDL2.DLL'..'SDL_RenderDrawLinesF' +++'_SDL_RenderDrawPoint'.'SDL2.DLL'..'SDL_RenderDrawPoint' +++'_SDL_RenderDrawPointF'.'SDL2.DLL'..'SDL_RenderDrawPointF' +++'_SDL_RenderDrawPoints'.'SDL2.DLL'..'SDL_RenderDrawPoints' +++'_SDL_RenderDrawPointsF'.'SDL2.DLL'..'SDL_RenderDrawPointsF' +++'_SDL_RenderDrawRect'.'SDL2.DLL'..'SDL_RenderDrawRect' +++'_SDL_RenderDrawRectF'.'SDL2.DLL'..'SDL_RenderDrawRectF' +++'_SDL_RenderDrawRects'.'SDL2.DLL'..'SDL_RenderDrawRects' +++'_SDL_RenderDrawRectsF'.'SDL2.DLL'..'SDL_RenderDrawRectsF' +++'_SDL_RenderFillRect'.'SDL2.DLL'..'SDL_RenderFillRect' +++'_SDL_RenderFillRectF'.'SDL2.DLL'..'SDL_RenderFillRectF' +++'_SDL_RenderFillRects'.'SDL2.DLL'..'SDL_RenderFillRects' +++'_SDL_RenderFillRectsF'.'SDL2.DLL'..'SDL_RenderFillRectsF' +++'_SDL_RenderFlush'.'SDL2.DLL'..'SDL_RenderFlush' +++'_SDL_RenderGetClipRect'.'SDL2.DLL'..'SDL_RenderGetClipRect' +++'_SDL_RenderGetD3D9Device'.'SDL2.DLL'..'SDL_RenderGetD3D9Device' +++'_SDL_RenderGetIntegerScale'.'SDL2.DLL'..'SDL_RenderGetIntegerScale' +++'_SDL_RenderGetLogicalSize'.'SDL2.DLL'..'SDL_RenderGetLogicalSize' +++'_SDL_RenderGetMetalCommandEncoder'.'SDL2.DLL'..'SDL_RenderGetMetalCommandEncoder' +++'_SDL_RenderGetMetalLayer'.'SDL2.DLL'..'SDL_RenderGetMetalLayer' +++'_SDL_RenderGetScale'.'SDL2.DLL'..'SDL_RenderGetScale' +++'_SDL_RenderGetViewport'.'SDL2.DLL'..'SDL_RenderGetViewport' +++'_SDL_RenderIsClipEnabled'.'SDL2.DLL'..'SDL_RenderIsClipEnabled' +++'_SDL_RenderPresent'.'SDL2.DLL'..'SDL_RenderPresent' +++'_SDL_RenderReadPixels'.'SDL2.DLL'..'SDL_RenderReadPixels' +++'_SDL_RenderSetClipRect'.'SDL2.DLL'..'SDL_RenderSetClipRect' +++'_SDL_RenderSetIntegerScale'.'SDL2.DLL'..'SDL_RenderSetIntegerScale' +++'_SDL_RenderSetLogicalSize'.'SDL2.DLL'..'SDL_RenderSetLogicalSize' +++'_SDL_RenderSetScale'.'SDL2.DLL'..'SDL_RenderSetScale' +++'_SDL_RenderSetViewport'.'SDL2.DLL'..'SDL_RenderSetViewport' +++'_SDL_RenderTargetSupported'.'SDL2.DLL'..'SDL_RenderTargetSupported' +++'_SDL_ReportAssertion'.'SDL2.DLL'..'SDL_ReportAssertion' +++'_SDL_ResetAssertionReport'.'SDL2.DLL'..'SDL_ResetAssertionReport' +++'_SDL_RestoreWindow'.'SDL2.DLL'..'SDL_RestoreWindow' +++'_SDL_SIMDAlloc'.'SDL2.DLL'..'SDL_SIMDAlloc' +++'_SDL_SIMDFree'.'SDL2.DLL'..'SDL_SIMDFree' +++'_SDL_SIMDGetAlignment'.'SDL2.DLL'..'SDL_SIMDGetAlignment' +++'_SDL_SaveAllDollarTemplates'.'SDL2.DLL'..'SDL_SaveAllDollarTemplates' +++'_SDL_SaveBMP_RW'.'SDL2.DLL'..'SDL_SaveBMP_RW' +++'_SDL_SaveDollarTemplate'.'SDL2.DLL'..'SDL_SaveDollarTemplate' +++'_SDL_SemPost'.'SDL2.DLL'..'SDL_SemPost' +++'_SDL_SemTryWait'.'SDL2.DLL'..'SDL_SemTryWait' +++'_SDL_SemValue'.'SDL2.DLL'..'SDL_SemValue' +++'_SDL_SemWait'.'SDL2.DLL'..'SDL_SemWait' +++'_SDL_SemWaitTimeout'.'SDL2.DLL'..'SDL_SemWaitTimeout' +++'_SDL_SensorClose'.'SDL2.DLL'..'SDL_SensorClose' +++'_SDL_SensorFromInstanceID'.'SDL2.DLL'..'SDL_SensorFromInstanceID' +++'_SDL_SensorGetData'.'SDL2.DLL'..'SDL_SensorGetData' +++'_SDL_SensorGetDeviceInstanceID'.'SDL2.DLL'..'SDL_SensorGetDeviceInstanceID' +++'_SDL_SensorGetDeviceName'.'SDL2.DLL'..'SDL_SensorGetDeviceName' +++'_SDL_SensorGetDeviceNonPortableType'.'SDL2.DLL'..'SDL_SensorGetDeviceNonPortableType' +++'_SDL_SensorGetDeviceType'.'SDL2.DLL'..'SDL_SensorGetDeviceType' +++'_SDL_SensorGetInstanceID'.'SDL2.DLL'..'SDL_SensorGetInstanceID' +++'_SDL_SensorGetName'.'SDL2.DLL'..'SDL_SensorGetName' +++'_SDL_SensorGetNonPortableType'.'SDL2.DLL'..'SDL_SensorGetNonPortableType' +++'_SDL_SensorGetType'.'SDL2.DLL'..'SDL_SensorGetType' +++'_SDL_SensorOpen'.'SDL2.DLL'..'SDL_SensorOpen' +++'_SDL_SensorUpdate'.'SDL2.DLL'..'SDL_SensorUpdate' +++'_SDL_SetAssertionHandler'.'SDL2.DLL'..'SDL_SetAssertionHandler' +++'_SDL_SetClipRect'.'SDL2.DLL'..'SDL_SetClipRect' +++'_SDL_SetClipboardText'.'SDL2.DLL'..'SDL_SetClipboardText' +++'_SDL_SetColorKey'.'SDL2.DLL'..'SDL_SetColorKey' +++'_SDL_SetCursor'.'SDL2.DLL'..'SDL_SetCursor' +++'_SDL_SetError'.'SDL2.DLL'..'SDL_SetError' +++'_SDL_SetEventFilter'.'SDL2.DLL'..'SDL_SetEventFilter' +++'_SDL_SetHint'.'SDL2.DLL'..'SDL_SetHint' +++'_SDL_SetHintWithPriority'.'SDL2.DLL'..'SDL_SetHintWithPriority' +++'_SDL_SetMainReady'.'SDL2.DLL'..'SDL_SetMainReady' +++'_SDL_SetMemoryFunctions'.'SDL2.DLL'..'SDL_SetMemoryFunctions' +++'_SDL_SetModState'.'SDL2.DLL'..'SDL_SetModState' +++'_SDL_SetPaletteColors'.'SDL2.DLL'..'SDL_SetPaletteColors' +++'_SDL_SetPixelFormatPalette'.'SDL2.DLL'..'SDL_SetPixelFormatPalette' +++'_SDL_SetRelativeMouseMode'.'SDL2.DLL'..'SDL_SetRelativeMouseMode' +++'_SDL_SetRenderDrawBlendMode'.'SDL2.DLL'..'SDL_SetRenderDrawBlendMode' +++'_SDL_SetRenderDrawColor'.'SDL2.DLL'..'SDL_SetRenderDrawColor' +++'_SDL_SetRenderTarget'.'SDL2.DLL'..'SDL_SetRenderTarget' +++'_SDL_SetSurfaceAlphaMod'.'SDL2.DLL'..'SDL_SetSurfaceAlphaMod' +++'_SDL_SetSurfaceBlendMode'.'SDL2.DLL'..'SDL_SetSurfaceBlendMode' +++'_SDL_SetSurfaceColorMod'.'SDL2.DLL'..'SDL_SetSurfaceColorMod' +++'_SDL_SetSurfacePalette'.'SDL2.DLL'..'SDL_SetSurfacePalette' +++'_SDL_SetSurfaceRLE'.'SDL2.DLL'..'SDL_SetSurfaceRLE' +++'_SDL_SetTextInputRect'.'SDL2.DLL'..'SDL_SetTextInputRect' +++'_SDL_SetTextureAlphaMod'.'SDL2.DLL'..'SDL_SetTextureAlphaMod' +++'_SDL_SetTextureBlendMode'.'SDL2.DLL'..'SDL_SetTextureBlendMode' +++'_SDL_SetTextureColorMod'.'SDL2.DLL'..'SDL_SetTextureColorMod' +++'_SDL_SetThreadPriority'.'SDL2.DLL'..'SDL_SetThreadPriority' +++'_SDL_SetWindowBordered'.'SDL2.DLL'..'SDL_SetWindowBordered' +++'_SDL_SetWindowBrightness'.'SDL2.DLL'..'SDL_SetWindowBrightness' +++'_SDL_SetWindowData'.'SDL2.DLL'..'SDL_SetWindowData' +++'_SDL_SetWindowDisplayMode'.'SDL2.DLL'..'SDL_SetWindowDisplayMode' +++'_SDL_SetWindowFullscreen'.'SDL2.DLL'..'SDL_SetWindowFullscreen' +++'_SDL_SetWindowGammaRamp'.'SDL2.DLL'..'SDL_SetWindowGammaRamp' +++'_SDL_SetWindowGrab'.'SDL2.DLL'..'SDL_SetWindowGrab' +++'_SDL_SetWindowHitTest'.'SDL2.DLL'..'SDL_SetWindowHitTest' +++'_SDL_SetWindowIcon'.'SDL2.DLL'..'SDL_SetWindowIcon' +++'_SDL_SetWindowInputFocus'.'SDL2.DLL'..'SDL_SetWindowInputFocus' +++'_SDL_SetWindowMaximumSize'.'SDL2.DLL'..'SDL_SetWindowMaximumSize' +++'_SDL_SetWindowMinimumSize'.'SDL2.DLL'..'SDL_SetWindowMinimumSize' +++'_SDL_SetWindowModalFor'.'SDL2.DLL'..'SDL_SetWindowModalFor' +++'_SDL_SetWindowOpacity'.'SDL2.DLL'..'SDL_SetWindowOpacity' +++'_SDL_SetWindowPosition'.'SDL2.DLL'..'SDL_SetWindowPosition' +++'_SDL_SetWindowResizable'.'SDL2.DLL'..'SDL_SetWindowResizable' +++'_SDL_SetWindowShape'.'SDL2.DLL'..'SDL_SetWindowShape' +++'_SDL_SetWindowSize'.'SDL2.DLL'..'SDL_SetWindowSize' +++'_SDL_SetWindowTitle'.'SDL2.DLL'..'SDL_SetWindowTitle' +++'_SDL_SetWindowsMessageHook'.'SDL2.DLL'..'SDL_SetWindowsMessageHook' +++'_SDL_SetYUVConversionMode'.'SDL2.DLL'..'SDL_SetYUVConversionMode' +++'_SDL_ShowCursor'.'SDL2.DLL'..'SDL_ShowCursor' +++'_SDL_ShowMessageBox'.'SDL2.DLL'..'SDL_ShowMessageBox' +++'_SDL_ShowSimpleMessageBox'.'SDL2.DLL'..'SDL_ShowSimpleMessageBox' +++'_SDL_ShowWindow'.'SDL2.DLL'..'SDL_ShowWindow' +++'_SDL_SoftStretch'.'SDL2.DLL'..'SDL_SoftStretch' +++'_SDL_StartTextInput'.'SDL2.DLL'..'SDL_StartTextInput' +++'_SDL_StopTextInput'.'SDL2.DLL'..'SDL_StopTextInput' +++'_SDL_TLSCreate'.'SDL2.DLL'..'SDL_TLSCreate' +++'_SDL_TLSGet'.'SDL2.DLL'..'SDL_TLSGet' +++'_SDL_TLSSet'.'SDL2.DLL'..'SDL_TLSSet' +++'_SDL_ThreadID'.'SDL2.DLL'..'SDL_ThreadID' +++'_SDL_TryLockMutex'.'SDL2.DLL'..'SDL_TryLockMutex' +++'_SDL_UnionRect'.'SDL2.DLL'..'SDL_UnionRect' +++'_SDL_UnloadObject'.'SDL2.DLL'..'SDL_UnloadObject' +++'_SDL_UnlockAudio'.'SDL2.DLL'..'SDL_UnlockAudio' +++'_SDL_UnlockAudioDevice'.'SDL2.DLL'..'SDL_UnlockAudioDevice' +++'_SDL_UnlockJoysticks'.'SDL2.DLL'..'SDL_UnlockJoysticks' +++'_SDL_UnlockMutex'.'SDL2.DLL'..'SDL_UnlockMutex' +++'_SDL_UnlockSurface'.'SDL2.DLL'..'SDL_UnlockSurface' +++'_SDL_UnlockTexture'.'SDL2.DLL'..'SDL_UnlockTexture' +++'_SDL_UnregisterApp'.'SDL2.DLL'..'SDL_UnregisterApp' +++'_SDL_UpdateTexture'.'SDL2.DLL'..'SDL_UpdateTexture' +++'_SDL_UpdateWindowSurface'.'SDL2.DLL'..'SDL_UpdateWindowSurface' +++'_SDL_UpdateWindowSurfaceRects'.'SDL2.DLL'..'SDL_UpdateWindowSurfaceRects' +++'_SDL_UpdateYUVTexture'.'SDL2.DLL'..'SDL_UpdateYUVTexture' +++'_SDL_UpperBlit'.'SDL2.DLL'..'SDL_UpperBlit' +++'_SDL_UpperBlitScaled'.'SDL2.DLL'..'SDL_UpperBlitScaled' +++'_SDL_VideoInit'.'SDL2.DLL'..'SDL_VideoInit' +++'_SDL_VideoQuit'.'SDL2.DLL'..'SDL_VideoQuit' +++'_SDL_Vulkan_CreateSurface'.'SDL2.DLL'..'SDL_Vulkan_CreateSurface' +++'_SDL_Vulkan_GetDrawableSize'.'SDL2.DLL'..'SDL_Vulkan_GetDrawableSize' +++'_SDL_Vulkan_GetInstanceExtensions'.'SDL2.DLL'..'SDL_Vulkan_GetInstanceExtensions' +++'_SDL_Vulkan_GetVkGetInstanceProcAddr'.'SDL2.DLL'..'SDL_Vulkan_GetVkGetInstanceProcAddr' +++'_SDL_Vulkan_LoadLibrary'.'SDL2.DLL'..'SDL_Vulkan_LoadLibrary' +++'_SDL_Vulkan_UnloadLibrary'.'SDL2.DLL'..'SDL_Vulkan_UnloadLibrary' +++'_SDL_WaitEvent'.'SDL2.DLL'..'SDL_WaitEvent' +++'_SDL_WaitEventTimeout'.'SDL2.DLL'..'SDL_WaitEventTimeout' +++'_SDL_WaitThread'.'SDL2.DLL'..'SDL_WaitThread' +++'_SDL_WarpMouseGlobal'.'SDL2.DLL'..'SDL_WarpMouseGlobal' +++'_SDL_WarpMouseInWindow'.'SDL2.DLL'..'SDL_WarpMouseInWindow' +++'_SDL_WasInit'.'SDL2.DLL'..'SDL_WasInit' +++'_SDL_WriteBE16'.'SDL2.DLL'..'SDL_WriteBE16' +++'_SDL_WriteBE32'.'SDL2.DLL'..'SDL_WriteBE32' +++'_SDL_WriteBE64'.'SDL2.DLL'..'SDL_WriteBE64' +++'_SDL_WriteLE16'.'SDL2.DLL'..'SDL_WriteLE16' +++'_SDL_WriteLE32'.'SDL2.DLL'..'SDL_WriteLE32' +++'_SDL_WriteLE64'.'SDL2.DLL'..'SDL_WriteLE64' +++'_SDL_WriteU8'.'SDL2.DLL'..'SDL_WriteU8' +++'_SDL_abs'.'SDL2.DLL'..'SDL_abs' +++'_SDL_acos'.'SDL2.DLL'..'SDL_acos' +++'_SDL_acosf'.'SDL2.DLL'..'SDL_acosf' +++'_SDL_asin'.'SDL2.DLL'..'SDL_asin' +++'_SDL_asinf'.'SDL2.DLL'..'SDL_asinf' +++'_SDL_atan'.'SDL2.DLL'..'SDL_atan' +++'_SDL_atan2'.'SDL2.DLL'..'SDL_atan2' +++'_SDL_atan2f'.'SDL2.DLL'..'SDL_atan2f' +++'_SDL_atanf'.'SDL2.DLL'..'SDL_atanf' +++'_SDL_atof'.'SDL2.DLL'..'SDL_atof' +++'_SDL_atoi'.'SDL2.DLL'..'SDL_atoi' +++'_SDL_calloc'.'SDL2.DLL'..'SDL_calloc' +++'_SDL_ceil'.'SDL2.DLL'..'SDL_ceil' +++'_SDL_ceilf'.'SDL2.DLL'..'SDL_ceilf' +++'_SDL_copysign'.'SDL2.DLL'..'SDL_copysign' +++'_SDL_copysignf'.'SDL2.DLL'..'SDL_copysignf' +++'_SDL_cos'.'SDL2.DLL'..'SDL_cos' +++'_SDL_cosf'.'SDL2.DLL'..'SDL_cosf' +++'_SDL_exp'.'SDL2.DLL'..'SDL_exp' +++'_SDL_expf'.'SDL2.DLL'..'SDL_expf' +++'_SDL_fabs'.'SDL2.DLL'..'SDL_fabs' +++'_SDL_fabsf'.'SDL2.DLL'..'SDL_fabsf' +++'_SDL_floor'.'SDL2.DLL'..'SDL_floor' +++'_SDL_floorf'.'SDL2.DLL'..'SDL_floorf' +++'_SDL_fmod'.'SDL2.DLL'..'SDL_fmod' +++'_SDL_fmodf'.'SDL2.DLL'..'SDL_fmodf' +++'_SDL_free'.'SDL2.DLL'..'SDL_free' +++'_SDL_getenv'.'SDL2.DLL'..'SDL_getenv' +++'_SDL_iconv'.'SDL2.DLL'..'SDL_iconv' +++'_SDL_iconv_close'.'SDL2.DLL'..'SDL_iconv_close' +++'_SDL_iconv_open'.'SDL2.DLL'..'SDL_iconv_open' +++'_SDL_iconv_string'.'SDL2.DLL'..'SDL_iconv_string' +++'_SDL_isdigit'.'SDL2.DLL'..'SDL_isdigit' +++'_SDL_isspace'.'SDL2.DLL'..'SDL_isspace' +++'_SDL_itoa'.'SDL2.DLL'..'SDL_itoa' +++'_SDL_lltoa'.'SDL2.DLL'..'SDL_lltoa' +++'_SDL_log'.'SDL2.DLL'..'SDL_log' +++'_SDL_log10'.'SDL2.DLL'..'SDL_log10' +++'_SDL_log10f'.'SDL2.DLL'..'SDL_log10f' +++'_SDL_logf'.'SDL2.DLL'..'SDL_logf' +++'_SDL_ltoa'.'SDL2.DLL'..'SDL_ltoa' +++'_SDL_malloc'.'SDL2.DLL'..'SDL_malloc' +++'_SDL_memcmp'.'SDL2.DLL'..'SDL_memcmp' +++'_SDL_memcpy'.'SDL2.DLL'..'SDL_memcpy' +++'_SDL_memmove'.'SDL2.DLL'..'SDL_memmove' +++'_SDL_memset'.'SDL2.DLL'..'SDL_memset' +++'_SDL_pow'.'SDL2.DLL'..'SDL_pow' +++'_SDL_powf'.'SDL2.DLL'..'SDL_powf' +++'_SDL_qsort'.'SDL2.DLL'..'SDL_qsort' +++'_SDL_realloc'.'SDL2.DLL'..'SDL_realloc' +++'_SDL_scalbn'.'SDL2.DLL'..'SDL_scalbn' +++'_SDL_scalbnf'.'SDL2.DLL'..'SDL_scalbnf' +++'_SDL_setenv'.'SDL2.DLL'..'SDL_setenv' +++'_SDL_sin'.'SDL2.DLL'..'SDL_sin' +++'_SDL_sinf'.'SDL2.DLL'..'SDL_sinf' +++'_SDL_snprintf'.'SDL2.DLL'..'SDL_snprintf' +++'_SDL_sqrt'.'SDL2.DLL'..'SDL_sqrt' +++'_SDL_sqrtf'.'SDL2.DLL'..'SDL_sqrtf' +++'_SDL_sscanf'.'SDL2.DLL'..'SDL_sscanf' +++'_SDL_strcasecmp'.'SDL2.DLL'..'SDL_strcasecmp' +++'_SDL_strchr'.'SDL2.DLL'..'SDL_strchr' +++'_SDL_strcmp'.'SDL2.DLL'..'SDL_strcmp' +++'_SDL_strdup'.'SDL2.DLL'..'SDL_strdup' +++'_SDL_strlcat'.'SDL2.DLL'..'SDL_strlcat' +++'_SDL_strlcpy'.'SDL2.DLL'..'SDL_strlcpy' +++'_SDL_strlen'.'SDL2.DLL'..'SDL_strlen' +++'_SDL_strlwr'.'SDL2.DLL'..'SDL_strlwr' +++'_SDL_strncasecmp'.'SDL2.DLL'..'SDL_strncasecmp' +++'_SDL_strncmp'.'SDL2.DLL'..'SDL_strncmp' +++'_SDL_strrchr'.'SDL2.DLL'..'SDL_strrchr' +++'_SDL_strrev'.'SDL2.DLL'..'SDL_strrev' +++'_SDL_strstr'.'SDL2.DLL'..'SDL_strstr' +++'_SDL_strtod'.'SDL2.DLL'..'SDL_strtod' +++'_SDL_strtol'.'SDL2.DLL'..'SDL_strtol' +++'_SDL_strtoll'.'SDL2.DLL'..'SDL_strtoll' +++'_SDL_strtoul'.'SDL2.DLL'..'SDL_strtoul' +++'_SDL_strtoull'.'SDL2.DLL'..'SDL_strtoull' +++'_SDL_strupr'.'SDL2.DLL'..'SDL_strupr' +++'_SDL_tan'.'SDL2.DLL'..'SDL_tan' +++'_SDL_tanf'.'SDL2.DLL'..'SDL_tanf' +++'_SDL_tolower'.'SDL2.DLL'..'SDL_tolower' +++'_SDL_toupper'.'SDL2.DLL'..'SDL_toupper' +++'_SDL_uitoa'.'SDL2.DLL'..'SDL_uitoa' +++'_SDL_ulltoa'.'SDL2.DLL'..'SDL_ulltoa' +++'_SDL_ultoa'.'SDL2.DLL'..'SDL_ultoa' +++'_SDL_utf8strlcpy'.'SDL2.DLL'..'SDL_utf8strlcpy' +++'_SDL_utf8strlen'.'SDL2.DLL'..'SDL_utf8strlen' +++'_SDL_vsnprintf'.'SDL2.DLL'..'SDL_vsnprintf' +++'_SDL_vsscanf'.'SDL2.DLL'..'SDL_vsscanf' +++'_SDL_wcscmp'.'SDL2.DLL'..'SDL_wcscmp' +++'_SDL_wcsdup'.'SDL2.DLL'..'SDL_wcsdup' +++'_SDL_wcslcat'.'SDL2.DLL'..'SDL_wcslcat' +++'_SDL_wcslcpy'.'SDL2.DLL'..'SDL_wcslcpy' +++'_SDL_wcslen'.'SDL2.DLL'..'SDL_wcslen' diff --git a/engine/Windows/SDL2/watcom/def2lbc.awk b/engine/Windows/SDL2/watcom/def2lbc.awk new file mode 100644 index 0000000..84767f6 --- /dev/null +++ b/engine/Windows/SDL2/watcom/def2lbc.awk @@ -0,0 +1,38 @@ +# get uppercased module name +/^[ \t]*LIBRARY/ { ModuleName = toupper( $2 ); next } + +# skip uninteresting lines +/^[ \t]*(EXPORTS|;)/ { next } + +# NB: Calling conventions essentially do not exist on non-x86 platforms, +# we simply strip the decoration unless 'cpu' equals 386. + +# process fastcall symbols "@symbol@size" +/^[ \t]*@[A-Za-z0-9_]+@[0-9]+/ { + split( $1, parts, "@" ) # split the import name on the at signs + if( cpu == "386" ) + printf( "++'%s'.'%s'..'%s'\n", $1, ModuleName, parts[2] ) + else + printf( "++'%s'.'%s'\n", parts[2], ModuleName ) + next +} + +# process stdcall symbols using "symbol@size" format +/^[ \t]*[A-Za-z0-9_]+@[0-9]+/ { + split( $1, parts, "@" ) # split the import name on the at sign + if( cpu == "386" ) + printf( "++'_%s'.'%s'..'%s'\n", $1, ModuleName, parts[1] ) + else + printf( "++'%s'.'%s'\n", parts[1], ModuleName ) + next +} + +# process cdecl symbols using plain "symbol" format +/^[ \t]*[A-Za-z0-9_]+/ { + split( $1, parts, "@" ) # split the import name on the at sign + if( cpu == "386" ) + printf( "++'_%s'.'%s'..'%s'\n", $1, ModuleName, $1 ) + else + printf( "++'%s'.'%s'\n", parts[1], ModuleName ) + next +} diff --git a/engine/Windows/SDL2/watcom/makefile b/engine/Windows/SDL2/watcom/makefile new file mode 100644 index 0000000..adfcc61 --- /dev/null +++ b/engine/Windows/SDL2/watcom/makefile @@ -0,0 +1,11 @@ +# Open Watcom makefile to generate SDL2.lib +# def2lbc.awk (from OW source tree) requires 'awk' +# run 'wmake' + +all: SDL2.lib + +SDL2.exp: SDL2.def def2lbc.awk + awk -v cpu=386 -f def2lbc.awk SDL2.def > SDL2.exp + +SDL2.lib: SDL2.exp + wlib -q -b -n -c -pa -s -t -zld -ii -io SDL2.lib @SDL2.exp diff --git a/engine/Windows/VisualStudio/uniquake.sln b/engine/Windows/VisualStudio/uniquake.sln new file mode 100644 index 0000000..67bf12c --- /dev/null +++ b/engine/Windows/VisualStudio/uniquake.sln @@ -0,0 +1,31 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 15 +VisualStudioVersion = 15.0.28307.1433 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "uniquake", "uniquake.vcxproj", "{AE77266F-0A23-4F08-A491-369DE664B273}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {AE77266F-0A23-4F08-A491-369DE664B273}.Debug|x64.ActiveCfg = Debug|x64 + {AE77266F-0A23-4F08-A491-369DE664B273}.Debug|x64.Build.0 = Debug|x64 + {AE77266F-0A23-4F08-A491-369DE664B273}.Debug|x86.ActiveCfg = Debug|Win32 + {AE77266F-0A23-4F08-A491-369DE664B273}.Debug|x86.Build.0 = Debug|Win32 + {AE77266F-0A23-4F08-A491-369DE664B273}.Release|x64.ActiveCfg = Release|x64 + {AE77266F-0A23-4F08-A491-369DE664B273}.Release|x64.Build.0 = Release|x64 + {AE77266F-0A23-4F08-A491-369DE664B273}.Release|x86.ActiveCfg = Release|Win32 + {AE77266F-0A23-4F08-A491-369DE664B273}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {835DE3D3-A57A-4DEF-8017-D752CB3ECAC6} + EndGlobalSection +EndGlobal diff --git a/engine/Windows/VisualStudio/uniquake.vcxproj b/engine/Windows/VisualStudio/uniquake.vcxproj new file mode 100644 index 0000000..5a00994 --- /dev/null +++ b/engine/Windows/VisualStudio/uniquake.vcxproj @@ -0,0 +1,349 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {AE77266F-0A23-4F08-A491-369DE664B273} + quakespasm-sdl2 + Win32Proj + 8.1 + + + + Application + v141 + NotSet + true + + + DynamicLibrary + v141 + NotSet + + + Application + v141 + NotSet + true + + + DynamicLibrary + v141 + NotSet + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>15.0.28307.799 + + + $(SolutionDir)Build-$(ProjectName)\x86\$(Configuration)\ + Build-$(ProjectName)\x86\$(Configuration)\ + true + + + $(SolutionDir)Build-$(ProjectName)\x86\$(Configuration)\ + Build-$(ProjectName)\x86\$(Configuration)\ + false + + + $(SolutionDir)Build-$(ProjectName)\$(Platform)\$(Configuration)\ + Build-$(ProjectName)\$(Platform)\$(Configuration)\ + true + + + $(SolutionDir)Build-$(ProjectName)\$(Platform)\$(Configuration)\ + Build-$(ProjectName)\$(Platform)\$(Configuration)\ + false + + + + Disabled + ..\SDL2\include;..\codecs\include;..\misc\include;..\..\Quake;%(AdditionalIncludeDirectories) + UNIQUAKE_EXPORTS;UQ_SDLREF;WIN32;_DEBUG;_WINDOWS;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_WARNINGS;_WINSOCK_DEPRECATED_NO_WARNINGS;USE_SDL2;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + + Level3 + EditAndContinue + CompileAsC + + + wsock32.lib;opengl32.lib;winmm.lib;SDL2.lib;SDL2main.lib;%(AdditionalDependencies) + ..\codecs\x86;..\SDL2\lib;%(AdditionalLibraryDirectories) + msvcrt.lib;%(IgnoreSpecificDefaultLibraries) + true + Windows + MachineX86 + + + copy $(TargetDir)$(TargetName).dll $(SolutionDir)..\..\..\Assets\Plugins\windows\x86\uniquake.dll + + + + + MaxSpeed + true + ..\SDL2\include;..\codecs\include;..\misc\include;..\..\Quake;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_WARNINGS;_WINSOCK_DEPRECATED_NO_WARNINGS;USE_SDL2;USE_CODEC_MP3;USE_CODEC_VORBIS;USE_CODEC_WAVE;USE_CODEC_FLAC;USE_CODEC_OPUS;USE_CODEC_MIKMOD;USE_CODEC_UMX;%(PreprocessorDefinitions) + MultiThreadedDLL + true + + Level3 + ProgramDatabase + CompileAsC + + + libvorbisfile.lib;libvorbis.lib;libopusfile.lib;libopus.lib;libFLAC.lib;libogg.lib;libmad.lib;libmikmod.lib;wsock32.lib;opengl32.lib;winmm.lib;SDL2.lib;SDL2main.lib;%(AdditionalDependencies) + ..\codecs\x86;..\SDL2\lib;%(AdditionalLibraryDirectories) + true + Windows + true + true + MachineX86 + + + copy "$(SolutionDir)\..\codecs\x86\*.dll" "$(TargetDir)" +copy "$(SolutionDir)\..\SDL2\lib\*.dll" "$(TargetDir)" + + + + + X64 + + + Disabled + ..\SDL2\include;..\codecs\include;..\misc\include;..\..\Quake;%(AdditionalIncludeDirectories) + UNIQUAKE_EXPORTS;UQ_SDLREF;WIN32;_DEBUG;_WINDOWS;_USE_WINSOCK2;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_WARNINGS;_WINSOCK_DEPRECATED_NO_WARNINGS;USE_SDL2;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + + Level3 + ProgramDatabase + CompileAsC + + + ws2_32.lib;opengl32.lib;winmm.lib;SDL2.lib;SDL2main.lib;%(AdditionalDependencies) + ..\codecs\x64;..\SDL2\lib64;%(AdditionalLibraryDirectories) + msvcrt.lib;%(IgnoreSpecificDefaultLibraries) + true + Windows + MachineX64 + + + copy $(TargetDir)$(TargetName).dll $(SolutionDir)..\..\..\Assets\Plugins\windows\x86_64\uniquake.dll + + + + + X64 + + + MaxSpeed + true + ..\SDL2\include;..\codecs\include;..\misc\include;..\..\Quake;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;_USE_WINSOCK2;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_WARNINGS;_WINSOCK_DEPRECATED_NO_WARNINGS;USE_SDL2;USE_CODEC_MP3;USE_CODEC_VORBIS;USE_CODEC_WAVE;USE_CODEC_FLAC;USE_CODEC_OPUS;USE_CODEC_MIKMOD;USE_CODEC_UMX;%(PreprocessorDefinitions) + MultiThreadedDLL + true + + Level3 + ProgramDatabase + CompileAsC + + + libvorbisfile.lib;libvorbis.lib;libopusfile.lib;libopus.lib;libFLAC.lib;libogg.lib;libmad.lib;libmikmod.lib;ws2_32.lib;opengl32.lib;winmm.lib;SDL2.lib;SDL2main.lib;%(AdditionalDependencies) + ..\codecs\x64;..\SDL2\lib64;%(AdditionalLibraryDirectories) + true + Windows + true + true + MachineX64 + + + copy "$(SolutionDir)\..\codecs\x64\*.dll" "$(TargetDir)" +copy "$(SolutionDir)\..\SDL2\lib64\*.dll" "$(TargetDir)" + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/engine/Windows/VisualStudio/uniquake.vcxproj.filters b/engine/Windows/VisualStudio/uniquake.vcxproj.filters new file mode 100644 index 0000000..ab605bf --- /dev/null +++ b/engine/Windows/VisualStudio/uniquake.vcxproj.filters @@ -0,0 +1,444 @@ + + + + + engine + + + engine + + + engine + + + engine + + + engine + + + engine + + + engine + + + engine + + + engine + + + engine + + + engine + + + engine + + + engine + + + engine + + + engine + + + engine + + + engine + + + engine + + + engine + + + engine + + + engine + + + engine + + + engine + + + engine + + + engine + + + engine + + + engine + + + engine + + + engine + + + engine + + + engine + + + engine + + + engine + + + engine + + + engine + + + engine + + + engine + + + engine + + + engine + + + engine + + + engine + + + engine + + + engine + + + engine + + + engine + + + engine + + + engine + + + engine + + + engine + + + engine + + + engine + + + engine + + + engine + + + engine + + + engine + + + engine + + + engine + + + engine + + + engine + + + engine + + + engine + + + engine + + + engine + + + engine + + + engine + + + engine + + + engine + + + engine + + + engine + + + engine + + + engine + + + engine + + + engine + + + engine + + + engine + + + uniquake + + + uniquake + + + uniquake + + + + + engine + + + engine + + + engine + + + engine + + + engine + + + engine + + + engine + + + engine + + + engine + + + engine + + + engine + + + engine + + + engine + + + engine + + + engine + + + engine + + + engine + + + engine + + + engine + + + engine + + + engine + + + engine + + + engine + + + engine + + + engine + + + engine + + + engine + + + engine + + + engine + + + engine + + + engine + + + engine + + + engine + + + engine + + + engine + + + engine + + + engine + + + engine + + + engine + + + engine + + + engine + + + engine + + + engine + + + engine + + + engine + + + engine + + + engine + + + engine + + + engine + + + engine + + + engine + + + engine + + + engine + + + engine + + + engine + + + engine + + + engine + + + engine + + + engine + + + engine + + + engine + + + engine + + + engine + + + engine + + + uniquake + + + + + {fda46709-d1f0-43fd-9d53-c214ee4e56c8} + + + {43c1b6ff-c2ad-4168-87d5-d2e62a880e77} + + + \ No newline at end of file diff --git a/engine/code/3dfx.txt b/engine/code/3dfx.txt deleted file mode 100644 index 404aa9a..0000000 --- a/engine/code/3dfx.txt +++ /dev/null @@ -1,69 +0,0 @@ -GLQuake Drivers - -Graphics Subsystem: Voodoo Graphics or Voodoo Rush - -Copyright ( 1997 3Dfx Interactive, Inc. ) -All Rights Reserved - -3Dfx Interactive, Inc. -www: www.3dfx.com -news: news.3dfx.com - ------------------------------------------------------------------------ -NOTE: GLQuake requires DirectX support DirectSound. DirectX can be -installed from the media provided with your Voodoo Based 3D Accelerator. - -Glide 2.31 or HIGHER runtime drivers *MUST* be installed to use this -GLQuake driver. Please download these drivers from your board -manufacturer OR unsupported drivers from http://www.3dfx.com ------------------------------------------------------------------------ - -Release Notes for GLQuake's mini-GL driver - -What's in the distribution? ---------------------------- - -This distribution contains GLQuake Drivers for Voodoo Based 3D -Accelerators. These drivers were tested on the following boards: - -Voodoo Graphics: -- Quantum 3D Obsidian -- Diamond Monster 3D -- Orchid Righteous 3D -- Deltron Realvision Flash 3D -- Guillemot MaxiGamer -- Skywell Magic 3D - -Voodoo Rush: -- Hercules Stringray 128-3D -- Intergraph Intense 3D Voodoo -- Jazz Multimedia Adrenaline Rush - -NOTE: The enclosed drivers are not meant to replace any Direct3D or -Glide drivers provided by your Voodoo Graphics card manufacturer. -Please obtain supported drivers from your board manufacturer. - -OEMSR2 and NT users: Do NOT replace OPENGL32.DLL located in your -Windows\SYSTEM directory. - -Requirements ------------- - -- Voodoo Graphics or Voodoo Rush Based 3D Accelerator -- Windows 95 (Windows NT is supported for Voodoo Rush) -- A PC with a Pentium 90 or higher CPU -- 16MB of RAM -- 2D Video card set at 16 bit color - -Support and Frequently Asked Questions --------------------------------------- - -GLQuake is currently unsupported. You may however find answers to -questions on various Quake dedicated websites. 3Dfx provides a GLQuake -newsgroup on news.3dfx.com (Newsgroup name is 3dfx.games.glquake ) to -discuss GLQuake with other users. 3Dfx also provides a regularly -updated GLQuake FAQ at: http://www.3dfx.com/game_dev/quake_faq.html - - -Voodoo Graphics and Voodoo Rush are trademarks of 3Dfx Interactive, Inc. -All other trademarks are the property of their respective owners. \ No newline at end of file diff --git a/engine/code/WinQuake.sln b/engine/code/WinQuake.sln deleted file mode 100644 index 49a6129..0000000 --- a/engine/code/WinQuake.sln +++ /dev/null @@ -1,22 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 14 -VisualStudioVersion = 14.0.25420.1 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "WinQuake", "WinQuake.vcxproj", "{6BF8FC22-9003-40F6-BF03-68A262C348BA}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Win32 = Debug|Win32 - Release|Win32 = Release|Win32 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {6BF8FC22-9003-40F6-BF03-68A262C348BA}.Debug|Win32.ActiveCfg = Debug|Win32 - {6BF8FC22-9003-40F6-BF03-68A262C348BA}.Debug|Win32.Build.0 = Debug|Win32 - {6BF8FC22-9003-40F6-BF03-68A262C348BA}.Release|Win32.ActiveCfg = Release|Win32 - {6BF8FC22-9003-40F6-BF03-68A262C348BA}.Release|Win32.Build.0 = Release|Win32 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection -EndGlobal diff --git a/engine/code/WinQuake.vcxproj b/engine/code/WinQuake.vcxproj deleted file mode 100644 index 917eb7d..0000000 --- a/engine/code/WinQuake.vcxproj +++ /dev/null @@ -1,305 +0,0 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - - {6BF8FC22-9003-40F6-BF03-68A262C348BA} - 10.0.17763.0 - - - - Application - false - v141 - - - Application - false - v141 - - - - - - - - - - - - - - - <_ProjectFileVersion>10.0.40219.1 - .\Release\ - .\Release\ - .\Debug\ - .\Debug\ - AllRules.ruleset - - - AllRules.ruleset - - - UQE-Quake - UQE-Quake - - - false - - - false - - - - NDEBUG;%(PreprocessorDefinitions) - true - true - Win32 - $(TargetDir)/$(ProjectName).tlb - - - - - _CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_WINDOWS;GLQUAKE - .\Release\WinQuake.pch - .\Release\ - .\Release\ - .\Release\ - MultiThreaded - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - .\Release\UQE-Quake.exe - false - Windows - kernel32.lib;user32.lib;gdi32.lib;opengl32.lib;winmm.lib;wsock32.lib;glu32.lib - - - true - $(TargetDir)/$(ProjectName).bsc - - - - - _DEBUG;%(PreprocessorDefinitions) - true - true - Win32 - $(TargetDir)/$(ProjectName).tlb - - - - - .\Debug\WinQuake.pch - .\Debug\ - .\Debug\ - .\Debug\ - _CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_WINDOWS;GLQUAKE - Disabled - MultiThreadedDebug - true - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - .\Debug\UQE-Quake.exe - kernel32.lib;user32.lib;gdi32.lib;opengl32.lib;winmm.lib;wsock32.lib;glu32.lib - Windows - - - true - $(TargetDir)/$(ProjectName).bsc - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - true - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/engine/code/anorm_dots.h b/engine/code/anorm_dots.h deleted file mode 100644 index 2845fa2..0000000 --- a/engine/code/anorm_dots.h +++ /dev/null @@ -1,37 +0,0 @@ -/* -Copyright (C) 1996-1997 Id Software, Inc. - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ -{ -{1.23,1.30,1.47,1.35,1.56,1.71,1.37,1.38,1.59,1.60,1.79,1.97,1.88,1.92,1.79,1.02,0.93,1.07,0.82,0.87,0.88,0.94,0.96,1.14,1.11,0.82,0.83,0.89,0.89,0.86,0.94,0.91,1.00,1.21,0.98,1.48,1.30,1.57,0.96,1.07,1.14,1.60,1.61,1.40,1.37,1.72,1.78,1.79,1.93,1.99,1.90,1.68,1.71,1.86,1.60,1.68,1.78,1.86,1.93,1.99,1.97,1.44,1.22,1.49,0.93,0.99,0.99,1.23,1.22,1.44,1.49,0.89,0.89,0.97,0.91,0.98,1.19,0.82,0.76,0.82,0.71,0.72,0.73,0.76,0.79,0.86,0.83,0.72,0.76,0.76,0.89,0.82,0.89,0.82,0.89,0.91,0.83,0.96,1.14,0.97,1.40,1.19,0.98,0.94,1.00,1.07,1.37,1.21,1.48,1.30,1.57,1.61,1.37,0.86,0.83,0.91,0.82,0.82,0.88,0.89,0.96,1.14,0.98,0.87,0.93,0.94,1.02,1.30,1.07,1.35,1.38,1.11,1.56,1.92,1.79,1.79,1.59,1.60,1.72,1.90,1.79,0.80,0.85,0.79,0.93,0.80,0.85,0.77,0.74,0.72,0.77,0.74,0.72,0.70,0.70,0.71,0.76,0.73,0.79,0.79,0.73,0.76,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00}, -{1.26,1.26,1.48,1.23,1.50,1.71,1.14,1.19,1.38,1.46,1.64,1.94,1.87,1.84,1.71,1.02,0.92,1.00,0.79,0.85,0.84,0.91,0.90,0.98,0.99,0.77,0.77,0.83,0.82,0.79,0.86,0.84,0.92,0.99,0.91,1.24,1.03,1.33,0.88,0.94,0.97,1.41,1.39,1.18,1.11,1.51,1.61,1.59,1.80,1.91,1.76,1.54,1.65,1.76,1.70,1.70,1.85,1.85,1.97,1.99,1.93,1.28,1.09,1.39,0.92,0.97,0.99,1.18,1.26,1.52,1.48,0.83,0.85,0.90,0.88,0.93,1.00,0.77,0.73,0.78,0.72,0.71,0.74,0.75,0.79,0.86,0.81,0.75,0.81,0.79,0.96,0.88,0.94,0.86,0.93,0.92,0.85,1.08,1.33,1.05,1.55,1.31,1.01,1.05,1.27,1.31,1.60,1.47,1.70,1.54,1.76,1.76,1.57,0.93,0.90,0.99,0.88,0.88,0.95,0.97,1.11,1.39,1.20,0.92,0.97,1.01,1.10,1.39,1.22,1.51,1.58,1.32,1.64,1.97,1.85,1.91,1.77,1.74,1.88,1.99,1.91,0.79,0.86,0.80,0.94,0.84,0.88,0.74,0.74,0.71,0.82,0.77,0.76,0.70,0.73,0.72,0.73,0.70,0.74,0.85,0.77,0.82,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00}, -{1.34,1.27,1.53,1.17,1.46,1.71,0.98,1.05,1.20,1.34,1.48,1.86,1.82,1.71,1.62,1.09,0.94,0.99,0.79,0.85,0.82,0.90,0.87,0.93,0.96,0.76,0.74,0.79,0.76,0.74,0.79,0.78,0.85,0.92,0.85,1.00,0.93,1.06,0.81,0.86,0.89,1.16,1.12,0.97,0.95,1.28,1.38,1.35,1.60,1.77,1.57,1.33,1.50,1.58,1.69,1.63,1.82,1.74,1.91,1.92,1.80,1.04,0.97,1.21,0.90,0.93,0.97,1.05,1.21,1.48,1.37,0.77,0.80,0.84,0.85,0.88,0.92,0.73,0.71,0.74,0.74,0.71,0.75,0.73,0.79,0.84,0.78,0.79,0.86,0.81,1.05,0.94,0.99,0.90,0.95,0.92,0.86,1.24,1.44,1.14,1.59,1.34,1.02,1.27,1.50,1.49,1.80,1.69,1.86,1.72,1.87,1.80,1.69,1.00,0.98,1.23,0.95,0.96,1.09,1.16,1.37,1.63,1.46,0.99,1.10,1.25,1.24,1.51,1.41,1.67,1.77,1.55,1.72,1.95,1.89,1.98,1.91,1.86,1.97,1.99,1.94,0.81,0.89,0.85,0.98,0.90,0.94,0.75,0.78,0.73,0.89,0.83,0.82,0.72,0.77,0.76,0.72,0.70,0.71,0.91,0.83,0.89,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00}, -{1.46,1.34,1.60,1.16,1.46,1.71,0.94,0.99,1.05,1.26,1.33,1.74,1.76,1.57,1.54,1.23,0.98,1.05,0.83,0.89,0.84,0.92,0.87,0.91,0.96,0.78,0.74,0.79,0.72,0.72,0.75,0.76,0.80,0.88,0.83,0.94,0.87,0.95,0.76,0.80,0.82,0.97,0.96,0.89,0.88,1.08,1.11,1.10,1.37,1.59,1.37,1.07,1.27,1.34,1.57,1.45,1.69,1.55,1.77,1.79,1.60,0.93,0.90,0.99,0.86,0.87,0.93,0.96,1.07,1.35,1.18,0.73,0.76,0.77,0.81,0.82,0.85,0.70,0.71,0.72,0.78,0.73,0.77,0.73,0.79,0.82,0.76,0.83,0.90,0.84,1.18,0.98,1.03,0.92,0.95,0.90,0.86,1.32,1.45,1.15,1.53,1.27,0.99,1.42,1.65,1.58,1.93,1.83,1.94,1.81,1.88,1.74,1.70,1.19,1.17,1.44,1.11,1.15,1.36,1.41,1.61,1.81,1.67,1.22,1.34,1.50,1.42,1.65,1.61,1.82,1.91,1.75,1.80,1.89,1.89,1.98,1.99,1.94,1.98,1.92,1.87,0.86,0.95,0.92,1.14,0.98,1.03,0.79,0.84,0.77,0.97,0.90,0.89,0.76,0.82,0.82,0.74,0.72,0.71,0.98,0.89,0.97,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00}, -{1.60,1.44,1.68,1.22,1.49,1.71,0.93,0.99,0.99,1.23,1.22,1.60,1.68,1.44,1.49,1.40,1.14,1.19,0.89,0.96,0.89,0.97,0.89,0.91,0.98,0.82,0.76,0.82,0.71,0.72,0.73,0.76,0.79,0.86,0.83,0.91,0.83,0.89,0.72,0.76,0.76,0.89,0.89,0.82,0.82,0.98,0.96,0.97,1.14,1.40,1.19,0.94,1.00,1.07,1.37,1.21,1.48,1.30,1.57,1.61,1.37,0.86,0.83,0.91,0.82,0.82,0.88,0.89,0.96,1.14,0.98,0.70,0.72,0.73,0.77,0.76,0.79,0.70,0.72,0.71,0.82,0.77,0.80,0.74,0.79,0.80,0.74,0.87,0.93,0.85,1.23,1.02,1.02,0.93,0.93,0.87,0.85,1.30,1.35,1.07,1.38,1.11,0.94,1.47,1.71,1.56,1.97,1.88,1.92,1.79,1.79,1.59,1.60,1.30,1.35,1.56,1.37,1.38,1.59,1.60,1.79,1.92,1.79,1.48,1.57,1.72,1.61,1.78,1.79,1.93,1.99,1.90,1.86,1.78,1.86,1.93,1.99,1.97,1.90,1.79,1.72,0.94,1.07,1.00,1.37,1.21,1.30,0.86,0.91,0.83,1.14,0.98,0.96,0.82,0.88,0.89,0.79,0.76,0.73,1.07,0.94,1.11,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00}, -{1.74,1.57,1.76,1.33,1.54,1.71,0.94,1.05,0.99,1.26,1.16,1.46,1.60,1.34,1.46,1.59,1.37,1.37,0.97,1.11,0.96,1.10,0.95,0.94,1.08,0.89,0.82,0.88,0.72,0.76,0.75,0.80,0.80,0.88,0.87,0.91,0.83,0.87,0.72,0.76,0.74,0.83,0.84,0.78,0.79,0.96,0.89,0.92,0.98,1.23,1.05,0.86,0.92,0.95,1.11,0.98,1.22,1.03,1.34,1.42,1.14,0.79,0.77,0.84,0.78,0.76,0.82,0.82,0.89,0.97,0.90,0.70,0.71,0.71,0.73,0.72,0.74,0.73,0.76,0.72,0.86,0.81,0.82,0.76,0.79,0.77,0.73,0.90,0.95,0.86,1.18,1.03,0.98,0.92,0.90,0.83,0.84,1.19,1.17,0.98,1.15,0.97,0.89,1.42,1.65,1.44,1.93,1.83,1.81,1.67,1.61,1.36,1.41,1.32,1.45,1.58,1.57,1.53,1.74,1.70,1.88,1.94,1.81,1.69,1.77,1.87,1.79,1.89,1.92,1.98,1.99,1.98,1.89,1.65,1.80,1.82,1.91,1.94,1.75,1.61,1.50,1.07,1.34,1.27,1.60,1.45,1.55,0.93,0.99,0.90,1.35,1.18,1.07,0.87,0.93,0.96,0.85,0.82,0.77,1.15,0.99,1.27,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00}, -{1.86,1.71,1.82,1.48,1.62,1.71,0.98,1.20,1.05,1.34,1.17,1.34,1.53,1.27,1.46,1.77,1.60,1.57,1.16,1.38,1.12,1.35,1.06,1.00,1.28,0.97,0.89,0.95,0.76,0.81,0.79,0.86,0.85,0.92,0.93,0.93,0.85,0.87,0.74,0.78,0.74,0.79,0.82,0.76,0.79,0.96,0.85,0.90,0.94,1.09,0.99,0.81,0.85,0.89,0.95,0.90,0.99,0.94,1.10,1.24,0.98,0.75,0.73,0.78,0.74,0.72,0.77,0.76,0.82,0.89,0.83,0.73,0.71,0.71,0.71,0.70,0.72,0.77,0.80,0.74,0.90,0.85,0.84,0.78,0.79,0.75,0.73,0.92,0.95,0.86,1.05,0.99,0.94,0.90,0.86,0.79,0.81,1.00,0.98,0.91,0.96,0.89,0.83,1.27,1.50,1.23,1.80,1.69,1.63,1.46,1.37,1.09,1.16,1.24,1.44,1.49,1.69,1.59,1.80,1.69,1.87,1.86,1.72,1.82,1.91,1.94,1.92,1.95,1.99,1.98,1.91,1.97,1.89,1.51,1.72,1.67,1.77,1.86,1.55,1.41,1.25,1.33,1.58,1.50,1.80,1.63,1.74,1.04,1.21,0.97,1.48,1.37,1.21,0.93,0.97,1.05,0.92,0.88,0.84,1.14,1.02,1.34,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00}, -{1.94,1.84,1.87,1.64,1.71,1.71,1.14,1.38,1.19,1.46,1.23,1.26,1.48,1.26,1.50,1.91,1.80,1.76,1.41,1.61,1.39,1.59,1.33,1.24,1.51,1.18,0.97,1.11,0.82,0.88,0.86,0.94,0.92,0.99,1.03,0.98,0.91,0.90,0.79,0.84,0.77,0.79,0.84,0.77,0.83,0.99,0.85,0.91,0.92,1.02,1.00,0.79,0.80,0.86,0.88,0.84,0.92,0.88,0.97,1.10,0.94,0.74,0.71,0.74,0.72,0.70,0.73,0.72,0.76,0.82,0.77,0.77,0.73,0.74,0.71,0.70,0.73,0.83,0.85,0.78,0.92,0.88,0.86,0.81,0.79,0.74,0.75,0.92,0.93,0.85,0.96,0.94,0.88,0.86,0.81,0.75,0.79,0.93,0.90,0.85,0.88,0.82,0.77,1.05,1.27,0.99,1.60,1.47,1.39,1.20,1.11,0.95,0.97,1.08,1.33,1.31,1.70,1.55,1.76,1.57,1.76,1.70,1.54,1.85,1.97,1.91,1.99,1.97,1.99,1.91,1.77,1.88,1.85,1.39,1.64,1.51,1.58,1.74,1.32,1.22,1.01,1.54,1.76,1.65,1.93,1.70,1.85,1.28,1.39,1.09,1.52,1.48,1.26,0.97,0.99,1.18,1.00,0.93,0.90,1.05,1.01,1.31,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00}, -{1.97,1.92,1.88,1.79,1.79,1.71,1.37,1.59,1.38,1.60,1.35,1.23,1.47,1.30,1.56,1.99,1.93,1.90,1.60,1.78,1.61,1.79,1.57,1.48,1.72,1.40,1.14,1.37,0.89,0.96,0.94,1.07,1.00,1.21,1.30,1.14,0.98,0.96,0.86,0.91,0.83,0.82,0.88,0.82,0.89,1.11,0.87,0.94,0.93,1.02,1.07,0.80,0.79,0.85,0.82,0.80,0.87,0.85,0.93,1.02,0.93,0.77,0.72,0.74,0.71,0.70,0.70,0.71,0.72,0.77,0.74,0.82,0.76,0.79,0.72,0.73,0.76,0.89,0.89,0.82,0.93,0.91,0.86,0.83,0.79,0.73,0.76,0.91,0.89,0.83,0.89,0.89,0.82,0.82,0.76,0.72,0.76,0.86,0.83,0.79,0.82,0.76,0.73,0.94,1.00,0.91,1.37,1.21,1.14,0.98,0.96,0.88,0.89,0.96,1.14,1.07,1.60,1.40,1.61,1.37,1.57,1.48,1.30,1.78,1.93,1.79,1.99,1.92,1.90,1.79,1.59,1.72,1.79,1.30,1.56,1.35,1.38,1.60,1.11,1.07,0.94,1.68,1.86,1.71,1.97,1.68,1.86,1.44,1.49,1.22,1.44,1.49,1.22,0.99,0.99,1.23,1.19,0.98,0.97,0.97,0.98,1.19,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00}, -{1.94,1.97,1.87,1.91,1.85,1.71,1.60,1.77,1.58,1.74,1.51,1.26,1.48,1.39,1.64,1.99,1.97,1.99,1.70,1.85,1.76,1.91,1.76,1.70,1.88,1.55,1.33,1.57,0.96,1.08,1.05,1.31,1.27,1.47,1.54,1.39,1.20,1.11,0.93,0.99,0.90,0.88,0.95,0.88,0.97,1.32,0.92,1.01,0.97,1.10,1.22,0.84,0.80,0.88,0.79,0.79,0.85,0.86,0.92,1.02,0.94,0.82,0.76,0.77,0.72,0.73,0.70,0.72,0.71,0.74,0.74,0.88,0.81,0.85,0.75,0.77,0.82,0.94,0.93,0.86,0.92,0.92,0.86,0.85,0.79,0.74,0.79,0.88,0.85,0.81,0.82,0.83,0.77,0.78,0.73,0.71,0.75,0.79,0.77,0.74,0.77,0.73,0.70,0.86,0.92,0.84,1.14,0.99,0.98,0.91,0.90,0.84,0.83,0.88,0.97,0.94,1.41,1.18,1.39,1.11,1.33,1.24,1.03,1.61,1.80,1.59,1.91,1.84,1.76,1.64,1.38,1.51,1.71,1.26,1.50,1.23,1.19,1.46,0.99,1.00,0.91,1.70,1.85,1.65,1.93,1.54,1.76,1.52,1.48,1.26,1.28,1.39,1.09,0.99,0.97,1.18,1.31,1.01,1.05,0.90,0.93,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00}, -{1.86,1.95,1.82,1.98,1.89,1.71,1.80,1.91,1.77,1.86,1.67,1.34,1.53,1.51,1.72,1.92,1.91,1.99,1.69,1.82,1.80,1.94,1.87,1.86,1.97,1.59,1.44,1.69,1.05,1.24,1.27,1.49,1.50,1.69,1.72,1.63,1.46,1.37,1.00,1.23,0.98,0.95,1.09,0.96,1.16,1.55,0.99,1.25,1.10,1.24,1.41,0.90,0.85,0.94,0.79,0.81,0.85,0.89,0.94,1.09,0.98,0.89,0.82,0.83,0.74,0.77,0.72,0.76,0.73,0.75,0.78,0.94,0.86,0.91,0.79,0.83,0.89,0.99,0.95,0.90,0.90,0.92,0.84,0.86,0.79,0.75,0.81,0.85,0.80,0.78,0.76,0.77,0.73,0.74,0.71,0.71,0.73,0.74,0.74,0.71,0.76,0.72,0.70,0.79,0.85,0.78,0.98,0.92,0.93,0.85,0.87,0.82,0.79,0.81,0.89,0.86,1.16,0.97,1.12,0.95,1.06,1.00,0.93,1.38,1.60,1.35,1.77,1.71,1.57,1.48,1.20,1.28,1.62,1.27,1.46,1.17,1.05,1.34,0.96,0.99,0.90,1.63,1.74,1.50,1.80,1.33,1.58,1.48,1.37,1.21,1.04,1.21,0.97,0.97,0.93,1.05,1.34,1.02,1.14,0.84,0.88,0.92,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00}, -{1.74,1.89,1.76,1.98,1.89,1.71,1.93,1.99,1.91,1.94,1.82,1.46,1.60,1.65,1.80,1.79,1.77,1.92,1.57,1.69,1.74,1.87,1.88,1.94,1.98,1.53,1.45,1.70,1.18,1.32,1.42,1.58,1.65,1.83,1.81,1.81,1.67,1.61,1.19,1.44,1.17,1.11,1.36,1.15,1.41,1.75,1.22,1.50,1.34,1.42,1.61,0.98,0.92,1.03,0.83,0.86,0.89,0.95,0.98,1.23,1.14,0.97,0.89,0.90,0.78,0.82,0.76,0.82,0.77,0.79,0.84,0.98,0.90,0.98,0.83,0.89,0.97,1.03,0.95,0.92,0.86,0.90,0.82,0.86,0.79,0.77,0.84,0.81,0.76,0.76,0.72,0.73,0.70,0.72,0.71,0.73,0.73,0.72,0.74,0.71,0.78,0.74,0.72,0.75,0.80,0.76,0.94,0.88,0.91,0.83,0.87,0.84,0.79,0.76,0.82,0.80,0.97,0.89,0.96,0.88,0.95,0.94,0.87,1.11,1.37,1.10,1.59,1.57,1.37,1.33,1.05,1.08,1.54,1.34,1.46,1.16,0.99,1.26,0.96,1.05,0.92,1.45,1.55,1.27,1.60,1.07,1.34,1.35,1.18,1.07,0.93,0.99,0.90,0.93,0.87,0.96,1.27,0.99,1.15,0.77,0.82,0.85,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00}, -{1.60,1.78,1.68,1.93,1.86,1.71,1.97,1.99,1.99,1.97,1.93,1.60,1.68,1.78,1.86,1.61,1.57,1.79,1.37,1.48,1.59,1.72,1.79,1.92,1.90,1.38,1.35,1.60,1.23,1.30,1.47,1.56,1.71,1.88,1.79,1.92,1.79,1.79,1.30,1.56,1.35,1.37,1.59,1.38,1.60,1.90,1.48,1.72,1.57,1.61,1.79,1.21,1.00,1.30,0.89,0.94,0.96,1.07,1.14,1.40,1.37,1.14,0.96,0.98,0.82,0.88,0.82,0.89,0.83,0.86,0.91,1.02,0.93,1.07,0.87,0.94,1.11,1.02,0.93,0.93,0.82,0.87,0.80,0.85,0.79,0.80,0.85,0.77,0.72,0.74,0.71,0.70,0.70,0.71,0.72,0.77,0.74,0.72,0.76,0.73,0.82,0.79,0.76,0.73,0.79,0.76,0.93,0.86,0.91,0.83,0.89,0.89,0.82,0.72,0.76,0.76,0.89,0.82,0.89,0.82,0.89,0.91,0.83,0.96,1.14,0.97,1.40,1.44,1.19,1.22,0.99,0.98,1.49,1.44,1.49,1.22,0.99,1.23,0.98,1.19,0.97,1.21,1.30,1.00,1.37,0.94,1.07,1.14,0.98,0.96,0.86,0.91,0.83,0.88,0.82,0.89,1.11,0.94,1.07,0.73,0.76,0.79,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00}, -{1.46,1.65,1.60,1.82,1.80,1.71,1.93,1.91,1.99,1.94,1.98,1.74,1.76,1.89,1.89,1.42,1.34,1.61,1.11,1.22,1.36,1.50,1.61,1.81,1.75,1.15,1.17,1.41,1.18,1.19,1.42,1.44,1.65,1.83,1.67,1.94,1.81,1.88,1.32,1.58,1.45,1.57,1.74,1.53,1.70,1.98,1.69,1.87,1.77,1.79,1.92,1.45,1.27,1.55,0.97,1.07,1.11,1.34,1.37,1.59,1.60,1.35,1.07,1.18,0.86,0.93,0.87,0.96,0.90,0.93,0.99,1.03,0.95,1.15,0.90,0.99,1.27,0.98,0.90,0.92,0.78,0.83,0.77,0.84,0.79,0.82,0.86,0.73,0.71,0.73,0.72,0.70,0.73,0.72,0.76,0.81,0.76,0.76,0.82,0.77,0.89,0.85,0.82,0.75,0.80,0.80,0.94,0.88,0.94,0.87,0.95,0.96,0.88,0.72,0.74,0.76,0.83,0.78,0.84,0.79,0.87,0.91,0.83,0.89,0.98,0.92,1.23,1.34,1.05,1.16,0.99,0.96,1.46,1.57,1.54,1.33,1.05,1.26,1.08,1.37,1.10,0.98,1.03,0.92,1.14,0.86,0.95,0.97,0.90,0.89,0.79,0.84,0.77,0.82,0.76,0.82,0.97,0.89,0.98,0.71,0.72,0.74,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00}, -{1.34,1.51,1.53,1.67,1.72,1.71,1.80,1.77,1.91,1.86,1.98,1.86,1.82,1.95,1.89,1.24,1.10,1.41,0.95,0.99,1.09,1.25,1.37,1.63,1.55,0.96,0.98,1.16,1.05,1.00,1.27,1.23,1.50,1.69,1.46,1.86,1.72,1.87,1.24,1.49,1.44,1.69,1.80,1.59,1.69,1.97,1.82,1.94,1.91,1.92,1.99,1.63,1.50,1.74,1.16,1.33,1.38,1.58,1.60,1.77,1.80,1.48,1.21,1.37,0.90,0.97,0.93,1.05,0.97,1.04,1.21,0.99,0.95,1.14,0.92,1.02,1.34,0.94,0.86,0.90,0.74,0.79,0.75,0.81,0.79,0.84,0.86,0.71,0.71,0.73,0.76,0.73,0.77,0.74,0.80,0.85,0.78,0.81,0.89,0.84,0.97,0.92,0.88,0.79,0.85,0.86,0.98,0.92,1.00,0.93,1.06,1.12,0.95,0.74,0.74,0.78,0.79,0.76,0.82,0.79,0.87,0.93,0.85,0.85,0.94,0.90,1.09,1.27,0.99,1.17,1.05,0.96,1.46,1.71,1.62,1.48,1.20,1.34,1.28,1.57,1.35,0.90,0.94,0.85,0.98,0.81,0.89,0.89,0.83,0.82,0.75,0.78,0.73,0.77,0.72,0.76,0.89,0.83,0.91,0.71,0.70,0.72,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00}, -{1.26,1.39,1.48,1.51,1.64,1.71,1.60,1.58,1.77,1.74,1.91,1.94,1.87,1.97,1.85,1.10,0.97,1.22,0.88,0.92,0.95,1.01,1.11,1.39,1.32,0.88,0.90,0.97,0.96,0.93,1.05,0.99,1.27,1.47,1.20,1.70,1.54,1.76,1.08,1.31,1.33,1.70,1.76,1.55,1.57,1.88,1.85,1.91,1.97,1.99,1.99,1.70,1.65,1.85,1.41,1.54,1.61,1.76,1.80,1.91,1.93,1.52,1.26,1.48,0.92,0.99,0.97,1.18,1.09,1.28,1.39,0.94,0.93,1.05,0.92,1.01,1.31,0.88,0.81,0.86,0.72,0.75,0.74,0.79,0.79,0.86,0.85,0.71,0.73,0.75,0.82,0.77,0.83,0.78,0.85,0.88,0.81,0.88,0.97,0.90,1.18,1.00,0.93,0.86,0.92,0.94,1.14,0.99,1.24,1.03,1.33,1.39,1.11,0.79,0.77,0.84,0.79,0.77,0.84,0.83,0.90,0.98,0.91,0.85,0.92,0.91,1.02,1.26,1.00,1.23,1.19,0.99,1.50,1.84,1.71,1.64,1.38,1.46,1.51,1.76,1.59,0.84,0.88,0.80,0.94,0.79,0.86,0.82,0.77,0.76,0.74,0.74,0.71,0.73,0.70,0.72,0.82,0.77,0.85,0.74,0.70,0.73,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00} -} diff --git a/engine/code/anorms.h b/engine/code/anorms.h deleted file mode 100644 index 11a9007..0000000 --- a/engine/code/anorms.h +++ /dev/null @@ -1,181 +0,0 @@ -/* -Copyright (C) 1996-1997 Id Software, Inc. - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ -{-0.525731, 0.000000, 0.850651}, -{-0.442863, 0.238856, 0.864188}, -{-0.295242, 0.000000, 0.955423}, -{-0.309017, 0.500000, 0.809017}, -{-0.162460, 0.262866, 0.951056}, -{0.000000, 0.000000, 1.000000}, -{0.000000, 0.850651, 0.525731}, -{-0.147621, 0.716567, 0.681718}, -{0.147621, 0.716567, 0.681718}, -{0.000000, 0.525731, 0.850651}, -{0.309017, 0.500000, 0.809017}, -{0.525731, 0.000000, 0.850651}, -{0.295242, 0.000000, 0.955423}, -{0.442863, 0.238856, 0.864188}, -{0.162460, 0.262866, 0.951056}, -{-0.681718, 0.147621, 0.716567}, -{-0.809017, 0.309017, 0.500000}, -{-0.587785, 0.425325, 0.688191}, -{-0.850651, 0.525731, 0.000000}, -{-0.864188, 0.442863, 0.238856}, -{-0.716567, 0.681718, 0.147621}, -{-0.688191, 0.587785, 0.425325}, -{-0.500000, 0.809017, 0.309017}, -{-0.238856, 0.864188, 0.442863}, -{-0.425325, 0.688191, 0.587785}, -{-0.716567, 0.681718, -0.147621}, -{-0.500000, 0.809017, -0.309017}, -{-0.525731, 0.850651, 0.000000}, -{0.000000, 0.850651, -0.525731}, -{-0.238856, 0.864188, -0.442863}, -{0.000000, 0.955423, -0.295242}, -{-0.262866, 0.951056, -0.162460}, -{0.000000, 1.000000, 0.000000}, -{0.000000, 0.955423, 0.295242}, -{-0.262866, 0.951056, 0.162460}, -{0.238856, 0.864188, 0.442863}, -{0.262866, 0.951056, 0.162460}, -{0.500000, 0.809017, 0.309017}, -{0.238856, 0.864188, -0.442863}, -{0.262866, 0.951056, -0.162460}, -{0.500000, 0.809017, -0.309017}, -{0.850651, 0.525731, 0.000000}, -{0.716567, 0.681718, 0.147621}, -{0.716567, 0.681718, -0.147621}, -{0.525731, 0.850651, 0.000000}, -{0.425325, 0.688191, 0.587785}, -{0.864188, 0.442863, 0.238856}, -{0.688191, 0.587785, 0.425325}, -{0.809017, 0.309017, 0.500000}, -{0.681718, 0.147621, 0.716567}, -{0.587785, 0.425325, 0.688191}, -{0.955423, 0.295242, 0.000000}, -{1.000000, 0.000000, 0.000000}, -{0.951056, 0.162460, 0.262866}, -{0.850651, -0.525731, 0.000000}, -{0.955423, -0.295242, 0.000000}, -{0.864188, -0.442863, 0.238856}, -{0.951056, -0.162460, 0.262866}, -{0.809017, -0.309017, 0.500000}, -{0.681718, -0.147621, 0.716567}, -{0.850651, 0.000000, 0.525731}, -{0.864188, 0.442863, -0.238856}, -{0.809017, 0.309017, -0.500000}, -{0.951056, 0.162460, -0.262866}, -{0.525731, 0.000000, -0.850651}, -{0.681718, 0.147621, -0.716567}, -{0.681718, -0.147621, -0.716567}, -{0.850651, 0.000000, -0.525731}, -{0.809017, -0.309017, -0.500000}, -{0.864188, -0.442863, -0.238856}, -{0.951056, -0.162460, -0.262866}, -{0.147621, 0.716567, -0.681718}, -{0.309017, 0.500000, -0.809017}, -{0.425325, 0.688191, -0.587785}, -{0.442863, 0.238856, -0.864188}, -{0.587785, 0.425325, -0.688191}, -{0.688191, 0.587785, -0.425325}, -{-0.147621, 0.716567, -0.681718}, -{-0.309017, 0.500000, -0.809017}, -{0.000000, 0.525731, -0.850651}, -{-0.525731, 0.000000, -0.850651}, -{-0.442863, 0.238856, -0.864188}, -{-0.295242, 0.000000, -0.955423}, -{-0.162460, 0.262866, -0.951056}, -{0.000000, 0.000000, -1.000000}, -{0.295242, 0.000000, -0.955423}, -{0.162460, 0.262866, -0.951056}, -{-0.442863, -0.238856, -0.864188}, -{-0.309017, -0.500000, -0.809017}, -{-0.162460, -0.262866, -0.951056}, -{0.000000, -0.850651, -0.525731}, -{-0.147621, -0.716567, -0.681718}, -{0.147621, -0.716567, -0.681718}, -{0.000000, -0.525731, -0.850651}, -{0.309017, -0.500000, -0.809017}, -{0.442863, -0.238856, -0.864188}, -{0.162460, -0.262866, -0.951056}, -{0.238856, -0.864188, -0.442863}, -{0.500000, -0.809017, -0.309017}, -{0.425325, -0.688191, -0.587785}, -{0.716567, -0.681718, -0.147621}, -{0.688191, -0.587785, -0.425325}, -{0.587785, -0.425325, -0.688191}, -{0.000000, -0.955423, -0.295242}, -{0.000000, -1.000000, 0.000000}, -{0.262866, -0.951056, -0.162460}, -{0.000000, -0.850651, 0.525731}, -{0.000000, -0.955423, 0.295242}, -{0.238856, -0.864188, 0.442863}, -{0.262866, -0.951056, 0.162460}, -{0.500000, -0.809017, 0.309017}, -{0.716567, -0.681718, 0.147621}, -{0.525731, -0.850651, 0.000000}, -{-0.238856, -0.864188, -0.442863}, -{-0.500000, -0.809017, -0.309017}, -{-0.262866, -0.951056, -0.162460}, -{-0.850651, -0.525731, 0.000000}, -{-0.716567, -0.681718, -0.147621}, -{-0.716567, -0.681718, 0.147621}, -{-0.525731, -0.850651, 0.000000}, -{-0.500000, -0.809017, 0.309017}, -{-0.238856, -0.864188, 0.442863}, -{-0.262866, -0.951056, 0.162460}, -{-0.864188, -0.442863, 0.238856}, -{-0.809017, -0.309017, 0.500000}, -{-0.688191, -0.587785, 0.425325}, -{-0.681718, -0.147621, 0.716567}, -{-0.442863, -0.238856, 0.864188}, -{-0.587785, -0.425325, 0.688191}, -{-0.309017, -0.500000, 0.809017}, -{-0.147621, -0.716567, 0.681718}, -{-0.425325, -0.688191, 0.587785}, -{-0.162460, -0.262866, 0.951056}, -{0.442863, -0.238856, 0.864188}, -{0.162460, -0.262866, 0.951056}, -{0.309017, -0.500000, 0.809017}, -{0.147621, -0.716567, 0.681718}, -{0.000000, -0.525731, 0.850651}, -{0.425325, -0.688191, 0.587785}, -{0.587785, -0.425325, 0.688191}, -{0.688191, -0.587785, 0.425325}, -{-0.955423, 0.295242, 0.000000}, -{-0.951056, 0.162460, 0.262866}, -{-1.000000, 0.000000, 0.000000}, -{-0.850651, 0.000000, 0.525731}, -{-0.955423, -0.295242, 0.000000}, -{-0.951056, -0.162460, 0.262866}, -{-0.864188, 0.442863, -0.238856}, -{-0.951056, 0.162460, -0.262866}, -{-0.809017, 0.309017, -0.500000}, -{-0.864188, -0.442863, -0.238856}, -{-0.951056, -0.162460, -0.262866}, -{-0.809017, -0.309017, -0.500000}, -{-0.681718, 0.147621, -0.716567}, -{-0.681718, -0.147621, -0.716567}, -{-0.850651, 0.000000, -0.525731}, -{-0.688191, 0.587785, -0.425325}, -{-0.587785, 0.425325, -0.688191}, -{-0.425325, 0.688191, -0.587785}, -{-0.425325, -0.688191, -0.587785}, -{-0.587785, -0.425325, -0.688191}, -{-0.688191, -0.587785, -0.425325}, diff --git a/engine/code/cd_win.c b/engine/code/cd_win.c deleted file mode 100644 index e97aa86..0000000 --- a/engine/code/cd_win.c +++ /dev/null @@ -1,596 +0,0 @@ -/* -Copyright (C) 1996-1997 Id Software, Inc. - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ -// Quake is a trademark of Id Software, Inc., (c) 1996 Id Software, Inc. All -// rights reserved. -#ifdef UQ_WINDEBUG - -#include "quakedef.h" - -#ifndef UQE_FMOD_CDAUDIO -#include - -extern HWND mainwindow; -extern cvar_t bgmvolume; - -static qboolean cdValid = false; -static qboolean playing = false; -static qboolean wasPlaying = false; -static qboolean initialized = false; -static qboolean enabled = false; -static qboolean playLooping = false; -static float cdvolume; -static byte remap[100]; -static byte cdrom; -static byte playTrack; -static byte maxTrack; - -// jkrige - cd audio volume fix -static UINT CD_ID; -static unsigned long CD_OrigVolume; -// jkrige - cd audio volume fix - -UINT wDeviceID; - -// jkrige - CD Resume -static DWORD end_pos; -// jkrige - CD Resume - - -static void CDAudio_Eject(void) -{ - DWORD dwReturn; - - if (dwReturn = mciSendCommand(wDeviceID, MCI_SET, MCI_SET_DOOR_OPEN, (DWORD_PTR)NULL)) - Con_DPrintf("MCI_SET_DOOR_OPEN failed (%i)\n", dwReturn); -} - - -static void CDAudio_CloseDoor(void) -{ - DWORD dwReturn; - - if (dwReturn = mciSendCommand(wDeviceID, MCI_SET, MCI_SET_DOOR_CLOSED, (DWORD_PTR)NULL)) - Con_DPrintf("MCI_SET_DOOR_CLOSED failed (%i)\n", dwReturn); -} - - -static int CDAudio_GetAudioDiskInfo(void) -{ - DWORD dwReturn; - MCI_STATUS_PARMS mciStatusParms; - - - cdValid = false; - - mciStatusParms.dwItem = MCI_STATUS_READY; - dwReturn = mciSendCommand(wDeviceID, MCI_STATUS, MCI_STATUS_ITEM | MCI_WAIT, (DWORD_PTR) (LPVOID) &mciStatusParms); - if (dwReturn) - { - Con_DPrintf("CDAudio: drive ready test - get status failed\n"); - return -1; - } - if (!mciStatusParms.dwReturn) - { - Con_DPrintf("CDAudio: drive not ready\n"); - return -1; - } - - mciStatusParms.dwItem = MCI_STATUS_NUMBER_OF_TRACKS; - dwReturn = mciSendCommand(wDeviceID, MCI_STATUS, MCI_STATUS_ITEM | MCI_WAIT, (DWORD_PTR) (LPVOID) &mciStatusParms); - if (dwReturn) - { - Con_DPrintf("CDAudio: get tracks - status failed\n"); - return -1; - } - if (mciStatusParms.dwReturn < 1) - { - Con_DPrintf("CDAudio: no music tracks\n"); - return -1; - } - - cdValid = true; - maxTrack = mciStatusParms.dwReturn; - - return 0; -} - - -void CDAudio_Play(byte track, qboolean looping) -{ - DWORD dwReturn; - MCI_PLAY_PARMS mciPlayParms; - MCI_STATUS_PARMS mciStatusParms; - - if (!enabled) - return; - - if (!cdValid) - { - CDAudio_GetAudioDiskInfo(); - if (!cdValid) - return; - } - - track = remap[track]; - - if (track < 1 || track > maxTrack) - { - Con_DPrintf("CDAudio: Bad track number %u.\n", track); - return; - } - - // don't try to play a non-audio track - mciStatusParms.dwItem = MCI_CDA_STATUS_TYPE_TRACK; - mciStatusParms.dwTrack = track; - dwReturn = mciSendCommand(wDeviceID, MCI_STATUS, MCI_STATUS_ITEM | MCI_TRACK | MCI_WAIT, (DWORD_PTR) (LPVOID) &mciStatusParms); - if (dwReturn) - { - Con_DPrintf("MCI_STATUS failed (%i)\n", dwReturn); - return; - } - if (mciStatusParms.dwReturn != MCI_CDA_TRACK_AUDIO) - { - Con_Printf("CDAudio: track %i is not audio\n", track); - return; - } - - // get the length of the track to be played - mciStatusParms.dwItem = MCI_STATUS_LENGTH; - mciStatusParms.dwTrack = track; - dwReturn = mciSendCommand(wDeviceID, MCI_STATUS, MCI_STATUS_ITEM | MCI_TRACK | MCI_WAIT, (DWORD_PTR) (LPVOID) &mciStatusParms); - if (dwReturn) - { - Con_DPrintf("MCI_STATUS failed (%i)\n", dwReturn); - return; - } - - if (playing) - { - if (playTrack == track) - return; - CDAudio_Stop(); - } - - mciPlayParms.dwFrom = MCI_MAKE_TMSF(track, 0, 0, 0); - mciPlayParms.dwTo = (mciStatusParms.dwReturn << 8) | track; - - // jkrige - CD Resume - end_pos = mciPlayParms.dwTo; - // jkrige - CD Resume - - mciPlayParms.dwCallback = (DWORD_PTR)mainwindow; - dwReturn = mciSendCommand(wDeviceID, MCI_PLAY, MCI_NOTIFY | MCI_FROM | MCI_TO, (DWORD_PTR)(LPVOID) &mciPlayParms); - if (dwReturn) - { - Con_DPrintf("CDAudio: MCI_PLAY failed (%i)\n", dwReturn); - return; - } - - playLooping = looping; - playTrack = track; - playing = true; - - if (cdvolume == 0.0) - CDAudio_Pause (); -} - - -void CDAudio_Stop(void) -{ - DWORD dwReturn; - - if (!enabled) - return; - - if (!playing) - return; - - if (dwReturn = mciSendCommand(wDeviceID, MCI_STOP, 0, (DWORD_PTR)NULL)) - Con_DPrintf("MCI_STOP failed (%i)", dwReturn); - - wasPlaying = false; - playing = false; -} - - -void CDAudio_Pause(void) -{ - DWORD dwReturn; - MCI_GENERIC_PARMS mciGenericParms; - - if (!enabled) - return; - - if (!playing) - return; - - mciGenericParms.dwCallback = (DWORD_PTR)mainwindow; - if (dwReturn = mciSendCommand(wDeviceID, MCI_PAUSE, 0, (DWORD_PTR)(LPVOID) &mciGenericParms)) - Con_DPrintf("MCI_PAUSE failed (%i)", dwReturn); - - wasPlaying = playing; - playing = false; -} - - -void CDAudio_Resume(void) -{ - DWORD dwReturn; - - // jkrige - CD Resume - MCI_STATUS_PARMS mciStatusParms; - // jkrige - CD Resume - - MCI_PLAY_PARMS mciPlayParms; - - if (!enabled) - return; - - if (!cdValid) - return; - - if (!wasPlaying) - return; - - // jkrige - CD Resume - //mciPlayParms.dwFrom = MCI_MAKE_TMSF(playTrack, 0, 0, 0); - //mciPlayParms.dwTo = MCI_MAKE_TMSF(playTrack + 1, 0, 0, 0); - //mciPlayParms.dwCallback = (DWORD)mainwindow; - //dwReturn = mciSendCommand(wDeviceID, MCI_PLAY, MCI_TO | MCI_NOTIFY, (DWORD)(LPVOID) &mciPlayParms); - - mciStatusParms.dwItem = MCI_STATUS_POSITION; - dwReturn = mciSendCommand(wDeviceID, MCI_STATUS, MCI_STATUS_ITEM | MCI_WAIT, (DWORD_PTR) (LPVOID) &mciStatusParms); - if (dwReturn) - { - Con_DPrintf("MCI_STATUS failed (%i)\n", dwReturn); - return; - } - mciPlayParms.dwFrom = mciStatusParms.dwReturn; - mciPlayParms.dwTo = end_pos; // set in CDAudio_Play() - mciPlayParms.dwCallback = (DWORD_PTR)mainwindow; - dwReturn = mciSendCommand(wDeviceID, MCI_PLAY, MCI_FROM | MCI_TO | MCI_NOTIFY, (DWORD_PTR)(LPVOID) &mciPlayParms); - // jkrige - CD Resume - - - if (dwReturn) - { - Con_DPrintf("CDAudio: MCI_PLAY failed (%i)\n", dwReturn); - return; - } - playing = true; -} - - -static void CD_f (void) -{ - char *command; - int ret; - int n; - int startAddress; - - if (Cmd_Argc() < 2) - return; - - command = Cmd_Argv (1); - - if (Q_strcasecmp(command, "on") == 0) - { - enabled = true; - return; - } - - if (Q_strcasecmp(command, "off") == 0) - { - if (playing) - CDAudio_Stop(); - enabled = false; - return; - } - - if (Q_strcasecmp(command, "reset") == 0) - { - enabled = true; - if (playing) - CDAudio_Stop(); - for (n = 0; n < 100; n++) - remap[n] = n; - CDAudio_GetAudioDiskInfo(); - return; - } - - if (Q_strcasecmp(command, "remap") == 0) - { - ret = Cmd_Argc() - 2; - if (ret <= 0) - { - for (n = 1; n < 100; n++) - if (remap[n] != n) - Con_Printf(" %u -> %u\n", n, remap[n]); - return; - } - for (n = 1; n <= ret; n++) - remap[n] = Q_atoi(Cmd_Argv (n+1)); - return; - } - - if (Q_strcasecmp(command, "close") == 0) - { - CDAudio_CloseDoor(); - return; - } - - if (!cdValid) - { - CDAudio_GetAudioDiskInfo(); - if (!cdValid) - { - Con_Printf("No CD in player.\n"); - return; - } - } - - if (Q_strcasecmp(command, "play") == 0) - { - CDAudio_Play((byte)Q_atoi(Cmd_Argv (2)), false); - return; - } - - if (Q_strcasecmp(command, "loop") == 0) - { - CDAudio_Play((byte)Q_atoi(Cmd_Argv (2)), true); - return; - } - - if (Q_strcasecmp(command, "stop") == 0) - { - CDAudio_Stop(); - return; - } - - if (Q_strcasecmp(command, "pause") == 0) - { - CDAudio_Pause(); - return; - } - - if (Q_strcasecmp(command, "resume") == 0) - { - CDAudio_Resume(); - return; - } - - if (Q_strcasecmp(command, "eject") == 0) - { - if (playing) - CDAudio_Stop(); - CDAudio_Eject(); - cdValid = false; - return; - } - - if (Q_strcasecmp(command, "info") == 0) - { - Con_Printf("%u tracks\n", maxTrack); - if (playing) - Con_Printf("Currently %s track %u\n", playLooping ? "looping" : "playing", playTrack); - else if (wasPlaying) - Con_Printf("Paused %s track %u\n", playLooping ? "looping" : "playing", playTrack); - Con_Printf("Volume is %f\n", cdvolume); - return; - } -} - - -LONG CDAudio_MessageHandler(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) -{ - if (lParam != wDeviceID) - return 1; - - switch (wParam) - { - case MCI_NOTIFY_SUCCESSFUL: - if (playing) - { - playing = false; - if (playLooping) - CDAudio_Play(playTrack, true); - } - break; - - case MCI_NOTIFY_ABORTED: - case MCI_NOTIFY_SUPERSEDED: - break; - - case MCI_NOTIFY_FAILURE: - Con_DPrintf("MCI_NOTIFY_FAILURE\n"); - CDAudio_Stop (); - cdValid = false; - break; - - default: - Con_DPrintf("Unexpected MM_MCINOTIFY type (%i)\n", wParam); - return 1; - } - - return 0; -} - -// jkrige - cd audio volume fix -void CD_SetVolume(unsigned long Volume) -{ - if (CD_ID != -1) - auxSetVolume(CD_ID,(Volume<<16)+Volume); -} - -void CD_FindCDAux(void) -{ - UINT NumDevs,counter; - MMRESULT Result; - AUXCAPS Caps; - - CD_ID = -1; - if (!COM_CheckParm("-usecdvolume")) - return; - NumDevs = auxGetNumDevs(); - for(counter=0;counter 0 && - { - return 0; // don't need another message yet - } - } - - // get the next message - fread (&net_message.cursize, 4, 1, cls.demofile); - VectorCopy (cl.mviewangles[0], cl.mviewangles[1]); - for (i=0 ; i<3 ; i++) - { - r = fread (&f, 4, 1, cls.demofile); - cl.mviewangles[0][i] = LittleFloat (f); - } - - net_message.cursize = LittleLong (net_message.cursize); - if (net_message.cursize > MAX_MSGLEN) - Sys_Error ("Demo message > MAX_MSGLEN"); - r = fread (net_message.data, net_message.cursize, 1, cls.demofile); - if (r != 1) - { - CL_StopPlayback (); - return 0; - } - - return 1; - } - - while (1) - { - r = NET_GetMessage (cls.netcon); - - if (r != 1 && r != 2) - return r; - - // discard nop keepalive message - if (net_message.cursize == 1 && net_message.data[0] == svc_nop) - Con_Printf ("<-- server to client keepalive\n"); - else - break; - } - - if (cls.demorecording) - CL_WriteDemoMessage (); - - return r; -}*/ - -int CL_GetMessage (void) -{ - int r, i; - float f; - - if (cls.demoplayback) - { - // decide if it is time to grab the next message - if (cls.signon == SIGNONS) // always grab until fully connected - { - // jkrige - fix demo playback across maps - // Pa3PyX: always wait for full frame update on stuff - // messages. If the server stuffs a reconnect, - // we must wait for the client to re-initialize - // before accepting further messages. Otherwise - // demo playback may freeze. - if (stufftext_frame == host_framecount) { - return 0; - } - // jkrige - fix demo playback across maps - - if (cls.timedemo) - { - if (host_framecount == cls.td_lastframe) - return 0; // allready read this frame's message - cls.td_lastframe = host_framecount; - // if this is the second frame, grab the real td_starttime - // so the bogus time on the first frame doesn't count - if (host_framecount == cls.td_startframe + 1) - cls.td_starttime = realtime; - } - else if (/* cl.time > 0 && */ cl.time <= cl.mtime[0]) - { - return 0; // don't need another message yet - } - } - - // get the next message - - //fread (&net_message.cursize, 4, 1, cls.demofile); - net_message.cursize = ( (cls.demobuffer[cls.demobufferposition + 3] << 24) + (cls.demobuffer[cls.demobufferposition + 2] << 16) + (cls.demobuffer[cls.demobufferposition + 1] << 8) + (cls.demobuffer[cls.demobufferposition + 0]) ); - cls.demobufferposition += 4; - net_message.cursize = LittleLong (net_message.cursize); - - VectorCopy (cl.mviewangles[0], cl.mviewangles[1]); - for (i=0 ; i<3 ; i++) - { - //r = fread (&f, 4, 1, cls.demofile); - memcpy(&f, &cls.demobuffer[cls.demobufferposition], 4); - cls.demobufferposition += 4; - cl.mviewangles[0][i] = LittleFloat (f); - } - - if (net_message.cursize > MAX_MSGLEN) - Sys_Error ("Demo message > MAX_MSGLEN"); - - //r = fread (net_message.data, net_message.cursize, 1, cls.demofile); - //if (r != 1) - //{ - // CL_StopPlayback (); - // return 0; - //} - - if(net_message.cursize == 0 || net_message.cursize > (cls.demobufferlength - cls.demobufferposition)) - { - CL_StopPlayback (); - return 0; - } - - for(i = 0; i < net_message.cursize; i++) - { - net_message.data[i] = cls.demobuffer[cls.demobufferposition++]; - } - - return 1; - } - - while (1) - { - r = NET_GetMessage (cls.netcon); - - if (r != 1 && r != 2) - return r; - - // discard nop keepalive message - if (net_message.cursize == 1 && net_message.data[0] == svc_nop) - Con_Printf ("<-- server to client keepalive\n"); - else - break; - } - - if (cls.demorecording) - CL_WriteDemoMessage (); - - return r; -} -// jkrige - pk3 file support - - -/* -==================== -CL_Stop_f - -stop recording a demo -==================== -*/ -void CL_Stop_f (void) -{ - if (cmd_source != src_command) - return; - - if (!cls.demorecording) - { - Con_Printf ("Not recording a demo.\n"); - return; - } - -// write a disconnect message to the demo file - SZ_Clear (&net_message); - MSG_WriteByte (&net_message, svc_disconnect); - CL_WriteDemoMessage (); - -// finish up - fclose (cls.demofile); - cls.demofile = NULL; - cls.demorecording = false; - Con_Printf ("Completed demo\n"); -} - -/* -==================== -CL_Record_f - -record [cd track] -==================== -*/ -void CL_Record_f (void) -{ - int c; - char name[MAX_OSPATH]; - int track; - - if (cmd_source != src_command) - return; - - c = Cmd_Argc(); - if (c != 2 && c != 3 && c != 4) - { - Con_Printf ("record [ [cd track]]\n"); - return; - } - - if (strstr(Cmd_Argv(1), "..")) - { - Con_Printf ("Relative pathnames are not allowed.\n"); - return; - } - - if (c == 2 && cls.state == ca_connected) - { - Con_Printf("Can not record - already connected to server\nClient demo recording must be started before connecting\n"); - return; - } - -// write the forced cd track number, or -1 - if (c == 4) - { - track = atoi(Cmd_Argv(3)); - Con_Printf ("Forcing CD track to %i\n", cls.forcetrack); - } - else - track = -1; - - sprintf (name, "%s/%s", com_gamedir, Cmd_Argv(1)); - -// -// start the map up -// - if (c > 2) - Cmd_ExecuteString ( va("map %s", Cmd_Argv(2)), src_command); - -// -// open the demo file -// - COM_DefaultExtension (name, ".dem"); - - Con_Printf ("recording to %s.\n", name); - cls.demofile = fopen (name, "wb"); - if (!cls.demofile) - { - Con_Printf ("ERROR: couldn't open.\n"); - return; - } - - cls.forcetrack = track; - fprintf (cls.demofile, "%i\n", cls.forcetrack); - - cls.demorecording = true; -} - - -/* -==================== -CL_PlayDemo_f - -play [demoname] -==================== -*/ - -// jkrige - get rid of the menu and/or console -#define m_none 0 // enumerated menu state from menu.c -extern int m_state; -// jkrige - get rid of the menu and/or console - -// jkrige - pk3 file support -/*void CL_PlayDemo_f (void) -{ - char name[256]; - int c; - qboolean neg = false; - - if (cmd_source != src_command) - return; - - if (Cmd_Argc() != 2) - { - Con_Printf ("play : plays a demo\n"); - return; - } - -// -// disconnect from server -// - CL_Disconnect (); - -// -// open the demo file -// - strcpy (name, Cmd_Argv(1)); - COM_DefaultExtension (name, ".dem"); - - Con_Printf ("Playing demo from %s.\n", name); - COM_FOpenFile (name, &cls.demofile); - if (!cls.demofile) - { - Con_Printf ("ERROR: couldn't open.\n"); - cls.demonum = -1; // stop demo loop - return; - } - - cls.demoplayback = true; - cls.state = ca_connected; - cls.forcetrack = 0; - - while ((c = getc(cls.demofile)) != '\n') - if (c == '-') - neg = true; - else - cls.forcetrack = cls.forcetrack * 10 + (c - '0'); - - if (neg) - cls.forcetrack = -cls.forcetrack; -// ZOID, fscanf is evil -// fscanf (cls.demofile, "%i\n", &cls.forcetrack); - - // jkrige - moved to CL_PlayDemo_f - // Get a new message on playback start. - cls.td_lastframe = -1; - // jkrige - moved to CL_PlayDemo_f -}*/ -void CL_PlayDemo_f (void) -{ - char name[256]; - int c; - //int fi; - qboolean neg = false; - - if (cmd_source != src_command) - return; - - if (Cmd_Argc() != 2) - { - Con_Printf ("playdemo : plays a demo\n"); - return; - } - -// -// disconnect from server -// - CL_Disconnect (); - -// -// open the demo file -// - strcpy (name, Cmd_Argv(1)); - COM_DefaultExtension (name, ".dem"); - - Con_Printf ("Playing demo from %s.\n", name); - cls.demobufferlength = COM_FOpenFile (name, &cls.demofile); - cls.demobufferposition = 0; - - if (/*!cls.demofile |*/ cls.demobufferlength < 1) - { - Con_Printf ("ERROR: couldn't open.\n"); - cls.demonum = -1; // stop demo loop - return; - } - - cls.demobuffer = COM_FReadFile(cls.demofile, cls.demobufferlength); - if (!cls.demobuffer) - return; - - cls.demoplayback = true; - cls.state = ca_connected; - cls.forcetrack = 0; - - while ((c = cls.demobuffer[cls.demobufferposition++]) != '\n') - { - if (c == '-') - neg = true; - else - cls.forcetrack = cls.forcetrack * 10 + (c - '0'); - } - - if (neg) - cls.forcetrack = -cls.forcetrack; - - // jkrige - get rid of the menu and/or console - if (key_dest == key_console || key_dest == key_menu) - { - key_dest = key_game; - m_state = m_none; - } - // jkrige - get rid of the menu and/or console - - -// ZOID, fscanf is evil -// fscanf (cls.demofile, "%i\n", &cls.forcetrack); - - // jkrige - moved to CL_PlayDemo_f - // Get a new message on playback start. - cls.td_lastframe = -1; - // jkrige - moved to CL_PlayDemo_f -} -// jkrige - pk3 file support - - -/* -==================== -CL_FinishTimeDemo - -==================== -*/ -void CL_FinishTimeDemo (void) -{ - int frames; - float time; - - cls.timedemo = false; - -// the first frame didn't count - frames = (host_framecount - cls.td_startframe) - 1; - time = realtime - cls.td_starttime; - if (!time) - time = 1; - Con_Printf ("%i frames %5.1f seconds %5.1f fps\n", frames, time, frames/time); -} - -/* -==================== -CL_TimeDemo_f - -timedemo [demoname] -==================== -*/ -void CL_TimeDemo_f (void) -{ - if (cmd_source != src_command) - return; - - if (Cmd_Argc() != 2) - { - Con_Printf ("timedemo : gets demo speeds\n"); - return; - } - - CL_PlayDemo_f (); - -// cls.td_starttime will be grabbed at the second frame of the demo, so -// all the loading time doesn't get counted - - cls.timedemo = true; - cls.td_startframe = host_framecount; - - // jkrige - moved to CL_PlayDemo_f() - //cls.td_lastframe = -1; // get a new message this frame - // jkrige - moved to CL_PlayDemo_f() -} - diff --git a/engine/code/common.c b/engine/code/common.c deleted file mode 100644 index d92b663..0000000 --- a/engine/code/common.c +++ /dev/null @@ -1,2226 +0,0 @@ -/* -Copyright (C) 1996-1997 Id Software, Inc. - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ -// common.c -- misc functions used in client and server - -#include "quakedef.h" - -// jkrige - scale2d -#ifdef _WIN32 -#include "winquake.h" -#endif -// jkrige - scale2d - - -#define NUM_SAFE_ARGVS 7 - -static char *largv[MAX_NUM_ARGVS + NUM_SAFE_ARGVS + 1]; -static char *argvdummy = " "; - -static char *safeargvs[NUM_SAFE_ARGVS] = - {"-stdvid", "-nolan", "-nosound", "-nocdaudio", "-nojoy", "-nomouse", "-dibonly"}; - -cvar_t registered = {"registered","0"}; -cvar_t cmdline = {"cmdline","0", false, true}; - -qboolean com_modified; // set true if using non-id files - -qboolean proghack; - -int static_registered = 1; // only for startup check, then set - -qboolean msg_suppress_1 = 0; - -void COM_InitFilesystem (void); - -// if a packfile directory differs from this, it is assumed to be hacked -#define PAK0_COUNT 339 -#define PAK0_CRC 32981 - -char com_token[1024]; -int com_argc; -char **com_argv; - -#define CMDLINE_LENGTH 256 -char com_cmdline[CMDLINE_LENGTH]; - -qboolean standard_quake = true, rogue, hipnotic; - -// this graphic needs to be in the pak file to use registered features -unsigned short pop[] = -{ - 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000 -,0x0000,0x0000,0x6600,0x0000,0x0000,0x0000,0x6600,0x0000 -,0x0000,0x0066,0x0000,0x0000,0x0000,0x0000,0x0067,0x0000 -,0x0000,0x6665,0x0000,0x0000,0x0000,0x0000,0x0065,0x6600 -,0x0063,0x6561,0x0000,0x0000,0x0000,0x0000,0x0061,0x6563 -,0x0064,0x6561,0x0000,0x0000,0x0000,0x0000,0x0061,0x6564 -,0x0064,0x6564,0x0000,0x6469,0x6969,0x6400,0x0064,0x6564 -,0x0063,0x6568,0x6200,0x0064,0x6864,0x0000,0x6268,0x6563 -,0x0000,0x6567,0x6963,0x0064,0x6764,0x0063,0x6967,0x6500 -,0x0000,0x6266,0x6769,0x6a68,0x6768,0x6a69,0x6766,0x6200 -,0x0000,0x0062,0x6566,0x6666,0x6666,0x6666,0x6562,0x0000 -,0x0000,0x0000,0x0062,0x6364,0x6664,0x6362,0x0000,0x0000 -,0x0000,0x0000,0x0000,0x0062,0x6662,0x0000,0x0000,0x0000 -,0x0000,0x0000,0x0000,0x0061,0x6661,0x0000,0x0000,0x0000 -,0x0000,0x0000,0x0000,0x0000,0x6500,0x0000,0x0000,0x0000 -,0x0000,0x0000,0x0000,0x0000,0x6400,0x0000,0x0000,0x0000 -}; - -/* - - -All of Quake's data access is through a hierchal file system, but the contents of the file system can be transparently merged from several sources. - -The "base directory" is the path to the directory holding the quake.exe and all game directories. The sys_* files pass this to host_init in quakeparms_t->basedir. This can be overridden with the "-basedir" command line parm to allow code debugging in a different directory. The base directory is -only used during filesystem initialization. - -The "game directory" is the first tree on the search path and directory that all generated files (savegames, screenshots, demos, config files) will be saved to. This can be overridden with the "-game" command line parameter. The game directory can never be changed while quake is executing. This is a precacution against having a malicious server instruct clients to write files over areas they shouldn't. - -The "cache directory" is only used during development to save network bandwidth, especially over ISDN / T1 lines. If there is a cache directory -specified, when a file is found by the normal search path, it will be mirrored -into the cache directory, then opened there. - - - -FIXME: -The file "parms.txt" will be read out of the game directory and appended to the current command line arguments to allow different games to initialize startup parms differently. This could be used to add a "-sspeed 22050" for the high quality sound edition. Because they are added at the end, they will not override an explicit setting on the original command line. - -*/ - -//============================================================================ - - -// ClearLink is used for new headnodes -void ClearLink (link_t *l) -{ - l->prev = l->next = l; -} - -void RemoveLink (link_t *l) -{ - l->next->prev = l->prev; - l->prev->next = l->next; -} - -void InsertLinkBefore (link_t *l, link_t *before) -{ - l->next = before; - l->prev = before->prev; - l->prev->next = l; - l->next->prev = l; -} -void InsertLinkAfter (link_t *l, link_t *after) -{ - l->next = after->next; - l->prev = after; - l->prev->next = l; - l->next->prev = l; -} - - -// jkrige - scale2d -int Scale2DWidth; -int Scale2DHeight; -float Scale2DFactor; - -void COM_SetScale2D() -{ - float AspectRatio; - - AspectRatio = (float)modelist[(int)vid_mode.value].width / (float)modelist[(int)vid_mode.value].height; - Scale2DFactor = ceil((float)modelist[(int)vid_mode.value].height / (float)BASEHEIGHT); - - if (Scale2DFactor < 2.0f) - Scale2DFactor = 2.0f; - - Scale2DHeight = (float)modelist[(int)vid_mode.value].height / Scale2DFactor; - Scale2DWidth = (float)Scale2DHeight * AspectRatio; -} -// jkrige - scale2d - - -/* -============================================================================ - - LIBRARY REPLACEMENT FUNCTIONS - -============================================================================ -*/ - -void Q_memset (void *dest, int fill, int count) -{ - int i; - - if ( (((intptr_t)dest | count) & 3) == 0) - { - count >>= 2; - fill = fill | (fill<<8) | (fill<<16) | (fill<<24); - for (i=0 ; i>=2; - for (i=0 ; i= 'a' && c1 <= 'z') - c1 -= ('a' - 'A'); - if (c2 >= 'a' && c2 <= 'z') - c2 -= ('a' - 'A'); - if (c1 != c2) - return -1; // strings not equal - } - if (!c1) - return 0; // strings are equal -// s1++; -// s2++; - } - - return -1; -} - -int Q_strcasecmp (char *s1, char *s2) -{ - return Q_strncasecmp (s1, s2, 99999); -} - -int Q_atoi (char *str) -{ - int val; - int sign; - int c; - - if (*str == '-') - { - sign = -1; - str++; - } - else - sign = 1; - - val = 0; - -// -// check for hex -// - if (str[0] == '0' && (str[1] == 'x' || str[1] == 'X') ) - { - str += 2; - while (1) - { - c = *str++; - if (c >= '0' && c <= '9') - val = (val<<4) + c - '0'; - else if (c >= 'a' && c <= 'f') - val = (val<<4) + c - 'a' + 10; - else if (c >= 'A' && c <= 'F') - val = (val<<4) + c - 'A' + 10; - else - return val*sign; - } - } - -// -// check for character -// - if (str[0] == '\'') - { - return sign * str[1]; - } - -// -// assume decimal -// - while (1) - { - c = *str++; - if (c <'0' || c > '9') - return val*sign; - val = val*10 + c - '0'; - } - - return 0; -} - - -float Q_atof (char *str) -{ - double val; - int sign; - int c; - int decimal, total; - - if (*str == '-') - { - sign = -1; - str++; - } - else - sign = 1; - - val = 0; - -// -// check for hex -// - if (str[0] == '0' && (str[1] == 'x' || str[1] == 'X') ) - { - str += 2; - while (1) - { - c = *str++; - if (c >= '0' && c <= '9') - val = (val*16) + c - '0'; - else if (c >= 'a' && c <= 'f') - val = (val*16) + c - 'a' + 10; - else if (c >= 'A' && c <= 'F') - val = (val*16) + c - 'A' + 10; - else - return val*sign; - } - } - -// -// check for character -// - if (str[0] == '\'') - { - return sign * str[1]; - } - -// -// assume decimal -// - decimal = -1; - total = 0; - while (1) - { - c = *str++; - if (c == '.') - { - decimal = total; - continue; - } - if (c <'0' || c > '9') - break; - val = val*10 + c - '0'; - total++; - } - - if (decimal == -1) - return val*sign; - while (total > decimal) - { - val /= 10; - total--; - } - - return val*sign; -} - -/* -============================================================================ - - BYTE ORDER FUNCTIONS - -============================================================================ -*/ - -qboolean bigendien; - -short (*BigShort) (short l); -short (*LittleShort) (short l); -int (*BigLong) (int l); -int (*LittleLong) (int l); -float (*BigFloat) (float l); -float (*LittleFloat) (float l); - -short ShortSwap (short l) -{ - byte b1,b2; - - b1 = l&255; - b2 = (l>>8)&255; - - return (b1<<8) + b2; -} - -short ShortNoSwap (short l) -{ - return l; -} - -int LongSwap (int l) -{ - byte b1,b2,b3,b4; - - b1 = l&255; - b2 = (l>>8)&255; - b3 = (l>>16)&255; - b4 = (l>>24)&255; - - return ((int)b1<<24) + ((int)b2<<16) + ((int)b3<<8) + b4; -} - -int LongNoSwap (int l) -{ - return l; -} - -float FloatSwap (float f) -{ - union - { - float f; - byte b[4]; - } dat1, dat2; - - - dat1.f = f; - dat2.b[0] = dat1.b[3]; - dat2.b[1] = dat1.b[2]; - dat2.b[2] = dat1.b[1]; - dat2.b[3] = dat1.b[0]; - return dat2.f; -} - -float FloatNoSwap (float f) -{ - return f; -} - -/* -============================================================================== - - MESSAGE IO FUNCTIONS - -Handles byte ordering and avoids alignment errors -============================================================================== -*/ - -// -// writing functions -// - -void MSG_WriteChar (sizebuf_t *sb, int c) -{ - byte *buf; - -#ifdef PARANOID - if (c < -128 || c > 127) - Sys_Error ("MSG_WriteChar: range error"); -#endif - - buf = SZ_GetSpace (sb, 1); - buf[0] = c; -} - -void MSG_WriteByte (sizebuf_t *sb, int c) -{ - byte *buf; - -#ifdef PARANOID - if (c < 0 || c > 255) - Sys_Error ("MSG_WriteByte: range error"); -#endif - - buf = SZ_GetSpace (sb, 1); - buf[0] = c; -} - -void MSG_WriteShort (sizebuf_t *sb, int c) -{ - byte *buf; - -#ifdef PARANOID - if (c < ((short)0x8000) || c > (short)0x7fff) - Sys_Error ("MSG_WriteShort: range error"); -#endif - - buf = SZ_GetSpace (sb, 2); - buf[0] = c&0xff; - buf[1] = c>>8; -} - -void MSG_WriteLong (sizebuf_t *sb, int c) -{ - byte *buf; - - buf = SZ_GetSpace (sb, 4); - buf[0] = c&0xff; - buf[1] = (c>>8)&0xff; - buf[2] = (c>>16)&0xff; - buf[3] = c>>24; -} - -void MSG_WriteFloat (sizebuf_t *sb, float f) -{ - union - { - float f; - int l; - } dat; - - - dat.f = f; - dat.l = LittleLong (dat.l); - - SZ_Write (sb, &dat.l, 4); -} - -void MSG_WriteString (sizebuf_t *sb, char *s) -{ - if (!s) - SZ_Write (sb, "", 1); - else - SZ_Write (sb, s, Q_strlen(s)+1); -} - -void MSG_WriteCoord (sizebuf_t *sb, float f) -{ - // jkrige - round to nearest value, rather than rounding toward zero - if (f >= 0) - MSG_WriteShort (sb, (int)(f * 8.0 + 0.5)); - else - MSG_WriteShort (sb, (int)(f * 8.0 - 0.5)); - - - //MSG_WriteShort (sb, (int)(f*8)); -} - -void MSG_WriteAngle (sizebuf_t *sb, float f) -{ - // jkrige - round to nearest value, rather than rounding toward zero - if (f >= 0) - MSG_WriteByte (sb, (int)(f*(256.0/360.0) + 0.5) & 255); - else - MSG_WriteByte (sb, (int)(f*(256.0/360.0) - 0.5) & 255); - - - //MSG_WriteByte (sb, ((int)f*256/360) & 255); -} - -// -// reading functions -// -int msg_readcount; -qboolean msg_badread; - -void MSG_BeginReading (void) -{ - msg_readcount = 0; - msg_badread = false; -} - -// returns -1 and sets msg_badread if no more characters are available -int MSG_ReadChar (void) -{ - int c; - - if (msg_readcount+1 > net_message.cursize) - { - msg_badread = true; - return -1; - } - - c = (signed char)net_message.data[msg_readcount]; - msg_readcount++; - - return c; -} - -int MSG_ReadByte (void) -{ - int c; - - if (msg_readcount+1 > net_message.cursize) - { - msg_badread = true; - return -1; - } - - c = (unsigned char)net_message.data[msg_readcount]; - msg_readcount++; - - return c; -} - -int MSG_ReadShort (void) -{ - int c; - - if (msg_readcount+2 > net_message.cursize) - { - msg_badread = true; - return -1; - } - - c = (short)(net_message.data[msg_readcount] - + (net_message.data[msg_readcount+1]<<8)); - - msg_readcount += 2; - - return c; -} - -int MSG_ReadLong (void) -{ - int c; - - if (msg_readcount+4 > net_message.cursize) - { - msg_badread = true; - return -1; - } - - c = net_message.data[msg_readcount] - + (net_message.data[msg_readcount+1]<<8) - + (net_message.data[msg_readcount+2]<<16) - + (net_message.data[msg_readcount+3]<<24); - - msg_readcount += 4; - - return c; -} - -float MSG_ReadFloat (void) -{ - union - { - byte b[4]; - float f; - int l; - } dat; - - dat.b[0] = net_message.data[msg_readcount]; - dat.b[1] = net_message.data[msg_readcount+1]; - dat.b[2] = net_message.data[msg_readcount+2]; - dat.b[3] = net_message.data[msg_readcount+3]; - msg_readcount += 4; - - dat.l = LittleLong (dat.l); - - return dat.f; -} - -char *MSG_ReadString (void) -{ - static char string[2048]; - int l,c; - - l = 0; - do - { - c = MSG_ReadChar (); - if (c == -1 || c == 0) - break; - string[l] = c; - l++; - } while (l < sizeof(string)-1); - - string[l] = 0; - - return string; -} - -float MSG_ReadCoord (void) -{ - return MSG_ReadShort() * (1.0/8); -} - -float MSG_ReadAngle (void) -{ - return MSG_ReadChar() * (360.0/256); -} - - - -//=========================================================================== - -void SZ_Alloc (sizebuf_t *buf, int startsize) -{ - if (startsize < 256) - startsize = 256; - buf->data = Hunk_AllocName (startsize, "sizebuf"); - buf->maxsize = startsize; - buf->cursize = 0; -} - - -void SZ_Free (sizebuf_t *buf) -{ -// Z_Free (buf->data); -// buf->data = NULL; -// buf->maxsize = 0; - buf->cursize = 0; -} - -void SZ_Clear (sizebuf_t *buf) -{ - buf->cursize = 0; -} - -void *SZ_GetSpace (sizebuf_t *buf, int length) -{ - void *data; - - if (buf->cursize + length > buf->maxsize) - { - if (!buf->allowoverflow) - Sys_Error ("SZ_GetSpace: overflow without allowoverflow set"); - - if (length > buf->maxsize) - Sys_Error ("SZ_GetSpace: %i is > full buffer size", length); - - buf->overflowed = true; - Con_Printf ("SZ_GetSpace: overflow"); - SZ_Clear (buf); - } - - data = buf->data + buf->cursize; - buf->cursize += length; - - return data; -} - -void SZ_Write (sizebuf_t *buf, void *data, int length) -{ - Q_memcpy (SZ_GetSpace(buf,length),data,length); -} - -void SZ_Print (sizebuf_t *buf, char *data) -{ - int len; - - len = Q_strlen(data)+1; - -// byte * cast to keep VC++ happy - if (buf->data[buf->cursize-1]) - Q_memcpy ((byte *)SZ_GetSpace(buf, len),data,len); // no trailing 0 - else - Q_memcpy ((byte *)SZ_GetSpace(buf, len-1)-1,data,len); // write over trailing 0 -} - - -//============================================================================ - - -/* -============ -COM_SkipPath -============ -*/ -char *COM_SkipPath (char *pathname) -{ - char *last; - - last = pathname; - while (*pathname) - { - if (*pathname=='/') - last = pathname+1; - pathname++; - } - return last; -} - -/* -============ -COM_StripExtension -============ -*/ -void COM_StripExtension (char *in, char *out) -{ - while (*in && *in != '.') - *out++ = *in++; - *out = 0; -} - -/* -============ -COM_FileExtension -============ -*/ -char *COM_FileExtension (char *in) -{ - static char exten[8]; - int i; - - while (*in && *in != '.') - in++; - if (!*in) - return ""; - in++; - for (i=0 ; i<7 && *in ; i++,in++) - exten[i] = *in; - exten[i] = 0; - return exten; -} - -/* -============ -COM_FileBase -============ -*/ -void COM_FileBase (char *in, char *out) -{ - char *s, *s2; - - s = in + strlen(in) - 1; - - while (s != in && *s != '.') - s--; - - /* Pa3PyX: no range checking -- used to trash the stack and crash the - game randomly upon loading progs, for instance (or in any other - instance where one would supply a filename witout a path */ -// for (s2 = s ; *s2 && *s2 != '/' ; s2--); - for (s2 = s; *s2 && *s2 != '/' && s2 >= in; s2--); - - if (s-s2 < 2) - strcpy (out,"?model?"); - else - { - s--; - strncpy (out,s2+1, s-s2); - out[s-s2] = 0; - } -} - - -/* -================== -COM_DefaultExtension -================== -*/ -void COM_DefaultExtension (char *path, char *extension) -{ - char *src; -// -// if path doesn't have a .EXT, append extension -// (extension should include the .) -// - src = path + strlen(path) - 1; - - while (*src != '/' && src != path) - { - if (*src == '.') - return; // it has an extension - src--; - } - - strcat (path, extension); -} - - -/* -============== -COM_Parse - -Parse a token out of a string -============== -*/ -char *COM_Parse (char *data) -{ - int c; - int len; - - len = 0; - com_token[0] = 0; - - if (!data) - return NULL; - -// skip whitespace -skipwhite: - while ( (c = *data) <= ' ') - { - if (c == 0) - return NULL; // end of file; - data++; - } - -// skip // comments - if (c=='/' && data[1] == '/') - { - while (*data && *data != '\n') - data++; - goto skipwhite; - } - - -// handle quoted strings specially - if (c == '\"') - { - data++; - while (1) - { - c = *data++; - if (c=='\"' || !c) - { - com_token[len] = 0; - return data; - } - com_token[len] = c; - len++; - } - } - -// parse single characters - if (c=='{' || c=='}'|| c==')'|| c=='(' || c=='\'' || c==':') - { - com_token[len] = c; - len++; - com_token[len] = 0; - return data+1; - } - -// parse a regular word - do - { - com_token[len] = c; - data++; - len++; - c = *data; - if (c=='{' || c=='}'|| c==')'|| c=='(' || c=='\'' || c==':') - break; - } while (c>32); - - com_token[len] = 0; - return data; -} - - -/* -================ -COM_CheckParm - -Returns the position (1 to argc-1) in the program's argument list -where the given parameter apears, or 0 if not present -================ -*/ -int COM_CheckParm (char *parm) -{ - int i; - - for (i=1 ; inext) - { - if (s->pack) - { - Con_Printf ("%s (%i files)\n", s->pack->filename, s->pack->numfiles); - } - else - Con_Printf ("%s\n", s->filename); - } -} - -/* -============ -COM_WriteFile - -The filename will be prefixed by the current game directory -============ -*/ -void COM_WriteFile (char *filename, void *data, int len) -{ - int handle; - char name[MAX_OSPATH]; - - sprintf (name, "%s/%s", com_gamedir, filename); - - handle = Sys_FileOpenWrite (name); - if (handle == -1) - { - Sys_Printf ("COM_WriteFile: failed on %s\n", name); - return; - } - - Sys_Printf ("COM_WriteFile: %s\n", name); - Sys_FileWrite (handle, data, len); - Sys_FileClose (handle); -} - - -/* -============ -COM_CreatePath - -Only used for CopyFile -============ -*/ -void COM_CreatePath (char *path) -{ - char *ofs; - - for (ofs = path+1 ; *ofs ; ofs++) - { - if (*ofs == '/') - { // create the directory - *ofs = 0; - Sys_mkdir (path); - *ofs = '/'; - } - } -} - - -/* -=========== -COM_CopyFile - -Copies a file over from the net to the local cache, creating any directories -needed. This is for the convenience of developers using ISDN from home. -=========== -*/ -void COM_CopyFile (char *netpath, char *cachepath) -{ - int in, out; - int remaining, count; - char buf[4096]; - - remaining = Sys_FileOpenRead (netpath, &in); - COM_CreatePath (cachepath); // create directories up to the cache file - out = Sys_FileOpenWrite (cachepath); - - while (remaining) - { - if (remaining < sizeof(buf)) - count = remaining; - else - count = sizeof(buf); - Sys_FileRead (in, buf, count); - Sys_FileWrite (out, buf, count); - remaining -= count; - } - - Sys_FileClose (in); - Sys_FileClose (out); -} - -// jkrige - pk3 file support -qboolean LoadFromPK3; -// jkrige - pk3 file support - -/* -=========== -COM_FindFile - -Finds the file in the search path. -Sets com_filesize and one of handle or file -=========== -*/ -int COM_FindFile (char *filename, int *handle, FILE **file) -{ - searchpath_t *search; - char netpath[MAX_OSPATH]; - char cachepath[MAX_OSPATH]; - pack_t *pak; - int i; - int findtime, cachetime; - - if (file && handle) - Sys_Error ("COM_FindFile: both handle and file set"); - if (!file && !handle) - Sys_Error ("COM_FindFile: neither handle or file set"); - - LoadFromPK3 = false; // jkrige - pk3 file support - -// -// search through the path, one element at a time -// - search = com_searchpaths; - if (proghack) - { // gross hack to use quake 1 progs with quake 2 maps - if (!strcmp(filename, "progs.dat")) - search = search->next; - } - - for ( ; search ; search = search->next) - { - // is the element a pak file? - if (search->pack) - { - // look through all the pak file elements - pak = search->pack; - for (i=0 ; inumfiles ; i++) - if (!strcmp (pak->files[i].name, filename)) - { // found it! - Sys_Printf ("PackFile: %s : %s\n",pak->filename, filename); - com_filesize = 0; - - if (handle) - { - *handle = pak->handle; - - // jkrige - pk3 file support - //Sys_FileSeek (pak->handle, pak->files[i].filepos); - if(pak->ident == ZPAKHEADER) - { - if(unzSetCurrentFileInfoPosition (pak->uzf, pak->files[i].filepos) == UNZ_OK) - { - if(unzOpenCurrentFile (pak->uzf) == UNZ_OK) - com_filesize = pak->files[i].filelen; - } - //unzLocateFile (pak->uzf, pak->files[i].name, 0); - - LoadFromPK3 = true; - } - else - { - Sys_FileSeek (pak->handle, pak->files[i].filepos); - com_filesize = pak->files[i].filelen; - } - // jkrige - pk3 file support - } - else - { - // open a new file on the pakfile - - // jkrige - pk3 file support - // *file = fopen (pak->filename, "rb"); - //if (*file) - // fseek (*file, pak->files[i].filepos, SEEK_SET); - if(pak->ident == ZPAKHEADER) - { - *file = pak->uzf; - - if(unzSetCurrentFileInfoPosition (pak->uzf, pak->files[i].filepos) == UNZ_OK) - { - if(unzOpenCurrentFile (pak->uzf) == UNZ_OK) - com_filesize = pak->files[i].filelen; - } - //unzLocateFile (pak->uzf, pak->files[i].name, 0); - - LoadFromPK3 = true; - } - else - { - *file = fopen (pak->filename, "rb"); - if (*file) - { - fseek (*file, pak->files[i].filepos, SEEK_SET); - com_filesize = pak->files[i].filelen; - } - } - // jkrige - pk3 file support - } - - return com_filesize; - } - } - else - { - // check a file in the directory tree - if (!static_registered) - { // if not a registered version, don't ever go beyond base - if ( strchr (filename, '/') || strchr (filename,'\\')) - continue; - } - - sprintf (netpath, "%s/%s",search->filename, filename); - - findtime = Sys_FileTime (netpath); - if (findtime == -1) - continue; - - // see if the file needs to be updated in the cache - if (!com_cachedir[0]) - strcpy (cachepath, netpath); - else - { -#if defined(_WIN32) - if ((strlen(netpath) < 2) || (netpath[1] != ':')) - sprintf (cachepath,"%s%s", com_cachedir, netpath); - else - sprintf (cachepath,"%s%s", com_cachedir, netpath+2); -#else - sprintf (cachepath,"%s%s", com_cachedir, netpath); -#endif - - cachetime = Sys_FileTime (cachepath); - - if (cachetime < findtime) - COM_CopyFile (netpath, cachepath); - strcpy (netpath, cachepath); - } - - Sys_Printf ("FindFile: %s\n",netpath); - com_filesize = Sys_FileOpenRead (netpath, &i); - if (handle) - *handle = i; - else - { - Sys_FileClose (i); - *file = fopen (netpath, "rb"); - } - return com_filesize; - } - - } - - Sys_Printf ("FindFile: can't find %s\n", filename); - - if (handle) - *handle = -1; - else - *file = NULL; - com_filesize = -1; - return -1; -} - - -/* -=========== -COM_OpenFile - -filename never has a leading slash, but may contain directory walks -returns a handle and a length -it may actually be inside a pak file -=========== -*/ -int COM_OpenFile (char *filename, int *handle) -{ - return COM_FindFile (filename, handle, NULL); -} - -/* -=========== -COM_FOpenFile - -If the requested file is inside a packfile, a new FILE * will be opened -into the file. -=========== -*/ -int COM_FOpenFile (char *filename, FILE **file) -{ - return COM_FindFile (filename, NULL, file); -} - -/* -============ -COM_CloseFile - -If it is a pak file handle, don't really close it -============ -*/ -void COM_CloseFile (int h) -{ - searchpath_t *s; - - for (s = com_searchpaths ; s ; s=s->next) - if (s->pack && s->pack->handle == h) - return; - - Sys_FileClose (h); -} - - -// jkrige - pk3 file support -byte *COM_ReadFile (int handle, int len) -{ - byte *buf; - - buf = NULL; // quiet compiler warning - buf = malloc (len+1); - - if (!buf) - Sys_Error ("COM_ReadFile: not enough space."); - - ((byte *)buf)[len] = 0; - - Draw_BeginDisc (); - - if(LoadFromPK3 == true) - { - if (unzReadCurrentFile(sys_zhandles[handle], buf, len) < 1) - { - free(buf); - buf = NULL; - } - - if (unzCloseCurrentFile(sys_zhandles[handle]) != UNZ_OK) - { - free(buf); - buf = NULL; - } - - LoadFromPK3 = false; - } - else - { - int result; - - result = Sys_FileRead (handle, buf, len); - Sys_FileClose (handle); - - if (result = 0) - { - free(buf); - buf = NULL; - } - } - - Draw_EndDisc (); - - return buf; -} - -byte *COM_FReadFile (FILE *file, int len) -{ - byte *buf; - - buf = NULL; // quiet compiler warning - buf = malloc (len+1); - - if (!buf) - Sys_Error ("COM_FReadFile: not enough space."); - - ((byte *)buf)[len] = 0; - - Draw_BeginDisc (); - - if(LoadFromPK3 == true) - { - if (unzReadCurrentFile(file, buf, len) < 1) - { - free(buf); - buf = NULL; - } - - if (unzCloseCurrentFile(file) != UNZ_OK) - { - free(buf); - buf = NULL; - } - - LoadFromPK3 = false; - } - else - { - int result; - - result = Sys_FFileRead (file, buf, len); - Sys_FFileClose (file); - - if (result = 0) - { - free(buf); - buf = NULL; - } - } - - Draw_EndDisc (); - - return buf; -} -// jkrige - pk3 file support - - -/* -============ -COM_LoadFile - -Filename are reletive to the quake directory. -Allways appends a 0 byte. -============ -*/ -cache_user_t *loadcache; -byte *loadbuf; -int loadsize; -byte *COM_LoadFile (char *path, int usehunk) -{ - int h; - byte *buf; - char base[32]; - int len; - - buf = NULL; // quiet compiler warning - -// look for it in the filesystem or pack files - len = COM_OpenFile (path, &h); - if (h == -1) - return NULL; - -// extract the filename base name for hunk tag - COM_FileBase (path, base); - - if (usehunk == 1) - buf = Hunk_AllocName (len+1, base); - else if (usehunk == 2) - buf = Hunk_TempAlloc (len+1); - else if (usehunk == 0) - buf = Z_Malloc (len+1); - else if (usehunk == 3) - buf = Cache_Alloc (loadcache, len+1, base); - else if (usehunk == 4) - { - if (len+1 > loadsize) - buf = Hunk_TempAlloc (len+1); - else - buf = loadbuf; - } - else - Sys_Error ("COM_LoadFile: bad usehunk"); - - if (!buf) - Sys_Error ("COM_LoadFile: not enough space for %s", path); - - ((byte *)buf)[len] = 0; - - Draw_BeginDisc (); - - Sys_FileRead (h, buf, len); - COM_CloseFile (h); - - Draw_EndDisc (); - - return buf; -} - -byte *COM_LoadHunkFile (char *path) -{ - return COM_LoadFile (path, 1); -} - -byte *COM_LoadTempFile (char *path) -{ - return COM_LoadFile (path, 2); -} - -void COM_LoadCacheFile (char *path, struct cache_user_s *cu) -{ - loadcache = cu; - COM_LoadFile (path, 3); -} - -// uses temp hunk if larger than bufsize -byte *COM_LoadStackFile (char *path, void *buffer, int bufsize) -{ - byte *buf; - - loadbuf = (byte *)buffer; - loadsize = bufsize; - buf = COM_LoadFile (path, 4); - - return buf; -} - -/* -================= -COM_LoadPackFile - -Takes an explicit (not game tree related) path to a pak file. - -Loads the header and directory, adding the files at the beginning -of the list so they override previous pack files. -================= -*/ -pack_t *COM_LoadPackFile (char *packfile) -{ - dpackheader_t header; - int i; - packfile_t *newfiles; - int numpackfiles; - pack_t *pack; - int packhandle; - dpackfile_t info[MAX_FILES_IN_PACK]; - unsigned short crc; - - if (Sys_FileOpenRead (packfile, &packhandle) == -1) - { - return NULL; - } - - Sys_FileRead (packhandle, (void *)&header, sizeof(header)); - - // jkrige - pk3 file support - //if (header.id[0] != 'P' || header.id[1] != 'A' || header.id[2] != 'C' || header.id[3] != 'K') - // Sys_Error ("%s is not a packfile", packfile); - if (LittleLong(header.ident) != IDPAKHEADER) - Sys_Error ("%s is not a packfile", packfile); - // jkrige - pk3 file support - - header.dirofs = LittleLong (header.dirofs); - header.dirlen = LittleLong (header.dirlen); - - numpackfiles = header.dirlen / sizeof(dpackfile_t); - - if (numpackfiles > MAX_FILES_IN_PACK) - Sys_Error ("%s has %i files", packfile, numpackfiles); - - if (numpackfiles != PAK0_COUNT) - com_modified = true; // not the original file - - newfiles = Hunk_AllocName (numpackfiles * sizeof(packfile_t), "packfile"); - - Sys_FileSeek (packhandle, header.dirofs); - Sys_FileRead (packhandle, (void *)info, header.dirlen); - -// crc the directory to check for modifications - CRC_Init (&crc); - for (i=0 ; iident = IDPAKHEADER; // jkrige - pk3 file support - strcpy (pack->filename, packfile); - pack->handle = packhandle; - pack->numfiles = numpackfiles; - pack->files = newfiles; - - Con_Printf ("Added packfile %s (%i files)\n", packfile, numpackfiles); - return pack; -} - -// jkrige - pk3 file support -pack_t *COM_LoadZPackFile (char *packfile) -{ - dzpackheader_t header; - int i; - packfile_t *newfiles; - pack_t *pack; - int packhandle; - //FILE *uf; - unzFile uf; - dpackfile_t info[MAX_FILES_IN_PACK]; - - int err; - unz_global_info gi; - unz_file_info file_info; - char filename_inzip[MAX_ZPATH]; - int len; - - unsigned long filepos; - - uf = unzOpen(packfile); - if(uf == NULL) - return NULL; - - packhandle = findhandle(true); - sys_zhandles[packhandle] = uf; - - err = unzGetGlobalInfo (uf, &gi); - - if (err != UNZ_OK) - return NULL; - - len = 0; - unzGoToFirstFile(uf); - for (i = 0; i < gi.number_entry; i++) - { - err = unzGetCurrentFileInfo(uf, &file_info, filename_inzip, sizeof(filename_inzip), NULL, 0, NULL, 0); - if (err != UNZ_OK) { - break; - } - len += strlen(filename_inzip) + 1; - unzGoToNextFile(uf); - } - - newfiles = Hunk_AllocName (gi.number_entry * sizeof(packfile_t)+ len, "packfile"); - - unzGoToFirstFile(uf); - for (i = 0; i < gi.number_entry; i++) - { - err = unzGetCurrentFileInfo(uf, &file_info, filename_inzip, sizeof(filename_inzip), NULL, 0, NULL, 0); - if (err != UNZ_OK) - break; - - //strlwr( filename_inzip ); - strcpy( newfiles[i].name, filename_inzip ); - - unzGetCurrentFileInfoPosition(uf, &filepos); - newfiles[i].filepos = filepos; - newfiles[i].filelen = file_info.uncompressed_size; - - unzGoToNextFile(uf); - } - - pack = Hunk_Alloc (sizeof (pack_t)); - pack->ident = ZPAKHEADER; - pack->uzf = uf; - strcpy (pack->filename, packfile); - pack->handle = packhandle; - pack->numfiles = gi.number_entry; - pack->files = newfiles; - - Con_Printf ("Added packfile %s (%i files)\n", packfile, pack->numfiles); - return pack; -} -// jkrige - pk3 file support - - -/* -================ -COM_AddGameDirectory - -Sets com_gamedir, adds the directory to the head of the path, -then loads and adds pak1.pak pak2.pak ... -================ -*/ -void COM_AddGameDirectory (char *dir) -{ - // jkrige - pack naming convention - //int i; - // jkrige - pack naming convention - - searchpath_t *search; - pack_t *pak; - char pakfile[MAX_OSPATH]; - - // jkrige - pack naming convention - char dirstring[1024]; - intptr_t handle; - struct _finddata_t fileinfo; - // jkrige - pack naming convention - - - strcpy (com_gamedir, dir); - -// -// add the directory to the search path -// - search = Hunk_Alloc (sizeof(searchpath_t)); - strcpy (search->filename, dir); - search->next = com_searchpaths; - com_searchpaths = search; - - -// -// add any pak files in the format pak0.pak pak1.pak, ... -// - // jkrige - pack naming convention - /*for (i=0 ; ; i++) - { - sprintf (pakfile, "%s/pak%i.pak", dir, i); - pak = COM_LoadPackFile (pakfile); - if (!pak) - break; - search = Hunk_Alloc (sizeof(searchpath_t)); - search->pack = pak; - search->next = com_searchpaths; - com_searchpaths = search; - }*/ - - - // we are going to add pak files first so they can be overridden by pk3 files - // we want pk3 to take presidence over pak - sprintf (dirstring, "%s/*.pak", dir); - handle = _findfirst (dirstring, &fileinfo); - if (handle != -1) - { - do - { - if (fileinfo.name[0] == '.') - continue; - - sprintf(pakfile,"%s/%s", dir, fileinfo.name); - pak = COM_LoadPackFile (pakfile); - - if (!pak) - break; - - search = Hunk_Alloc (sizeof(searchpath_t)); - search->pack = pak; - search->next = com_searchpaths; - com_searchpaths = search; - } - while (_findnext( handle, &fileinfo ) != -1); - - _findclose (handle); - } - - - sprintf (dirstring, "%s/*.pk3", dir); - handle = _findfirst (dirstring, &fileinfo); - if (handle != -1) - { - do - { - if (fileinfo.name[0] == '.') - continue; - - sprintf(pakfile,"%s/%s", dir, fileinfo.name); - pak = COM_LoadZPackFile (pakfile); - - if (!pak) - break; - - search = Hunk_Alloc (sizeof(searchpath_t)); - search->pack = pak; - search->next = com_searchpaths; - com_searchpaths = search; - } - while (_findnext( handle, &fileinfo ) != -1); - - _findclose (handle); - } - // jkrige - pack naming convention - -// -// add the contents of the parms.txt file to the end of the command line -// - -} - -/* -================ -COM_InitFilesystem -================ -*/ -void COM_InitFilesystem (void) -{ - int i, j; - char basedir[MAX_OSPATH]; - searchpath_t *search; - -// -// -basedir -// Overrides the system supplied base directory (under GAMENAME) -// - i = COM_CheckParm ("-basedir"); - if (i && i < com_argc-1) - strcpy (basedir, com_argv[i+1]); - else - strcpy (basedir, host_parms.basedir); - - j = strlen (basedir); - - if (j > 0) - { - if ((basedir[j-1] == '\\') || (basedir[j-1] == '/')) - basedir[j-1] = 0; - } - -// -// -cachedir -// Overrides the system supplied cache directory (NULL or /qcache) -// -cachedir - will disable caching. -// - i = COM_CheckParm ("-cachedir"); - if (i && i < com_argc-1) - { - if (com_argv[i+1][0] == '-') - com_cachedir[0] = 0; - else - strcpy (com_cachedir, com_argv[i+1]); - } - else if (host_parms.cachedir) - strcpy (com_cachedir, host_parms.cachedir); - else - com_cachedir[0] = 0; - -// -// start up with GAMENAME by default (id1) -// - COM_AddGameDirectory (va("%s/"GAMENAME, basedir) ); - - if (COM_CheckParm ("-rogue")) - COM_AddGameDirectory (va("%s/rogue", basedir) ); - if (COM_CheckParm ("-hipnotic")) - COM_AddGameDirectory (va("%s/hipnotic", basedir) ); - - // jkrige - added Dimension of the Past - begin - if (COM_CheckParm("-dopa")) - COM_AddGameDirectory(va("%s/dopa", basedir)); - // jkrige - added Dimension of the Past - end - -// -// -game -// Adds basedir/gamedir as an override game -// - i = COM_CheckParm ("-game"); - if (i && i < com_argc-1) - { - com_modified = true; - COM_AddGameDirectory (va("%s/%s", basedir, com_argv[i+1])); - } - -// -// -path [] ... -// Fully specifies the exact serach path, overriding the generated one -// - i = COM_CheckParm ("-path"); - if (i) - { - com_modified = true; - com_searchpaths = NULL; - while (++i < com_argc) - { - if (!com_argv[i] || com_argv[i][0] == '+' || com_argv[i][0] == '-') - break; - - search = Hunk_Alloc (sizeof(searchpath_t)); - if ( !strcmp(COM_FileExtension(com_argv[i]), "pak") ) - { - search->pack = COM_LoadPackFile (com_argv[i]); - if (!search->pack) - Sys_Error ("Couldn't load packfile: %s", com_argv[i]); - } - else if ( !strcmp(COM_FileExtension(com_argv[i]), "pk3") ) // jkrige - pk3 file support - { - search->pack = COM_LoadZPackFile (com_argv[i]); - if (!search->pack) - Sys_Error ("Couldn't load packfile: %s", com_argv[i]); - } // jkrige - pk3 file support - else - strcpy (search->filename, com_argv[i]); - search->next = com_searchpaths; - com_searchpaths = search; - } - } - - if (COM_CheckParm ("-proghack")) - proghack = true; -} - - diff --git a/engine/code/common.h b/engine/code/common.h deleted file mode 100644 index 12844a4..0000000 --- a/engine/code/common.h +++ /dev/null @@ -1,198 +0,0 @@ -/* -Copyright (C) 1996-1997 Id Software, Inc. - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ -// comndef.h -- general definitions - -#if !defined BYTE_DEFINED -typedef unsigned char byte; -#define BYTE_DEFINED 1 -#endif - -#undef true -#undef false - -typedef enum {false, true} qboolean; - -//============================================================================ - -typedef struct sizebuf_s -{ - qboolean allowoverflow; // if false, do a Sys_Error - qboolean overflowed; // set to true if the buffer size failed - byte *data; - int maxsize; - int cursize; -} sizebuf_t; - -void SZ_Alloc (sizebuf_t *buf, int startsize); -void SZ_Free (sizebuf_t *buf); -void SZ_Clear (sizebuf_t *buf); -void *SZ_GetSpace (sizebuf_t *buf, int length); -void SZ_Write (sizebuf_t *buf, void *data, int length); -void SZ_Print (sizebuf_t *buf, char *data); // strcats onto the sizebuf - -//============================================================================ - -typedef struct link_s -{ - struct link_s *prev, *next; -} link_t; - - -void ClearLink (link_t *l); -void RemoveLink (link_t *l); -void InsertLinkBefore (link_t *l, link_t *before); -void InsertLinkAfter (link_t *l, link_t *after); - -// (type *)STRUCT_FROM_LINK(link_t *link, type, member) -// ent = STRUCT_FROM_LINK(link,entity_t,order) -// FIXME: remove this mess! -#define STRUCT_FROM_LINK(l,t,m) ((t *)((byte *)l - (intptr_t)&(((t *)0)->m))) - -//============================================================================ - -#ifndef NULL -#define NULL ((void *)0) -#endif - -#define Q_MAXCHAR ((char)0x7f) -#define Q_MAXSHORT ((short)0x7fff) -#define Q_MAXINT ((int)0x7fffffff) -#define Q_MAXLONG ((int)0x7fffffff) -#define Q_MAXFLOAT ((int)0x7fffffff) - -#define Q_MINCHAR ((char)0x80) -#define Q_MINSHORT ((short)0x8000) -#define Q_MININT ((int)0x80000000) -#define Q_MINLONG ((int)0x80000000) -#define Q_MINFLOAT ((int)0x7fffffff) - -//============================================================================ - -extern qboolean bigendien; - -extern short (*BigShort) (short l); -extern short (*LittleShort) (short l); -extern int (*BigLong) (int l); -extern int (*LittleLong) (int l); -extern float (*BigFloat) (float l); -extern float (*LittleFloat) (float l); - -//============================================================================ - -void MSG_WriteChar (sizebuf_t *sb, int c); -void MSG_WriteByte (sizebuf_t *sb, int c); -void MSG_WriteShort (sizebuf_t *sb, int c); -void MSG_WriteLong (sizebuf_t *sb, int c); -void MSG_WriteFloat (sizebuf_t *sb, float f); -void MSG_WriteString (sizebuf_t *sb, char *s); -void MSG_WriteCoord (sizebuf_t *sb, float f); -void MSG_WriteAngle (sizebuf_t *sb, float f); - -extern int msg_readcount; -extern qboolean msg_badread; // set if a read goes beyond end of message - -void MSG_BeginReading (void); -int MSG_ReadChar (void); -int MSG_ReadByte (void); -int MSG_ReadShort (void); -int MSG_ReadLong (void); -float MSG_ReadFloat (void); -char *MSG_ReadString (void); - -float MSG_ReadCoord (void); -float MSG_ReadAngle (void); - -//============================================================================ - -// jkrige - scale2d -extern int Scale2DWidth; -extern int Scale2DHeight; -extern float Scale2DFactor; -extern void COM_SetScale2D(); -// jkrige - scale2d - -void Q_memset (void *dest, int fill, int count); -void Q_memcpy (void *dest, void *src, int count); -int Q_memcmp (void *m1, void *m2, int count); -void Q_strcpy (char *dest, char *src); -void Q_strncpy (char *dest, char *src, int count); -int Q_strlen (char *str); -char *Q_strrchr (char *s, char c); -void Q_strcat (char *dest, char *src); -int Q_strcmp (char *s1, char *s2); -int Q_strncmp (char *s1, char *s2, int count); -int Q_strcasecmp (char *s1, char *s2); -int Q_strncasecmp (char *s1, char *s2, int n); -int Q_atoi (char *str); -float Q_atof (char *str); - -//============================================================================ - -extern char com_token[1024]; -extern qboolean com_eof; - -char *COM_Parse (char *data); - - -extern int com_argc; -extern char **com_argv; - -int COM_CheckParm (char *parm); -void COM_Init (char *path); -void COM_InitArgv (int argc, char **argv); - -char *COM_SkipPath (char *pathname); -void COM_StripExtension (char *in, char *out); -void COM_FileBase (char *in, char *out); -void COM_DefaultExtension (char *path, char *extension); - -char *va(char *format, ...); -// does a varargs printf into a temp buffer - - -//============================================================================ - -extern int com_filesize; -struct cache_user_s; - -extern char com_gamedir[MAX_OSPATH]; - -void COM_WriteFile (char *filename, void *data, int len); -int COM_OpenFile (char *filename, int *hndl); -int COM_FOpenFile (char *filename, FILE **file); -void COM_CloseFile (int h); - - -// jkrige - pk3 file support -extern qboolean LoadFromPK3; -byte *COM_ReadFile (int handle, int len); -byte *COM_FReadFile (FILE *file, int len); -// jkrige - pk3 file support - - -byte *COM_LoadStackFile (char *path, void *buffer, int bufsize); -byte *COM_LoadTempFile (char *path); -byte *COM_LoadHunkFile (char *path); -void COM_LoadCacheFile (char *path, struct cache_user_s *cu); - - -extern struct cvar_s registered; - -extern qboolean standard_quake, rogue, hipnotic; diff --git a/engine/code/conproc.c b/engine/code/conproc.c deleted file mode 100644 index 43c20ca..0000000 --- a/engine/code/conproc.c +++ /dev/null @@ -1,365 +0,0 @@ -/* -Copyright (C) 1996-1997 Id Software, Inc. - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ -// conproc.c - -#include -#include "conproc.h" -#include "quakedef.h" - -HANDLE heventDone; -HANDLE hfileBuffer; -HANDLE heventChildSend; -HANDLE heventParentSend; -HANDLE hStdout; -HANDLE hStdin; - -DWORD RequestProc (DWORD dwNichts); -LPVOID GetMappedBuffer (HANDLE hfileBuffer); -void ReleaseMappedBuffer (LPVOID pBuffer); -BOOL GetScreenBufferLines (int *piLines); -BOOL SetScreenBufferLines (int iLines); -BOOL ReadText (LPTSTR pszText, int iBeginLine, int iEndLine); -BOOL WriteText (LPCTSTR szText); -int CharToCode (char c); -BOOL SetConsoleCXCY(HANDLE hStdout, int cx, int cy); - - -void InitConProc (HANDLE hFile, HANDLE heventParent, HANDLE heventChild) -{ - DWORD dwID; - CONSOLE_SCREEN_BUFFER_INFO info; - int wheight, wwidth; - -// ignore if we don't have all the events. - if (!hFile || !heventParent || !heventChild) - return; - - hfileBuffer = hFile; - heventParentSend = heventParent; - heventChildSend = heventChild; - -// so we'll know when to go away. - heventDone = CreateEvent (NULL, FALSE, FALSE, NULL); - - if (!heventDone) - { - Con_SafePrintf ("Couldn't create heventDone\n"); - return; - } - - if (!CreateThread (NULL, - 0, - (LPTHREAD_START_ROUTINE) RequestProc, - 0, - 0, - &dwID)) - { - CloseHandle (heventDone); - Con_SafePrintf ("Couldn't create QHOST thread\n"); - return; - } - -// save off the input/output handles. - hStdout = GetStdHandle (STD_OUTPUT_HANDLE); - hStdin = GetStdHandle (STD_INPUT_HANDLE); - -// force 80 character width, at least 25 character height - SetConsoleCXCY (hStdout, 80, 25); -} - - -void DeinitConProc (void) -{ - if (heventDone) - SetEvent (heventDone); -} - - -DWORD RequestProc (DWORD dwNichts) -{ - int *pBuffer; - DWORD dwRet; - HANDLE heventWait[2]; - int iBeginLine, iEndLine; - - heventWait[0] = heventParentSend; - heventWait[1] = heventDone; - - while (1) - { - dwRet = WaitForMultipleObjects (2, heventWait, FALSE, INFINITE); - - // heventDone fired, so we're exiting. - if (dwRet == WAIT_OBJECT_0 + 1) - break; - - pBuffer = (int *) GetMappedBuffer (hfileBuffer); - - // hfileBuffer is invalid. Just leave. - if (!pBuffer) - { - Con_SafePrintf ("Invalid hfileBuffer\n"); - break; - } - - switch (pBuffer[0]) - { - case CCOM_WRITE_TEXT: - // Param1 : Text - pBuffer[0] = WriteText ((LPCTSTR) (pBuffer + 1)); - break; - - case CCOM_GET_TEXT: - // Param1 : Begin line - // Param2 : End line - iBeginLine = pBuffer[1]; - iEndLine = pBuffer[2]; - pBuffer[0] = ReadText ((LPTSTR) (pBuffer + 1), iBeginLine, - iEndLine); - break; - - case CCOM_GET_SCR_LINES: - // No params - pBuffer[0] = GetScreenBufferLines (&pBuffer[1]); - break; - - case CCOM_SET_SCR_LINES: - // Param1 : Number of lines - pBuffer[0] = SetScreenBufferLines (pBuffer[1]); - break; - } - - ReleaseMappedBuffer (pBuffer); - SetEvent (heventChildSend); - } - - return 0; -} - - -LPVOID GetMappedBuffer (HANDLE hfileBuffer) -{ - LPVOID pBuffer; - - pBuffer = MapViewOfFile (hfileBuffer, - FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0); - - return pBuffer; -} - - -void ReleaseMappedBuffer (LPVOID pBuffer) -{ - UnmapViewOfFile (pBuffer); -} - - -BOOL GetScreenBufferLines (int *piLines) -{ - CONSOLE_SCREEN_BUFFER_INFO info; - BOOL bRet; - - bRet = GetConsoleScreenBufferInfo (hStdout, &info); - - if (bRet) - *piLines = info.dwSize.Y; - - return bRet; -} - - -BOOL SetScreenBufferLines (int iLines) -{ - - return SetConsoleCXCY (hStdout, 80, iLines); -} - - -BOOL ReadText (LPTSTR pszText, int iBeginLine, int iEndLine) -{ - COORD coord; - DWORD dwRead; - BOOL bRet; - - coord.X = 0; - coord.Y = iBeginLine; - - bRet = ReadConsoleOutputCharacter( - hStdout, - pszText, - 80 * (iEndLine - iBeginLine + 1), - coord, - &dwRead); - - // Make sure it's null terminated. - if (bRet) - pszText[dwRead] = '\0'; - - return bRet; -} - - -BOOL WriteText (LPCTSTR szText) -{ - DWORD dwWritten; - INPUT_RECORD rec; - char upper, *sz; - - sz = (LPTSTR) szText; - - while (*sz) - { - // 13 is the code for a carriage return (\n) instead of 10. - if (*sz == 10) - *sz = 13; - - upper = toupper(*sz); - - rec.EventType = KEY_EVENT; - rec.Event.KeyEvent.bKeyDown = TRUE; - rec.Event.KeyEvent.wRepeatCount = 1; - rec.Event.KeyEvent.wVirtualKeyCode = upper; - rec.Event.KeyEvent.wVirtualScanCode = CharToCode (*sz); - rec.Event.KeyEvent.uChar.AsciiChar = *sz; - rec.Event.KeyEvent.uChar.UnicodeChar = *sz; - rec.Event.KeyEvent.dwControlKeyState = isupper(*sz) ? 0x80 : 0x0; - - WriteConsoleInput( - hStdin, - &rec, - 1, - &dwWritten); - - rec.Event.KeyEvent.bKeyDown = FALSE; - - WriteConsoleInput( - hStdin, - &rec, - 1, - &dwWritten); - - sz++; - } - - return TRUE; -} - - -int CharToCode (char c) -{ - char upper; - - upper = toupper(c); - - switch (c) - { - case 13: - return 28; - - default: - break; - } - - if (isalpha(c)) - return (30 + upper - 65); - - if (isdigit(c)) - return (1 + upper - 47); - - return c; -} - - -BOOL SetConsoleCXCY(HANDLE hStdout, int cx, int cy) -{ - CONSOLE_SCREEN_BUFFER_INFO info; - COORD coordMax; - - coordMax = GetLargestConsoleWindowSize(hStdout); - - if (cy > coordMax.Y) - cy = coordMax.Y; - - if (cx > coordMax.X) - cx = coordMax.X; - - if (!GetConsoleScreenBufferInfo(hStdout, &info)) - return FALSE; - -// height - info.srWindow.Left = 0; - info.srWindow.Right = info.dwSize.X - 1; - info.srWindow.Top = 0; - info.srWindow.Bottom = cy - 1; - - if (cy < info.dwSize.Y) - { - if (!SetConsoleWindowInfo(hStdout, TRUE, &info.srWindow)) - return FALSE; - - info.dwSize.Y = cy; - - if (!SetConsoleScreenBufferSize(hStdout, info.dwSize)) - return FALSE; - } - else if (cy > info.dwSize.Y) - { - info.dwSize.Y = cy; - - if (!SetConsoleScreenBufferSize(hStdout, info.dwSize)) - return FALSE; - - if (!SetConsoleWindowInfo(hStdout, TRUE, &info.srWindow)) - return FALSE; - } - - if (!GetConsoleScreenBufferInfo(hStdout, &info)) - return FALSE; - -// width - info.srWindow.Left = 0; - info.srWindow.Right = cx - 1; - info.srWindow.Top = 0; - info.srWindow.Bottom = info.dwSize.Y - 1; - - if (cx < info.dwSize.X) - { - if (!SetConsoleWindowInfo(hStdout, TRUE, &info.srWindow)) - return FALSE; - - info.dwSize.X = cx; - - if (!SetConsoleScreenBufferSize(hStdout, info.dwSize)) - return FALSE; - } - else if (cx > info.dwSize.X) - { - info.dwSize.X = cx; - - if (!SetConsoleScreenBufferSize(hStdout, info.dwSize)) - return FALSE; - - if (!SetConsoleWindowInfo(hStdout, TRUE, &info.srWindow)) - return FALSE; - } - - return TRUE; -} - diff --git a/engine/code/conproc.h b/engine/code/conproc.h deleted file mode 100644 index 743526f..0000000 --- a/engine/code/conproc.h +++ /dev/null @@ -1,37 +0,0 @@ -/* -Copyright (C) 1996-1997 Id Software, Inc. - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ -// conproc.h - -#define CCOM_WRITE_TEXT 0x2 -// Param1 : Text - -#define CCOM_GET_TEXT 0x3 -// Param1 : Begin line -// Param2 : End line - -#define CCOM_GET_SCR_LINES 0x4 -// No params - -#define CCOM_SET_SCR_LINES 0x5 -// Param1 : Number of lines - -void InitConProc (HANDLE hFile, HANDLE heventParent, HANDLE heventChild); -void DeinitConProc (void); - diff --git a/engine/code/console.c b/engine/code/console.c deleted file mode 100644 index 68df650..0000000 --- a/engine/code/console.c +++ /dev/null @@ -1,671 +0,0 @@ -/* -Copyright (C) 1996-1997 Id Software, Inc. - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ -// console.c - -#ifdef NeXT -#include -#endif -#ifndef _MSC_VER -#include -#endif -#include -#include "quakedef.h" - -// jkrige - scale2d -#ifdef _WIN32 -#include "winquake.h" -#endif -// jkrige - scale2d - -int con_linewidth; - -float con_cursorspeed = 4; - -#define CON_TEXTSIZE 16384 - -qboolean con_forcedup; // because no entities to refresh - -int con_totallines; // total lines in console scrollback -int con_backscroll; // lines up from bottom to display -int con_current; // where next message will be printed -int con_x; // offset in current line for next print -char *con_text=0; - -cvar_t con_notifytime = {"con_notifytime","3"}; //seconds - -#define NUM_CON_TIMES 4 -float con_times[NUM_CON_TIMES]; // realtime time the line was generated - // for transparent notify lines - -int con_vislines; - -qboolean con_debuglog; - -#define MAXCMDLINE 256 -extern char key_lines[32][MAXCMDLINE]; -extern int edit_line; -extern int key_linepos; - - -qboolean con_initialized; - -int con_notifylines; // scan lines to clear for notify lines - -extern void M_Menu_Main_f (void); - -/* -================ -Con_ToggleConsole_f -================ -*/ -void Con_ToggleConsole_f (void) -{ - if (key_dest == key_console) - { - if (cls.state == ca_connected) - { - key_dest = key_game; - key_lines[edit_line][1] = 0; // clear any typing - key_linepos = 1; - } - else - { - M_Menu_Main_f (); - } - } - else - key_dest = key_console; - - SCR_EndLoadingPlaque (); - memset (con_times, 0, sizeof(con_times)); -} - -/* -================ -Con_Clear_f -================ -*/ -void Con_Clear_f (void) -{ - if (con_text) - Q_memset (con_text, ' ', CON_TEXTSIZE); -} - - -/* -================ -Con_ClearNotify -================ -*/ -void Con_ClearNotify (void) -{ - int i; - - for (i=0 ; i 1.0f) - { - vid.width = vid.conwidth = conback->width = Scale2DWidth; - vid.height = vid.conheight = conback->height = Scale2DHeight; - } - else - { - vid.width = vid.conwidth = conback->width = modelist[(int)vid_mode.value].width; - vid.height = vid.conheight = conback->height = modelist[(int)vid_mode.value].height; - } -#endif - // jkrige - scale2d - - - width = (vid.width >> 3) - 2; - - if (width == con_linewidth) - return; - - if (width < 1) // video hasn't been initialized yet - { - width = 38; - con_linewidth = width; - con_totallines = CON_TEXTSIZE / con_linewidth; - Q_memset (con_text, ' ', CON_TEXTSIZE); - } - else - { - oldwidth = con_linewidth; - con_linewidth = width; - oldtotallines = con_totallines; - con_totallines = CON_TEXTSIZE / con_linewidth; - numlines = oldtotallines; - - if (con_totallines < numlines) - numlines = con_totallines; - - numchars = oldwidth; - - if (con_linewidth < numchars) - numchars = con_linewidth; - - Q_memcpy (tbuf, con_text, CON_TEXTSIZE); - Q_memset (con_text, ' ', CON_TEXTSIZE); - - for (i=0 ; i con_linewidth) ) - con_x = 0; - - txt++; - - if (cr) - { - con_current--; - cr = false; - } - - - if (!con_x) - { - Con_Linefeed (); - // mark time for transparent overlay - if (con_current >= 0) - con_times[con_current % NUM_CON_TIMES] = realtime; - } - - switch (c) - { - case '\n': - con_x = 0; - break; - - case '\r': - con_x = 0; - cr = 1; - break; - - default: // display character and advance - y = con_current % con_totallines; - con_text[y*con_linewidth+con_x] = c | mask; - con_x++; - if (con_x >= con_linewidth) - con_x = 0; - break; - } - - } -} - - -/* -================ -Con_DebugLog -================ -*/ -void Con_DebugLog(char *file, char *fmt, ...) -{ - va_list argptr; - static char data[1024]; - int fd; - - va_start(argptr, fmt); - vsprintf(data, fmt, argptr); - va_end(argptr); - fd = open(file, O_WRONLY | O_CREAT | O_APPEND, 0666); - write(fd, data, strlen(data)); - close(fd); -} - - -/* -================ -Con_Printf - -Handles cursor positioning, line wrapping, etc -================ -*/ -#define MAXPRINTMSG 4096 -// FIXME: make a buffer size safe vsprintf? -void Con_Printf (char *fmt, ...) -{ - va_list argptr; - char msg[MAXPRINTMSG]; - static qboolean inupdate; - - va_start (argptr,fmt); - vsprintf (msg,fmt,argptr); - va_end (argptr); - -// also echo to debugging console - Sys_Printf ("%s", msg); // also echo to debugging console - -// log all messages to file - if (con_debuglog) - Con_DebugLog(va("%s/qconsole.log",com_gamedir), "%s", msg); - - if (!con_initialized) - return; - - if (cls.state == ca_dedicated) - return; // no graphics mode - -// write it to the scrollable buffer - Con_Print (msg); - -// update the screen if the console is displayed - if (cls.signon != SIGNONS && !scr_disabled_for_loading ) - { - // protect against infinite loop if something in SCR_UpdateScreen calls - // Con_Printd - if (!inupdate) - { - inupdate = true; - SCR_UpdateScreen (); - inupdate = false; - } - } -} - -/* -================ -Con_DPrintf - -A Con_Printf that only shows up if the "developer" cvar is set -================ -*/ -void Con_DPrintf (char *fmt, ...) -{ - va_list argptr; - char msg[MAXPRINTMSG]; - - if (!developer.value) - return; // don't confuse non-developers with techie stuff... - - va_start (argptr,fmt); - vsprintf (msg,fmt,argptr); - va_end (argptr); - - Con_Printf ("%s", msg); -} - - -/* -================== -Con_SafePrintf - -Okay to call even when the screen can't be updated -================== -*/ -void Con_SafePrintf (char *fmt, ...) -{ - va_list argptr; - char msg[1024]; - int temp; - - va_start (argptr,fmt); - vsprintf (msg,fmt,argptr); - va_end (argptr); - - temp = scr_disabled_for_loading; - scr_disabled_for_loading = true; - Con_Printf ("%s", msg); - scr_disabled_for_loading = temp; -} - - -/* -============================================================================== - -DRAWING - -============================================================================== -*/ - - -/* -================ -Con_DrawInput - -The input line scrolls horizontally if typing goes beyond the right edge -================ -*/ -void Con_DrawInput (void) -{ - int y; - int i; - char *text; - - if (key_dest != key_console && !con_forcedup) - return; // don't draw anything - - text = key_lines[edit_line]; - -// add the cursor frame - text[key_linepos] = 10+((int)(realtime*con_cursorspeed)&1); - -// fill out remainder with spaces - for (i=key_linepos+1 ; i< con_linewidth ; i++) - text[i] = ' '; - -// prestep if horizontally scrolling - if (key_linepos >= con_linewidth) - text += 1 + key_linepos - con_linewidth; - -// draw it - y = con_vislines-16; - - for (i=0 ; i con_notifytime.value) - continue; - text = con_text + (i % con_totallines)*con_linewidth; - - clearnotify = 0; - scr_copytop = 1; - - for (x = 0 ; x < con_linewidth ; x++) - Draw_Character ( (x+1)<<3, v, text[x]); - - v += 8; - } - - - if (key_dest == key_message) - { - clearnotify = 0; - scr_copytop = 1; - - x = 0; - - Draw_String (8, v, "say:"); - while(chat_buffer[x]) - { - Draw_Character ( (x+5)<<3, v, chat_buffer[x]); - x++; - } - Draw_Character ( (x+5)<<3, v, 10+((int)(realtime*con_cursorspeed)&1)); - v += 8; - } - - if (v > con_notifylines) - con_notifylines = v; -} - -/* -================ -Con_DrawConsole - -Draws the console with the solid background -The typing input line at the bottom should only be drawn if typing is allowed -================ -*/ -void Con_DrawConsole (int lines, qboolean drawinput) -{ - int i, x, y; - int rows; - char *text; - int j; - - if (lines <= 0) - return; - -// draw the background - Draw_ConsoleBackground (lines); - -// draw the text - con_vislines = lines; - - rows = (lines-16)>>3; // rows of text to draw - y = lines - 16 - (rows<<3); // may start slightly negative - - for (i= con_current - rows + 1 ; i<=con_current ; i++, y+=8 ) - { - j = i - con_backscroll; - if (j<0) - j = 0; - text = con_text + (j % con_totallines)*con_linewidth; - - for (x=0 ; x 1) - { - partial = Cmd_Argv (1); - len = strlen(partial); - } - else - { - partial = NULL; - len = 0; - } - - count=0; - - for (cvar=cvar_vars ; cvar ; cvar=cvar->next) - { - if (partial && strncmp (partial,cvar->name, len)) - { - continue; - } - - Con_Printf ("\"%s\" is \"%s\"\n", cvar->name, cvar->string); - - count++; - } - - Con_Printf ("%i cvar(s)", count); - - if (partial) - { - Con_Printf (" beginning with \"%s\"", partial); - } - - Con_Printf ("\n"); -} -// jkrige - cvarlist - -/* -============ -Cvar_FindVar -============ -*/ -cvar_t *Cvar_FindVar (char *var_name) -{ - cvar_t *var; - - for (var=cvar_vars ; var ; var=var->next) - if (!Q_strcmp (var_name, var->name)) - return var; - - return NULL; -} - -/* -============ -Cvar_VariableValue -============ -*/ -float Cvar_VariableValue (char *var_name) -{ - cvar_t *var; - - var = Cvar_FindVar (var_name); - if (!var) - return 0; - return Q_atof (var->string); -} - - -/* -============ -Cvar_VariableString -============ -*/ -char *Cvar_VariableString (char *var_name) -{ - cvar_t *var; - - var = Cvar_FindVar (var_name); - if (!var) - return cvar_null_string; - return var->string; -} - - -/* -============ -Cvar_CompleteVariable -============ -*/ -char *Cvar_CompleteVariable (char *partial) -{ - cvar_t *cvar; - int len; - - len = Q_strlen(partial); - - if (!len) - return NULL; - -// check functions - for (cvar=cvar_vars ; cvar ; cvar=cvar->next) - if (!Q_strncmp (partial,cvar->name, len)) - return cvar->name; - - return NULL; -} - - -/* -============ -Cvar_Set -============ -*/ -void Cvar_Set (char *var_name, char *value) -{ - cvar_t *var; - qboolean changed; - - var = Cvar_FindVar (var_name); - if (!var) - { // there is an error in C code if this happens - Con_Printf ("Cvar_Set: variable %s not found\n", var_name); - return; - } - - changed = Q_strcmp(var->string, value); - - Z_Free (var->string); // free the old value string - - var->string = Z_Malloc (Q_strlen(value)+1); - Q_strcpy (var->string, value); - var->value = Q_atof (var->string); - if (var->server && changed) - { - if (sv.active) - SV_BroadcastPrintf ("\"%s\" changed to \"%s\"\n", var->name, var->string); - } - - // jkrige - deathmatch/coop not at the same time fix - if ( (var->value != 0) && (!Q_strcmp (var->name, deathmatch.name)) ) - Cvar_Set ("coop", "0"); - - if ( (var->value != 0) && (!Q_strcmp (var->name, coop.name)) ) - Cvar_Set ("deathmatch", "0"); - // jkrige - deathmatch/coop not at the same time fix -} - -/* -============ -Cvar_SetValue -============ -*/ -void Cvar_SetValue (char *var_name, float value) -{ - char val[32]; - - // jkrige - cvar zeros fix - //sprintf (val, "%f",value); - if (value == (int)value) - sprintf (val, "%d", (int)value); - else - sprintf (val, "%f",value); - // jkrige - cvar zeros fix - - Cvar_Set (var_name, val); -} - - -/* -============ -Cvar_RegisterVariable - -Adds a freestanding variable to the variable list. -============ -*/ -void Cvar_RegisterVariable (cvar_t *variable) -{ - char *oldstr; - -// first check to see if it has allready been defined - if (Cvar_FindVar (variable->name)) - { - Con_Printf ("Can't register variable %s, allready defined\n", variable->name); - return; - } - -// check for overlap with a command - if (Cmd_Exists (variable->name)) - { - Con_Printf ("Cvar_RegisterVariable: %s is a command\n", variable->name); - return; - } - -// copy the value off, because future sets will Z_Free it - oldstr = variable->string; - variable->string = Z_Malloc (Q_strlen(variable->string)+1); - Q_strcpy (variable->string, oldstr); - variable->value = Q_atof (variable->string); - -// link the variable in - variable->next = cvar_vars; - cvar_vars = variable; -} - -/* -============ -Cvar_Command - -Handles variable inspection and changing from the console -============ -*/ -qboolean Cvar_Command (void) -{ - cvar_t *v; - -// check variables - v = Cvar_FindVar (Cmd_Argv(0)); - if (!v) - return false; - -// perform a variable print or set - if (Cmd_Argc() == 1) - { - Con_Printf ("\"%s\" is \"%s\"\n", v->name, v->string); - return true; - } - - Cvar_Set (v->name, Cmd_Argv(1)); - return true; -} - - -/* -============ -Cvar_WriteVariables - -Writes lines containing "set variable value" for all variables -with the archive flag set to true. -============ -*/ -void Cvar_WriteVariables (FILE *f) -{ - cvar_t *var; - - for (var = cvar_vars ; var ; var = var->next) - if (var->archive) - fprintf (f, "%s \"%s\"\n", var->name, var->string); -} - diff --git a/engine/code/cvar.h b/engine/code/cvar.h deleted file mode 100644 index 5b84761..0000000 --- a/engine/code/cvar.h +++ /dev/null @@ -1,99 +0,0 @@ -/* -Copyright (C) 1996-1997 Id Software, Inc. - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ -// cvar.h - -/* - -cvar_t variables are used to hold scalar or string variables that can be changed or displayed at the console or prog code as well as accessed directly -in C code. - -it is sufficient to initialize a cvar_t with just the first two fields, or -you can add a ,true flag for variables that you want saved to the configuration -file when the game is quit: - -cvar_t r_draworder = {"r_draworder","1"}; -cvar_t scr_screensize = {"screensize","1",true}; - -Cvars must be registered before use, or they will have a 0 value instead of the float interpretation of the string. Generally, all cvar_t declarations should be registered in the apropriate init function before any console commands are executed: -Cvar_RegisterVariable (&host_framerate); - - -C code usually just references a cvar in place: -if ( r_draworder.value ) - -It could optionally ask for the value to be looked up for a string name: -if (Cvar_VariableValue ("r_draworder")) - -Interpreted prog code can access cvars with the cvar(name) or -cvar_set (name, value) internal functions: -teamplay = cvar("teamplay"); -cvar_set ("registered", "1"); - -The user can access cvars from the console in two ways: -r_draworder prints the current value -r_draworder 0 sets the current value to 0 -Cvars are restricted from having the same names as commands to keep this -interface from being ambiguous. -*/ - -typedef struct cvar_s -{ - char *name; - char *string; - qboolean archive; // set to true to cause it to be saved to vars.rc - qboolean server; // notifies players when changed - float value; - struct cvar_s *next; -} cvar_t; - -void Cvar_RegisterVariable (cvar_t *variable); -// registers a cvar that allready has the name, string, and optionally the -// archive elements set. - -void Cvar_Set (char *var_name, char *value); -// equivelant to " " typed at the console - -void Cvar_SetValue (char *var_name, float value); -// expands value to a string and calls Cvar_Set - -float Cvar_VariableValue (char *var_name); -// returns 0 if not defined or non numeric - -char *Cvar_VariableString (char *var_name); -// returns an empty string if not defined - -char *Cvar_CompleteVariable (char *partial); -// attempts to match a partial variable name for command line completion -// returns NULL if nothing fits - -qboolean Cvar_Command (void); -// called by Cmd_ExecuteString when Cmd_Argv(0) doesn't match a known -// command. Returns true if the command was a variable reference that -// was handled. (print or change) - -void Cvar_WriteVariables (FILE *f); -// Writes lines containing "set variable value" for all variables -// with the archive flag set to true. - -cvar_t *Cvar_FindVar (char *var_name); - -void Cvar_List_f (void); // jkrige - cvarlist - -extern cvar_t *cvar_vars; diff --git a/engine/code/gl_draw.c b/engine/code/gl_draw.c deleted file mode 100644 index 0c877dd..0000000 --- a/engine/code/gl_draw.c +++ /dev/null @@ -1,2492 +0,0 @@ -/* -Copyright (C) 1996-1997 Id Software, Inc. - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ - -// draw.c -- this is the only file outside the refresh that touches the -// vid buffer - -#include "quakedef.h" - -// jkrige - scale2d -#ifdef _WIN32 -#include "winquake.h" -#endif -// jkrige - scale2d - -// jkrige - jpg -#include "../jpeg-6/jpeglib.h" -byte *jpeg_rgba; -// jkrige - jpg - -//#define GL_COLOR_INDEX8_EXT 0x80E5 - -extern unsigned char d_15to8table[65536]; - -cvar_t gl_nobind = {"gl_nobind", "0"}; -cvar_t gl_max_size = {"gl_max_size", "1024"}; -cvar_t gl_picmip = {"gl_picmip", "0"}; - -// jkrige - luma textures -cvar_t gl_lumatex_render = {"gl_lumatex_render", "1", true}; -// jkrige - luma textures - -byte *draw_chars; // 8*8 graphic characters -qpic_t *draw_disc; -qpic_t *draw_backtile; - -int translate_texture; -int char_texture; - -typedef struct -{ - int texnum; - float sl, tl, sh, th; -} glpic_t; - -byte conback_buffer[sizeof(qpic_t) + sizeof(glpic_t)]; -qpic_t *conback = (qpic_t *)&conback_buffer; - -// jkrige - .lit colored lights -//int gl_lightmap_format = 4; -// jkrige - .lit colored lights -int gl_solid_format = 3; -int gl_alpha_format = 4; - -// jkrige - change bilinear texture filtering to trilinear texture filtering -//int gl_filter_min = GL_LINEAR_MIPMAP_NEAREST; -//int gl_filter_max = GL_LINEAR; -int gl_filter_min = GL_LINEAR_MIPMAP_LINEAR; -int gl_filter_max = GL_LINEAR_MIPMAP_LINEAR; -// jkrige - change bilinear texture filtering to trilinear texture filtering - -float tex_mode = -1.0f; - -int texels; - -// jkrige - moved to glquake.h -/*typedef struct -{ - int texnum; - - qboolean tex_luma; // jkrige - luma textures - - char identifier[64]; - int width, height; - qboolean mipmap; -} gltexture_t; - -#define MAX_GLTEXTURES 1024*/ -// jkrige - moved to glquake.h - -gltexture_t gltextures[MAX_GLTEXTURES]; -int numgltextures; - - -void GL_Bind (int texnum) -{ - if (gl_nobind.value) - texnum = char_texture; - if (currenttexture == texnum) - return; - currenttexture = texnum; - -#ifdef UQ_GLDEBUG -// jkrige - opengl's bind function -//#ifdef _WIN32 -// bindTexFunc (GL_TEXTURE_2D, texnum); -//#else - glBindTexture(GL_TEXTURE_2D, texnum); -//#endif -// jkrige - opengl's bind function -#endif // UQ_GLDEBUG -} - - -/* -============================================================================= - - scrap allocation - - Allocate all the little status bar obejcts into a single texture - to crutch up stupid hardware / drivers - -============================================================================= -*/ - -#define MAX_SCRAPS 2 -#define BLOCK_WIDTH 256 -#define BLOCK_HEIGHT 256 - -int scrap_allocated[MAX_SCRAPS][BLOCK_WIDTH]; -byte scrap_texels[MAX_SCRAPS][BLOCK_WIDTH*BLOCK_HEIGHT*4]; -qboolean scrap_dirty; -int scrap_texnum; - -// returns a texture number and the position inside it -int Scrap_AllocBlock (int w, int h, int *x, int *y) -{ - int i, j; - int best, best2; - int bestx; - int texnum; - - for (texnum=0 ; texnum= best) - break; - if (scrap_allocated[texnum][i+j] > best2) - best2 = scrap_allocated[texnum][i+j]; - } - if (j == w) - { // this is a valid spot - *x = i; - *y = best = best2; - } - } - - if (best + h > BLOCK_HEIGHT) - continue; - - for (i=0 ; idata; - - // load little ones into the scrap - if (p->width < 64 && p->height < 64) - { - int x, y; - int i, j, k; - int texnum; - - texnum = Scrap_AllocBlock (p->width, p->height, &x, &y); - scrap_dirty = true; - k = 0; - for (i=0 ; iheight ; i++) - for (j=0 ; jwidth ; j++, k++) - scrap_texels[texnum][(y+i)*BLOCK_WIDTH + x + j] = p->data[k]; - texnum += scrap_texnum; - gl->texnum = texnum; - gl->sl = (x+0.01)/(float)BLOCK_WIDTH; - gl->sh = (x+p->width-0.01)/(float)BLOCK_WIDTH; - gl->tl = (y+0.01)/(float)BLOCK_WIDTH; - gl->th = (y+p->height-0.01)/(float)BLOCK_WIDTH; - - pic_count++; - pic_texels += p->width*p->height; - } - else - { - gl->texnum = GL_LoadPicTexture (p); - gl->sl = 0; - gl->sh = 1; - gl->tl = 0; - gl->th = 1; - } - - return p; -} - - -/* -================ -Draw_CachePic -================ -*/ -qpic_t *Draw_CachePic (char *path) -{ - cachepic_t *pic; - int i; - qpic_t *dat; - glpic_t *gl; - - for (pic=menu_cachepics, i=0 ; iname)) - return &pic->pic; - - if (menu_numcachepics == MAX_CACHED_PICS) - Sys_Error ("menu_numcachepics == MAX_CACHED_PICS"); - menu_numcachepics++; - strcpy (pic->name, path); - -// -// load the pic from disk -// - dat = (qpic_t *)COM_LoadTempFile (path); - if (!dat) - Sys_Error ("Draw_CachePic: failed to load %s", path); - SwapPic (dat); - - // HACK HACK HACK --- we need to keep the bytes for - // the translatable player picture just for the menu - // configuration dialog - if (!strcmp (path, "gfx/menuplyr.lmp")) - memcpy (menuplyr_pixels, dat->data, dat->width*dat->height); - - pic->pic.width = dat->width; - pic->pic.height = dat->height; - - gl = (glpic_t *)pic->pic.data; - gl->texnum = GL_LoadPicTexture (dat); - gl->sl = 0; - gl->sh = 1; - gl->tl = 0; - gl->th = 1; - - return &pic->pic; -} - - -/*void Draw_CharToConback (int num, byte *dest) -{ - int row, col; - byte *source; - int drawline; - int x; - - row = num>>4; - col = num&15; - source = draw_chars + (row<<10) + (col<<3); - - drawline = 8; - - while (drawline--) - { - for (x=0 ; x<8 ; x++) - if (source[x] != 255) - dest[x] = 0x60 + source[x]; - source += 128; - dest += 320; - } - -}*/ - -typedef struct -{ - char *name; - int minimize, maximize; -} glmode_t; - -glmode_t modes[] = { - {"GL_NEAREST", GL_NEAREST, GL_NEAREST}, - {"GL_LINEAR", GL_LINEAR, GL_LINEAR}, - {"GL_NEAREST_MIPMAP_NEAREST", GL_NEAREST_MIPMAP_NEAREST, GL_NEAREST}, - {"GL_LINEAR_MIPMAP_NEAREST", GL_LINEAR_MIPMAP_NEAREST, GL_LINEAR}, - {"GL_NEAREST_MIPMAP_LINEAR", GL_NEAREST_MIPMAP_LINEAR, GL_NEAREST}, - {"GL_LINEAR_MIPMAP_LINEAR", GL_LINEAR_MIPMAP_LINEAR, GL_LINEAR} -}; - -/* -=============== -Draw_TextureMode_f -=============== -*/ -/*void Draw_TextureMode_f (void) -{ - int i; - gltexture_t *glt; - - if (Cmd_Argc() == 1) - { - for (i=0 ; i< 6 ; i++) - if (gl_filter_min == modes[i].minimize) - { - Con_Printf ("%s\n", modes[i].name); - return; - } - Con_Printf ("current filter is unknown???\n"); - return; - } - - for (i=0 ; i< 6 ; i++) - { - if (!Q_strcasecmp (modes[i].name, Cmd_Argv(1) ) ) - break; - } - if (i == 6) - { - Con_Printf ("bad filter name\n"); - return; - } - - gl_filter_min = modes[i].minimize; - gl_filter_max = modes[i].maximize; - - // change all the existing mipmap texture objects - for (i=0, glt=gltextures ; imipmap) - { - GL_Bind (glt->texnum); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_filter_min); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filter_max); - } - } -}*/ - -// jkrige - texture mode -extern int solidskytexture; -extern int alphaskytexture; - -void Draw_TextureMode_f (void) -{ - int i, j; - gltexture_t *glt; - int AnisotropyModes = 0; - - if(tex_mode < 0.0f) - tex_mode = gl_texturemode.value; - - if(tex_mode == gl_texturemode.value) - return; - - if(floor(gl_texturemode.value) < 0.0f | gl_texturemode.value != floor(gl_texturemode.value)) - { - Con_Printf ("unknown texture mode\n"); - Cvar_Set ("gl_texturemode", "2"); - - return; - } - - i = 0; - - if(gl_texturemode.value == 1.0f) - i = 3; - - if(gl_texturemode.value >= 2.0f) - i = 5; - - if(anisotropic_ext == true) - AnisotropyModes = (int)floor((log(maximumAnisotrophy)/log(2.0f)) + 0.5f); - else - AnisotropyModes = 0; - - if(anisotropic_ext == false) - { - if (gl_texturemode.value > 2.0f) - { - Con_Printf ("unknown texture mode\n"); - Cvar_Set ("gl_texturemode", "2"); - - return; - } - } - - if(anisotropic_ext == true) - { - if (gl_texturemode.value > (2.0f + (float)AnisotropyModes)) - { - Con_Printf ("unknown texture mode\n"); - Cvar_SetValue ("gl_texturemode", (2.0f + (float)AnisotropyModes)); - - return; - } - } - - gl_filter_min = modes[i].minimize; - gl_filter_max = modes[i].maximize; - -#ifdef UQ_GLDEBUG - // change all the existing mipmap texture objects - for (j=0, glt=gltextures ; jmipmap) - { - GL_Bind (glt->texnum); - - if(gl_texturemode.value <= 2.0f) - { - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_filter_min); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filter_max); - if(anisotropic_ext == true) - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1.0f); - } - - // jkrige - anisotropic filtering - if(gl_texturemode.value > 2.0f && anisotropic_ext == true) - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, pow(2.0f, gl_texturemode.value - 2.0f)); - // jkrige - anisotropic filtering - - - // jkrige - luma textures - if(glt->tex_luma == true) - { - GL_Bind (JK_LUMA_TEX + glt->texnum); - - if(gl_texturemode.value <= 2.0f) - { - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_filter_min); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filter_max); - if(anisotropic_ext == true) - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1.0f); - } - - // jkrige - anisotropic filtering - if(gl_texturemode.value > 2.0f && anisotropic_ext == true) - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, pow(2.0f, gl_texturemode.value - 2.0f)); - // jkrige - anisotropic filtering - } - // jkrige - luma textures - } - } - - - // sky textures - if(gl_texturemode.value == 0.0f) - { - GL_Bind (solidskytexture); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - - GL_Bind (alphaskytexture); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - } - else - { - GL_Bind (solidskytexture); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - - GL_Bind (alphaskytexture); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - } - // sky textures -#endif // UQ_GLDEBUG - - tex_mode = gl_texturemode.value; -} -// jkrige - texture mode - -/* -=============== -Draw_Init -=============== -*/ -void Draw_Init (void) -{ - int i; - qpic_t *cb; - byte *dest, *src; - int x, y; - char ver[40]; - glpic_t *gl; - int start; - byte *ncdata; - int f, fstep; - - - Cvar_RegisterVariable (&gl_nobind); - Cvar_RegisterVariable (&gl_max_size); - Cvar_RegisterVariable (&gl_picmip); - - // jkrige - luma textures - Cvar_RegisterVariable (&gl_lumatex_render); - // jkrige - luma textures - - - // 3dfx can only handle 256 wide textures - if (!Q_strncasecmp ((char *)gl_renderer, "3dfx",4) || strstr((char *)gl_renderer, "Glide")) - Cvar_Set ("gl_max_size", "256"); - - //Cmd_AddCommand ("gl_texturemode", &Draw_TextureMode_f); // jkrige - texture mode - - // load the console background and the charset - // by hand, because we need to write the version - // string into the background before turning - // it into a texture - draw_chars = W_GetLumpName ("conchars"); - for (i=0 ; i<256*64 ; i++) - if (draw_chars[i] == 0) - draw_chars[i] = 255; // proper transparent color - - // now turn them into textures - - - // jkrige - external texture loading - //char_texture = GL_LoadTexture ("charset", 128, 128, draw_chars, false, true); - char_texture = GL_LoadTexture ("charset", "lump", 128, 128, draw_chars, false, true, 1); - // jkrige - external texture loading - - //glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - //glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - - start = Hunk_LowMark(); - - cb = (qpic_t *)COM_LoadTempFile ("gfx/conback.lmp"); - if (!cb) - Sys_Error ("Couldn't load gfx/conback.lmp"); - SwapPic (cb); - - // jkrige - print version info to the console - // hack the version number directly into the pic -/*#if defined(__linux__) - sprintf (ver, "(Linux %2.2f, gl %4.2f) %4.2f", (float)LINUX_VERSION, (float)GLQUAKE_VERSION, (float)VERSION); -#else - sprintf (ver, "(gl %4.2f) %4.2f", (float)GLQUAKE_VERSION, (float)VERSION); -#endif - dest = cb->data + 320*186 + 320 - 11 - 8*strlen(ver); - y = strlen(ver); - for (x=0 ; xwidth = vid.conwidth; - conback->height = vid.conheight; - - // scale console to vid size - dest = ncdata = Hunk_AllocName(vid.conwidth * vid.conheight, "conback"); - - for (y=0 ; ydata + cb->width * (y*cb->height/vid.conheight); - if (vid.conwidth == cb->width) - memcpy (dest, src, vid.conwidth); - else - { - f = 0; - fstep = cb->width*0x10000/vid.conwidth; - for (x=0 ; x>16]; - f += fstep; - dest[x+1] = src[f>>16]; - f += fstep; - dest[x+2] = src[f>>16]; - f += fstep; - dest[x+3] = src[f>>16]; - f += fstep; - } - } - } -#else - conback->width = cb->width; - conback->height = cb->height; - ncdata = cb->data; -#endif - - gl = (glpic_t *)conback->data; - - // jkrige - external texture loading - //gl->texnum = GL_LoadTexture ("conback", conback->width, conback->height, ncdata, false, false); - gl->texnum = GL_LoadTexture ("conback", "lump", conback->width, conback->height, ncdata, false, false, 1); - // jkrige - external texture loading - -#ifdef UQ_GLDEBUG - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); -#endif // UQ_GLDEBUG - gl->sl = 0; - gl->sh = 1; - gl->tl = 0; - gl->th = 1; - conback->width = vid.width; - conback->height = vid.height; - - // free loaded console - Hunk_FreeToLowMark(start); - - // save a texture slot for translated picture - translate_texture = texture_extension_number++; - - // save slots for scraps - scrap_texnum = texture_extension_number; - texture_extension_number += MAX_SCRAPS; - - // - // get the other pics we need - // - draw_disc = Draw_PicFromWad ("disc"); - draw_backtile = Draw_PicFromWad ("backtile"); -} - - - -/* -================ -Draw_Character - -Draws one 8*8 graphics character with 0 being transparent. -It can be clipped to the top of the screen to allow the console to be -smoothly scrolled off. -================ -*/ -void Draw_Character (int x, int y, int num) -{ -#ifdef UQ_GLDEBUG - byte *dest; - byte *source; - unsigned short *pusdest; - int drawline; - int row, col; - float frow, fcol, size; - - if (num == 32) - return; // space - - num &= 255; - - if (y <= -8) - return; // totally off screen - - row = num>>4; - col = num&15; - - frow = row*0.0625; - fcol = col*0.0625; - size = 0.0625; - - GL_Bind (char_texture); - - glBegin (GL_QUADS); - glTexCoord2f (fcol, frow); - glVertex2f (x, y); - glTexCoord2f (fcol + size, frow); - glVertex2f (x+8, y); - glTexCoord2f (fcol + size, frow + size); - glVertex2f (x+8, y+8); - glTexCoord2f (fcol, frow + size); - glVertex2f (x, y+8); - glEnd (); -#endif // UQ_GLDEBUG -} - -/* -================ -Draw_String -================ -*/ -void Draw_String (int x, int y, char *str) -{ - while (*str) - { - Draw_Character (x, y, *str); - str++; - x += 8; - } -} - -/* -================ -Draw_DebugChar - -Draws a single character directly to the upper right corner of the screen. -This is for debugging lockups by drawing different chars in different parts -of the code. -================ -*/ -void Draw_DebugChar (char num) -{ -} - -/* -============= -Draw_AlphaPic -============= -*/ -void Draw_AlphaPic (int x, int y, qpic_t *pic, float alpha) -{ -#ifdef UQ_GLDEBUG - byte *dest, *source; - unsigned short *pusdest; - int v, u; - glpic_t *gl; - - if (scrap_dirty) - Scrap_Upload (); - gl = (glpic_t *)pic->data; - glDisable(GL_ALPHA_TEST); - glEnable (GL_BLEND); -// glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); -// glCullFace(GL_FRONT); - glColor4f (1,1,1,alpha); - GL_Bind (gl->texnum); - glBegin (GL_QUADS); - glTexCoord2f (gl->sl, gl->tl); - glVertex2f (x, y); - glTexCoord2f (gl->sh, gl->tl); - glVertex2f (x+pic->width, y); - glTexCoord2f (gl->sh, gl->th); - glVertex2f (x+pic->width, y+pic->height); - glTexCoord2f (gl->sl, gl->th); - glVertex2f (x, y+pic->height); - glEnd (); - glColor4f (1,1,1,1); - glEnable(GL_ALPHA_TEST); - glDisable (GL_BLEND); -#endif -} - - -/* -============= -Draw_Pic -============= -*/ -void Draw_Pic (int x, int y, qpic_t *pic) -{ -#ifdef UQ_GLDEBUG - byte *dest, *source; - unsigned short *pusdest; - int v, u; - glpic_t *gl; - - if (scrap_dirty) - Scrap_Upload (); - gl = (glpic_t *)pic->data; - glColor4f (1,1,1,1); - GL_Bind (gl->texnum); - glBegin (GL_QUADS); - glTexCoord2f (gl->sl, gl->tl); - glVertex2f (x, y); - glTexCoord2f (gl->sh, gl->tl); - glVertex2f (x+pic->width, y); - glTexCoord2f (gl->sh, gl->th); - glVertex2f (x+pic->width, y+pic->height); - glTexCoord2f (gl->sl, gl->th); - glVertex2f (x, y+pic->height); - glEnd (); -#endif -} - - -/* -============= -Draw_TransPic -============= -*/ -void Draw_TransPic (int x, int y, qpic_t *pic) -{ - byte *dest, *source, tbyte; - unsigned short *pusdest; - int v, u; - - if (x < 0 || (unsigned)(x + pic->width) > vid.width || y < 0 || (unsigned)(y + pic->height) > vid.height) - { - Sys_Error ("Draw_TransPic: bad coordinates"); - } - - Draw_Pic (x, y, pic); -} - - -/* -============= -Draw_TransPicTranslate - -Only used for the player color selection menu -============= -*/ -void Draw_TransPicTranslate (int x, int y, qpic_t *pic, byte *translation) -{ -#ifdef UQ_GLDEBUG - int v, u, c; - unsigned trans[64*64], *dest; - byte *src; - int p; - - GL_Bind (translate_texture); - - c = pic->width * pic->height; - - dest = trans; - for (v=0 ; v<64 ; v++, dest += 64) - { - src = &menuplyr_pixels[ ((v*pic->height)>>6) *pic->width]; - for (u=0 ; u<64 ; u++) - { - p = src[(u*pic->width)>>6]; - if (p == 255) - dest[u] = p; - else - dest[u] = d_8to24table[translation[p]]; - } - } - - glTexImage2D (GL_TEXTURE_2D, 0, gl_alpha_format, 64, 64, 0, GL_RGBA, GL_UNSIGNED_BYTE, trans); - - // jkrige - use "point sampled" texture mode - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - // jkrige - use "point sampled" texture mode - - glColor3f (1,1,1); - glBegin (GL_QUADS); - glTexCoord2f (0, 0); - glVertex2f (x, y); - glTexCoord2f (1, 0); - glVertex2f (x+pic->width, y); - glTexCoord2f (1, 1); - glVertex2f (x+pic->width, y+pic->height); - glTexCoord2f (0, 1); - glVertex2f (x, y+pic->height); - glEnd (); -#endif // UQ_GLDEBUG -} - -// jkrige - print version info to the console -void Console_Print (int cx, int cy, char *str) -{ - while (*str) - { - Draw_Character (cx, cy, ((unsigned char)(*str))+256); - str++; - cx += 8; - } -} -// jkrige - print version info to the console - -/* -================ -Draw_ConsoleBackground - -================ -*/ -void Draw_ConsoleBackground (int lines) -{ - // jkrige - removed alpha console background - //int y = (vid.height * 3) >> 2; - // jkrige - removed alpha console background - - - // jkrige - print version info to the console - int ver_x, ver_y; - char engineversion[32]; - sprintf(engineversion, "UQE Quake %.2f", QUAKE_VERSION); - ver_x = (int)vid.width - (strlen(engineversion)*8) /*- 8*/; - ver_y = (int)vid.height - 8; //- 16; - // jkrige - print version info to the console - - - // jkrige - removed alpha console background - //if (lines > y) - // Draw_Pic(0, lines - vid.height, conback); - //else - // Draw_AlphaPic (0, lines - vid.height, conback, (float)(1.2 * lines)/y); - Draw_Pic(0, lines - vid.height, conback); - // jkrige - removed alpha console background - - - // jkrige - print version info to the console - Console_Print(ver_x, lines - (int)vid.height + ver_y, engineversion); - // jkrige - print version info to the console -} - - -/* -============= -Draw_TileClear - -This repeats a 64*64 tile graphic to fill the screen around a sized down -refresh window. -============= -*/ -void Draw_TileClear (int x, int y, int w, int h) -{ -#ifdef UQ_GLDEBUG - glColor3f (1,1,1); - GL_Bind (*(int *)draw_backtile->data); - glBegin (GL_QUADS); - glTexCoord2f (x/64.0, y/64.0); - glVertex2f (x, y); - glTexCoord2f ( (x+w)/64.0, y/64.0); - glVertex2f (x+w, y); - glTexCoord2f ( (x+w)/64.0, (y+h)/64.0); - glVertex2f (x+w, y+h); - glTexCoord2f ( x/64.0, (y+h)/64.0 ); - glVertex2f (x, y+h); - glEnd (); -#endif // UQ_GLDEBUG -} - - -/* -============= -Draw_Fill - -Fills a box of pixels with a single color -============= -*/ -void Draw_Fill (int x, int y, int w, int h, int c) -{ -#ifdef UQ_GLDEBUG - glDisable (GL_TEXTURE_2D); - glColor3f (host_basepal[c*3]/255.0, - host_basepal[c*3+1]/255.0, - host_basepal[c*3+2]/255.0); - - glBegin (GL_QUADS); - - glVertex2f (x,y); - glVertex2f (x+w, y); - glVertex2f (x+w, y+h); - glVertex2f (x, y+h); - - glEnd (); - glColor3f (1,1,1); - glEnable (GL_TEXTURE_2D); -#endif -} -//============================================================================= - -/* -================ -Draw_FadeScreen - -================ -*/ -void Draw_FadeScreen (void) -{ -#ifdef UQ_GLDEBUG - glEnable (GL_BLEND); - glDisable (GL_TEXTURE_2D); - glColor4f (0, 0, 0, 0.8); - glBegin (GL_QUADS); - - glVertex2f (0,0); - glVertex2f (vid.width, 0); - glVertex2f (vid.width, vid.height); - glVertex2f (0, vid.height); - - glEnd (); - glColor4f (1,1,1,1); - glEnable (GL_TEXTURE_2D); - glDisable (GL_BLEND); - - //Sbar_Changed(); // jkrige - always draw sbar -#endif -} - -//============================================================================= - -/* -================ -Draw_BeginDisc - -Draws the little blue disc in the corner of the screen. -Call before beginning any disc IO. -================ -*/ -void Draw_BeginDisc (void) -{ -#ifdef UQ_GLDEBUG - if (!draw_disc) - return; - glDrawBuffer (GL_FRONT); - Draw_Pic (vid.width - 24, 0, draw_disc); - glDrawBuffer (GL_BACK); -#endif -} - - -/* -================ -Draw_EndDisc - -Erases the disc icon. -Call after completing any disc IO -================ -*/ -void Draw_EndDisc (void) -{ -} - -/* -================ -GL_Set2D - -Setup as if the screen was 320*200 -================ -*/ -void GL_Set2D (void) -{ -#ifdef UQ_GLDEBUG - glViewport (glx, gly, glwidth, glheight); - - glMatrixMode(GL_PROJECTION); - glLoadIdentity (); - glOrtho (0, vid.width, vid.height, 0, -99999, 99999); - - glMatrixMode(GL_MODELVIEW); - glLoadIdentity (); - - glDisable (GL_DEPTH_TEST); - glDisable (GL_CULL_FACE); - glDisable (GL_BLEND); - glEnable (GL_ALPHA_TEST); -// glDisable (GL_ALPHA_TEST); - - glColor4f (1,1,1,1); -#endif -} - -//==================================================================== - -/* -================ -GL_FindTexture -================ -*/ -int GL_FindTexture (char *identifier) -{ - int i; - gltexture_t *glt; - - for (i=0, glt=gltextures ; iidentifier)) - return gltextures[i].texnum; - } - - return -1; -} - -/* -================ -GL_ResampleTexture -================ -*/ -void GL_ResampleTexture (unsigned *in, int inwidth, int inheight, unsigned *out, int outwidth, int outheight) -{ - int i, j; - unsigned *inrow; - unsigned frac, fracstep; - - fracstep = inwidth*0x10000/outwidth; - for (i=0 ; i> 1; - for (j=0 ; j>16]; - frac += fracstep; - out[j+1] = inrow[frac>>16]; - frac += fracstep; - out[j+2] = inrow[frac>>16]; - frac += fracstep; - out[j+3] = inrow[frac>>16]; - frac += fracstep; - } - } -} - -/* -================ -GL_Resample8BitTexture -- JACK -================ -*/ -void GL_Resample8BitTexture (unsigned char *in, int inwidth, int inheight, unsigned char *out, int outwidth, int outheight) -{ - int i, j; - unsigned char *inrow; - unsigned frac, fracstep; - - fracstep = inwidth*0x10000/outwidth; - for (i=0 ; i> 1; - for (j=0 ; j>16]; - frac += fracstep; - out[j+1] = inrow[frac>>16]; - frac += fracstep; - out[j+2] = inrow[frac>>16]; - frac += fracstep; - out[j+3] = inrow[frac>>16]; - frac += fracstep; - } - } -} - - -/* -================ -GL_MipMap - -Operates in place, quartering the size of the texture -================ -*/ -void GL_MipMap (byte *in, int width, int height) -{ - int i, j; - byte *out; - - width <<=2; - height >>= 1; - out = in; - for (i=0 ; i>2; - out[1] = (in[1] + in[5] + in[width+1] + in[width+5])>>2; - out[2] = (in[2] + in[6] + in[width+2] + in[width+6])>>2; - out[3] = (in[3] + in[7] + in[width+3] + in[width+7])>>2; - } - } -} - -/* -================ -GL_MipMap8Bit - -Mipping for 8 bit textures -================ -*/ -void GL_MipMap8Bit (byte *in, int width, int height) -{ - int i, j; - unsigned short r,g,b; - byte *out, *at1, *at2, *at3, *at4; - -// width <<=2; - height >>= 1; - out = in; - for (i=0 ; i>=5; - g = (at1[1]+at2[1]+at3[1]+at4[1]); g>>=5; - b = (at1[2]+at2[2]+at3[2]+at4[2]); b>>=5; - - out[0] = d_15to8table[(r<<0) + (g<<5) + (b<<10)]; - } - } -} - -/* -=============== -GL_Upload32 -=============== -*/ -void GL_Upload32 (unsigned *data, int width, int height, qboolean mipmap, qboolean alpha) -{ -#ifdef UQ_GLDEBUG - int samples; - - // jkrige - doubled textures - //static unsigned scaled[1024 * 512]; // [512*256]; - static unsigned scaled[2048 * 2048]; - // jkrige - doubled textures - - int scaled_width, scaled_height; - - // jkrige - anisotropic filtering - int i = 3; - int AnisotropyModes = 0; - // jkrige - anisotropic filtering - - // jkrige - non power of two - //for (scaled_width = 1 ; scaled_width < width ; scaled_width<<=1); - //for (scaled_height = 1 ; scaled_height < height ; scaled_height<<=1); - if(npow2_ext == true && gl_texture_non_power_of_two.value == 1.0f /*&& !mipmap*/) - { - scaled_width = width; - scaled_height = height; - } - else - { - for (scaled_width = 1 ; scaled_width < width ; scaled_width<<=1); - for (scaled_height = 1 ; scaled_height < height ; scaled_height<<=1); - } - // jkrige - non power of two - - if ((scaled_width >> (int)gl_picmip.value) && (scaled_height >> (int)gl_picmip.value)) - { - scaled_width >>= (int)gl_picmip.value; - scaled_height >>= (int)gl_picmip.value; - } - //scaled_width >>= (int)gl_picmip.value; - //scaled_height >>= (int)gl_picmip.value; - - if (scaled_width > gl_max_size.value) - scaled_width = gl_max_size.value; - - if (scaled_height > gl_max_size.value) - scaled_height = gl_max_size.value; - - if (scaled_width * scaled_height > sizeof(scaled)/4) - Sys_Error ("GL_LoadTexture: too big"); - - samples = alpha ? gl_alpha_format : gl_solid_format; - -#if 0 - if (mipmap) - gluBuild2DMipmaps (GL_TEXTURE_2D, samples, width, height, GL_RGBA, GL_UNSIGNED_BYTE, trans); - else if (scaled_width == width && scaled_height == height) - glTexImage2D (GL_TEXTURE_2D, 0, samples, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, trans); - else - { - gluScaleImage (GL_RGBA, width, height, GL_UNSIGNED_BYTE, trans, - scaled_width, scaled_height, GL_UNSIGNED_BYTE, scaled); - glTexImage2D (GL_TEXTURE_2D, 0, samples, scaled_width, scaled_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, scaled); - } -#else -texels += scaled_width * scaled_height; - - if (scaled_width == width && scaled_height == height) - { - if (!mipmap) - { - glTexImage2D (GL_TEXTURE_2D, 0, samples, scaled_width, scaled_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data); - goto done; - } - memcpy (scaled, data, width*height*4); - } - else - GL_ResampleTexture (data, width, height, scaled, scaled_width, scaled_height); - - glTexImage2D (GL_TEXTURE_2D, 0, samples, scaled_width, scaled_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, scaled); - if (mipmap) - { - int miplevel; - - miplevel = 0; - while (scaled_width > 1 || scaled_height > 1) - { - GL_MipMap ((byte *)scaled, scaled_width, scaled_height); - - - // jkrige - non power of two - scaled_width >>= 1; - scaled_height >>= 1; - /*if(npow2_ext == true && gl_texture_non_power_of_two.value == 1.0f && !mipmap) - { - scaled_width = (int)floor (width / pow(2, miplevel+1)); - scaled_height = (int)floor (height / pow (2, miplevel+1)); - } - else - { - scaled_width >>= 1; - scaled_height >>= 1; - }*/ - // jkrige - non power of two - - - if (scaled_width < 1) - scaled_width = 1; - if (scaled_height < 1) - scaled_height = 1; - miplevel++; - glTexImage2D (GL_TEXTURE_2D, miplevel, samples, scaled_width, scaled_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, scaled); - } - } -done: ; -#endif - - // jkrige - anisotropic filtering - if (mipmap) - { - // jkrige - texture modes - if(floor(gl_texturemode.value) < 0.0f | gl_texturemode.value != floor(gl_texturemode.value)) - { - Con_Printf ("unknown texture mode\n"); - Cvar_Set ("gl_texturemode", "2"); - } - - if(gl_texturemode.value == 0.0f) - i = 0; - - if(gl_texturemode.value == 1.0f) - i = 3; - - if(gl_texturemode.value >= 2.0f) - i = 5; - - if(anisotropic_ext == true) - AnisotropyModes = (int)floor((log(maximumAnisotrophy)/log(2.0f)) + 0.5f); - else - AnisotropyModes = 0; - - if(anisotropic_ext == false) - { - if (gl_texturemode.value > 2.0f) - { - Con_Printf ("unknown texture mode\n"); - Cvar_Set ("gl_texturemode", "2"); - - return; - } - } - - if(anisotropic_ext == true) - { - if (gl_texturemode.value > (2.0f + (float)AnisotropyModes)) - { - Con_Printf ("unknown texture mode\n"); - Cvar_SetValue ("gl_texturemode", (2.0f + (float)AnisotropyModes)); - - return; - } - } - - gl_filter_min = modes[i].minimize; - gl_filter_max = modes[i].maximize; - - if(gl_texturemode.value <= 2.0f) - { - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_filter_min); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filter_max); - if(anisotropic_ext == true) - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1.0f); - } - - // jkrige - anisotropic filtering - if(gl_texturemode.value > 2.0f && anisotropic_ext == true) - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, pow(2.0f, gl_texturemode.value - 2.0f)); - // jkrige - anisotropic filtering - - // jkrige - texture modes - - - /* - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_filter_min); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filter_max); - - // jkrige - anisotropic filtering - for (i = 0; i < 6; i++) - { - if (gl_filter_min == modes[i].minimize) - break; - } - - if(i == 5 && anisotropic_ext == true) - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, maximumAnisotrophy); - // jkrige - anisotropic filtering - */ - } - else - { - // jkrige - scale2d - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - // jkrige - scale2d - - //glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR /*gl_filter_max*/); // jkrige - change bilinear texture filtering to trilinear texture filtering - //glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR /*gl_filter_max*/); // jkrige - change bilinear texture filtering to trilinear texture filtering - } - // jkrige - anisotropic filtering - - /*if (mipmap) - { - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_filter_min); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filter_max); - } - else - { - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_filter_max); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filter_max); - }*/ -#endif // UQ_GLDEBUG -} - - -// jkrige - no 8bit palette extensions -/*void GL_Upload8_EXT (byte *data, int width, int height, qboolean mipmap, qboolean alpha) -{ - int i, s; - qboolean noalpha; - int p; - static unsigned j; - int samples; - static unsigned char scaled[1024*512]; // [512*256]; - int scaled_width, scaled_height; - - s = width*height; - // if there are no transparent pixels, make it a 3 component - // texture even if it was specified as otherwise - if (alpha) - { - noalpha = true; - for (i=0 ; i>= (int)gl_picmip.value; - scaled_height >>= (int)gl_picmip.value; - - if (scaled_width > gl_max_size.value) - scaled_width = gl_max_size.value; - if (scaled_height > gl_max_size.value) - scaled_height = gl_max_size.value; - - if (scaled_width * scaled_height > sizeof(scaled)) - Sys_Error ("GL_LoadTexture: too big"); - - samples = 1; // alpha ? gl_alpha_format : gl_solid_format; - - texels += scaled_width * scaled_height; - - if (scaled_width == width && scaled_height == height) - { - if (!mipmap) - { - glTexImage2D (GL_TEXTURE_2D, 0, GL_COLOR_INDEX8_EXT, scaled_width, scaled_height, 0, GL_COLOR_INDEX , GL_UNSIGNED_BYTE, data); - goto done; - } - memcpy (scaled, data, width*height); - } - else - GL_Resample8BitTexture (data, width, height, scaled, scaled_width, scaled_height); - - glTexImage2D (GL_TEXTURE_2D, 0, GL_COLOR_INDEX8_EXT, scaled_width, scaled_height, 0, GL_COLOR_INDEX, GL_UNSIGNED_BYTE, scaled); - if (mipmap) - { - int miplevel; - - miplevel = 0; - while (scaled_width > 1 || scaled_height > 1) - { - GL_MipMap8Bit ((byte *)scaled, scaled_width, scaled_height); - scaled_width >>= 1; - scaled_height >>= 1; - if (scaled_width < 1) - scaled_width = 1; - if (scaled_height < 1) - scaled_height = 1; - miplevel++; - glTexImage2D (GL_TEXTURE_2D, miplevel, GL_COLOR_INDEX8_EXT, scaled_width, scaled_height, 0, GL_COLOR_INDEX, GL_UNSIGNED_BYTE, scaled); - } - } -done: ; - - - if (mipmap) - { - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_filter_min); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filter_max); - } - else - { - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_filter_max); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filter_max); - } -}*/ -// jkrige - no 8bit palette extensions - -// jkrige - doubled textures -//static unsigned trans[640 * 480]; // jkrige - FIXME, temporary -static unsigned trans[2048 * 2048]; -// jkrige - doubled textures - -/* -=============== -GL_Upload8 -=============== -*/ -void GL_Upload8 (byte *data, int width, int height, qboolean mipmap, qboolean alpha) -{ - int i, s; - qboolean noalpha; - int p; - //static unsigned trans[640*480]; // FIXME, temporary - - - // jkrige - doubled textures - byte *dtdata; - int x, y; - - if (mipmap) - { - width *= 2; - height *= 2; - - s = width * height; - dtdata = malloc(s); - - for (y = 0; y < height / 2; y++) - { - for (x = 0; x < width / 2; x++) - { - dtdata[(y * (width * 2)) + (x * 2) + 0] = data[(y * (width / 2)) + x]; - dtdata[(y * (width * 2)) + (x * 2) + 1] = data[(y * (width / 2)) + x]; - - dtdata[(y * (width * 2)) + (x * 2) + 0 + width] = data[(y * (width / 2)) + x]; - dtdata[(y * (width * 2)) + (x * 2) + 1 + width] = data[(y * (width / 2)) + x]; - } - } - } - else - { - s = width * height; - dtdata = data; - } - //s = width * height; - // jkrige - doubled textures - - - // if there are no transparent pixels, make it a 3 component - // texture even if it was specified as otherwise - if (alpha) - { - noalpha = true; - for (i=0 ; iidentifier)) - { - if (width != glt->width || height != glt->height) - Sys_Error ("GL_LoadTexture: cache mismatch"); - return gltextures[i].texnum; - } - } - } - //else { // jkrige - threewave? - glt = &gltextures[numgltextures]; - numgltextures++; - //} - - strcpy (glt->identifier, identifier); - glt->texnum = texture_extension_number; - glt->width = width; - glt->height = height; - glt->mipmap = mipmap; - - GL_Bind(texture_extension_number ); - - GL_Upload8 (data, width, height, mipmap, alpha); - - texture_extension_number++; - - return texture_extension_number-1; -}*/ - -int lhcsumtable[256]; -int GL_LoadTexture (char *identifier, char *textype, int width, int height, byte *data, qboolean mipmap, qboolean alpha, int bytesperpixel) -{ -#ifdef UQ_GLDEBUG - //qboolean noalpha; - int i, /*p,*/ s, lhcsum; - gltexture_t *glt; - - - // jkrige - fullbright pixels - byte *data2 = data; - // jkrige - fullbright pixels - - - // occurances. well this isn't exactly a checksum, it's better than that but - // not following any standards. - lhcsum = 0; - s = width*height*bytesperpixel; - //s = width*height; - for (i = 0;i < 256;i++) lhcsumtable[i] = i + 1; - for (i = 0;i < s;i++) lhcsum += (lhcsumtable[data[i] & 255]++); - - // see if the texture is allready present - if (identifier[0]) - { - for (i=0, glt=gltextures ; i < numgltextures ; i++, glt++) - { - if (!strcmp (identifier, glt->identifier)) - { - if (lhcsum != glt->lhcsum || width != glt->width || height != glt->height) - { - Con_DPrintf("GL_LoadTexture: cache mismatch\n"); - goto GL_LoadTexture_setup; - } - return glt->texnum; - } - } - } - // whoever at id or threewave must've been half asleep... - glt = &gltextures[numgltextures]; - numgltextures++; - - strcpy (glt->identifier, identifier); - glt->texnum = texture_extension_number; - texture_extension_number++; - - GL_LoadTexture_setup: - glt->lhcsum = lhcsum; - glt->width = width; - glt->height = height; - glt->mipmap = mipmap; - - // jkrige - luma textures (reset) - glt->tex_luma = false; - glt->tex_luma8bit = false; - // jkrige - luma textures (reset) - - if (!isDedicated) - { - GL_Bind(glt->texnum); - - //if (strcmp (textype, "bloom")) - { - if (bytesperpixel == 1) - { - GL_Upload8 (data, width, height, mipmap, alpha); - } - else if (bytesperpixel == 3 | bytesperpixel == 4) - { - if(image_alpha == 3) - GL_Upload32 ((void *)data, width, height, mipmap, false); - else - GL_Upload32 ((void *)data, width, height, mipmap, true); - } - else - Sys_Error("GL_LoadTexture: unknown bytes per pixel\n"); - } - - // jkrige - reset external image - image_width = 0; - image_height = 0; - image_bits = 8; - image_alpha = 3; - // jkrige - reset external image - - - // jkrige - luma textures - if (!strcmp (textype, "texture")) - { - char *ch_dot = strrchr(identifier, '.'); - - if (ch_dot != NULL) - { - char *ident; - char ch_name[MAX_PATH]; - byte *lumadata; - - i = 0; - ident = identifier; - - while (*identifier && *identifier != '.') - ch_name[i++] = *identifier++; - ch_name[i++] = 0; - - strcat(ch_name, "_luma"); - strcat(ch_name, ch_dot); - identifier = ident; - - if ((lumadata = LoadImagePixels (ch_name, false))) - { - GL_Bind(JK_LUMA_TEX + glt->texnum); - GL_Upload32((unsigned int *)lumadata, width, height, mipmap, true); - free(lumadata); - - glt->tex_luma = true; - } - } - } - // jkrige - luma textures - - - // jkrige - fullbright pixels - if ((!strcmp(textype, "texture") || !strcmp(textype, "skin")) && bytesperpixel == 1) - { - // if fullbright pixels are detected a new texture will - // be generated and it will be used asif its a luma texture - qboolean fullbright; - byte *fbdata; - - fbdata = malloc(width * height * 4); - - if (GL_FullbrightTexture(data, fbdata, width, height) == true) - { - GL_Bind(JK_LUMA_TEX + glt->texnum); - GL_Upload32((unsigned int *)fbdata, width, height, mipmap, alpha); - - glt->tex_luma = true; - glt->tex_luma8bit = true; - } - - if (fbdata) - free(fbdata); - } - // jkrige - fullbright pixels - - - glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); - } - - return glt->texnum; -#endif // UQ_GLDEBUG -} -// jkrige - memleak & texture mismatch - -/* -================ -GL_LoadPicTexture -================ -*/ -int GL_LoadPicTexture (qpic_t *pic) -{ - int i; - - // jkrige - external texture loading - //i = GL_LoadTexture ("", pic->width, pic->height, pic->data, false, true); - i = GL_LoadTexture ("", "", pic->width, pic->height, pic->data, false, true, 1); - // jkrige - external texture loading - - // jkrige - scale2d - //glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - //glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - // jkrige - scale2d - - return i; -} - - - - -// jkrige - external texture loading -int image_width; -int image_height; -int image_bits; -int image_alpha; - -byte Convert24to8(byte *palette, byte Red, byte Green, byte Blue) -{ - int i; - - for(i=0; i<768; i+=3) - { - if(palette[i] == Red && palette[i+1] == Green && palette[i+2] == Blue) - return 255-(i/3); - } - - return 0; -} - -/* -======== -LoadJPG -======== -*/ -byte *LoadJPG ( const char *filename) -{ - /* This struct contains the JPEG decompression parameters and pointers to - * working space (which is allocated as needed by the JPEG library). - */ - struct jpeg_decompress_struct cinfo; - /* We use our private extension JPEG error handler. - * Note that this struct must live as long as the main JPEG parameter - * struct, to avoid dangling-pointer problems. - */ - /* This struct represents a JPEG error handler. It is declared separately - * because applications often want to supply a specialized error handler - * (see the second half of this file for an example). But here we just - * take the easy way out and use the standard error handler, which will - * print a message on stderr and call exit() if compression fails. - * Note that this struct must live as long as the main JPEG parameter - * struct, to avoid dangling-pointer problems. - */ - struct jpeg_error_mgr jerr; - /* More stuff */ - JSAMPARRAY buffer; /* Output row buffer */ - int row_stride; /* physical row width in output buffer */ - unsigned char *out; - byte *fbuffer; - byte *bbuf; - - /* In this example we want to open the input file before doing anything else, - * so that the setjmp() error recovery below can assume the file is open. - * VERY IMPORTANT: use "b" option to fopen() if you are on a machine that - * requires it in order to read binary files. - */ - - - // jkrige - pk3 file support - int len; - FILE *f; - byte *pic; - - // - // load the file - // - len = COM_FOpenFile (( char * )filename, &f); - if(len < 1) - return NULL; - - fbuffer = COM_FReadFile(f, len); - if (!fbuffer) - return NULL; - - pic = NULL; - // jkrige - pk3 file support - - - /* Step 1: allocate and initialize JPEG decompression object */ - - /* We have to set up the error handler first, in case the initialization - * step fails. (Unlikely, but it could happen if you are out of memory.) - * This routine fills in the contents of struct jerr, and returns jerr's - * address which we place into the link field in cinfo. - */ - cinfo.err = jpeg_std_error(&jerr); - - /* Now we can initialize the JPEG decompression object. */ - jpeg_create_decompress(&cinfo); - - /* Step 2: specify data source (eg, a file) */ - - jpeg_stdio_src(&cinfo, fbuffer); - - /* Step 3: read file parameters with jpeg_read_header() */ - - (void) jpeg_read_header(&cinfo, TRUE); - /* We can ignore the return value from jpeg_read_header since - * (a) suspension is not possible with the stdio data source, and - * (b) we passed TRUE to reject a tables-only JPEG file as an error. - * See libjpeg.doc for more info. - */ - - /* Step 4: set parameters for decompression */ - - /* In this example, we don't need to change any of the defaults set by - * jpeg_read_header(), so we do nothing here. - */ - - /* Step 5: Start decompressor */ - - (void) jpeg_start_decompress(&cinfo); - /* We can ignore the return value since suspension is not possible - * with the stdio data source. - */ - - /* We may need to do some setup of our own at this point before reading - * the data. After jpeg_start_decompress() we have the correct scaled - * output image dimensions available, as well as the output colormap - * if we asked for color quantization. - * In this example, we need to make an output work buffer of the right size. - */ - /* JSAMPLEs per row in output buffer */ - row_stride = cinfo.output_width * cinfo.output_components; - - out = malloc(cinfo.output_width*cinfo.output_height*cinfo.output_components); - - // jkrige - // *pic = out; - // *width = cinfo.output_width; - // *height = cinfo.output_height; - pic = out; - image_width = cinfo.image_width; - image_height = cinfo.image_height; - // jkrige - - /* Step 6: while (scan lines remain to be read) */ - /* jpeg_read_scanlines(...); */ - - /* Here we use the library's state variable cinfo.output_scanline as the - * loop counter, so that we don't have to keep track ourselves. - */ - while (cinfo.output_scanline < cinfo.output_height) - { - /* jpeg_read_scanlines expects an array of pointers to scanlines. - * Here the array is only one element long, but you could ask for - * more than one scanline at a time if that's more convenient. - */ - bbuf = ((out+(row_stride*cinfo.output_scanline))); - buffer = &bbuf; - (void) jpeg_read_scanlines(&cinfo, buffer, 1); - } - - // clear all the alphas to 255 - { - int i, j; - byte *buf; - - buf = pic; - - j = cinfo.output_width * cinfo.output_height * 4; - for ( i = 3 ; i < j ; i+=4 ) - { - buf[i] = 255; - } - } - - /* Step 7: Finish decompression */ - - (void) jpeg_finish_decompress(&cinfo); - /* We can ignore the return value since suspension is not possible - * with the stdio data source. - */ - - /* Step 8: Release JPEG decompression object */ - - /* This is an important step since it will release a good deal of memory. */ - jpeg_destroy_decompress(&cinfo); - - /* After finish_decompress, we can close the input file. - * Here we postpone it until after no more JPEG errors are possible, - * so as to simplify the setjmp error logic above. (Actually, I don't - * think that jpeg_destroy can do an error exit, but why assume anything...) - */ - - image_bits = 32; - image_alpha = 3; - - free (fbuffer); - - /* At this point you may want to check to see whether any corrupt-data - * warnings occurred (test whether jerr.pub.num_warnings is nonzero). - */ - - /* And we're done! */ - return pic; -} - - -/* -============= -TARGA LOADING -============= -*/ - -typedef struct _TargaHeader -{ - unsigned char id_length, colormap_type, image_type; - unsigned short colormap_index, colormap_length; - unsigned char colormap_size; - unsigned short x_origin, y_origin, width, height; - unsigned char pixel_size, attributes; -} TargaHeader; - - -TargaHeader targa_header; - -int fgetLittleShort (FILE *f) -{ - byte b1, b2; - - b1 = fgetc(f); - b2 = fgetc(f); - - return (short)(b1 + b2*256); -} - -int fgetLittleLong (FILE *f) -{ - byte b1, b2, b3, b4; - - b1 = fgetc(f); - b2 = fgetc(f); - b3 = fgetc(f); - b4 = fgetc(f); - - return b1 + (b2<<8) + (b3<<16) + (b4<<24); -} - - -/* -======== -LoadTGA -======== -*/ -byte *LoadTGA ( const char *name) -{ - int columns, rows, numPixels; - byte *pixbuf; - int row, column; - byte *buf_p; - byte *buffer; - TargaHeader targa_header; - byte *targa_rgba; - - // jkrige - bitsperpixel check - int i; - // jkrige - bitsperpixel check - - - // jkrige - pk3 file support - int len; - FILE *f; - byte *pic; - // jkrige - pk3 file support - - - // *pic = NULL; // jkrige - pic = NULL; - buffer = NULL; - - // - // load the file - // - len = COM_FOpenFile (( char * )name, &f); - if(len < 1) - return NULL; - - buffer = COM_FReadFile(f, len); - - - if (!buffer) - return NULL; - - buf_p = buffer; - - targa_header.id_length = *buf_p++; - targa_header.colormap_type = *buf_p++; - targa_header.image_type = *buf_p++; - - targa_header.colormap_index = LittleShort ( *(short *)buf_p ); - buf_p += 2; - targa_header.colormap_length = LittleShort ( *(short *)buf_p ); - buf_p += 2; - targa_header.colormap_size = *buf_p++; - targa_header.x_origin = LittleShort ( *(short *)buf_p ); - buf_p += 2; - targa_header.y_origin = LittleShort ( *(short *)buf_p ); - buf_p += 2; - targa_header.width = LittleShort ( *(short *)buf_p ); - buf_p += 2; - targa_header.height = LittleShort ( *(short *)buf_p ); - buf_p += 2; - targa_header.pixel_size = *buf_p++; - targa_header.attributes = *buf_p++; - - if (targa_header.image_type!=2 && targa_header.image_type!=10 && targa_header.image_type != 3 ) - { - Sys_Error ("LoadTGA: Only type 2 (RGB), 3 (gray), and 10 (RGB) TGA images supported\n"); - } - - if ( targa_header.colormap_type != 0 ) - { - Sys_Error ("LoadTGA: colormaps not supported\n" ); - } - - if ( ( targa_header.pixel_size != 32 && targa_header.pixel_size != 24 ) && targa_header.image_type != 3 ) - { - Sys_Error ("LoadTGA: Only 32 or 24 bit images supported (no colormaps)\n"); - } - - columns = targa_header.width; - rows = targa_header.height; - numPixels = columns * rows; - - // jkrige - /*if (width) - *width = columns; - if (height) - *height = rows;*/ - image_width = columns; - image_height = rows; - // jkrige - - targa_rgba = malloc (numPixels*4); - // *pic = targa_rgba; // jkrige - pic = targa_rgba; - - if (targa_header.id_length != 0) - buf_p += targa_header.id_length; // skip TARGA image comment - - if ( targa_header.image_type == 2 || targa_header.image_type == 3 ) - { - // Uncompressed RGB or gray scale image - for(row=rows-1; row>=0; row--) - { - pixbuf = targa_rgba + row*columns*4; - for(column=0; column=0; row--) - { - pixbuf = targa_rgba + row*columns*4; - for(column=0; column0) - row--; - else - goto breakOut; - pixbuf = targa_rgba + row*columns*4; - } - } - } - else - { // non run-length packet - for(j=0;j0) - row--; - else - goto breakOut; - pixbuf = targa_rgba + row*columns*4; - } - } - } - } - breakOut:; - } - } - -//#if 0 - // TTimo: this is the chunk of code to ensure a behavior that meets TGA specs - // bk0101024 - fix from Leonardo - // bit 5 set => top-down - if (targa_header.attributes & 0x20) - { - unsigned char *flip = (unsigned char*)malloc (columns*4); - unsigned char *src, *dst; - - for (row = 0; row < rows/2; row++) - { - src = targa_rgba + row * 4 * columns; - dst = targa_rgba + (rows - row - 1) * 4 * columns; - - memcpy (flip, src, columns*4); - memcpy (src, dst, columns*4); - memcpy (dst, flip, columns*4); - } - free (flip); - } -//#endif - // instead we just print a warning - //if (targa_header.attributes & 0x20) - //{ - // Con_Printf("WARNING: '%s' TGA file header declares top-down image, ignoring\n", name); - //} - - - // jkrige - bitsperpixel check - image_bits = 32; - image_alpha = gl_solid_format; - for (i = 0;i < image_width*image_height;i++) - { - if (targa_rgba[i*4+3] < 255) - { - image_alpha = gl_alpha_format; - break; - } - } - // jkrige - bitsperpixel check - - - free (buffer); - - return pic; -} - -byte* LoadImagePixels (char* filename, qboolean complain) -{ - char basename[128], name[128]; - byte *data; - - COM_StripExtension(filename, basename); // strip the extension to allow more filetypes - - sprintf (name, "%s.tga", basename); - data = LoadTGA(name); - if(data) - return data; - - sprintf (name, "%s.jpg", basename); - data = LoadJPG(name); - if(data) - return data; - - if (complain) - Con_Printf ("Couldn't load %s\n", name); - - return NULL; -} - -int LoadTextureImage (char* filename, char *textype, int matchwidth, int matchheight, qboolean complain, qboolean mipmap) -{ - int texnum; - int i; - qboolean alpha; - byte *data; - - if (!(data = LoadImagePixels (filename, complain))) - return 0; - - if(image_alpha == 4) - alpha = true; - else - alpha = false; - - if(image_bits != 32) - texnum = GL_LoadTexture (filename, textype, image_width, image_height, data, mipmap, true, 1); - else - texnum = GL_LoadTexture (filename, textype, image_width, image_height, data, mipmap, alpha, image_alpha); - - if (data) - free(data); - - return texnum; -} -// jkrige - external texture loading - - - - - - - - -// jkrige - remove multitexture -/*static GLenum oldtarget = TEXTURE0_SGIS; - -void GL_SelectTexture (GLenum target) -{ - if (!gl_mtexable) - return; - qglSelectTextureSGIS(target); - if (target == oldtarget) - return; - cnttextures[oldtarget-TEXTURE0_SGIS] = currenttexture; - currenttexture = cnttextures[target-TEXTURE0_SGIS]; - oldtarget = target; -}*/ -// jkrige - remove multitexture \ No newline at end of file diff --git a/engine/code/gl_fullbright.c b/engine/code/gl_fullbright.c deleted file mode 100644 index 1797018..0000000 --- a/engine/code/gl_fullbright.c +++ /dev/null @@ -1,88 +0,0 @@ -/* -Copyright (C) 1996-1997 Id Software, Inc. - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ -// gl_fullbright.c: fullbright pixel processing - -// Developed by Jacques Krige -// Ultimate Quake Engine -// http://www.jacqueskrige.com - - -#include "quakedef.h" - - -qboolean GL_FullbrightTexture (byte *in, byte *out, int width, int height) -{ - int i, j; - int p; - int numpixels; - qboolean fbtex; - - numpixels = width * height; - fbtex = false; - - // check if this texture has fullbrights - for (i = 0; i < numpixels; i++) - { - p = in[i]; - - if (p > 238 && p != 255) - { - fbtex = true; - break; - } - } - - - // replace non fullbrights with black - if (fbtex == true) - { - for (i = 0, j = 0; i < numpixels; i++, j+=4) - { - if (in[i] < 239) - in[i] = 0; - - p = in[i]; - - if (p == 0) - { - out[j+0] = 0; - out[j+1] = 0; - out[j+2] = 0; - out[j+3] = 255; - } - else if (p == 255) - { - out[j+0] = 0; - out[j+1] = 0; - out[j+2] = 0; - out[j+3] = 0; - } - else - { - out[j+0] = host_basepal[(p*3)+0]; - out[j+1] = host_basepal[(p*3)+1]; - out[j+2] = host_basepal[(p*3)+2]; - out[j+3] = 255; - } - } - } - - return fbtex; -} diff --git a/engine/code/gl_fullbright.h b/engine/code/gl_fullbright.h deleted file mode 100644 index 8e89e13..0000000 --- a/engine/code/gl_fullbright.h +++ /dev/null @@ -1,27 +0,0 @@ -/* -Copyright (C) 1996-1997 Id Software, Inc. - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ -// gl_fullbright.h: fullbright pixel processing - -// Developed by Jacques Krige -// Ultimate Quake Engine -// http://www.jacqueskrige.com - - -qboolean GL_FullbrightTexture (byte *in, byte *out, int width, int height); diff --git a/engine/code/gl_mesh.c b/engine/code/gl_mesh.c deleted file mode 100644 index a62fa48..0000000 --- a/engine/code/gl_mesh.c +++ /dev/null @@ -1,362 +0,0 @@ -/* -Copyright (C) 1996-1997 Id Software, Inc. - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ -// gl_mesh.c: triangle model functions - -#include "quakedef.h" - -/* -================================================================= - -ALIAS MODEL DISPLAY LIST GENERATION - -================================================================= -*/ - -model_t *aliasmodel; -aliashdr_t *paliashdr; - -qboolean used[8192]; - -// the command list holds counts and s/t values that are valid for -// every frame -int commands[8192]; -int numcommands; - -// all frames will have their vertexes rearranged and expanded -// so they are in the order expected by the command list -int vertexorder[8192]; -int numorder; - -int allverts, alltris; - -int stripverts[128]; -int striptris[128]; -int stripcount; - -/* -================ -StripLength -================ -*/ -int StripLength (int starttri, int startv) -{ - int m1, m2; - int j; - mtriangle_t *last, *check; - int k; - - used[starttri] = 2; - - last = &triangles[starttri]; - - stripverts[0] = last->vertindex[(startv)%3]; - stripverts[1] = last->vertindex[(startv+1)%3]; - stripverts[2] = last->vertindex[(startv+2)%3]; - - striptris[0] = starttri; - stripcount = 1; - - m1 = last->vertindex[(startv+2)%3]; - m2 = last->vertindex[(startv+1)%3]; - - // look for a matching triangle -nexttri: - for (j=starttri+1, check=&triangles[starttri+1] ; jnumtris ; j++, check++) - { - if (check->facesfront != last->facesfront) - continue; - for (k=0 ; k<3 ; k++) - { - if (check->vertindex[k] != m1) - continue; - if (check->vertindex[ (k+1)%3 ] != m2) - continue; - - // this is the next part of the fan - - // if we can't use this triangle, this tristrip is done - if (used[j]) - goto done; - - // the new edge - if (stripcount & 1) - m2 = check->vertindex[ (k+2)%3 ]; - else - m1 = check->vertindex[ (k+2)%3 ]; - - stripverts[stripcount+2] = check->vertindex[ (k+2)%3 ]; - striptris[stripcount] = j; - stripcount++; - - used[j] = 2; - goto nexttri; - } - } -done: - - // clear the temp used flags - for (j=starttri+1 ; jnumtris ; j++) - if (used[j] == 2) - used[j] = 0; - - return stripcount; -} - -/* -=========== -FanLength -=========== -*/ -int FanLength (int starttri, int startv) -{ - int m1, m2; - int j; - mtriangle_t *last, *check; - int k; - - used[starttri] = 2; - - last = &triangles[starttri]; - - stripverts[0] = last->vertindex[(startv)%3]; - stripverts[1] = last->vertindex[(startv+1)%3]; - stripverts[2] = last->vertindex[(startv+2)%3]; - - striptris[0] = starttri; - stripcount = 1; - - m1 = last->vertindex[(startv+0)%3]; - m2 = last->vertindex[(startv+2)%3]; - - - // look for a matching triangle -nexttri: - for (j=starttri+1, check=&triangles[starttri+1] ; jnumtris ; j++, check++) - { - if (check->facesfront != last->facesfront) - continue; - for (k=0 ; k<3 ; k++) - { - if (check->vertindex[k] != m1) - continue; - if (check->vertindex[ (k+1)%3 ] != m2) - continue; - - // this is the next part of the fan - - // if we can't use this triangle, this tristrip is done - if (used[j]) - goto done; - - // the new edge - m2 = check->vertindex[ (k+2)%3 ]; - - stripverts[stripcount+2] = m2; - striptris[stripcount] = j; - stripcount++; - - used[j] = 2; - goto nexttri; - } - } -done: - - // clear the temp used flags - for (j=starttri+1 ; jnumtris ; j++) - if (used[j] == 2) - used[j] = 0; - - return stripcount; -} - - -/* -================ -BuildTris - -Generate a list of trifans or strips -for the model, which holds for all frames -================ -*/ -void BuildTris (void) -{ - int i, j, k; - int startv; - mtriangle_t *last, *check; - int m1, m2; - int striplength; - trivertx_t *v; - mtriangle_t *tv; - float s, t; - int index; - int len, bestlen, besttype; - int bestverts[1024]; - int besttris[1024]; - int type; - - // - // build tristrips - // - numorder = 0; - numcommands = 0; - memset (used, 0, sizeof(used)); - for (i=0 ; inumtris ; i++) - { - // pick an unused triangle and start the trifan - if (used[i]) - continue; - - bestlen = 0; - for (type = 0 ; type < 2 ; type++) -// type = 1; - { - for (startv =0 ; startv < 3 ; startv++) - { - if (type == 1) - len = StripLength (i, startv); - else - len = FanLength (i, startv); - if (len > bestlen) - { - besttype = type; - bestlen = len; - for (j=0 ; jskinwidth / 2; // on back side - s = (s + 0.5) / pheader->skinwidth; - t = (t + 0.5) / pheader->skinheight; - - *(float *)&commands[numcommands++] = s; - *(float *)&commands[numcommands++] = t; - } - } - - commands[numcommands++] = 0; // end of list marker - - Con_DPrintf ("%3i tri %3i vert %3i cmd\n", pheader->numtris, numorder, numcommands); - - allverts += numorder; - alltris += pheader->numtris; -} - - -/* -================ -GL_MakeAliasModelDisplayLists -================ -*/ -void GL_MakeAliasModelDisplayLists (model_t *m, aliashdr_t *hdr) -{ - int i, j; - maliasgroup_t *paliasgroup; - int *cmds; - trivertx_t *verts; - char cache[MAX_QPATH], fullpath[MAX_OSPATH], *c; - FILE *f; - int len; - byte *data; - - aliasmodel = m; - paliashdr = hdr; // (aliashdr_t *)Mod_Extradata (m); - - // jkrige - mdl meshing removal - // - // look for a cached version - // - /*strcpy (cache, "glquake/"); - COM_StripExtension (m->name+strlen("progs/"), cache+strlen("glquake/")); - strcat (cache, ".ms2"); - - COM_FOpenFile (cache, &f); - if (f) - { - fread (&numcommands, 4, 1, f); - fread (&numorder, 4, 1, f); - fread (&commands, numcommands * sizeof(commands[0]), 1, f); - fread (&vertexorder, numorder * sizeof(vertexorder[0]), 1, f); - fclose (f); - } - else - { - // - // build it from scratch - // - Con_Printf ("meshing %s...\n",m->name); - - BuildTris (); // trifans or lists - - // - // save out the cached version - // - sprintf (fullpath, "%s/%s", com_gamedir, cache); - f = fopen (fullpath, "wb"); - if (f) - { - fwrite (&numcommands, 4, 1, f); - fwrite (&numorder, 4, 1, f); - fwrite (&commands, numcommands * sizeof(commands[0]), 1, f); - fwrite (&vertexorder, numorder * sizeof(vertexorder[0]), 1, f); - fclose (f); - } - }*/ - BuildTris (); - // jkrige - mdl meshing removal - - // save the data out - - paliashdr->poseverts = numorder; - - cmds = Hunk_Alloc (numcommands * 4); - paliashdr->commands = (byte *)cmds - (byte *)paliashdr; - memcpy (cmds, commands, numcommands * 4); - - verts = Hunk_Alloc (paliashdr->numposes * paliashdr->poseverts - * sizeof(trivertx_t) ); - paliashdr->posedata = (byte *)verts - (byte *)paliashdr; - for (i=0 ; inumposes ; i++) - for (j=0 ; jcache); - if (r) - return r; - - Mod_LoadModel (mod, true); - - if (!mod->cache.data) - Sys_Error ("Mod_Extradata: caching failed"); - return mod->cache.data; -} - -/* -=============== -Mod_PointInLeaf -=============== -*/ -mleaf_t *Mod_PointInLeaf (vec3_t p, model_t *model) -{ - mnode_t *node; - float d; - mplane_t *plane; - - if (!model || !model->nodes) - Sys_Error ("Mod_PointInLeaf: bad model"); - - node = model->nodes; - while (1) - { - if (node->contents < 0) - return (mleaf_t *)node; - plane = node->plane; - d = DotProduct (p,plane->normal) - plane->dist; - if (d > 0) - node = node->children[0]; - else - node = node->children[1]; - } - - return NULL; // never reached -} - - -/* -=================== -Mod_DecompressVis -=================== -*/ -byte *Mod_DecompressVis (byte *in, model_t *model) -{ - static byte decompressed[MAX_MAP_LEAFS/8]; - int c; - byte *out; - int row; - - row = (model->numleafs+7)>>3; - out = decompressed; - -#if 0 - memcpy (out, in, row); -#else - if (!in) - { // no vis info, so make all visible - while (row) - { - *out++ = 0xff; - row--; - } - return decompressed; - } - - do - { - if (*in) - { - *out++ = *in++; - continue; - } - - c = in[1]; - in += 2; - while (c) - { - *out++ = 0; - c--; - } - } while (out - decompressed < row); -#endif - - return decompressed; -} - -byte *Mod_LeafPVS (mleaf_t *leaf, model_t *model) -{ - if (leaf == model->leafs) - return mod_novis; - return Mod_DecompressVis (leaf->compressed_vis, model); -} - -/* -=================== -Mod_ClearAll -=================== -*/ -void Mod_ClearAll (void) -{ - int i; - model_t *mod; - - for (i=0 , mod=mod_known ; itype != mod_alias) - mod->needload = true; -} - -/* -================== -Mod_FindName - -================== -*/ -model_t *Mod_FindName (char *name) -{ - int i; - model_t *mod; - - if (!name[0]) - Sys_Error ("Mod_ForName: NULL name"); - -// -// search the currently loaded models -// - for (i=0 , mod=mod_known ; iname, name) ) - break; - - if (i == mod_numknown) - { - if (mod_numknown == MAX_MOD_KNOWN) - Sys_Error ("mod_numknown == MAX_MOD_KNOWN"); - strcpy (mod->name, name); - mod->needload = true; - mod_numknown++; - } - - return mod; -} - -/* -================== -Mod_TouchModel - -================== -*/ -void Mod_TouchModel (char *name) -{ - model_t *mod; - - mod = Mod_FindName (name); - - if (!mod->needload) - { - if (mod->type == mod_alias) - Cache_Check (&mod->cache); - } -} - -/* -================== -Mod_LoadModel - -Loads a model into the cache -================== -*/ -model_t *Mod_LoadModel (model_t *mod, qboolean crash) -{ - void *d; - unsigned *buf; - byte stackbuf[1024]; // avoid dirtying the cache heap - - if (!mod->needload) - { - if (mod->type == mod_alias) - { - d = Cache_Check (&mod->cache); - if (d) - return mod; - } - else - return mod; // not cached at all - } - -// -// because the world is so huge, load it one piece at a time -// - if (!crash) - { - - } - -// -// load the file -// - buf = (unsigned *)COM_LoadStackFile (mod->name, stackbuf, sizeof(stackbuf)); - if (!buf) - { - if (crash) - Sys_Error ("Mod_NumForName: %s not found", mod->name); - return NULL; - } - -// -// allocate a new model -// - COM_FileBase (mod->name, loadname); - - loadmodel = mod; - -// -// fill it in -// - -// call the apropriate loader - mod->needload = false; - - switch (LittleLong(*(unsigned *)buf)) - { - case IDPOLYHEADER: - Mod_LoadAliasModel (mod, buf); - break; - - case IDSPRITEHEADER: - Mod_LoadSpriteModel (mod, buf); - break; - - default: - Mod_LoadBrushModel (mod, buf); - break; - } - - return mod; -} - -/* -================== -Mod_ForName - -Loads in a model for the given name -================== -*/ -model_t *Mod_ForName (char *name, qboolean crash) -{ - model_t *mod; - - mod = Mod_FindName (name); - - return Mod_LoadModel (mod, crash); -} - - -/* -=============================================================================== - - BRUSHMODEL LOADING - -=============================================================================== -*/ - -byte *mod_base; - - -/* -================= -Mod_LoadTextures -================= -*/ -void Mod_LoadTextures (lump_t *l) -{ - int i, j, pixels, num, max, altmax; - miptex_t *mt; - texture_t *tx, *tx2; - texture_t *anims[10]; - texture_t *altanims[10]; - dmiptexlump_t *m; - - // jkrige - external texture loading - FILE *f2; - //int pcxmip[4]; - char texname[MAX_QPATH]; - // jkrige - external texture loading - - // jkrige - fullbright pixels - char fbr_name[64]; - int fbr_pixels; - // jkrige - fullbright pixels - - if (!l->filelen) - { - loadmodel->textures = NULL; - return; - } - m = (dmiptexlump_t *)(mod_base + l->fileofs); - - m->nummiptex = LittleLong (m->nummiptex); - - loadmodel->numtextures = m->nummiptex; - loadmodel->textures = Hunk_AllocName (m->nummiptex * sizeof(*loadmodel->textures) , loadname); - - for (i=0 ; inummiptex ; i++) - { - m->dataofs[i] = LittleLong(m->dataofs[i]); - if (m->dataofs[i] == -1) - continue; - mt = (miptex_t *)((byte *)m + m->dataofs[i]); - mt->width = LittleLong (mt->width); - mt->height = LittleLong (mt->height); - for (j=0 ; joffsets[j] = LittleLong (mt->offsets[j]); - - if ( (mt->width & 15) || (mt->height & 15) ) - Sys_Error ("Texture %s is not 16 aligned", mt->name); - pixels = mt->width*mt->height/64*85; - tx = Hunk_AllocName (sizeof(texture_t) +pixels, loadname ); - loadmodel->textures[i] = tx; - - memcpy (tx->name, mt->name, sizeof(tx->name)); - tx->width = mt->width; - tx->height = mt->height; - for (j=0 ; joffsets[j] = mt->offsets[j] + sizeof(texture_t) - sizeof(miptex_t); - - // the pixels immediately follow the structures - memcpy ( tx+1, mt+1, pixels); - - // jkrige - fullbright pixels - fbr_pixels = pixels; - // jkrige - fullbright pixels - - - if (!Q_strncmp(mt->name,"sky",3)) - R_InitSky (tx); - else - { - // jkrige - luma textures - tx->tex_luma = false; - // jkrige - luma textures - - - texture_mode = GL_LINEAR_MIPMAP_NEAREST; //_LINEAR; - - - // jkrige - external texture loading - if(mt->name[0] == '*' || mt->name[0] == '#') - { - //sprintf (texname, "textures/%s.tga", strnset(mt_wal->name, '-', 1)); - - sprintf (texname, "textures/%s/%s.tga", sv.name, strnset(mt->name , '#', 1)); - tx->gl_texturenum = LoadTextureImage (texname, "texture", 0, 0, false, true); - - if (tx->gl_texturenum == 0) - { - sprintf (texname, "textures/%s.tga", strnset(mt->name , '#', 1)); - tx->gl_texturenum = LoadTextureImage (texname, "texture", 0, 0, false, true); - } - } - else - { - //sprintf (texname, "textures/%s.tga", mt_wal->name); - - sprintf (texname, "textures/%s/%s.tga", sv.name, mt->name); - tx->gl_texturenum = LoadTextureImage (texname, "texture", 0, 0, false, true); - - if (tx->gl_texturenum == 0) - { - sprintf (texname, "textures/%s.tga", mt->name); - tx->gl_texturenum = LoadTextureImage (texname, "texture", 0, 0, false, true); - } - } - - - //tx->gl_texturenum = GL_LoadTexture (mt->name, tx->width, tx->height, (byte *)(tx+1), true, false); - if (tx->gl_texturenum == 0)// did not find a matching external texture... - { - tx->gl_texturenum = GL_LoadTexture (mt->name, "texture", tx->width, tx->height, (byte *)(tx+1), true, false, 1); - } - - - // jkrige - fullbright pixels - // jkrige - luma textures - for(j = 0; j < numgltextures; j++) - { - if(tx->gl_texturenum == gltextures[j].texnum) - { - tx->tex_luma = gltextures[j].tex_luma; - tx->tex_luma8bit = gltextures[j].tex_luma8bit; - - break; - } - } - // jkrige - luma textures - // jkrige - fullbright pixels - - - texture_mode = GL_LINEAR; - } - } - -// -// sequence the animations -// - for (i=0 ; inummiptex ; i++) - { - tx = loadmodel->textures[i]; - if (!tx || tx->name[0] != '+') - continue; - if (tx->anim_next) - continue; // allready sequenced - - // find the number of frames in the animation - memset (anims, 0, sizeof(anims)); - memset (altanims, 0, sizeof(altanims)); - - max = tx->name[1]; - altmax = 0; - if (max >= 'a' && max <= 'z') - max -= 'a' - 'A'; - if (max >= '0' && max <= '9') - { - max -= '0'; - altmax = 0; - anims[max] = tx; - max++; - } - else if (max >= 'A' && max <= 'J') - { - altmax = max - 'A'; - max = 0; - altanims[altmax] = tx; - altmax++; - } - else - Sys_Error ("Bad animating texture %s", tx->name); - - for (j=i+1 ; jnummiptex ; j++) - { - tx2 = loadmodel->textures[j]; - if (!tx2 || tx2->name[0] != '+') - continue; - if (strcmp (tx2->name+2, tx->name+2)) - continue; - - num = tx2->name[1]; - if (num >= 'a' && num <= 'z') - num -= 'a' - 'A'; - if (num >= '0' && num <= '9') - { - num -= '0'; - anims[num] = tx2; - if (num+1 > max) - max = num + 1; - } - else if (num >= 'A' && num <= 'J') - { - num = num - 'A'; - altanims[num] = tx2; - if (num+1 > altmax) - altmax = num+1; - } - else - Sys_Error ("Bad animating texture %s", tx->name); - } - -#define ANIM_CYCLE 2 - // link them all together - for (j=0 ; jname); - tx2->anim_total = max * ANIM_CYCLE; - tx2->anim_min = j * ANIM_CYCLE; - tx2->anim_max = (j+1) * ANIM_CYCLE; - tx2->anim_next = anims[ (j+1)%max ]; - if (altmax) - tx2->alternate_anims = altanims[0]; - } - for (j=0 ; jname); - tx2->anim_total = altmax * ANIM_CYCLE; - tx2->anim_min = j * ANIM_CYCLE; - tx2->anim_max = (j+1) * ANIM_CYCLE; - tx2->anim_next = altanims[ (j+1)%altmax ]; - if (max) - tx2->alternate_anims = anims[0]; - } - } -} - -/* -================= -Mod_LoadLighting -================= -*/ -// jkrige - .lit colored lights -void Mod_LoadLighting (lump_t *l) -{ - // LordHavoc: .lit support - int i; - byte *in, *out, *data; - byte d; - char litfilename[MAX_QPATH]; - - GL_SetupLightmapFmt(false); // setup the lightmap format to reflect any - // changes via the cvar gl_lightmapfmt - - // bound the gl_coloredlight value - if (gl_coloredlight.value < 0) - Cvar_SetValue ("gl_coloredlight", 0); - gl_coloredstatic = gl_coloredlight.value; - - if (gl_lightmap_format == GL_RGBA) - { - loadmodel->lightdata = NULL; - - if (gl_coloredlight.value == 1) - { // LordHavoc: check for a .lit file - strcpy(litfilename, loadmodel->name); - COM_StripExtension(litfilename, litfilename/*, sizeof(litfilename)*/); - strcat(litfilename, ".lit"); - Con_DPrintf("trying to load %s\n", litfilename); - data = (byte*) COM_LoadHunkFile (litfilename); - if (data) - { - if (data[0] == 'Q' && data[1] == 'L' && data[2] == 'I' && data[3] == 'T') - { - i = LittleLong(((int *)data)[1]); - if (i == 1) - { - Con_DPrintf("%s loaded\n", litfilename); - - Con_DPrintf("Mod_LoadLighting: Loaded colored light (32-bit)\n"); - - if ( gl_coloredlight.value == 1 ) - { - loadmodel->lightdata = data + 8; - return; - } - else - { - int min_light = 8; - int k = 0; - int mark, j, r, g, b; - float l2lc = 0; - float lc = 0; - float li = 0; - - if (!l->filelen) - { - loadmodel->lightdata = data + 8; - Con_DPrintf("Mod_LoadLighting: No white light data. Using colored only\n"); - return; - } - Con_DPrintf("Mod_LoadLighting: Loaded white light.\n"); - - // allocate memory and load light data from .bsp - mark = Hunk_LowMark(); - loadmodel->lightdata = /*(byte *)*/ Hunk_AllocName (l->filelen, "light"); - memcpy (loadmodel->lightdata, mod_base + l->fileofs, l->filelen); - - for (i = 0, j = 0, k = 0; i < l->filelen * 3; i += 3, j += 3) - { - // set some minimal light level - r = max(data[8+i], min_light); - g = max(data[8+i+1], min_light); - b = max(data[8+i+2], min_light); - - // compute brightness of colored ligths present in .lit file - lc = (r + g + b) / 3.0f; - li = (float) loadmodel->lightdata[k]; - - if (li == 0) - li = min_light; - if (lc == 0) - lc = min_light; - - // compute light amplification level - l2lc = (float) li/lc; - if ( l2lc < 1.5f ) - l2lc = 1; - - // update colors - data[8+j] = (byte) min(max( ceil(r*l2lc), min_light ),255); - data[8+j+1] = (byte) min(max( ceil(g*l2lc), min_light ),255); - data[8+j+2] = (byte) min(max( ceil(b*l2lc), min_light ),255); - k++; - } - Hunk_FreeToLowMark(mark); - - loadmodel->lightdata = data + 8; - Con_DPrintf("Mod_LoadLighting: Blended lightmaps.\n"); - - return; - } - } - else - { - Con_DPrintf("Mod_LoadLighting: Unknown .lit file version (%d)\n", i); - } - } - else - { - Con_DPrintf("Mod_LoadLighting: Corrupt .lit file (old version?), ignoring\n"); - } - } - } - // no .lit found, expand the white lighting data to color - if (!l->filelen) - { - //loadmodel->lightdata = NULL; - return; - } - loadmodel->lightdata = /*(byte *)*/ Hunk_AllocName ( l->filelen*3, "light" /*litfilename*/); - in = loadmodel->lightdata + l->filelen*2; // place the file at the end, so it will not be overwritten until the very last write - out = loadmodel->lightdata; - memcpy (in, mod_base + l->fileofs, l->filelen); - for (i = 0; i < l->filelen; i++) - { - d = *in++; - *out++ = d; - *out++ = d; - *out++ = d; - } - Con_DPrintf("Mod_LoadLighting: Loaded white light (32-bit)\n"); - } - else - { - if (!l->filelen) - { - loadmodel->lightdata = NULL; - return; - } - loadmodel->lightdata = /*(byte *)*/ Hunk_AllocName ( l->filelen, "light"); - memcpy (loadmodel->lightdata, mod_base + l->fileofs, l->filelen); - Con_DPrintf("Mod_LoadLighting: Loaded white light (8-bit)\n"); - } -} - -/*void Mod_LoadLighting (lump_t *l) -{ - if (!l->filelen) - { - loadmodel->lightdata = NULL; - return; - } - loadmodel->lightdata = Hunk_AllocName ( l->filelen, loadname); - memcpy (loadmodel->lightdata, mod_base + l->fileofs, l->filelen); -}*/ -// jkrige - .lit colored lights - - -/* -================= -Mod_LoadVisibility -================= -*/ -void Mod_LoadVisibility (lump_t *l) -{ - if (!l->filelen) - { - loadmodel->visdata = NULL; - return; - } - loadmodel->visdata = Hunk_AllocName ( l->filelen, loadname); - memcpy (loadmodel->visdata, mod_base + l->fileofs, l->filelen); -} - - -/* -================= -Mod_LoadEntities -================= -*/ -// jkrige - load external .ent files -void Mod_LoadEntities (lump_t *l) -{ - char entfilename[MAX_QPATH]; - char *ents; - int mark; - - strcpy(entfilename, loadmodel->name); - COM_StripExtension(entfilename, entfilename); - strcat(entfilename, ".ent"); - Con_DPrintf("trying to load %s\n", entfilename); - mark = Hunk_LowMark(); - ents = (char *) COM_LoadHunkFile (entfilename); - if (ents) - { - loadmodel->entities = ents; - Con_DPrintf("Loaded external entity file %s\n", entfilename); - return; - } - - if (!l->filelen) - { - loadmodel->entities = NULL; - return; - } - loadmodel->entities = (char *) Hunk_AllocName ( l->filelen, "entities"); - memcpy (loadmodel->entities, mod_base + l->fileofs, l->filelen); -} - -/*void Mod_LoadEntities (lump_t *l) -{ - if (!l->filelen) - { - loadmodel->entities = NULL; - return; - } - loadmodel->entities = Hunk_AllocName ( l->filelen, loadname); - memcpy (loadmodel->entities, mod_base + l->fileofs, l->filelen); -}*/ -// jkrige - load external .ent files - - -/* -================= -Mod_LoadVertexes -================= -*/ -void Mod_LoadVertexes (lump_t *l) -{ - dvertex_t *in; - mvertex_t *out; - int i, count; - - in = (void *)(mod_base + l->fileofs); - if (l->filelen % sizeof(*in)) - Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name); - count = l->filelen / sizeof(*in); - out = Hunk_AllocName ( count*sizeof(*out), loadname); - - loadmodel->vertexes = out; - loadmodel->numvertexes = count; - - for ( i=0 ; iposition[0] = LittleFloat (in->point[0]); - out->position[1] = LittleFloat (in->point[1]); - out->position[2] = LittleFloat (in->point[2]); - } -} - -/* -================= -Mod_LoadSubmodels -================= -*/ -void Mod_LoadSubmodels (lump_t *l) -{ - dmodel_t *in; - dmodel_t *out; - int i, j, count; - - in = (void *)(mod_base + l->fileofs); - if (l->filelen % sizeof(*in)) - Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name); - count = l->filelen / sizeof(*in); - out = Hunk_AllocName ( count*sizeof(*out), loadname); - - loadmodel->submodels = out; - loadmodel->numsubmodels = count; - - for ( i=0 ; imins[j] = LittleFloat (in->mins[j]) - 1; - out->maxs[j] = LittleFloat (in->maxs[j]) + 1; - out->origin[j] = LittleFloat (in->origin[j]); - } - for (j=0 ; jheadnode[j] = LittleLong (in->headnode[j]); - out->visleafs = LittleLong (in->visleafs); - out->firstface = LittleLong (in->firstface); - out->numfaces = LittleLong (in->numfaces); - } -} - -/* -================= -Mod_LoadEdges -================= -*/ -void Mod_LoadEdges (lump_t *l) -{ - dedge_t *in; - medge_t *out; - int i, count; - - in = (void *)(mod_base + l->fileofs); - if (l->filelen % sizeof(*in)) - Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name); - count = l->filelen / sizeof(*in); - out = Hunk_AllocName ( (count + 1) * sizeof(*out), loadname); - - loadmodel->edges = out; - loadmodel->numedges = count; - - for ( i=0 ; iv[0] = (unsigned short)LittleShort(in->v[0]); - out->v[1] = (unsigned short)LittleShort(in->v[1]); - } -} - -/* -================= -Mod_LoadTexinfo -================= -*/ -void Mod_LoadTexinfo (lump_t *l) -{ - texinfo_t *in; - mtexinfo_t *out; - int i, j, count; - int miptex; - float len1, len2; - - in = (void *)(mod_base + l->fileofs); - if (l->filelen % sizeof(*in)) - Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name); - count = l->filelen / sizeof(*in); - out = Hunk_AllocName ( count*sizeof(*out), loadname); - - loadmodel->texinfo = out; - loadmodel->numtexinfo = count; - - for ( i=0 ; ivecs[0][j] = LittleFloat (in->vecs[0][j]); - len1 = Length (out->vecs[0]); - len2 = Length (out->vecs[1]); - len1 = (len1 + len2)/2; - if (len1 < 0.32) - out->mipadjust = 4; - else if (len1 < 0.49) - out->mipadjust = 3; - else if (len1 < 0.99) - out->mipadjust = 2; - else - out->mipadjust = 1; -#if 0 - if (len1 + len2 < 0.001) - out->mipadjust = 1; // don't crash - else - out->mipadjust = 1 / floor( (len1+len2)/2 + 0.1 ); -#endif - - miptex = LittleLong (in->miptex); - out->flags = LittleLong (in->flags); - - if (!loadmodel->textures) - { - out->texture = r_notexture_mip; // checkerboard texture - out->flags = 0; - } - else - { - if (miptex >= loadmodel->numtextures) - Sys_Error ("miptex >= loadmodel->numtextures"); - out->texture = loadmodel->textures[miptex]; - if (!out->texture) - { - out->texture = r_notexture_mip; // texture not found - out->flags = 0; - } - } - } -} - -/* -================ -CalcSurfaceExtents - -Fills in s->texturemins[] and s->extents[] -================ -*/ -void CalcSurfaceExtents (msurface_t *s) -{ - float mins[2], maxs[2], val; - int i,j, e; - mvertex_t *v; - mtexinfo_t *tex; - int bmins[2], bmaxs[2]; - - mins[0] = mins[1] = 999999; - maxs[0] = maxs[1] = -99999; - - tex = s->texinfo; - - for (i=0 ; inumedges ; i++) - { - e = loadmodel->surfedges[s->firstedge+i]; - if (e >= 0) - v = &loadmodel->vertexes[loadmodel->edges[e].v[0]]; - else - v = &loadmodel->vertexes[loadmodel->edges[-e].v[1]]; - - for (j=0 ; j<2 ; j++) - { - val = v->position[0] * tex->vecs[j][0] + - v->position[1] * tex->vecs[j][1] + - v->position[2] * tex->vecs[j][2] + - tex->vecs[j][3]; - if (val < mins[j]) - mins[j] = val; - if (val > maxs[j]) - maxs[j] = val; - } - } - - for (i=0 ; i<2 ; i++) - { - bmins[i] = floor(mins[i]/16); - bmaxs[i] = ceil(maxs[i]/16); - - s->texturemins[i] = bmins[i] * 16; - s->extents[i] = (bmaxs[i] - bmins[i]) * 16; - if ( !(tex->flags & TEX_SPECIAL) && s->extents[i] > 512 /* 256 */ ) - Sys_Error ("Bad surface extents"); - } -} - - -/* -================= -Mod_LoadFaces -================= -*/ -void Mod_LoadFaces (lump_t *l) -{ - dface_t *in; - msurface_t *out; - int i, count, surfnum; - int planenum, side; - - in = (void *)(mod_base + l->fileofs); - if (l->filelen % sizeof(*in)) - Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name); - count = l->filelen / sizeof(*in); - out = Hunk_AllocName ( count*sizeof(*out), loadname); - - loadmodel->surfaces = out; - loadmodel->numsurfaces = count; - - for ( surfnum=0 ; surfnumfirstedge = LittleLong(in->firstedge); - out->numedges = LittleShort(in->numedges); - out->flags = 0; - - planenum = LittleShort(in->planenum); - side = LittleShort(in->side); - if (side) - out->flags |= SURF_PLANEBACK; - - out->plane = loadmodel->planes + planenum; - - out->texinfo = loadmodel->texinfo + LittleShort (in->texinfo); - - CalcSurfaceExtents (out); - - // lighting info - - for (i=0 ; istyles[i] = in->styles[i]; - i = LittleLong(in->lightofs); - if (i == -1) - { - out->samples = NULL; - } - else - { - // jkrige - .lit colored lights - if (gl_lightmap_format == GL_RGBA) - out->samples = loadmodel->lightdata + (i * 3); // LordHavoc - else - out->samples = loadmodel->lightdata + i; - //out->samples = loadmodel->lightdata + i; - // jkrige - .lit colored lights - } - - - // jkrige - overbrights - if (gl_overbright.value) - out->overbright = true; - else - out->overbright = false; - // jkrige - overbrights - - - // set the drawing flags flag - - if (!Q_strncmp(out->texinfo->texture->name,"sky",3)) // sky - { - out->flags |= (SURF_DRAWSKY | SURF_DRAWTILED); -#ifndef QUAKE2 - GL_SubdivideSurface (out); // cut up polygon for warps -#endif - continue; - } - - if (!Q_strncmp(out->texinfo->texture->name,"*",1)) // turbulent - { - out->flags |= (SURF_DRAWTURB | SURF_DRAWTILED); - for (i=0 ; i<2 ; i++) - { - out->extents[i] = 16384; - out->texturemins[i] = -8192; - } - GL_SubdivideSurface (out); // cut up polygon for warps - continue; - } - - } -} - - -/* -================= -Mod_SetParent -================= -*/ -void Mod_SetParent (mnode_t *node, mnode_t *parent) -{ - node->parent = parent; - if (node->contents < 0) - return; - Mod_SetParent (node->children[0], node); - Mod_SetParent (node->children[1], node); -} - -/* -================= -Mod_LoadNodes -================= -*/ -void Mod_LoadNodes (lump_t *l) -{ - int i, j, count, p; - dnode_t *in; - mnode_t *out; - - in = (void *)(mod_base + l->fileofs); - if (l->filelen % sizeof(*in)) - Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name); - count = l->filelen / sizeof(*in); - out = Hunk_AllocName ( count*sizeof(*out), loadname); - - loadmodel->nodes = out; - loadmodel->numnodes = count; - - for ( i=0 ; iminmaxs[j] = LittleShort (in->mins[j]); - out->minmaxs[3+j] = LittleShort (in->maxs[j]); - } - - p = LittleLong(in->planenum); - out->plane = loadmodel->planes + p; - - out->firstsurface = LittleShort (in->firstface); - out->numsurfaces = LittleShort (in->numfaces); - - for (j=0 ; j<2 ; j++) - { - p = LittleShort (in->children[j]); - if (p >= 0) - out->children[j] = loadmodel->nodes + p; - else - out->children[j] = (mnode_t *)(loadmodel->leafs + (-1 - p)); - } - } - - Mod_SetParent (loadmodel->nodes, NULL); // sets nodes and leafs -} - -/* -================= -Mod_LoadLeafs -================= -*/ -void Mod_LoadLeafs (lump_t *l) -{ - dleaf_t *in; - mleaf_t *out; - int i, j, count, p; - - in = (void *)(mod_base + l->fileofs); - if (l->filelen % sizeof(*in)) - Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name); - count = l->filelen / sizeof(*in); - out = Hunk_AllocName ( count*sizeof(*out), loadname); - - loadmodel->leafs = out; - loadmodel->numleafs = count; - - for ( i=0 ; iminmaxs[j] = LittleShort (in->mins[j]); - out->minmaxs[3+j] = LittleShort (in->maxs[j]); - } - - p = LittleLong(in->contents); - out->contents = p; - - out->firstmarksurface = loadmodel->marksurfaces + - LittleShort(in->firstmarksurface); - out->nummarksurfaces = LittleShort(in->nummarksurfaces); - - p = LittleLong(in->visofs); - if (p == -1) - out->compressed_vis = NULL; - else - out->compressed_vis = loadmodel->visdata + p; - out->efrags = NULL; - - for (j=0 ; j<4 ; j++) - out->ambient_sound_level[j] = in->ambient_level[j]; - - // gl underwater warp - if (out->contents != CONTENTS_EMPTY) - { - for (j=0 ; jnummarksurfaces ; j++) - out->firstmarksurface[j]->flags |= SURF_UNDERWATER; - } - } -} - -/* -================= -Mod_LoadClipnodes -================= -*/ -void Mod_LoadClipnodes (lump_t *l) -{ - dclipnode_t *in, *out; - int i, count; - hull_t *hull; - - in = (void *)(mod_base + l->fileofs); - if (l->filelen % sizeof(*in)) - Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name); - count = l->filelen / sizeof(*in); - out = Hunk_AllocName ( count*sizeof(*out), loadname); - - loadmodel->clipnodes = out; - loadmodel->numclipnodes = count; - - hull = &loadmodel->hulls[1]; - hull->clipnodes = out; - hull->firstclipnode = 0; - hull->lastclipnode = count-1; - hull->planes = loadmodel->planes; - hull->clip_mins[0] = -16; - hull->clip_mins[1] = -16; - hull->clip_mins[2] = -24; - hull->clip_maxs[0] = 16; - hull->clip_maxs[1] = 16; - hull->clip_maxs[2] = 32; - - hull = &loadmodel->hulls[2]; - hull->clipnodes = out; - hull->firstclipnode = 0; - hull->lastclipnode = count-1; - hull->planes = loadmodel->planes; - hull->clip_mins[0] = -32; - hull->clip_mins[1] = -32; - hull->clip_mins[2] = -24; - hull->clip_maxs[0] = 32; - hull->clip_maxs[1] = 32; - hull->clip_maxs[2] = 64; - - for (i=0 ; iplanenum = LittleLong(in->planenum); - out->children[0] = LittleShort(in->children[0]); - out->children[1] = LittleShort(in->children[1]); - } -} - -/* -================= -Mod_MakeHull0 - -Deplicate the drawing hull structure as a clipping hull -================= -*/ -void Mod_MakeHull0 (void) -{ - mnode_t *in, *child; - dclipnode_t *out; - int i, j, count; - hull_t *hull; - - hull = &loadmodel->hulls[0]; - - in = loadmodel->nodes; - count = loadmodel->numnodes; - out = Hunk_AllocName ( count*sizeof(*out), loadname); - - hull->clipnodes = out; - hull->firstclipnode = 0; - hull->lastclipnode = count-1; - hull->planes = loadmodel->planes; - - for (i=0 ; iplanenum = in->plane - loadmodel->planes; - for (j=0 ; j<2 ; j++) - { - child = in->children[j]; - if (child->contents < 0) - out->children[j] = child->contents; - else - out->children[j] = child - loadmodel->nodes; - } - } -} - -/* -================= -Mod_LoadMarksurfaces -================= -*/ -void Mod_LoadMarksurfaces (lump_t *l) -{ - int i, j, count; - short *in; - msurface_t **out; - - in = (void *)(mod_base + l->fileofs); - if (l->filelen % sizeof(*in)) - Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name); - count = l->filelen / sizeof(*in); - out = Hunk_AllocName ( count*sizeof(*out), loadname); - - loadmodel->marksurfaces = out; - loadmodel->nummarksurfaces = count; - - for ( i=0 ; i= loadmodel->numsurfaces) - Sys_Error ("Mod_ParseMarksurfaces: bad surface number"); - out[i] = loadmodel->surfaces + j; - } -} - -/* -================= -Mod_LoadSurfedges -================= -*/ -void Mod_LoadSurfedges (lump_t *l) -{ - int i, count; - int *in, *out; - - in = (void *)(mod_base + l->fileofs); - if (l->filelen % sizeof(*in)) - Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name); - count = l->filelen / sizeof(*in); - out = Hunk_AllocName ( count*sizeof(*out), loadname); - - loadmodel->surfedges = out; - loadmodel->numsurfedges = count; - - for ( i=0 ; ifileofs); - if (l->filelen % sizeof(*in)) - Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name); - count = l->filelen / sizeof(*in); - out = Hunk_AllocName ( count*2*sizeof(*out), loadname); - - loadmodel->planes = out; - loadmodel->numplanes = count; - - for ( i=0 ; inormal[j] = LittleFloat (in->normal[j]); - if (out->normal[j] < 0) - bits |= 1<dist = LittleFloat (in->dist); - out->type = LittleLong (in->type); - out->signbits = bits; - } -} - -/* -================= -RadiusFromBounds -================= -*/ -float RadiusFromBounds (vec3_t mins, vec3_t maxs) -{ - int i; - vec3_t corner; - - for (i=0 ; i<3 ; i++) - { - corner[i] = fabs(mins[i]) > fabs(maxs[i]) ? fabs(mins[i]) : fabs(maxs[i]); - } - - return Length (corner); -} - -/* -================= -Mod_LoadBrushModel -================= -*/ -void Mod_LoadBrushModel (model_t *mod, void *buffer) -{ - int i, j; - dheader_t *header; - dmodel_t *bm; - - loadmodel->type = mod_brush; - - - header = (dheader_t *)buffer; - - i = LittleLong (header->version); - - // jkrige - bsp version crash - //if (i != BSPVERSION) - // Sys_Error ("Mod_LoadBrushModel: %s has wrong version number (%i should be %i)", mod->name, i, BSPVERSION); - if (i != BSPVERSION) - { - Con_Printf("Mod_LoadBrushModel: %s has wrong version number (%i should be %i)", mod->name, i, BSPVERSION); - mod->numvertexes = -1; // HACK - incorrect BSP version is no longer fatal - return; - } - // jkrige - bsp version crash - -// swap all the lumps - mod_base = (byte *)header; - - for (i=0 ; ilumps[LUMP_VERTEXES]); - Mod_LoadEdges (&header->lumps[LUMP_EDGES]); - Mod_LoadSurfedges (&header->lumps[LUMP_SURFEDGES]); - Mod_LoadTextures (&header->lumps[LUMP_TEXTURES]); - Mod_LoadLighting (&header->lumps[LUMP_LIGHTING]); - Mod_LoadPlanes (&header->lumps[LUMP_PLANES]); - Mod_LoadTexinfo (&header->lumps[LUMP_TEXINFO]); - Mod_LoadFaces (&header->lumps[LUMP_FACES]); - Mod_LoadMarksurfaces (&header->lumps[LUMP_MARKSURFACES]); - Mod_LoadVisibility (&header->lumps[LUMP_VISIBILITY]); - Mod_LoadLeafs (&header->lumps[LUMP_LEAFS]); - Mod_LoadNodes (&header->lumps[LUMP_NODES]); - Mod_LoadClipnodes (&header->lumps[LUMP_CLIPNODES]); - Mod_LoadEntities (&header->lumps[LUMP_ENTITIES]); - Mod_LoadSubmodels (&header->lumps[LUMP_MODELS]); - - Mod_MakeHull0 (); - - mod->numframes = 2; // regular and alternate animation - - - -// -// set up the submodels (FIXME: this is confusing) -// - for (i=0 ; inumsubmodels ; i++) - { - bm = &mod->submodels[i]; - - mod->hulls[0].firstclipnode = bm->headnode[0]; - for (j=1 ; jhulls[j].firstclipnode = bm->headnode[j]; - mod->hulls[j].lastclipnode = mod->numclipnodes-1; - } - - mod->firstmodelsurface = bm->firstface; - mod->nummodelsurfaces = bm->numfaces; - - VectorCopy (bm->maxs, mod->maxs); - VectorCopy (bm->mins, mod->mins); - - mod->radius = RadiusFromBounds (mod->mins, mod->maxs); - - mod->numleafs = bm->visleafs; - - if (i < mod->numsubmodels-1) - { // duplicate the basic information - char name[10]; - - sprintf (name, "*%i", i+1); - loadmodel = Mod_FindName (name); - *loadmodel = *mod; - strcpy (loadmodel->name, name); - mod = loadmodel; - } - } - - // TODO: upload brush model to UniQuake -} - -/* -============================================================================== - -ALIAS MODELS - -============================================================================== -*/ - -aliashdr_t *pheader; - -stvert_t stverts[MAXALIASVERTS]; -mtriangle_t triangles[MAXALIASTRIS]; - -// a pose is a single set of vertexes. a frame may be -// an animating sequence of poses -trivertx_t *poseverts[MAXALIASFRAMES]; -int posenum; - -byte **player_8bit_texels_tbl; -byte *player_8bit_texels; - -int aliasbboxmins[3], aliasbboxmaxs[3]; // jkrige - fix bounding boxes on models - -/* -================= -Mod_LoadAliasFrame -================= -*/ -void * Mod_LoadAliasFrame (void * pin, maliasframedesc_t *frame) -{ - trivertx_t *pframe, *pinframe; - int i, j; - daliasframe_t *pdaliasframe; - - pdaliasframe = (daliasframe_t *)pin; - - strcpy (frame->name, pdaliasframe->name); - frame->firstpose = posenum; - frame->numposes = 1; - - for (i=0 ; i<3 ; i++) - { - // these are byte values, so we don't have to worry about endianness - frame->bboxmin.v[i] = pdaliasframe->bboxmin.v[i]; - frame->bboxmin.v[i] = pdaliasframe->bboxmax.v[i]; - - // jkrige - fix bounding boxes on models - aliasbboxmins[i] = min (frame->bboxmin.v[i], aliasbboxmins[i]); - aliasbboxmaxs[i] = max (frame->bboxmax.v[i], aliasbboxmaxs[i]); - // jkrige - fix bounding boxes on models - } - - pinframe = (trivertx_t *)(pdaliasframe + 1); - - poseverts[posenum] = pinframe; - posenum++; - - pinframe += pheader->numverts; - - return (void *)pinframe; -} - - -/* -================= -Mod_LoadAliasGroup -================= -*/ -void *Mod_LoadAliasGroup (void * pin, maliasframedesc_t *frame) -{ - daliasgroup_t *pingroup; - int i, numframes; - daliasinterval_t *pin_intervals; - void *ptemp; - - pingroup = (daliasgroup_t *)pin; - - numframes = LittleLong (pingroup->numframes); - - frame->firstpose = posenum; - frame->numposes = numframes; - - for (i=0 ; i<3 ; i++) - { - // these are byte values, so we don't have to worry about endianness - frame->bboxmin.v[i] = pingroup->bboxmin.v[i]; - frame->bboxmin.v[i] = pingroup->bboxmax.v[i]; - - // jkrige - fix bounding boxes on models - aliasbboxmins[i] = min (frame->bboxmin.v[i], aliasbboxmins[i]); - aliasbboxmaxs[i] = max (frame->bboxmax.v[i], aliasbboxmaxs[i]); - // jkrige - fix bounding boxes on models - } - - pin_intervals = (daliasinterval_t *)(pingroup + 1); - - frame->interval = LittleFloat (pin_intervals->interval); - - pin_intervals += numframes; - - ptemp = (void *)pin_intervals; - - for (i=0 ; inumverts; - } - - return ptemp; -} - -//========================================================= - -/* -================= -Mod_FloodFillSkin - -Fill background pixels so mipmapping doesn't have haloes - Ed -================= -*/ - -typedef struct -{ - short x, y; -} floodfill_t; - -extern unsigned d_8to24table[]; - -// must be a power of 2 -#define FLOODFILL_FIFO_SIZE 0x1000 -#define FLOODFILL_FIFO_MASK (FLOODFILL_FIFO_SIZE - 1) - -#define FLOODFILL_STEP( off, dx, dy ) \ -{ \ - if (pos[off] == fillcolor) \ - { \ - pos[off] = 255; \ - fifo[inpt].x = x + (dx), fifo[inpt].y = y + (dy); \ - inpt = (inpt + 1) & FLOODFILL_FIFO_MASK; \ - } \ - else if (pos[off] != 255) fdc = pos[off]; \ -} - -void Mod_FloodFillSkin( byte *skin, int skinwidth, int skinheight ) -{ - byte fillcolor = *skin; // assume this is the pixel to fill - floodfill_t fifo[FLOODFILL_FIFO_SIZE]; - int inpt = 0, outpt = 0; - int filledcolor = -1; - int i; - - if (filledcolor == -1) - { - filledcolor = 0; - // attempt to find opaque black - for (i = 0; i < 256; ++i) - if (d_8to24table[i] == (255 << 0)) // alpha 1.0 - { - filledcolor = i; - break; - } - } - - // can't fill to filled color or to transparent color (used as visited marker) - if ((fillcolor == filledcolor) || (fillcolor == 255)) - { - //printf( "not filling skin from %d to %d\n", fillcolor, filledcolor ); - return; - } - - fifo[inpt].x = 0, fifo[inpt].y = 0; - inpt = (inpt + 1) & FLOODFILL_FIFO_MASK; - - while (outpt != inpt) - { - int x = fifo[outpt].x, y = fifo[outpt].y; - int fdc = filledcolor; - byte *pos = &skin[x + skinwidth * y]; - - outpt = (outpt + 1) & FLOODFILL_FIFO_MASK; - - if (x > 0) FLOODFILL_STEP( -1, -1, 0 ); - if (x < skinwidth - 1) FLOODFILL_STEP( 1, 1, 0 ); - if (y > 0) FLOODFILL_STEP( -skinwidth, 0, -1 ); - if (y < skinheight - 1) FLOODFILL_STEP( skinwidth, 0, 1 ); - skin[x + skinwidth * y] = fdc; - } -} - -/* -=============== -Mod_LoadAllSkins -=============== -*/ -void *Mod_LoadAllSkins (int numskins, daliasskintype_t *pskintype) -{ - int i, j, k; - - // jkrige - external texture loading - //char name[32]; - char name[64], model[64], model2[64]; - // jkrige - external texture loading - - int s; - byte *copy; - byte *skin; - byte *texels; - daliasskingroup_t *pinskingroup; - int groupskins; - daliasskininterval_t *pinskinintervals; - - skin = (byte *)(pskintype + 1); - - if (numskins < 1 || numskins > MAX_SKINS) - Sys_Error ("Mod_LoadAliasModel: Invalid # of skins: %d\n", numskins); - - s = pheader->skinwidth * pheader->skinheight; - - for (i=0 ; itype == ALIAS_SKIN_SINGLE) { - Mod_FloodFillSkin( skin, pheader->skinwidth, pheader->skinheight ); - - // save 8 bit texels for the player model to remap - // if (!strcmp(loadmodel->name,"progs/player.mdl")) { - texels = Hunk_AllocName(s, loadname); - pheader->texels[i] = texels - (byte *)pheader; - memcpy (texels, (byte *)(pskintype + 1), s); - // } - sprintf (name, "%s_%i", loadmodel->name, i); - - - // jkrige - external texture loading - //pheader->gl_texturenum[i][0] = - //pheader->gl_texturenum[i][1] = - //pheader->gl_texturenum[i][2] = - //pheader->gl_texturenum[i][3] = - // GL_LoadTexture (name, pheader->skinwidth, pheader->skinheight, (byte *)(pskintype + 1), true, false); - - COM_StripExtension(loadmodel->name, model); - sprintf (model2, "%s_%i", model, i); - pheader->gl_texturenum[i][0] = - pheader->gl_texturenum[i][1] = - pheader->gl_texturenum[i][2] = - pheader->gl_texturenum[i][3] = - LoadTextureImage (model2, "skin", 0, 0, false, true); - - if (pheader->gl_texturenum[i][0] == 0)// did not find a matching external texture... - { - pheader->gl_texturenum[i][0] = - pheader->gl_texturenum[i][1] = - pheader->gl_texturenum[i][2] = - pheader->gl_texturenum[i][3] = - GL_LoadTexture (name, "skin", pheader->skinwidth, pheader->skinheight, (byte *)(pskintype + 1), true, false, 1); - } - // jkrige - external texture loading - - - // jkrige - fullbright pixels - // jkrige - luma textures - for(j = 0; j < numgltextures; j++) - { - if(pheader->gl_texturenum[i][0] == gltextures[j].texnum) - { - pheader->skin_luma[i] = gltextures[j].tex_luma; - pheader->skin_luma8bit[i] = gltextures[j].tex_luma8bit; - - break; - } - } - // jkrige - luma textures - // jkrige - fullbright pixels - - - pskintype = (daliasskintype_t *)((byte *)(pskintype+1) + s); - } - else - { - // animating skin group. yuck. - pskintype++; - pinskingroup = (daliasskingroup_t *)pskintype; - groupskins = LittleLong (pinskingroup->numskins); - pinskinintervals = (daliasskininterval_t *)(pinskingroup + 1); - - pskintype = (void *)(pinskinintervals + groupskins); - - for (j=0 ; jskinwidth, pheader->skinheight ); - if (j == 0) { - texels = Hunk_AllocName(s, loadname); - pheader->texels[i] = texels - (byte *)pheader; - memcpy (texels, (byte *)(pskintype), s); - } - sprintf (name, "%s_%i_%i", loadmodel->name, i, j); - - - // jkrige - external texture loading - //pheader->gl_texturenum[i][j&3] = GL_LoadTexture (name, pheader->skinwidth, pheader->skinheight, (byte *)(pskintype), true, false); - - COM_StripExtension(loadmodel->name, model); - sprintf (model2, "%s_%i_%i", model, i, j); - pheader->gl_texturenum[i][j&3] = LoadTextureImage (model2, "skin", 0, 0, false, true); - - if (pheader->gl_texturenum[i][j&3] == 0)// did not find a matching external texture... - pheader->gl_texturenum[i][j&3] = GL_LoadTexture (name, "skin", pheader->skinwidth, pheader->skinheight, (byte *)(pskintype), true, false, 1); - // jkrige - external texture loading - - - // jkrige - fullbright pixels - // jkrige - luma textures - for(k = 0; k < numgltextures; k++) - { - if(pheader->gl_texturenum[i][j&3] == gltextures[k].texnum) - { - pheader->skin_luma[i] = gltextures[k].tex_luma; - pheader->skin_luma8bit[i] = gltextures[k].tex_luma8bit; - - break; - } - } - // jkrige - luma textures - // jkrige - fullbright pixels - - - pskintype = (daliasskintype_t *)((byte *)(pskintype) + s); - } - k = j; - for (/* */; j < 4; j++) - pheader->gl_texturenum[i][j&3] = pheader->gl_texturenum[i][j - k]; - } - } - - return (void *)pskintype; -} - -//========================================================================= - -/* -================= -Mod_LoadAliasModel -================= -*/ -void Mod_LoadAliasModel (model_t *mod, void *buffer) -{ - int i, j; - mdl_t *pinmodel; - stvert_t *pinstverts; - dtriangle_t *pintriangles; - int version, numframes, numskins; - int size; - daliasframetype_t *pframetype; - daliasskintype_t *pskintype; - int start, end, total; - - start = Hunk_LowMark (); - - pinmodel = (mdl_t *)buffer; - - version = LittleLong (pinmodel->version); - if (version != ALIAS_VERSION) - Sys_Error ("%s has wrong version number (%i should be %i)", - mod->name, version, ALIAS_VERSION); - -// -// allocate space for a working header, plus all the data except the frames, -// skin and group info -// - size = sizeof (aliashdr_t) - + (LittleLong (pinmodel->numframes) - 1) * - sizeof (pheader->frames[0]); - pheader = Hunk_AllocName (size, loadname); - - mod->flags = LittleLong (pinmodel->flags); - -// -// endian-adjust and copy the data, starting with the alias model header -// - pheader->boundingradius = LittleFloat (pinmodel->boundingradius); - pheader->numskins = LittleLong (pinmodel->numskins); - pheader->skinwidth = LittleLong (pinmodel->skinwidth); - pheader->skinheight = LittleLong (pinmodel->skinheight); - - if (pheader->skinheight > MAX_LBM_HEIGHT) - Sys_Error ("model %s has a skin taller than %d", mod->name, - MAX_LBM_HEIGHT); - - pheader->numverts = LittleLong (pinmodel->numverts); - - if (pheader->numverts <= 0) - Sys_Error ("model %s has no vertices", mod->name); - - if (pheader->numverts > MAXALIASVERTS) - Sys_Error ("model %s has too many vertices", mod->name); - - pheader->numtris = LittleLong (pinmodel->numtris); - - if (pheader->numtris <= 0) - Sys_Error ("model %s has no triangles", mod->name); - - pheader->numframes = LittleLong (pinmodel->numframes); - numframes = pheader->numframes; - if (numframes < 1) - Sys_Error ("Mod_LoadAliasModel: Invalid # of frames: %d\n", numframes); - - pheader->size = LittleFloat (pinmodel->size) * ALIAS_BASE_SIZE_RATIO; - mod->synctype = LittleLong (pinmodel->synctype); - mod->numframes = pheader->numframes; - - for (i=0 ; i<3 ; i++) - { - pheader->scale[i] = LittleFloat (pinmodel->scale[i]); - pheader->scale_origin[i] = LittleFloat (pinmodel->scale_origin[i]); - pheader->eyeposition[i] = LittleFloat (pinmodel->eyeposition[i]); - } - - -// -// load the skins -// - pskintype = (daliasskintype_t *)&pinmodel[1]; - pskintype = Mod_LoadAllSkins (pheader->numskins, pskintype); - -// -// load base s and t vertices -// - pinstverts = (stvert_t *)pskintype; - - for (i=0 ; inumverts ; i++) - { - stverts[i].onseam = LittleLong (pinstverts[i].onseam); - stverts[i].s = LittleLong (pinstverts[i].s); - stverts[i].t = LittleLong (pinstverts[i].t); - } - -// -// load triangle lists -// - pintriangles = (dtriangle_t *)&pinstverts[pheader->numverts]; - - for (i=0 ; inumtris ; i++) - { - triangles[i].facesfront = LittleLong (pintriangles[i].facesfront); - - for (j=0 ; j<3 ; j++) - { - triangles[i].vertindex[j] = - LittleLong (pintriangles[i].vertindex[j]); - } - } - -// -// load the frames -// - posenum = 0; - pframetype = (daliasframetype_t *)&pintriangles[pheader->numtris]; - - // jkrige - fix bounding boxes on models - aliasbboxmins[0] = aliasbboxmins[1] = aliasbboxmins[2] = -128; - aliasbboxmaxs[0] = aliasbboxmaxs[1] = aliasbboxmaxs[2] = 128; - // jkrige - fix bounding boxes on models - - for (i=0 ; itype); - - if (frametype == ALIAS_SINGLE) - { - pframetype = (daliasframetype_t *)Mod_LoadAliasFrame (pframetype + 1, &pheader->frames[i]); - } - else - { - pframetype = (daliasframetype_t *)Mod_LoadAliasGroup (pframetype + 1, &pheader->frames[i]); - } - } - - pheader->numposes = posenum; - - mod->type = mod_alias; - - // jkrige - fix bounding boxes on models - //mod->mins[0] = mod->mins[1] = mod->mins[2] = -16; - //mod->maxs[0] = mod->maxs[1] = mod->maxs[2] = 16; - for (i = 0; i < 3; i++) - { - mod->mins[i] = aliasbboxmins[i] * pheader->scale[i]; - mod->maxs[i] = aliasbboxmaxs[i] * pheader->scale[i]; - - if((mod->maxs[i] - mod->mins[i]) < 32.0f) - { - mod->mins[i] = -16; - mod->maxs[i] = 16; - } - } - // jkrige - fix bounding boxes on models - - // - // build the draw lists - // - GL_MakeAliasModelDisplayLists (mod, pheader); - - // TODO: upload model to UniQuake, receive & store identifier as a result - // Vertices = poseverts, UVs = stverts, indices = triangles - UQ_GL_UploadAliasModel(mod->name, pheader, poseverts, triangles, stverts); - -// -// move the complete, relocatable alias model to the cache -// - end = Hunk_LowMark (); - total = end - start; - - Cache_Alloc (&mod->cache, total, loadname); - if (!mod->cache.data) - return; - memcpy (mod->cache.data, pheader, total); - - Hunk_FreeToLowMark (start); -} - -//============================================================================= - -/* -================= -Mod_LoadSpriteFrame -================= -*/ -void * Mod_LoadSpriteFrame (void * pin, mspriteframe_t **ppframe, int framenum) -{ - dspriteframe_t *pinframe; - mspriteframe_t *pspriteframe; - int i, width, height, size, origin[2]; - unsigned short *ppixout; - byte *ppixin; - char name[64]; - - - // jkrige - external texture loading - char sprite[64]; - char sprite2[64]; - FILE *f2; - int FileFound = -1; - qboolean ExtOK = false; - - COM_FileBase(loadmodel->name, sprite); - - if(FileFound == -1) - { - sprintf (sprite2, "sprites/%s_%i.tga", sprite, framenum); - FileFound = COM_FOpenFile(sprite2, &f2); - } - if(FileFound == -1) - { - sprintf (sprite2, "sprites/%s_%i.jpg", sprite, framenum); - FileFound = COM_FOpenFile(sprite2, &f2); - } - if(FileFound == -1) - { - sprintf (sprite2, "sprites/%s_%i.pcx", sprite, framenum); - FileFound = COM_FOpenFile(sprite2, &f2); - } - // jkrige - external texture loading - - - pinframe = (dspriteframe_t *)pin; - - width = LittleLong (pinframe->width); - height = LittleLong (pinframe->height); - size = width * height; - - pspriteframe = Hunk_AllocName (sizeof (mspriteframe_t),loadname); - - Q_memset (pspriteframe, 0, sizeof (mspriteframe_t)); - - *ppframe = pspriteframe; - - pspriteframe->width = width; - pspriteframe->height = height; - origin[0] = LittleLong (pinframe->origin[0]); - origin[1] = LittleLong (pinframe->origin[1]); - - pspriteframe->up = origin[1]; - pspriteframe->down = origin[1] - height; - pspriteframe->left = origin[0]; - pspriteframe->right = width + origin[0]; - - //sprintf (name, "%s_%i", loadmodel->name, framenum); - //pspriteframe->gl_texturenum = GL_LoadTexture (name, width, height, (byte *)(pinframe + 1), true, true); - - - // jkrige - external texture loading - pspriteframe->gl_texturenum = LoadTextureImage (sprite2, "sprite", 0, 0, false, true); - if (pspriteframe->gl_texturenum == 0) // did not find a matching external files... - { - sprintf (name, "%s_%i", loadmodel->name, framenum); - pspriteframe->gl_texturenum = GL_LoadTexture (name, "sprite", width, height, (byte *)(pinframe + 1), true, true, 1); - } - // jkrige - external texture loading - - - return (void *)((byte *)pinframe + sizeof (dspriteframe_t) + size); -} - - -/* -================= -Mod_LoadSpriteGroup -================= -*/ -void * Mod_LoadSpriteGroup (void * pin, mspriteframe_t **ppframe, int framenum) -{ - dspritegroup_t *pingroup; - mspritegroup_t *pspritegroup; - int i, numframes; - dspriteinterval_t *pin_intervals; - float *poutintervals; - void *ptemp; - - pingroup = (dspritegroup_t *)pin; - - numframes = LittleLong (pingroup->numframes); - - pspritegroup = Hunk_AllocName (sizeof (mspritegroup_t) + - (numframes - 1) * sizeof (pspritegroup->frames[0]), loadname); - - pspritegroup->numframes = numframes; - - *ppframe = (mspriteframe_t *)pspritegroup; - - pin_intervals = (dspriteinterval_t *)(pingroup + 1); - - poutintervals = Hunk_AllocName (numframes * sizeof (float), loadname); - - pspritegroup->intervals = poutintervals; - - for (i=0 ; iinterval); - if (*poutintervals <= 0.0) - Sys_Error ("Mod_LoadSpriteGroup: interval<=0"); - - poutintervals++; - pin_intervals++; - } - - ptemp = (void *)pin_intervals; - - for (i=0 ; iframes[i], framenum * 100 + i); - } - - return ptemp; -} - - -/* -================= -Mod_LoadSpriteModel -================= -*/ -void Mod_LoadSpriteModel (model_t *mod, void *buffer) -{ - int i; - int version; - dsprite_t *pin; - msprite_t *psprite; - int numframes; - int size; - dspriteframetype_t *pframetype; - - pin = (dsprite_t *)buffer; - - version = LittleLong (pin->version); - if (version != SPRITE_VERSION) - Sys_Error ("%s has wrong version number " - "(%i should be %i)", mod->name, version, SPRITE_VERSION); - - numframes = LittleLong (pin->numframes); - - size = sizeof (msprite_t) + (numframes - 1) * sizeof (psprite->frames); - - psprite = Hunk_AllocName (size, loadname); - - mod->cache.data = psprite; - - psprite->type = LittleLong (pin->type); - psprite->maxwidth = LittleLong (pin->width); - psprite->maxheight = LittleLong (pin->height); - psprite->beamlength = LittleFloat (pin->beamlength); - mod->synctype = LittleLong (pin->synctype); - psprite->numframes = numframes; - - mod->mins[0] = mod->mins[1] = -psprite->maxwidth/2; - mod->maxs[0] = mod->maxs[1] = psprite->maxwidth/2; - mod->mins[2] = -psprite->maxheight/2; - mod->maxs[2] = psprite->maxheight/2; - -// -// load the frames -// - if (numframes < 1) - Sys_Error ("Mod_LoadSpriteModel: Invalid # of frames: %d\n", numframes); - - mod->numframes = numframes; - - pframetype = (dspriteframetype_t *)(pin + 1); - - for (i=0 ; itype); - psprite->frames[i].type = frametype; - - if (frametype == SPR_SINGLE) - { - pframetype = (dspriteframetype_t *) - Mod_LoadSpriteFrame (pframetype + 1, - &psprite->frames[i].frameptr, i); - } - else - { - pframetype = (dspriteframetype_t *) - Mod_LoadSpriteGroup (pframetype + 1, - &psprite->frames[i].frameptr, i); - } - } - - mod->type = mod_sprite; -} - -//============================================================================= - -/* -================ -Mod_Print -================ -*/ -void Mod_Print (void) -{ - int i; - model_t *mod; - - Con_Printf ("Cached models:\n"); - for (i=0, mod=mod_known ; i < mod_numknown ; i++, mod++) - { - Con_Printf ("%8p : %s\n",mod->cache.data, mod->name); - } -} - - diff --git a/engine/code/gl_rmain.c b/engine/code/gl_rmain.c deleted file mode 100644 index 0ce656d..0000000 --- a/engine/code/gl_rmain.c +++ /dev/null @@ -1,1710 +0,0 @@ -/* -Copyright (C) 1996-1997 Id Software, Inc. - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ -// r_main.c - -#include "quakedef.h" - -// jkrige - scale2d -#ifdef _WIN32 -#include "winquake.h" -#endif -// jkrige - scale2d - -entity_t r_worldentity; - -qboolean r_cache_thrash; // compatability - -vec3_t modelorg, r_entorigin; -entity_t *currententity; - -int r_visframecount; // bumped when going to a new PVS -int r_framecount; // used for dlight push checking - -mplane_t frustum[4]; - -int c_brush_polys, c_alias_polys; - -qboolean envmap; // true during envmap command capture - -int currenttexture = -1; // to avoid unnecessary texture sets - -int cnttextures[2] = {-1, -1}; // cached - -int particletexture_linear; // little dot for particles (jkrige - was named "particletexture") - -// jkrige - texture mode -int particletexture_point; -// jkrige - texture mode - -int playertextures; // up to 16 color translated skins - -int mirrortexturenum; // quake texturenum, not gltexturenum -qboolean mirror; -mplane_t *mirror_plane; - -// -// view origin -// -vec3_t vup; -vec3_t vpn; -vec3_t vright; -vec3_t r_origin; - -float r_world_matrix[16]; -float r_base_world_matrix[16]; - -// -// screen size info -// -refdef_t r_refdef; - -mleaf_t *r_viewleaf, *r_oldviewleaf; - -texture_t *r_notexture_mip; - -int d_lightstylevalue[256]; // 8.8 fraction of base light value - -// jkrige - .lit colored lights -int gl_coloredstatic; // used to store what type of static light we loaded in Mod_LoadLighting() -// jkrige - .lit colored lights - -void R_MarkLeaves (void); - -cvar_t r_norefresh = {"r_norefresh","0"}; -cvar_t r_drawentities = {"r_drawentities","1"}; -cvar_t r_drawviewmodel = {"r_drawviewmodel","1"}; -cvar_t r_speeds = {"r_speeds","0"}; -cvar_t r_fullbright = {"r_fullbright","0"}; -cvar_t r_lightmap = {"r_lightmap","0"}; -//cvar_t r_shadows = {"r_shadows","0"}; // jkrige - removed alias shadows -cvar_t r_mirroralpha = {"r_mirroralpha","1"}; -cvar_t r_wateralpha = {"r_wateralpha","1"}; -cvar_t r_dynamic = {"r_dynamic","1"}; -cvar_t r_novis = {"r_novis","0"}; - -// jkrige - fix dynamic light shine through -cvar_t r_dynamic_sidemark = {"r_dynamic_sidemark", "1", true}; -// jkrige - fix dynamic light shine through - -// jkrige - remove gl_finish -//cvar_t gl_finish = {"gl_finish","0"}; -// jkrige - remove gl_finish - -// jkrige - changed gl_clear default value -//cvar_t gl_clear = {"gl_clear", "0"}; -cvar_t gl_clear = {"gl_clear", "1", true}; -// jkrige - changed gl_clear default value - -cvar_t gl_cull = {"gl_cull","1"}; -cvar_t gl_texsort = {"gl_texsort","1"}; -cvar_t gl_smoothmodels = {"gl_smoothmodels","1"}; -cvar_t gl_affinemodels = {"gl_affinemodels","0"}; -cvar_t gl_polyblend = {"gl_polyblend","1"}; - -// jkrige - flashblend removal -//cvar_t gl_flashblend = {"gl_flashblend","1"}; -// jkrige - flashblend removal - -cvar_t gl_playermip = {"gl_playermip","0"}; -cvar_t gl_nocolors = {"gl_nocolors","0"}; - -// jkrige - disabled tjunction removal -//cvar_t gl_keeptjunctions = {"gl_keeptjunctions","0"}; -//cvar_t gl_reporttjunctions = {"gl_reporttjunctions","0"}; -// jkrige - disabled tjunction removal - -cvar_t gl_skytype = {"gl_skytype", "0"}; // jkrige - skybox : 0 = default, 1 = skybox - -cvar_t gl_doubleeyes = {"gl_doubleeys", "1"}; - -// jkrige - texture mode -cvar_t gl_texturemode = {"gl_texturemode", "0", true}; -// jkrige - texture mode - -// jkrige - wireframe -cvar_t gl_wireframe = {"gl_wireframe", "0"}; -// jkrige - wireframe - -// jkrige - .lit colored lights -cvar_t gl_coloredlight = {"gl_coloredlight", "0", true}; -// jkrige - .lit colored lights - -extern cvar_t gl_ztrick; - -/* -================= -R_CullBox - -Returns true if the box is completely outside the frustom -================= -*/ -qboolean R_CullBox (vec3_t mins, vec3_t maxs) -{ - int i; - - for (i=0 ; i<4 ; i++) - if (BoxOnPlaneSide (mins, maxs, &frustum[i]) == 2) - return true; - return false; -} - - -void R_RotateForEntity (entity_t *e) -{ -#ifdef UQ_GLDEBUG - glTranslatef (e->origin[0], e->origin[1], e->origin[2]); - - glRotatef (e->angles[1], 0, 0, 1); - glRotatef (-e->angles[0], 0, 1, 0); - glRotatef (e->angles[2], 1, 0, 0); -#endif -} - -/* -============================================================= - - SPRITE MODELS - -============================================================= -*/ - -/* -================ -R_GetSpriteFrame -================ -*/ -mspriteframe_t *R_GetSpriteFrame (entity_t *currententity) -{ - msprite_t *psprite; - mspritegroup_t *pspritegroup; - mspriteframe_t *pspriteframe; - int i, numframes, frame; - float *pintervals, fullinterval, targettime, time; - - psprite = currententity->model->cache.data; - frame = currententity->frame; - - if ((frame >= psprite->numframes) || (frame < 0)) - { - Con_Printf ("R_DrawSprite: no such frame %d\n", frame); - frame = 0; - } - - if (psprite->frames[frame].type == SPR_SINGLE) - { - pspriteframe = psprite->frames[frame].frameptr; - } - else - { - pspritegroup = (mspritegroup_t *)psprite->frames[frame].frameptr; - pintervals = pspritegroup->intervals; - numframes = pspritegroup->numframes; - fullinterval = pintervals[numframes-1]; - - time = cl.time + currententity->syncbase; - - // when loading in Mod_LoadSpriteGroup, we guaranteed all interval values - // are positive, so we don't have to worry about division by 0 - targettime = time - ((int)(time / fullinterval)) * fullinterval; - - for (i=0 ; i<(numframes-1) ; i++) - { - if (pintervals[i] > targettime) - break; - } - - pspriteframe = pspritegroup->frames[i]; - } - - return pspriteframe; -} - - -/* -================= -R_DrawSpriteModel - -================= -*/ -void R_DrawSpriteModel (entity_t *e) -{ -#ifdef UQ_GLDEBUG - vec3_t point; - mspriteframe_t *frame; - float *up, *right; - vec3_t v_forward, v_right, v_up; - msprite_t *psprite; - - // don't even bother culling, because it's just a single - // polygon without a surface cache - frame = R_GetSpriteFrame (e); - psprite = currententity->model->cache.data; - - if (psprite->type == SPR_ORIENTED) - { // bullet marks on walls - AngleVectors (currententity->angles, v_forward, v_right, v_up); - up = v_up; - right = v_right; - } - else - { // normal sprite - up = vup; - right = vright; - } - - glColor3f (1,1,1); - - // jkrige - remove multitexture - //GL_DisableMultitexture(); - // jkrige - remove multitexture - - GL_Bind(frame->gl_texturenum); - - glEnable (GL_ALPHA_TEST); - glBegin (GL_QUADS); - - glTexCoord2f (0, 1); - VectorMA (e->origin, frame->down, up, point); - VectorMA (point, frame->left, right, point); - glVertex3fv (point); - - glTexCoord2f (0, 0); - VectorMA (e->origin, frame->up, up, point); - VectorMA (point, frame->left, right, point); - glVertex3fv (point); - - glTexCoord2f (1, 0); - VectorMA (e->origin, frame->up, up, point); - VectorMA (point, frame->right, right, point); - glVertex3fv (point); - - glTexCoord2f (1, 1); - VectorMA (e->origin, frame->down, up, point); - VectorMA (point, frame->right, right, point); - glVertex3fv (point); - - glEnd (); - - glDisable (GL_ALPHA_TEST); -#endif // UQ_GLDEBUG -} - -/* -============================================================= - - ALIAS MODELS - -============================================================= -*/ - - -#define NUMVERTEXNORMALS 162 - -float r_avertexnormals[NUMVERTEXNORMALS][3] = { -#include "anorms.h" -}; - -// jkrige - removed alias shadows -//vec3_t shadevector; -// jkrige - removed alias shadows - -// jkrige - .lit colored lights -//float shadelight, ambientlight; -float shadelight; -// jkrige - .lit colored lights - - - -// precalculated dot products for quantized angles -#define SHADEDOT_QUANT 16 -float r_avertexnormal_dots[SHADEDOT_QUANT][256] = -#include "anorm_dots.h" -; - -float *shadedots = r_avertexnormal_dots[0]; - -// jkrige - static light vector -float cm_pitch; -float lightvec[3] = {0.0f, 0.0f, 0.0f}; -// jkrige - static light vector - - -// jkrige - light lerping -float *shadedots2 = r_avertexnormal_dots[0]; -float lightlerpoffset; -// jkrige - light lerping - - - -int lastposenum; - -// jkrige - .lit colored lights -extern vec3_t lightcolor; -// jkrige - .lit colored lights - - -// jkrige - fullbright pixels -void GL_DrawAliasFrame2 (aliashdr_t *paliashdr, int posenum, int anim, qboolean fullbrights) -{ -#ifdef UQ_GLDEBUG - float s, t; - float l; - int i, j; - int index; - trivertx_t *v, *verts; - int list; - int *order; - vec3_t point; - float *normal; - int count; - - // jkrige - static light vector - float dir_light; - // jkrige - static light vector - - // jkrige - light lerping - float l1, l2, diff; - // jkrige - light lerping - - lastposenum = posenum; - - verts = (trivertx_t *)((byte *)paliashdr + paliashdr->posedata); - verts += posenum * paliashdr->poseverts; - order = (int *)((byte *)paliashdr + paliashdr->commands); - - if (fullbrights == true) - { - if (r_fullbright.value) - return; - - if(gl_lumatex_render.value != 1) - return; - - GL_Bind (JK_LUMA_TEX + paliashdr->gl_texturenum[currententity->skinnum][anim]); - - glDepthMask (GL_FALSE); - glEnable(GL_BLEND); - - glBlendFunc (GL_ONE, GL_ONE); - } - - while (1) - { - // get the vertex count and primitive type - count = *order++; - if (!count) - break; // done - if (count < 0) - { - count = -count; - glBegin (GL_TRIANGLE_FAN); - } - else - glBegin (GL_TRIANGLE_STRIP); - - do - { - // texture coordinates come from the draw list - glTexCoord2f (((float *)order)[0], ((float *)order)[1]); - order += 2; - - // normals and vertexes come from the frame list - - if (fullbrights == false) - { - // jkrige - static light vector - dir_light = DotProduct(r_avertexnormals[verts->lightnormalindex], lightvec); - if (dir_light > 0.0f) - { - // jkrige - light lerping - l1 = (shadedots[verts->lightnormalindex] * shadelight) + dir_light; - l2 = (shadedots2[verts->lightnormalindex] * shadelight) + dir_light; - //l = ambientlight + dir_light; - // jkrige - light lerping - } - else - { - // jkrige - light lerping - l1 = shadedots[verts->lightnormalindex] * shadelight; - l2 = shadedots2[verts->lightnormalindex] * shadelight; - //l = ambientlight; - // jkrige - light lerping - } - // jkrige - static light vector - - - // jkrige - light lerping - if (l1 != l2) - { - if (l1 > l2) - { - diff = l1 - l2; - diff *= lightlerpoffset; - l = l1 - diff; - } - else - { - diff = l2 - l1; - diff *= lightlerpoffset; - l = l1 + diff; - } - } - else - { - l = l1; - } - // jkrige - light lerping - - // jkrige - wireframe - if (gl_wireframe.value) - l = 1; - // jkrige - wireframe - - // jkrige - .lit colored lights - //l = shadedots[verts->lightnormalindex]; - glColor3f (l * lightcolor[0], l * lightcolor[1], l * lightcolor[2]); - //l = shadedots[verts->lightnormalindex] * shadelight; - //glColor3f (l, l, l); - // jkrige - .lit colored lights - } - else - { - glColor3f (1.0f, 1.0f, 1.0f); - } - - - glVertex3f (verts->v[0], verts->v[1], verts->v[2]); - verts++; - } while (--count); - - glEnd (); - } - - if (fullbrights == true) - { - glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - - glDisable(GL_BLEND); - glDepthMask (GL_TRUE); - } -#endif // UQ_GLDEBUG -} -// jkrige - fullbright pixels - -/* -============= -GL_DrawAliasFrame -============= -*/ -void GL_DrawAliasFrame (aliashdr_t *paliashdr, int posenum, int skinnum, int anim) -{ - GL_DrawAliasFrame2(paliashdr, posenum, anim, false); - - if (paliashdr->skin_luma[skinnum] == true) - { - GL_DrawAliasFrame2(paliashdr, posenum, anim, true); - - if (paliashdr->skin_luma8bit[skinnum] == false) - GL_DrawAliasFrame2(paliashdr, posenum, anim, true); - } -} - - -/* -============= -GL_DrawAliasShadow -============= -*/ -//extern vec3_t lightspot; -// jkrige - removed alias shadows -/*void GL_DrawAliasShadow (aliashdr_t *paliashdr, int posenum) -{ - float s, t, l; - int i, j; - int index; - trivertx_t *v, *verts; - int list; - int *order; - vec3_t point; - float *normal; - float height, lheight; - int count; - - lheight = currententity->origin[2] - lightspot[2]; - - height = 0; - verts = (trivertx_t *)((byte *)paliashdr + paliashdr->posedata); - verts += posenum * paliashdr->poseverts; - order = (int *)((byte *)paliashdr + paliashdr->commands); - - height = -lheight + 1.0; - - while (1) - { - // get the vertex count and primitive type - count = *order++; - if (!count) - break; // done - if (count < 0) - { - count = -count; - glBegin (GL_TRIANGLE_FAN); - } - else - glBegin (GL_TRIANGLE_STRIP); - - do - { - // texture coordinates come from the draw list - // (skipped for shadows) glTexCoord2fv ((float *)order); - order += 2; - - // normals and vertexes come from the frame list - point[0] = verts->v[0] * paliashdr->scale[0] + paliashdr->scale_origin[0]; - point[1] = verts->v[1] * paliashdr->scale[1] + paliashdr->scale_origin[1]; - point[2] = verts->v[2] * paliashdr->scale[2] + paliashdr->scale_origin[2]; - - point[0] -= shadevector[0]*(point[2]+lheight); - point[1] -= shadevector[1]*(point[2]+lheight); - point[2] = height; -// height -= 0.001; - glVertex3fv (point); - - verts++; - } while (--count); - - glEnd (); - } -}*/ -// jkrige - removed alias shadows - - -/* -================= -R_SetupAliasFrame - -================= -*/ -void R_SetupAliasFrame (int frame, aliashdr_t *paliashdr, int skinnum, int anim) -{ - int pose, numposes; - float interval; - - if ((frame >= paliashdr->numframes) || (frame < 0)) - { - Con_DPrintf ("R_AliasSetupFrame: no such frame %d\n", frame); - frame = 0; - } - - pose = paliashdr->frames[frame].firstpose; - numposes = paliashdr->frames[frame].numposes; - - if (numposes > 1) - { - interval = paliashdr->frames[frame].interval; - pose += (int)(cl.time / interval) % numposes; - } - - GL_DrawAliasFrame (paliashdr, pose, skinnum, anim); -} - - -// jkrige - armabody.mdl hack -void R_DrawArmaBodyHack(entity_t *e) -{ -#ifdef UQ_GLDEBUG - int i; - int anim; - aliashdr_t *paliashdr; - - if (currententity->frame == 97) - return; - - if (strcmp(currententity->model->name, "progs/armalegs.mdl")) - return; - - paliashdr = (aliashdr_t *)Mod_Extradata(currententity->model - 1); - - c_alias_polys += paliashdr->numtris; - - // - // draw all the triangles - // - - glPushMatrix(); - - R_RotateForEntity(e); - - if (!strcmp(currententity->model->name, "progs/eyes.mdl") && gl_doubleeyes.value) - { - glTranslatef(paliashdr->scale_origin[0], paliashdr->scale_origin[1], paliashdr->scale_origin[2] - (22 + 8)); - - // double size of eyes, since they are really hard to see in gl - glScalef(paliashdr->scale[0] * 2, paliashdr->scale[1] * 2, paliashdr->scale[2] * 2); - } - else - { - glTranslatef(paliashdr->scale_origin[0], paliashdr->scale_origin[1], paliashdr->scale_origin[2]); - glScalef(paliashdr->scale[0], paliashdr->scale[1], paliashdr->scale[2]); - } - - anim = (int)(cl.time * 10) & 3; - GL_Bind(paliashdr->gl_texturenum[currententity->skinnum][anim]); - - // we can't dynamically colormap textures, so they are cached - // seperately for the players. Heads are just uncolored. - if (currententity->colormap != vid.colormap && !gl_nocolors.value) - { - i = currententity - cl_entities; - if (i >= 1 && i <= cl.maxclients /* && !strcmp (currententity->model->name, "progs/player.mdl") */) - GL_Bind(playertextures - 1 + i); - } - - if (gl_smoothmodels.value) - glShadeModel(GL_SMOOTH); - glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); - - if (gl_affinemodels.value) - glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST); - - - R_SetupAliasFrame(currententity->frame, paliashdr, currententity->skinnum, anim); - - - glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); - - glShadeModel(GL_FLAT); - if (gl_affinemodels.value) - glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); - - - glPopMatrix(); -#endif // UQ_GLDEBUG -} -// jkrige - armabody.mdl hack - - -/* -================= -R_DrawAliasModel - -================= -*/ -void R_DrawAliasModel (entity_t *e) -{ - int i, j; - int lnum; - vec3_t dist; - float add; - model_t *clmodel; - vec3_t mins, maxs; - aliashdr_t *paliashdr; - trivertx_t *verts, *v; - int index; - float s, t, an; - int anim; - - // jkrige - light lerping - float ang_ceil, ang_floor; - // jkrige - light lerping - - clmodel = currententity->model; - - VectorAdd (currententity->origin, clmodel->mins, mins); - VectorAdd (currententity->origin, clmodel->maxs, maxs); - - if (R_CullBox (mins, maxs)) - return; - - - VectorCopy (currententity->origin, r_entorigin); - VectorSubtract (r_origin, r_entorigin, modelorg); - - // - // get lighting information - // - - // jkrige - .lit colored lights - shadelight = R_LightPoint(currententity->origin); - //ambientlight = shadelight = R_LightPoint (currententity->origin); - // jkrige - .lit colored lights - - // allways give the gun some light - // jkrige - reduced amount of minimum light on gun (view weapon) - //if (e == &cl.viewent && ambientlight < 24) - // ambientlight = shadelight = 24; - - // jkrige - .lit colored lights - if (e == &cl.viewent) - { - if (lightcolor[0] < 10) - lightcolor[0] = 10; - if (lightcolor[1] < 10) - lightcolor[1] = 10; - if (lightcolor[2] < 10) - lightcolor[2] = 10; - - if(shadelight < 8) - shadelight = 8; - } - //if (e == &cl.viewent && ambientlight < 10) - // ambientlight = shadelight = 10; - // jkrige - .lit colored lights - - // jkrige - reduced amount of minimum light on gun (view weapon) - - - // jkrige - glowing rotating items - if (currententity->model->flags & EF_ROTATE) - { - float shadelightdelta = (255.0f - shadelight) / 2.0f; - lightcolor[0] = lightcolor[1] = lightcolor[2] = shadelight + ((shadelightdelta * sin(cl.time * 3.5f)) + shadelightdelta) / 2.0f; - } - // jkrige - glowing rotating items - - - for (lnum=0 ; lnum= cl.time) - { - VectorSubtract (currententity->origin, cl_dlights[lnum].origin, dist); - add = cl_dlights[lnum].radius - Length(dist); - - // jkrige - .lit colored lights - if (add > 0) - { - lightcolor[0] += add * cl_dlights[lnum].color[0]; - lightcolor[1] += add * cl_dlights[lnum].color[1]; - lightcolor[2] += add * cl_dlights[lnum].color[2]; - - //ambientlight += add; - //ZOID models should be affected by dlights as well - //shadelight += add; - } - // jkrige - .lit colored lights - } - } - - - // jkrige - static light vector - // Set up light direction (from above) - cm_pitch = currententity->angles[PITCH] * ((float)M_PI / 180.0f); - lightvec[0] = sin(cm_pitch); - lightvec[2] = cos(cm_pitch); - // jkrige - static light vector - - - // clamp lighting so it doesn't overbright as much - // jkrige - static light vector - //if (ambientlight > 128) - // ambientlight = 128; - //if (ambientlight + shadelight > 192) - // shadelight = 192 - ambientlight; - // jkrige - static light vector - - // ZOID: never allow players to go totally black - i = currententity - cl_entities; - if (i >= 1 && i<=cl.maxclients /* && !strcmp (currententity->model->name, "progs/player.mdl") */) - { - // jkrige - .lit colored lights - if (lightcolor[0] < 10) - lightcolor[0] = 10; - if (lightcolor[1] < 10) - lightcolor[1] = 10; - if (lightcolor[2] < 10) - lightcolor[2] = 10; - - if(shadelight < 8) - shadelight = 8; - //if (ambientlight < 8) - // ambientlight = shadelight = 8; - // jkrige - .lit colored lights - } - - // HACK HACK HACK -- no fullbright colors, so make torches full light - if ( - !strcmp (clmodel->name, "progs/flame2.mdl") - | !strcmp (clmodel->name, "progs/flame.mdl") - | !strcmp (clmodel->name, "progs/lavaball.mdl") // jkrige - lavaball fullbright - | !strcmp (clmodel->name, "progs/bolt.mdl") // jkrige - lightning bolt fullbright - | !strcmp (clmodel->name, "progs/bolt2.mdl") // jkrige - lightning bolt fullbright - | !strcmp (clmodel->name, "progs/bolt3.mdl") // jkrige - lightning bolt fullbright - | !strcmp (clmodel->name, "progs/k_spike.mdl") // jkrige - death knight spike fullbright - | !strcmp (clmodel->name, "progs/laser.mdl") // jkrige - enforcer laser fullbright - | !strcmp (clmodel->name, "progs/v_spike.mdl") // jkrige - vore spike fullbright - | !strcmp (clmodel->name, "progs/spike.mdl") // jkrige - nailgun spike fullbright - | !strcmp (clmodel->name, "progs/missile.mdl") // jkrige - rocket launcher missile fullbright - | !strcmp (clmodel->name, "progs/w_spike.mdl") // jkrige - scrag spike fullbright - | !strcmp (clmodel->name, "progs/b_g_key.mdl") // jkrige - b_g_key fullbright - | !strcmp (clmodel->name, "progs/b_s_key.mdl") // jkrige - b_s_key fullbright - | !strcmp (clmodel->name, "progs/m_g_key.mdl") // jkrige - b_g_key fullbright - | !strcmp (clmodel->name, "progs/m_s_key.mdl") // jkrige - b_s_key fullbright - | !strcmp (clmodel->name, "progs/w_g_key.mdl") // jkrige - w_g_key fullbright - | !strcmp (clmodel->name, "progs/w_s_key.mdl") // jkrige - w_s_key fullbright - | !strcmp (clmodel->name, "progs/boss.mdl") // jkrige - boss fullbright - | !strcmp (clmodel->name, "progs/end1.mdl") // jkrige - end1 fullbright - | !strcmp (clmodel->name, "progs/end2.mdl") // jkrige - end1 fullbright - | !strcmp (clmodel->name, "progs/end3.mdl") // jkrige - end1 fullbright - | !strcmp (clmodel->name, "progs/end4.mdl") // jkrige - end1 fullbright - ) - { - lightcolor[0] = lightcolor[1] = lightcolor[2] = 256; - shadelight = 256; - //ambientlight = shadelight = 256; - } - - - // jkrige - wireframe - if (gl_wireframe.value) - { - lightcolor[0] = lightcolor[1] = lightcolor[2] = 256; - shadelight = 256; - } - // jkrige - wireframe - - - // jkrige - light lerping - lightlerpoffset = e->angles[YAW] * (SHADEDOT_QUANT / 360.0); - ang_ceil = ceil(lightlerpoffset); - ang_floor = floor(lightlerpoffset); - - lightlerpoffset = ang_ceil - lightlerpoffset; - //shadedots = r_avertexnormal_dots[((int)(e->angles[1] * (SHADEDOT_QUANT / 360.0))) & (SHADEDOT_QUANT - 1)]; - shadedots = r_avertexnormal_dots[(int)ang_ceil & (SHADEDOT_QUANT - 1)]; - shadedots2 = r_avertexnormal_dots[(int)ang_floor & (SHADEDOT_QUANT - 1)]; - // jkrige - light lerping - - - // jkrige - .lit colored lights - VectorScale(lightcolor, 1.0f / 192.0f, lightcolor); - shadelight = shadelight / 192.0; - // jkrige - .lit colored lights - - - // jkrige - removed alias shadows - //an = e->angles[1]/180*M_PI; - //shadevector[0] = cos(-an); - //shadevector[1] = sin(-an); - //shadevector[2] = 1; - //VectorNormalize (shadevector); - // jkrige - removed alias shadows - - // - // locate the proper data - // - - paliashdr = (aliashdr_t *)Mod_Extradata(currententity->model); - - c_alias_polys += paliashdr->numtris; - -#ifdef UQ_GLDEBUG - - // - // draw all the triangles - // - - // jkrige - remove multitexture - //GL_DisableMultitexture(); - // jkrige - remove multitexture - - glPushMatrix(); - - - R_RotateForEntity(e); - - if (!strcmp(clmodel->name, "progs/eyes.mdl") && gl_doubleeyes.value) - { - glTranslatef(paliashdr->scale_origin[0], paliashdr->scale_origin[1], paliashdr->scale_origin[2] - (22 + 8)); - - // double size of eyes, since they are really hard to see in gl - glScalef(paliashdr->scale[0] * 2, paliashdr->scale[1] * 2, paliashdr->scale[2] * 2); - } - else - { - glTranslatef(paliashdr->scale_origin[0], paliashdr->scale_origin[1], paliashdr->scale_origin[2]); - glScalef(paliashdr->scale[0], paliashdr->scale[1], paliashdr->scale[2]); - } - - anim = (int)(cl.time * 10) & 3; - GL_Bind(paliashdr->gl_texturenum[currententity->skinnum][anim]); - - // we can't dynamically colormap textures, so they are cached - // seperately for the players. Heads are just uncolored. - if (currententity->colormap != vid.colormap && !gl_nocolors.value) - { - i = currententity - cl_entities; - if (i >= 1 && i <= cl.maxclients /* && !strcmp (currententity->model->name, "progs/player.mdl") */) - GL_Bind(playertextures - 1 + i); - } - - if (gl_smoothmodels.value) - glShadeModel(GL_SMOOTH); - glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); - - if (gl_affinemodels.value) - glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST); - - - R_SetupAliasFrame(currententity->frame, paliashdr, currententity->skinnum, anim); - - - glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); - - glShadeModel(GL_FLAT); - if (gl_affinemodels.value) - glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); - - - glPopMatrix(); - - // jkrige - armabody.mdl hack - R_DrawArmaBodyHack(e); - // jkrige - armabody.mdl hack - - - // jkrige - removed alias shadows - /*if (r_shadows.value) - { - glPushMatrix (); - R_RotateForEntity (e); - glDisable (GL_TEXTURE_2D); - glEnable (GL_BLEND); - glColor4f (0,0,0,0.5); - GL_DrawAliasShadow (paliashdr, lastposenum); - glEnable (GL_TEXTURE_2D); - glDisable (GL_BLEND); - glColor4f (1,1,1,1); - glPopMatrix (); - }*/ - // jkrige - removed alias shadows -#endif // UQ_GLDEBUG -} - -//================================================================================== - -/* -============= -R_DrawEntitiesOnList -============= -*/ -void R_DrawEntitiesOnList (void) -{ - int i; - - if (!r_drawentities.value) - return; - - // draw sprites seperately, because of alpha blending - for (i=0 ; imodel->type) - { - case mod_alias: - R_DrawAliasModel (currententity); - break; - - case mod_brush: - R_DrawBrushModel (currententity); - break; - - default: - break; - } - } - - for (i=0 ; imodel->type) - { - case mod_sprite: - R_DrawSpriteModel (currententity); - break; - } - } -} - -/* -============= -R_DrawViewModel -============= -*/ -void R_DrawViewModel (void) -{ - // jkrige - weirdly enough most of the code in this function is useless - // the min lighting is already handled within the "R_DrawAliasModel" function - - // jkrige - min light level - //float ambient[4], diffuse[4]; - //int j; - // jkrige - min light level - - //int lnum; - //vec3_t dist; - //float add; - //dlight_t *dl; - - // jkrige - min light level - //int ambientlight, shadelight; - // jkrige - min light level - - if (!r_drawviewmodel.value) - return; - - // jkrige - removed chase - //if (chase_active.value) - // return; - // jkrige - removed chase - - if (envmap) - return; - - if (!r_drawentities.value) - return; - - if (cl.items & IT_INVISIBILITY) - return; - - if (cl.stats[STAT_HEALTH] <= 0) - return; - - currententity = &cl.viewent; - if (!currententity->model) - return; - - // jkrige - min light level - //j = R_LightPoint (currententity->origin); - //if (j < 24) - // j = 24; // allways give some light on gun - //ambientlight = j; - //shadelight = j; - //ambientlight = 0.75f * R_LightPoint(currententity->origin); - //ambientlight = 0.01f; - // jkrige - min light level - -// add dynamic lights - /*for (lnum=0 ; lnumradius) - continue; - if (!dl->radius) - continue; - if (dl->die < cl.time) - continue; - - VectorSubtract (currententity->origin, dl->origin, dist); - add = dl->radius - Length(dist); - if (add > 0) - ambientlight += add; - }*/ - - // jkrige - min light level - //cl.light_level = (ambientlight > 255) ? 255 : ((ambientlight < 18) ? 18 : ambientlight); - // jkrige - min light level - - //ambient[0] = ambient[1] = ambient[2] = ambient[3] = (float)ambientlight / 128; - //diffuse[0] = diffuse[1] = diffuse[2] = diffuse[3] = (float)shadelight / 128; - -#ifdef UQ_GLDEBUG - // hack the depth range to prevent view model from poking into walls - glDepthRange (gldepthmin, gldepthmin + 0.3*(gldepthmax-gldepthmin)); - R_DrawAliasModel (currententity); - glDepthRange (gldepthmin, gldepthmax); -#endif // UQ_GLDEBUG -} - - -/* -============ -R_PolyBlend -============ -*/ -// jkrige - 2D polyblend -void R_PolyBlend (void) -{ -#ifdef UQ_GLDEBUG - if (!gl_polyblend.value) - return; - - if (!v_blend[3]) - return; - - glAlphaFunc(GL_ALWAYS, 0); - - glLoadIdentity (); - - glEnable (GL_BLEND); - glDisable (GL_TEXTURE_2D); - - glColor4fv (v_blend); - - glBegin (GL_QUADS); - glVertex2f (0,0); - glVertex2f (vid.width, 0); - glVertex2f (vid.width, vid.height); - glVertex2f (0, vid.height); - glEnd (); - - glColor4f (1,1,1,1); - - glEnable (GL_TEXTURE_2D); - glDisable (GL_BLEND); - - glAlphaFunc(GL_GREATER, 0.632); -#endif // UQ_GLDEBUG -} -/*void R_PolyBlend (void) -{ - if (!gl_polyblend.value) - return; - if (!v_blend[3]) - return; - - // jkrige - remove multitexture - //GL_DisableMultitexture(); - // jkrige - remove multitexture - - glDisable (GL_ALPHA_TEST); - glEnable (GL_BLEND); - glDisable (GL_DEPTH_TEST); - glDisable (GL_TEXTURE_2D); - - glLoadIdentity (); - - glRotatef (-90, 1, 0, 0); // put Z going up - glRotatef (90, 0, 0, 1); // put Z going up - - glColor4fv (v_blend); - - glBegin (GL_QUADS); - - glVertex3f (10, 100, 100); - glVertex3f (10, -100, 100); - glVertex3f (10, -100, -100); - glVertex3f (10, 100, -100); - glEnd (); - - glDisable (GL_BLEND); - glEnable (GL_TEXTURE_2D); - glEnable (GL_ALPHA_TEST); -}*/ -// jkrige - 2D polyblend - - -int SignbitsForPlane (mplane_t *out) -{ - int bits, j; - - // for fast box on planeside test - - bits = 0; - for (j=0 ; j<3 ; j++) - { - if (out->normal[j] < 0) - bits |= 1< 1) - Cvar_Set ("r_fullbright", "0"); - - R_AnimateLight (); - - r_framecount++; - -// build the transformation matrix for the given view angles - VectorCopy (r_refdef.vieworg, r_origin); - - AngleVectors (r_refdef.viewangles, vpn, vright, vup); - -// current viewleaf - r_oldviewleaf = r_viewleaf; - r_viewleaf = Mod_PointInLeaf (r_origin, cl.worldmodel); - - V_SetContentsColor (r_viewleaf->contents); - V_CalcBlend (); - - r_cache_thrash = false; - - c_brush_polys = 0; - c_alias_polys = 0; - -} - -#ifdef UQ_GLDEBUG -void MYgluPerspective( GLdouble fovy, GLdouble aspect, - GLdouble zNear, GLdouble zFar ) -{ - GLdouble xmin, xmax, ymin, ymax; - - ymax = zNear * tan( fovy * M_PI / 360.0 ); - ymin = -ymax; - - xmin = ymin * aspect; - xmax = ymax * aspect; - - glFrustum( xmin, xmax, ymin, ymax, zNear, zFar ); -} -#endif // UQ_GLDEBUG - - -/* -============= -R_SetupGL -============= -*/ -void R_SetupGL (void) -{ -#ifdef UQ_GLDEBUG - float screenaspect; - float yfov; - int i; - extern int glwidth, glheight; - int x, x2, y2, y, w, h; - - // jkrige - water warp (contents) - double f; - // jkrige - water warp (contents) - - - // - // set up viewpoint - // - glMatrixMode(GL_PROJECTION); - glLoadIdentity (); - - // jkrige - scale2d - //x = r_refdef.vrect.x * glwidth/vid.width; - //x2 = (r_refdef.vrect.x + r_refdef.vrect.width) * glwidth/vid.width; - //y = (vid.height-r_refdef.vrect.y) * glheight/vid.height; - //y2 = (vid.height - (r_refdef.vrect.y + r_refdef.vrect.height)) * glheight/vid.height; - if (Scale2DFactor > 1.0f) - { - x = r_refdef.vrect.x * glwidth/modelist[(int)vid_mode.value].width /*320*/; - x2 = (r_refdef.vrect.x + r_refdef.vrect.width) * glwidth/modelist[(int)vid_mode.value].width /*320*/; - y = (modelist[(int)vid_mode.value].height /*200*/ -r_refdef.vrect.y) * glheight/modelist[(int)vid_mode.value].height /*200*/; - y2 = (modelist[(int)vid_mode.value].height /*200*/ - (r_refdef.vrect.y + r_refdef.vrect.height)) * glheight/modelist[(int)vid_mode.value].height /*200*/; - } - else - { - // jkrige - scale2d (original) - x = r_refdef.vrect.x * glwidth/vid.width /*320*/; - x2 = (r_refdef.vrect.x + r_refdef.vrect.width) * glwidth/vid.width /*320*/; - y = (vid.height/*200*/-r_refdef.vrect.y) * glheight/vid.height /*200*/; - y2 = (vid.height/*200*/ - (r_refdef.vrect.y + r_refdef.vrect.height)) * glheight/vid.height /*200*/; - // jkrige - scale2d (original) - } - // jkrige - scale2d - - - // fudge around because of frac screen scale - if (x > 0) - x--; - if (x2 < glwidth) - x2++; - if (y2 < 0) - y2--; - if (y < glheight) - y++; - - w = x2 - x; - h = y - y2; - - if (envmap) - { - x = y2 = 0; - w = h = 256; - } - - glViewport (glx + x, gly + y2, w, h); - - // jkrige - field of view (fov) fix - //screenaspect = (float)r_refdef.vrect.width/(float)r_refdef.vrect.height; - //yfov = 2*atan((float)r_refdef.vrect.height/r_refdef.vrect.width)*180/M_PI; - screenaspect = (float)vid.width/(float)vid.height; - yfov = r_refdef.fov_y; - // jkrige - field of view (fov) fix - - - // jkrige - water warp (contents) - if ((r_viewleaf->contents == CONTENTS_WATER || r_viewleaf->contents == CONTENTS_LAVA || r_viewleaf->contents == CONTENTS_SLIME)) - { - f = sin(realtime * 0.15 * (M_PI * 2.7)); - screenaspect = screenaspect - (1 - f) * 0.05 * 1; - yfov = r_refdef.fov_y - (1 + f) * 1; - } - // jkrige - water warp (contents) - - - // jkrige - updated near & far planes - MYgluPerspective (yfov, screenaspect, 2, 6144); - //MYgluPerspective (r_refdef.fov_y, screenaspect, 4, 4096); - // jkrige - updated near & far planes - - - if (mirror) - { - if (mirror_plane->normal[2]) - glScalef (1, -1, 1); - else - glScalef (-1, 1, 1); - glCullFace(GL_BACK); - } - else - glCullFace(GL_FRONT); - - glMatrixMode(GL_MODELVIEW); - glLoadIdentity (); - - glRotatef (-90, 1, 0, 0); // put Z going up - glRotatef (90, 0, 0, 1); // put Z going up - glRotatef (-r_refdef.viewangles[2], 1, 0, 0); - glRotatef (-r_refdef.viewangles[0], 0, 1, 0); - glRotatef (-r_refdef.viewangles[1], 0, 0, 1); - glTranslatef (-r_refdef.vieworg[0], -r_refdef.vieworg[1], -r_refdef.vieworg[2]); - - glGetFloatv (GL_MODELVIEW_MATRIX, r_world_matrix); - - // - // set drawing parms - // - if (gl_cull.value) - glEnable(GL_CULL_FACE); - else - glDisable(GL_CULL_FACE); - - glDisable(GL_BLEND); - glDisable(GL_ALPHA_TEST); - glEnable(GL_DEPTH_TEST); -#endif // UQ_GLDEBUG -} - -/* -================ -R_RenderScene - -r_refdef must be set before the first call -================ -*/ -void R_RenderScene (void) -{ - R_SetupFrame (); - - R_SetFrustum (); - - R_SetupGL (); - - R_MarkLeaves (); // done here so we know if we're in water - - R_DrawWorld (); // adds static entities to the list - - S_ExtraUpdate (); // don't let sound get messed up if going slow - - R_DrawEntitiesOnList (); - - // jkrige - remove multitexture - //GL_DisableMultitexture(); - // jkrige - remove multitexture - - // jkrige - flashblend removal - //R_RenderDlights (); - // jkrige - flashblend removal - - R_DrawParticles (); - -#ifdef GLTEST - Test_Draw (); -#endif - -} - - -/* -============= -R_Clear -============= -*/ -void R_Clear (void) -{ -#ifdef UQ_GLDEBUG - if (r_mirroralpha.value != 1.0) - { - if (gl_clear.value) - glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - else - glClear (GL_DEPTH_BUFFER_BIT); - gldepthmin = 0; - gldepthmax = 0.5; - glDepthFunc (GL_LEQUAL); - } - else if (gl_ztrick.value) - { - static int trickframe; - - if (gl_clear.value) - glClear (GL_COLOR_BUFFER_BIT); - - trickframe++; - if (trickframe & 1) - { - gldepthmin = 0; - gldepthmax = 0.49999; - glDepthFunc (GL_LEQUAL); - } - else - { - gldepthmin = 1; - gldepthmax = 0.5; - glDepthFunc (GL_GEQUAL); - } - } - else - { - if (gl_clear.value) - glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - else - glClear (GL_DEPTH_BUFFER_BIT); - gldepthmin = 0; - gldepthmax = 1; - glDepthFunc (GL_LEQUAL); - } - - glDepthRange (gldepthmin, gldepthmax); -#endif // UQ_GLDEBUG -} - -/* -============= -R_Mirror -============= -*/ -void R_Mirror (void) -{ -#ifdef UQ_GLDEBUG - float d; - msurface_t *s; - entity_t *ent; - - if (!mirror) - return; - - memcpy (r_base_world_matrix, r_world_matrix, sizeof(r_base_world_matrix)); - - d = DotProduct (r_refdef.vieworg, mirror_plane->normal) - mirror_plane->dist; - VectorMA (r_refdef.vieworg, -2*d, mirror_plane->normal, r_refdef.vieworg); - - d = DotProduct (vpn, mirror_plane->normal); - VectorMA (vpn, -2*d, mirror_plane->normal, vpn); - - r_refdef.viewangles[0] = -asin (vpn[2])/M_PI*180; - r_refdef.viewangles[1] = atan2 (vpn[1], vpn[0])/M_PI*180; - r_refdef.viewangles[2] = -r_refdef.viewangles[2]; - - ent = &cl_entities[cl.viewentity]; - if (cl_numvisedicts < MAX_VISEDICTS) - { - cl_visedicts[cl_numvisedicts] = ent; - cl_numvisedicts++; - } - - gldepthmin = 0.5; - gldepthmax = 1; - glDepthRange (gldepthmin, gldepthmax); - glDepthFunc (GL_LEQUAL); - - R_RenderScene (); - R_DrawWaterSurfaces (); - - gldepthmin = 0; - gldepthmax = 0.5; - glDepthRange (gldepthmin, gldepthmax); - glDepthFunc (GL_LEQUAL); - - // blend on top - glEnable (GL_BLEND); - glMatrixMode(GL_PROJECTION); - if (mirror_plane->normal[2]) - glScalef (1,-1,1); - else - glScalef (-1,1,1); - glCullFace(GL_FRONT); - glMatrixMode(GL_MODELVIEW); - - glLoadMatrixf (r_base_world_matrix); - - glColor4f (1,1,1,r_mirroralpha.value); - s = cl.worldmodel->textures[mirrortexturenum]->texturechain; - for ( ; s ; s=s->texturechain) - R_RenderBrushPoly (s); - cl.worldmodel->textures[mirrortexturenum]->texturechain = NULL; - glDisable (GL_BLEND); - glColor4f (1,1,1,1); -#endif // UQ_GLDEBUG -} - -/* -================ -R_RenderView - -r_refdef must be set before the first call -================ -*/ -void R_RenderView (void) -{ - double time1, time2; - GLfloat colors[4] = {(GLfloat) 0.0, (GLfloat) 0.0, (GLfloat) 1, (GLfloat) 0.20}; - - if (r_norefresh.value) - return; - - if (!r_worldentity.model || !cl.worldmodel) - Sys_Error ("R_RenderView: NULL worldmodel"); - - if (r_speeds.value) - { -#ifdef UQ_GLDEBUG - glFinish (); -#endif // UQ_GLDEBUG - time1 = Sys_FloatTime (); - c_brush_polys = 0; - c_alias_polys = 0; - } - - mirror = false; - - // jkrige - remove gl_finish - //if (gl_finish.value) - // glFinish (); - // jkrige - remove gl_finish - - // jkrige - scale2d - COM_SetScale2D(); - // jkrige - scale2d - - R_Clear (); - - // render normal view - - /***** Experimental silly looking fog ****** - ****** Use r_fullbright if you enable ****** - glFogi(GL_FOG_MODE, GL_LINEAR); - glFogfv(GL_FOG_COLOR, colors); - glFogf(GL_FOG_END, 512.0); - glEnable(GL_FOG); - ********************************************/ - - - // jkrige - wireframe - if (gl_wireframe.value != 0.0f && gl_wireframe.value != 1.0f) - Cvar_Set("gl_wireframe", "0"); - - if (cl.gametype == GAME_DEATHMATCH) - Cvar_Set("gl_wireframe", "0"); - -#ifdef UQ_GLDEBUG - if (gl_wireframe.value) - glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); - // jkrige - wireframe -#endif // UQ_GLDEBUG - - - R_RenderScene (); - R_DrawViewModel (); - R_DrawWaterSurfaces (); - -// More fog right here :) -// glDisable(GL_FOG); -// End of all fog code... - - // render mirror view - R_Mirror (); - - // jkrige - 2D polyblend - //R_PolyBlend (); - // jkrige - 2D polyblend - -#ifdef UQ_GLDEBUG - // jkrige - wireframe - if (gl_wireframe.value) - glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); - // jkrige - wireframe -#endif // UQ_GLDEBUG - - if (r_speeds.value) - { -// glFinish (); - time2 = Sys_FloatTime (); - Con_Printf ("%3i ms %4i wpoly %4i epoly\n", (int)((time2-time1)*1000), c_brush_polys, c_alias_polys); - } -} diff --git a/engine/code/gl_rmisc.c b/engine/code/gl_rmisc.c deleted file mode 100644 index f7d7feb..0000000 --- a/engine/code/gl_rmisc.c +++ /dev/null @@ -1,552 +0,0 @@ -/* -Copyright (C) 1996-1997 Id Software, Inc. - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ -// r_misc.c - -#include "quakedef.h" - - - -/* -================== -R_InitTextures -================== -*/ -void R_InitTextures (void) -{ - int x,y, m; - byte *dest; - -// create a simple checkerboard texture for the default - r_notexture_mip = Hunk_AllocName (sizeof(texture_t) + 16*16+8*8+4*4+2*2, "notexture"); - - r_notexture_mip->width = r_notexture_mip->height = 16; - r_notexture_mip->offsets[0] = sizeof(texture_t); - r_notexture_mip->offsets[1] = r_notexture_mip->offsets[0] + 16*16; - r_notexture_mip->offsets[2] = r_notexture_mip->offsets[1] + 8*8; - r_notexture_mip->offsets[3] = r_notexture_mip->offsets[2] + 4*4; - - for (m=0 ; m<4 ; m++) - { - dest = (byte *)r_notexture_mip + r_notexture_mip->offsets[m]; - for (y=0 ; y< (16>>m) ; y++) - for (x=0 ; x< (16>>m) ; x++) - { - if ( (y< (8>>m) ) ^ (x< (8>>m) ) ) - *dest++ = 0; - else - *dest++ = 0xff; - } - } -} - -byte dottexture[8][8] = -{ - {0,1,1,0,0,0,0,0}, - {1,1,1,1,0,0,0,0}, - {1,1,1,1,0,0,0,0}, - {0,1,1,0,0,0,0,0}, - {0,0,0,0,0,0,0,0}, - {0,0,0,0,0,0,0,0}, - {0,0,0,0,0,0,0,0}, - {0,0,0,0,0,0,0,0}, -}; - -// jkrige - texture mode -byte dottexture_point[8][8] = -{ - {1,1,1,0,0,0,0,0}, - {1,1,1,0,0,0,0,0}, - {1,1,1,0,0,0,0,0}, - {0,0,0,0,0,0,0,0}, - {0,0,0,0,0,0,0,0}, - {0,0,0,0,0,0,0,0}, - {0,0,0,0,0,0,0,0}, - {0,0,0,0,0,0,0,0}, -}; - -void R_InitParticleTexture_Linear (void) -{ -#ifdef UQ_GLDEBUG - int x,y; - byte data[8][8][4]; - - // - // particle texture - // - particletexture_linear = texture_extension_number++; - GL_Bind(particletexture_linear); - - for (x=0 ; x<8 ; x++) - { - for (y=0 ; y<8 ; y++) - { - data[y][x][0] = 255; - data[y][x][1] = 255; - data[y][x][2] = 255; - data[y][x][3] = dottexture[x][y]*255; - } - } - glTexImage2D (GL_TEXTURE_2D, 0, gl_alpha_format, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE, data); - - glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); - - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); -#endif // UQ_GLDEBUG -} - -void R_InitParticleTexture_Point (void) -{ -#ifdef UQ_GLDEBUG - int x,y; - byte data[8][8][4]; - - // - // particle texture - // - particletexture_point = texture_extension_number++; - GL_Bind(particletexture_point); - - for (x=0 ; x<8 ; x++) - { - for (y=0 ; y<8 ; y++) - { - data[y][x][0] = 255; - data[y][x][1] = 255; - data[y][x][2] = 255; - data[y][x][3] = dottexture_point[x][y]*255; - } - } - glTexImage2D (GL_TEXTURE_2D, 0, gl_alpha_format, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE, data); - - glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); - - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); -#endif // UQ_GLDEBUG -} - -void R_InitParticleTexture (void) -{ - R_InitParticleTexture_Point(); - R_InitParticleTexture_Linear(); -} -// jkrige - texture mode - -/* -=============== -R_Envmap_f - -Grab six views for environment mapping tests -=============== -*/ -void R_Envmap_f (void) -{ -#ifdef UQ_GLDEBUG - byte buffer[256*256*4]; - char name[1024]; - - glDrawBuffer (GL_FRONT); - glReadBuffer (GL_FRONT); - envmap = true; - - r_refdef.vrect.x = 0; - r_refdef.vrect.y = 0; - r_refdef.vrect.width = 256; - r_refdef.vrect.height = 256; - - r_refdef.viewangles[0] = 0; - r_refdef.viewangles[1] = 0; - r_refdef.viewangles[2] = 0; - GL_BeginRendering (&glx, &gly, &glwidth, &glheight); - R_RenderView (); - glReadPixels (0, 0, 256, 256, GL_RGBA, GL_UNSIGNED_BYTE, buffer); - COM_WriteFile ("env0.rgb", buffer, sizeof(buffer)); - - r_refdef.viewangles[1] = 90; - GL_BeginRendering (&glx, &gly, &glwidth, &glheight); - R_RenderView (); - glReadPixels (0, 0, 256, 256, GL_RGBA, GL_UNSIGNED_BYTE, buffer); - COM_WriteFile ("env1.rgb", buffer, sizeof(buffer)); - - r_refdef.viewangles[1] = 180; - GL_BeginRendering (&glx, &gly, &glwidth, &glheight); - R_RenderView (); - glReadPixels (0, 0, 256, 256, GL_RGBA, GL_UNSIGNED_BYTE, buffer); - COM_WriteFile ("env2.rgb", buffer, sizeof(buffer)); - - r_refdef.viewangles[1] = 270; - GL_BeginRendering (&glx, &gly, &glwidth, &glheight); - R_RenderView (); - glReadPixels (0, 0, 256, 256, GL_RGBA, GL_UNSIGNED_BYTE, buffer); - COM_WriteFile ("env3.rgb", buffer, sizeof(buffer)); - - r_refdef.viewangles[0] = -90; - r_refdef.viewangles[1] = 0; - GL_BeginRendering (&glx, &gly, &glwidth, &glheight); - R_RenderView (); - glReadPixels (0, 0, 256, 256, GL_RGBA, GL_UNSIGNED_BYTE, buffer); - COM_WriteFile ("env4.rgb", buffer, sizeof(buffer)); - - r_refdef.viewangles[0] = 90; - r_refdef.viewangles[1] = 0; - GL_BeginRendering (&glx, &gly, &glwidth, &glheight); - R_RenderView (); - glReadPixels (0, 0, 256, 256, GL_RGBA, GL_UNSIGNED_BYTE, buffer); - COM_WriteFile ("env5.rgb", buffer, sizeof(buffer)); - - envmap = false; - glDrawBuffer (GL_BACK); - glReadBuffer (GL_BACK); - GL_EndRendering (); -#endif // UQ_GLDEBUG -} - -/* -=============== -R_Init -=============== -*/ -void R_Init (void) -{ - extern byte *hunk_base; - - // jkrige - remove gl_finish - //extern cvar_t gl_finish; - // jkrige - remove gl_finish - - Cmd_AddCommand ("timerefresh", R_TimeRefresh_f); - Cmd_AddCommand ("envmap", R_Envmap_f); - Cmd_AddCommand ("pointfile", R_ReadPointFile_f); - - Cvar_RegisterVariable (&r_norefresh); - Cvar_RegisterVariable (&r_lightmap); - Cvar_RegisterVariable (&r_fullbright); - Cvar_RegisterVariable (&r_drawentities); - Cvar_RegisterVariable (&r_drawviewmodel); - //Cvar_RegisterVariable (&r_shadows); // jkrige - removed alias shadows - Cvar_RegisterVariable (&r_mirroralpha); - Cvar_RegisterVariable (&r_wateralpha); - Cvar_RegisterVariable (&r_dynamic); - Cvar_RegisterVariable (&r_novis); - Cvar_RegisterVariable (&r_speeds); - - // jkrige - fix dynamic light shine through - Cvar_RegisterVariable (&r_dynamic_sidemark); - // jkrige - fix dynamic light shine through - - // jkrige - remove gl_finish - //Cvar_RegisterVariable (&gl_finish); - // jkrige - remove gl_finish - - Cvar_RegisterVariable (&gl_clear); - Cvar_RegisterVariable (&gl_texsort); - - // jkrige - remove multitexture - //if (gl_mtexable) - // Cvar_SetValue ("gl_texsort", 0.0); - // jkrige - remove multitexture - - Cvar_RegisterVariable (&gl_cull); - Cvar_RegisterVariable (&gl_smoothmodels); - Cvar_RegisterVariable (&gl_affinemodels); - Cvar_RegisterVariable (&gl_polyblend); - - // jkrige - flashblend removal - //Cvar_RegisterVariable (&gl_flashblend); - // jkrige - flashblend removal - - - Cvar_RegisterVariable (&gl_playermip); - Cvar_RegisterVariable (&gl_nocolors); - - // jkrige - disabled tjunction removal - //Cvar_RegisterVariable (&gl_keeptjunctions); - //Cvar_RegisterVariable (&gl_reporttjunctions); - // jkrige - disabled tjunction removal - - Cvar_RegisterVariable (&gl_skytype); // jkrige - skybox - - Cvar_RegisterVariable (&gl_doubleeyes); - - // jkrige - texture mode - Cvar_RegisterVariable (&gl_texturemode); - // jkrige - texture mode - - // jkrige - wireframe - Cvar_RegisterVariable(&gl_wireframe); - // jkrige - wireframe - - // jkrige - .lit colored lights - Cvar_RegisterVariable (&gl_lightmapfmt); - Cvar_RegisterVariable (&gl_coloredlight); - // jkrige - .lit colored lights - - R_InitParticles (); - R_InitParticleTexture (); - -#ifdef GLTEST - Test_Init (); -#endif - - playertextures = texture_extension_number; - texture_extension_number += 16; -} - -/* -=============== -R_TranslatePlayerSkin - -Translates a skin texture by the per-player color lookup -=============== -*/ -void R_TranslatePlayerSkin (int playernum) -{ - int top, bottom; - byte translate[256]; - unsigned translate32[256]; - int i, j, s; - model_t *model; - aliashdr_t *paliashdr; - byte *original; - unsigned pixels[512*256], *out; - unsigned scaled_width, scaled_height; - int inwidth, inheight; - byte *inrow; - unsigned frac, fracstep; - extern byte **player_8bit_texels_tbl; - - // jkrige - remove multitexture - //GL_DisableMultitexture(); - // jkrige - remove multitexture - - top = cl.scores[playernum].colors & 0xf0; - bottom = (cl.scores[playernum].colors &15)<<4; - - for (i=0 ; i<256 ; i++) - translate[i] = i; - - for (i=0 ; i<16 ; i++) - { - if (top < 128) // the artists made some backwards ranges. sigh. - translate[TOP_RANGE+i] = top+i; - else - translate[TOP_RANGE+i] = top+15-i; - - if (bottom < 128) - translate[BOTTOM_RANGE+i] = bottom+i; - else - translate[BOTTOM_RANGE+i] = bottom+15-i; - } - - // - // locate the original skin pixels - // - currententity = &cl_entities[1+playernum]; - model = currententity->model; - if (!model) - return; // player doesn't have a model yet - if (model->type != mod_alias) - return; // only translate skins on alias models - - paliashdr = (aliashdr_t *)Mod_Extradata (model); - s = paliashdr->skinwidth * paliashdr->skinheight; - if (currententity->skinnum < 0 || currententity->skinnum >= paliashdr->numskins) { - Con_Printf("(%d): Invalid player skin #%d\n", playernum, currententity->skinnum); - original = (byte *)paliashdr + paliashdr->texels[0]; - } else - original = (byte *)paliashdr + paliashdr->texels[currententity->skinnum]; - if (s & 3) - Sys_Error ("R_TranslateSkin: s&3"); - - inwidth = paliashdr->skinwidth; - inheight = paliashdr->skinheight; - -#ifdef UQ_GLDEBUG - // because this happens during gameplay, do it fast - // instead of sending it through gl_upload 8 - GL_Bind(playertextures + playernum); - -#if 0 - byte translated[320*200]; - - for (i=0 ; iskinwidth, paliashdr->skinheight, false, false, true); -#else - scaled_width = gl_max_size.value < 512 ? gl_max_size.value : 512; - scaled_height = gl_max_size.value < 256 ? gl_max_size.value : 256; - - // allow users to crunch sizes down even more if they want - scaled_width >>= (int)gl_playermip.value; - scaled_height >>= (int)gl_playermip.value; - - // jkrige - no 8bit palette extensions - /*if (VID_Is8bit()) { // 8bit texture upload - byte *out2; - - out2 = (byte *)pixels; - memset(pixels, 0, sizeof(pixels)); - fracstep = inwidth*0x10000/scaled_width; - for (i=0 ; i> 1; - for (j=0 ; j>16]]; - frac += fracstep; - out2[j+1] = translate[inrow[frac>>16]]; - frac += fracstep; - out2[j+2] = translate[inrow[frac>>16]]; - frac += fracstep; - out2[j+3] = translate[inrow[frac>>16]]; - frac += fracstep; - } - } - - GL_Upload8_EXT ((byte *)pixels, scaled_width, scaled_height, false, false); - return; - }*/ - // jkrige - no 8bit palette extensions - - for (i=0 ; i<256 ; i++) - translate32[i] = d_8to24table[translate[i]]; - - out = pixels; - fracstep = inwidth*0x10000/scaled_width; - for (i=0 ; i> 1; - for (j=0 ; j>16]]; - frac += fracstep; - out[j+1] = translate32[inrow[frac>>16]]; - frac += fracstep; - out[j+2] = translate32[inrow[frac>>16]]; - frac += fracstep; - out[j+3] = translate32[inrow[frac>>16]]; - frac += fracstep; - } - } - glTexImage2D (GL_TEXTURE_2D, 0, gl_solid_format, scaled_width, scaled_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels); - - glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); -#endif -#endif // UQ_GLDEBUG -} - - -/* -=============== -R_NewMap -=============== -*/ -void R_NewMap (void) -{ - int i; - - for (i=0 ; i<256 ; i++) - d_lightstylevalue[i] = 264; // normal light value - - memset (&r_worldentity, 0, sizeof(r_worldentity)); - r_worldentity.model = cl.worldmodel; - -// clear out efrags in case the level hasn't been reloaded -// FIXME: is this one short? - for (i=0 ; inumleafs ; i++) - cl.worldmodel->leafs[i].efrags = NULL; - - r_viewleaf = NULL; - R_ClearParticles (); - - GL_BuildLightmaps (); - - // identify sky texture - skytexturenum = -1; - mirrortexturenum = -1; - for (i=0 ; inumtextures ; i++) - { - if (!cl.worldmodel->textures[i]) - continue; - if (!Q_strncmp(cl.worldmodel->textures[i]->name,"sky",3) ) - skytexturenum = i; - if (!Q_strncmp(cl.worldmodel->textures[i]->name,"window02_1",10) ) - mirrortexturenum = i; - cl.worldmodel->textures[i]->texturechain = NULL; - } -//#ifdef QUAKE2 // jkrige - skybox -// R_LoadSkys (); -//#endif -} - - -/* -==================== -R_TimeRefresh_f - -For program optimization -==================== -*/ -void R_TimeRefresh_f (void) -{ -#ifdef UQ_GLDEBUG - int i; - float start, stop, time; - int startangle; - vrect_t vr; - - glDrawBuffer (GL_FRONT); - glFinish (); - - start = Sys_FloatTime (); - for (i=0 ; i<128 ; i++) - { - r_refdef.viewangles[1] = i/128.0*360.0; - R_RenderView (); - } - - glFinish (); - stop = Sys_FloatTime (); - time = stop-start; - Con_Printf ("%f seconds (%f fps)\n", time, 128/time); - - glDrawBuffer (GL_BACK); - GL_EndRendering (); -#endif -} - -void D_FlushCaches (void) -{ -} - - diff --git a/engine/code/gl_rsurf.c b/engine/code/gl_rsurf.c deleted file mode 100644 index 612bb4a..0000000 --- a/engine/code/gl_rsurf.c +++ /dev/null @@ -1,2245 +0,0 @@ -/* -Copyright (C) 1996-1997 Id Software, Inc. - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ -// r_surf.c: surface-related refresh code - -#include "quakedef.h" - -int skytexturenum; - -#ifndef GL_RGBA4 -#define GL_RGBA4 0 -#endif - - -// jkrige - .lit colored lights -int gl_lightmap_format = GL_RGBA; -cvar_t gl_lightmapfmt = {"gl_lightmapfmt", "GL_RGBA", true}; -int lightmap_bytes = 4; // 1, 2, or 4. default is 4 for GL_RGBA -GLuint lightmap_textures; -//int lightmap_bytes; // 1, 2, or 4 -//int lightmap_textures; -// jkrige - .lit colored lights - - -unsigned blocklights[18*18]; - -// jkrige - .lit colored lights -static unsigned int blocklightscolor[18*18*3]; // colored light support. *3 for RGB to the definitions at the top -// jkrige - .lit colored lights - -#define BLOCK_WIDTH 128 -#define BLOCK_HEIGHT 128 - -#define MAX_LIGHTMAPS 64 -int active_lightmaps; - -typedef struct glRect_s { - unsigned char l,t,w,h; -} glRect_t; - -glpoly_t *lightmap_polys[MAX_LIGHTMAPS]; -qboolean lightmap_modified[MAX_LIGHTMAPS]; -glRect_t lightmap_rectchange[MAX_LIGHTMAPS]; - -int allocated[MAX_LIGHTMAPS][BLOCK_WIDTH]; - -// the lightmap texture data needs to be kept in -// main memory so texsubimage can update properly -byte lightmaps[4*MAX_LIGHTMAPS*BLOCK_WIDTH*BLOCK_HEIGHT]; - -// For gl_texsort 0 -msurface_t *skychain = NULL; -msurface_t *waterchain = NULL; - -void R_RenderDynamicLightmaps (msurface_t *fa); - -/* -=============== -R_AddDynamicLights -=============== -*/ -void R_AddDynamicLights (msurface_t *surf) -{ - int lnum; - int sd, td; - float dist, rad, minlight; - vec3_t impact, local; - int s, t; - int i; - int smax, tmax; - mtexinfo_t *tex; - - // jkrige - .lit colored lights - float cred, cgreen, cblue, brightness; - unsigned int *bl; - // jkrige - .lit colored lights - - smax = (surf->extents[0]>>4)+1; - tmax = (surf->extents[1]>>4)+1; - tex = surf->texinfo; - - for (lnum=0 ; lnumdlightbits & (1<dlightbits[(lnum >> 3)] & (1 << (lnum & 7)))) - continue; - // jkrige - increase dlights - - rad = cl_dlights[lnum].radius; - dist = DotProduct (cl_dlights[lnum].origin, surf->plane->normal) - - surf->plane->dist; - rad -= fabs(dist); - minlight = cl_dlights[lnum].minlight; - if (rad < minlight) - continue; - minlight = rad - minlight; - - for (i=0 ; i<3 ; i++) - { - impact[i] = cl_dlights[lnum].origin[i] - - surf->plane->normal[i]*dist; - } - - local[0] = DotProduct (impact, tex->vecs[0]) + tex->vecs[0][3]; - local[1] = DotProduct (impact, tex->vecs[1]) + tex->vecs[1][3]; - - local[0] -= surf->texturemins[0]; - local[1] -= surf->texturemins[1]; - - - // jkrige - .lit colored lights - bl = blocklightscolor; - cred = cl_dlights[lnum].color[0] * 256.0f; - cgreen = cl_dlights[lnum].color[1] * 256.0f; - cblue = cl_dlights[lnum].color[2] * 256.0f; - - for (t = 0; t < tmax; t++) - { - td = local[1] - t*16; - if (td < 0) - td = -td; - for (s = 0; s < smax; s++) - { - sd = local[0] - s*16; - if (sd < 0) - sd = -sd; - if (sd > td) - dist = sd + (td>>1); - else - dist = td + (sd>>1); - if (dist < minlight) - { - brightness = rad - dist; - bl[0] += (int) (brightness * cred); - bl[1] += (int) (brightness * cgreen); - bl[2] += (int) (brightness * cblue); - - blocklights[t*smax + s] += (rad - dist)*256; - } - - bl += 3; - } - } - /*for (t = 0 ; t td) - dist = sd + (td>>1); - else - dist = td + (sd>>1); - if (dist < minlight) - blocklights[t*smax + s] += (rad - dist)*256; - } - }*/ - // jkrige - .lit colored lights - } -} - - -// jkrige - .lit colored lights -/* -=============== -GL_SetupLightmapFmt - -Used to setup the lightmap_format and lightmap_bytes -at every level change and at first video initialization. -Best to be called from Mod_LoadLighting() in gl_model.c -=============== -*/ -void GL_SetupLightmapFmt (qboolean check_cmdline) -{ - // only GL_LUMINANCE and GL_RGBA are actually supported - // commenting out other options - if (!Q_strcasecmp(gl_lightmapfmt.string, "GL_LUMINANCE")) - gl_lightmap_format = GL_LUMINANCE; - else if (!Q_strcasecmp(gl_lightmapfmt.string, "GL_RGBA")) - gl_lightmap_format = GL_RGBA; -#if 0 - else if (!Q_strcasecmp(gl_lightmapfmt.string, "GL_ALPHA")) - gl_lightmap_format = GL_ALPHA; - else if (!Q_strcasecmp(gl_lightmapfmt.string, "GL_INTENSITY")) - gl_lightmap_format = GL_INTENSITY; -#endif - else - { - gl_lightmap_format = GL_RGBA; - Cvar_Set ("gl_lightmapfmt", "GL_RGBA"); - } - - // check for commandline overrides - if (check_cmdline) - { - if (COM_CheckParm ("-lm_1")) - { - gl_lightmap_format = GL_LUMINANCE; - Cvar_Set ("gl_lightmapfmt", "GL_LUMINANCE"); - } - else if (COM_CheckParm ("-lm_4")) - { - gl_lightmap_format = GL_RGBA; - Cvar_Set ("gl_lightmapfmt", "GL_RGBA"); - } -#if 0 -// else if (COM_CheckParm ("-lm_2")) -// { -// gl_lightmap_format = GL_RGBA4; -// Cvar_Set ("gl_lightmapfmt", "GL_RGBA4"); -// } - else if (COM_CheckParm ("-lm_a")) - { - gl_lightmap_format = GL_ALPHA; - Cvar_Set ("gl_lightmapfmt", "GL_ALPHA"); - } - else if (COM_CheckParm ("-lm_i")) - { - gl_lightmap_format = GL_INTENSITY; - Cvar_Set ("gl_lightmapfmt", "GL_INTENSITY"); - } -#endif - } - - switch (gl_lightmap_format) - { - case GL_RGBA: - lightmap_bytes = 4; - break; -// case GL_RGBA4: -// lightmap_bytes = 2; -// break; - case GL_LUMINANCE: - case GL_INTENSITY: - case GL_ALPHA: - lightmap_bytes = 1; - break; - } -} -// jkrige - .lit colored lights - - -/* -=============== -R_BuildLightMap - -Combine and scale multiple lightmaps into the 8.8 format in blocklights -=============== -*/ -void R_BuildLightMap (msurface_t *surf, byte *dest, int stride) -{ - int smax, tmax; - int t; - // jkrige - .lit colored lights - int r, s, q; - // jkrige - .lit colored lights - int i, j, size; - byte *lightmap; - unsigned scale; - int maps; - //int lightadj[4]; - - // jkrige - .lit colored lights - //unsigned *bl; - unsigned int *bl, *blcr, *blcg, *blcb; - // jkrige - .lit colored lights - - // jkrige - overbrights - int lightshift; - - if (gl_overbright.value) - lightshift = 8; - else - lightshift = 7; - // jkrige - overbrights - - - surf->cached_dlight = (surf->dlightframe == r_framecount); - - smax = (surf->extents[0]>>4)+1; - tmax = (surf->extents[1]>>4)+1; - size = smax*tmax; - lightmap = surf->samples; - -// set to full bright if no light data - if (r_fullbright.value || !cl.worldmodel->lightdata) - { - // jkrige - .lit colored lights - for (i = 0; i < size; i++) - { - if (gl_lightmap_format == GL_RGBA) - blocklightscolor[i*3+0] = - blocklightscolor[i*3+1] = - blocklightscolor[i*3+2] = 65280; - else - blocklights[i] = 255*256; - } - //for (i=0 ; istyles[maps] != 255 ; - maps++) - { - scale = d_lightstylevalue[surf->styles[maps]]; - surf->cached_light[maps] = scale; // 8.8 fraction - - // jkrige - .lit colored lights - if (gl_lightmap_format == GL_RGBA) - { - for (i = 0, j = 0; i < size; i++) - { - blocklightscolor[i*3+0] += lightmap[j] * scale; - blocklightscolor[i*3+1] += lightmap[++j] * scale; - blocklightscolor[i*3+2] += lightmap[++j] * scale; - j++; - } - - lightmap += size * 3; - } - else - { - for (i = 0; i < size; i++) - blocklights[i] += lightmap[i] * scale; - lightmap += size; // skip to next lightmap - } - //for (i=0 ; idlightframe == r_framecount) - R_AddDynamicLights (surf); - -// bound, invert, and shift -store: - switch (gl_lightmap_format) - { - case GL_RGBA: - stride -= (smax<<2); - - // jkrige - .lit colored lights - blcr = &blocklightscolor[0]; - blcg = &blocklightscolor[1]; - blcb = &blocklightscolor[2]; - //bl = blocklights; - // jkrige - .lit colored lights - - for (i=0 ; i>= 7; - q >>= lightshift; - // jkrige - overbrights - - r = *blcg; - // jkrige - overbrights - //r >>= 7; - r >>= lightshift; - // jkrige - overbrights - - s = *blcb; - // jkrige - overbrights - //s >>= 7; - s >>= lightshift; - // jkrige - overbrights - - if (q > 255) - q = 255; - if (r > 255) - r = 255; - if (s > 255) - s = 255; - - if (gl_coloredlight.value == 1) - { - dest[0] = q; //255 - q; - dest[1] = r; //255 - r; - dest[2] = s; //255 - s; - dest[3] = 255; //(q+r+s)/3; - } - else - { - t = (int) ( ((float)q * 0.33f) + ((float)s * 0.33f) + ((float)r * 0.33f) ); - - if (t > 255) - t = 255; - dest[0] = t; - dest[1] = t; - dest[2] = t; - dest[3] = 255; //t; - } - - dest += 4; - - blcr += 3; - blcg += 3; - blcb += 3; - - //t = *bl++; - //t >>= 7; - //if (t > 255) - // t = 255; - //dest[3] = 255-t; - //dest += 4; - // jkrige - .lit colored lights - } - } - break; - case GL_ALPHA: - case GL_LUMINANCE: - case GL_INTENSITY: - bl = blocklights; - for (i=0 ; i>= 7; - t >>= lightshift; - // jkrige - overbrights - if (t > 255) - t = 255; - dest[j] = 255-t; - } - } - break; - default: - Sys_Error ("Bad lightmap format"); - } -} - - -/* -=============== -R_TextureAnimation - -Returns the proper texture for a given time and base texture -=============== -*/ -texture_t *R_TextureAnimation (texture_t *base) -{ - int reletive; - int count; - - if (currententity->frame) - { - if (base->alternate_anims) - base = base->alternate_anims; - } - - if (!base->anim_total) - return base; - - reletive = (int)(cl.time*10) % base->anim_total; - - count = 0; - while (base->anim_min > reletive || base->anim_max <= reletive) - { - base = base->anim_next; - if (!base) - Sys_Error ("R_TextureAnimation: broken cycle"); - if (++count > 100) - Sys_Error ("R_TextureAnimation: infinite cycle"); - } - - return base; -} - - -/* -============================================================= - - BRUSH MODELS - -============================================================= -*/ - - -extern int solidskytexture; -extern int alphaskytexture; -extern float speedscale; // for top sky and bottom sky - -void DrawGLWaterPoly (glpoly_t *p); -void DrawGLWaterPolyLightmap (glpoly_t *p); - -// jkrige - remove multitexture -/*lpMTexFUNC qglMTexCoord2fSGIS = NULL; -lpSelTexFUNC qglSelectTextureSGIS = NULL; - -qboolean mtexenabled = false; - -void GL_SelectTexture (GLenum target); - -void GL_DisableMultitexture(void) -{ - if (mtexenabled) { - glDisable(GL_TEXTURE_2D); - GL_SelectTexture(TEXTURE0_SGIS); - mtexenabled = false; - } -} - -void GL_EnableMultitexture(void) -{ - if (gl_mtexable) { - GL_SelectTexture(TEXTURE1_SGIS); - glEnable(GL_TEXTURE_2D); - mtexenabled = true; - } -}*/ -// jkrige - remove multitexture - -#if 0 -/* -================ -R_DrawSequentialPoly - -Systems that have fast state and texture changes can -just do everything as it passes with no need to sort -================ -*/ -void R_DrawSequentialPoly (msurface_t *s) -{ - glpoly_t *p; - float *v; - int i; - texture_t *t; - - // - // normal lightmaped poly - // - if (! (s->flags & (SURF_DRAWSKY|SURF_DRAWTURB/*|SURF_UNDERWATER*/) ) ) // jkrige - waterwarp removal - { - p = s->polys; - - t = R_TextureAnimation (s->texinfo->texture); - GL_Bind (t->gl_texturenum); - glBegin (GL_POLYGON); - v = p->verts[0]; - for (i=0 ; inumverts ; i++, v+= VERTEXSIZE) - { - glTexCoord2f (v[3], v[4]); - glVertex3fv (v); - } - glEnd (); - - GL_Bind (lightmap_textures + s->lightmaptexturenum); - glEnable (GL_BLEND); - glBegin (GL_POLYGON); - v = p->verts[0]; - for (i=0 ; inumverts ; i++, v+= VERTEXSIZE) - { - glTexCoord2f (v[5], v[6]); - glVertex3fv (v); - } - glEnd (); - - glDisable (GL_BLEND); - - return; - } - - // - // subdivided water surface warp - // - if (s->flags & SURF_DRAWTURB) - { - GL_Bind (s->texinfo->texture->gl_texturenum); - EmitWaterPolys (s); - return; - } - - // - // subdivided sky warp - // - if (s->flags & SURF_DRAWSKY) - { - GL_Bind (solidskytexture); - speedscale = realtime*8; - speedscale -= (int)speedscale; - - EmitSkyPolys (s); - - glEnable (GL_BLEND); - glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - GL_Bind (alphaskytexture); - speedscale = realtime*16; - speedscale -= (int)speedscale; - EmitSkyPolys (s); - if (gl_lightmap_format == GL_LUMINANCE) - glBlendFunc (GL_ZERO, GL_ONE_MINUS_SRC_COLOR); - - glDisable (GL_BLEND); - } - - // - // underwater warped with lightmap - // - p = s->polys; - - t = R_TextureAnimation (s->texinfo->texture); - GL_Bind (t->gl_texturenum); - DrawGLWaterPoly (p); - - GL_Bind (lightmap_textures + s->lightmaptexturenum); - glEnable (GL_BLEND); - DrawGLWaterPolyLightmap (p); - glDisable (GL_BLEND); -} -#else -/* -================ -R_DrawSequentialPoly - -Systems that have fast state and texture changes can -just do everything as it passes with no need to sort -================ -*/ -void R_DrawSequentialPoly (msurface_t *s) -{ -#ifdef UQ_GLDEBUG - glpoly_t *p; - float *v; - int i; - texture_t *t; - vec3_t nv, dir; - float ss, ss2, length; - float s1, t1; - glRect_t *theRect; - - // - // normal lightmaped poly - // - - if (! (s->flags & (SURF_DRAWSKY|SURF_DRAWTURB/*|SURF_UNDERWATER*/) ) ) // jkrige - waterwarp removal - { - R_RenderDynamicLightmaps (s); - /*if (gl_mtexable) { // jkrige - remove multitexture - p = s->polys; - - t = R_TextureAnimation (s->texinfo->texture); - // Binds world to texture env 0 - GL_SelectTexture(TEXTURE0_SGIS); - GL_Bind (t->gl_texturenum); - glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); - // Binds lightmap to texenv 1 - GL_EnableMultitexture(); // Same as SelectTexture (TEXTURE1) - GL_Bind (lightmap_textures + s->lightmaptexturenum); - i = s->lightmaptexturenum; - if (lightmap_modified[i]) - { - lightmap_modified[i] = false; - theRect = &lightmap_rectchange[i]; - glTexSubImage2D(GL_TEXTURE_2D, 0, 0, theRect->t, - BLOCK_WIDTH, theRect->h, gl_lightmap_format, GL_UNSIGNED_BYTE, - lightmaps+(i* BLOCK_HEIGHT + theRect->t) *BLOCK_WIDTH*lightmap_bytes); - theRect->l = BLOCK_WIDTH; - theRect->t = BLOCK_HEIGHT; - theRect->h = 0; - theRect->w = 0; - } - glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_BLEND); - glBegin(GL_POLYGON); - v = p->verts[0]; - for (i=0 ; inumverts ; i++, v+= VERTEXSIZE) - { - qglMTexCoord2fSGIS (TEXTURE0_SGIS, v[3], v[4]); - qglMTexCoord2fSGIS (TEXTURE1_SGIS, v[5], v[6]); - glVertex3fv (v); - } - glEnd (); - return; - } else {*/ // jkrige - remove multitexture - p = s->polys; - - t = R_TextureAnimation (s->texinfo->texture); - GL_Bind (t->gl_texturenum); - glBegin (GL_POLYGON); - v = p->verts[0]; - for (i=0 ; inumverts ; i++, v+= VERTEXSIZE) - { - glTexCoord2f (v[3], v[4]); - glVertex3fv (v); - } - glEnd (); - - GL_Bind (lightmap_textures + s->lightmaptexturenum); - glEnable (GL_BLEND); - - // jkrige - .lit colored lights - if (gl_lightmap_format == GL_LUMINANCE) - { - glBlendFunc (GL_ZERO, GL_ONE_MINUS_SRC_COLOR); - } - else if (gl_lightmap_format == GL_INTENSITY) - { - glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); - glColor4f (0.0f,0.0f,0.0f,1.0f); - glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - } - else if (gl_lightmap_format == GL_RGBA) - { - glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); - glColor4f (1.0f,1.0f,1.0f, 1.0f); - glBlendFunc(GL_ZERO, GL_SRC_COLOR); - } - // jkrige - .lit colored lights - - glBegin (GL_POLYGON); - v = p->verts[0]; - for (i=0 ; inumverts ; i++, v+= VERTEXSIZE) - { - glTexCoord2f (v[5], v[6]); - glVertex3fv (v); - } - glEnd (); - - glDisable (GL_BLEND); - //} // jkrige - remove multitexture - - return; - } - - // - // subdivided water surface warp - // - - if (s->flags & SURF_DRAWTURB) - { - // jkrige - remove multitexture - //GL_DisableMultitexture(); - // jkrige - remove multitexture - - GL_Bind (s->texinfo->texture->gl_texturenum); - EmitWaterPolys (s); - return; - } - - // - // subdivided sky warp - // - if (s->flags & SURF_DRAWSKY) - { - // jkrige - remove multitexture - //GL_DisableMultitexture(); - // jkrige - remove multitexture - - GL_Bind (solidskytexture); - speedscale = realtime*8; - speedscale -= (int)speedscale & ~127; - EmitSkyPolys (s); - - glEnable (GL_BLEND); - GL_Bind (alphaskytexture); - speedscale = realtime*16; - speedscale -= (int)speedscale & ~127; - EmitSkyPolys (s); - - glDisable (GL_BLEND); - return; - } - - // - // underwater warped with lightmap - // - R_RenderDynamicLightmaps (s); - /*if (gl_mtexable) { // jkrige - remove multitexture - p = s->polys; - - t = R_TextureAnimation (s->texinfo->texture); - GL_SelectTexture(TEXTURE0_SGIS); - GL_Bind (t->gl_texturenum); - glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); - GL_EnableMultitexture(); - GL_Bind (lightmap_textures + s->lightmaptexturenum); - i = s->lightmaptexturenum; - if (lightmap_modified[i]) - { - lightmap_modified[i] = false; - theRect = &lightmap_rectchange[i]; - glTexSubImage2D(GL_TEXTURE_2D, 0, 0, theRect->t, - BLOCK_WIDTH, theRect->h, gl_lightmap_format, GL_UNSIGNED_BYTE, - lightmaps+(i* BLOCK_HEIGHT + theRect->t) *BLOCK_WIDTH*lightmap_bytes); - theRect->l = BLOCK_WIDTH; - theRect->t = BLOCK_HEIGHT; - theRect->h = 0; - theRect->w = 0; - } - glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_BLEND); - glBegin (GL_TRIANGLE_FAN); - v = p->verts[0]; - for (i=0 ; inumverts ; i++, v+= VERTEXSIZE) - { - qglMTexCoord2fSGIS (TEXTURE0_SGIS, v[3], v[4]); - qglMTexCoord2fSGIS (TEXTURE1_SGIS, v[5], v[6]); - - nv[0] = v[0] + 8*sin(v[1]*0.05+realtime)*sin(v[2]*0.05+realtime); - nv[1] = v[1] + 8*sin(v[0]*0.05+realtime)*sin(v[2]*0.05+realtime); - nv[2] = v[2]; - - glVertex3fv (nv); - } - glEnd (); - - } else {*/ // jkrige - remove multitexture - p = s->polys; - - t = R_TextureAnimation (s->texinfo->texture); - GL_Bind (t->gl_texturenum); - DrawGLWaterPoly (p); - - GL_Bind (lightmap_textures + s->lightmaptexturenum); - glEnable (GL_BLEND); - - // jkrige - .lit colored lights - if (gl_lightmap_format == GL_LUMINANCE) - { - glBlendFunc (GL_ZERO, GL_ONE_MINUS_SRC_COLOR); - } - else if (gl_lightmap_format == GL_INTENSITY) - { - glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); - glColor4f (0.0f,0.0f,0.0f,1.0f); - glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - } - else if (gl_lightmap_format == GL_RGBA) - { - glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); - glColor4f (1.0f,1.0f,1.0f, 1.0f); - glBlendFunc(GL_ZERO, GL_SRC_COLOR); - } - // jkrige - .lit colored lights - - DrawGLWaterPolyLightmap (p); - glDisable (GL_BLEND); - - // jkrige - .lit colored lights - glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); - // jkrige - .lit colored lights - - // jkrige - luma textures - s->luma_mark = true; - // jkrige - luma textures - - - //} // jkrige - remove multitexture -#endif // UQ_GLDEBUG -} -#endif - - -/* -================ -DrawGLWaterPoly - -Warp the vertex coordinates -================ -*/ -void DrawGLWaterPoly (glpoly_t *p) -{ -#ifdef UQ_GLDEBUG - int i; - float *v; - float s, t, os, ot; - vec3_t nv; - - // jkrige - remove multitexture - //GL_DisableMultitexture(); - // jkrige - remove multitexture - - glBegin (GL_TRIANGLE_FAN); - v = p->verts[0]; - for (i=0 ; inumverts ; i++, v+= VERTEXSIZE) - { - glTexCoord2f (v[3], v[4]); - - // jkrige - waterwarp removal - nv[0] = v[0]; // + 8*sin(v[1]*0.05+realtime)*sin(v[2]*0.05+realtime); - nv[1] = v[1]; // + 8*sin(v[0]*0.05+realtime)*sin(v[2]*0.05+realtime); - nv[2] = v[2]; - // jkrige - waterwarp removal - - glVertex3fv (nv); - } - glEnd (); -#endif // UQ_GLDEBUG -} - -void DrawGLWaterPolyLightmap (glpoly_t *p) -{ -#ifdef UQ_GLDEBUG - int i; - float *v; - float s, t, os, ot; - vec3_t nv; - - // jkrige - remove multitexture - //GL_DisableMultitexture(); - // jkrige - remove multitexture - - glBegin (GL_TRIANGLE_FAN); - v = p->verts[0]; - for (i=0 ; inumverts ; i++, v+= VERTEXSIZE) - { - glTexCoord2f (v[5], v[6]); - - // jkrige - waterwarp removal - nv[0] = v[0]; // + 8*sin(v[1]*0.05+realtime)*sin(v[2]*0.05+realtime); - nv[1] = v[1]; // + 8*sin(v[0]*0.05+realtime)*sin(v[2]*0.05+realtime); - nv[2] = v[2]; - // jkrige - waterwarp removal - - glVertex3fv (nv); - } - glEnd (); -#endif -} - -/* -================ -DrawGLPoly -================ -*/ -void DrawGLPoly (glpoly_t *p) -{ -#ifdef UQ_GLDEBUG - int i; - float *v; - - glBegin (GL_POLYGON); - v = p->verts[0]; - for (i=0 ; inumverts ; i++, v+= VERTEXSIZE) - { - glTexCoord2f (v[3], v[4]); - glVertex3fv (v); - } - glEnd (); -#endif -} - - -/* -================ -R_BlendLightmaps -================ -*/ -void R_BlendLightmaps (void) -{ -#if UQ_GLDEBUG - int i, j; - glpoly_t *p; - float *v; - glRect_t *theRect; - - if (r_fullbright.value) - return; - - // jkrige - wireframe - if (gl_wireframe.value) - return; - // jkrige - wireframe - - if (!gl_texsort.value) - return; - - glDepthMask (0); // don't bother writing Z - - if (gl_lightmap_format == GL_LUMINANCE) - { - glBlendFunc (GL_ZERO, GL_ONE_MINUS_SRC_COLOR); - } - else if (gl_lightmap_format == GL_INTENSITY) - { - glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); - glColor4f (0,0,0,1); - glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - } - // jkrige - .lit colored lights - else if (gl_lightmap_format == GL_RGBA) - { - glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); - glColor4f (1.0f,1.0f,1.0f, 1.0f); - //glBlendFunc(GL_DST_COLOR, GL_SRC_COLOR); - glBlendFunc(GL_ZERO, GL_SRC_COLOR); - } - // jkrige - .lit colored lights - - - // jkrige - overbrights - if (gl_overbright.value) - glBlendFunc(GL_DST_COLOR, GL_SRC_COLOR); - // jkrige - overbrights - - if (!r_lightmap.value) - { - glEnable (GL_BLEND); - } - - for (i=0 ; ih, 0, -// gl_lightmap_format, GL_UNSIGNED_BYTE, lightmaps+(i*BLOCK_HEIGHT+theRect->t)*BLOCK_WIDTH*lightmap_bytes); - glTexSubImage2D(GL_TEXTURE_2D, 0, 0, theRect->t, - BLOCK_WIDTH, theRect->h, gl_lightmap_format, GL_UNSIGNED_BYTE, - lightmaps+(i* BLOCK_HEIGHT + theRect->t) *BLOCK_WIDTH*lightmap_bytes); - theRect->l = BLOCK_WIDTH; - theRect->t = BLOCK_HEIGHT; - theRect->h = 0; - theRect->w = 0; - } - for ( ; p ; p=p->chain) - { - if (p->flags & SURF_UNDERWATER) - DrawGLWaterPolyLightmap (p); - else - { - glBegin (GL_POLYGON); - v = p->verts[0]; - for (j=0 ; jnumverts ; j++, v+= VERTEXSIZE) - { - glTexCoord2f (v[5], v[6]); - glVertex3fv (v); - } - glEnd (); - } - } - } - - glDisable (GL_BLEND); - /* - if (gl_lightmap_format == GL_LUMINANCE) - { - glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - } - else if (gl_lightmap_format == GL_INTENSITY) - { - glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); - glColor4f (1,1,1,1); - } - // jkrige - .lit colored lights - else if (gl_lightmap_format == GL_RGBA) - { - glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); - } - // jkrige - .lit colored lights - */ - - // jkrige - .lit colored lights - glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); - glColor4f (1,1,1,1); - // jkrige - .lit colored lights - - glDepthMask (1); // back to normal Z buffering -#endif // UQ_GLDEBUG -} - -// jkrige - luma textures -void R_DrawLumaSurfaces (msurface_t *s, int num_surfaces) -{ -#ifdef UQ_GLDEBUG - int i; - msurface_t *fa; - texture_t *t; - qboolean luma_found = false; - - if (r_fullbright.value) - return; - - // jkrige - wireframe - if (gl_wireframe.value) - return; - // jkrige - wireframe - - if(gl_lumatex_render.value != 1) - return; - - for (fa = s, i = 0; i < num_surfaces; fa++, i++) - { - // find the correct texture - t = R_TextureAnimation (fa->texinfo->texture); - - if(fa->luma_mark == true && t->tex_luma == true) - { - if(luma_found == false) - { - glDepthMask (GL_FALSE); - glEnable (GL_BLEND); - - //glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glBlendFunc (GL_ONE, GL_ONE); - - luma_found = true; - } - - GL_Bind (JK_LUMA_TEX + t->gl_texturenum); - DrawGLPoly (fa->polys); - - // draw luma textures more than once to add more brightness to external textures (hacky?) - if (t->tex_luma8bit == false) - DrawGLPoly (fa->polys); - - fa->luma_mark = false; - } - } - - if(luma_found == true) - { - glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - - glDisable (GL_BLEND); - glDepthMask (GL_TRUE); - } -#endif -} -// jkrige - luma textures - -/* -================ -R_RenderBrushPoly -================ -*/ -void R_RenderBrushPoly (msurface_t *fa) -{ -#ifdef UQ_GLDEBUG - texture_t *t; - byte *base; - int maps; - glRect_t *theRect; - int smax, tmax; - - c_brush_polys++; - - if (fa->flags & SURF_DRAWSKY) - { // warp texture, no lightmaps - EmitBothSkyLayers (fa); - return; - } - - t = R_TextureAnimation (fa->texinfo->texture); - GL_Bind (t->gl_texturenum); - - if (fa->flags & SURF_DRAWTURB) - { // warp texture, no lightmaps - EmitWaterPolys (fa); - return; - } - - - // jkrige - external brushmodel lighting - if(currententity->model != cl.worldmodel && strlen(currententity->model->name) > 0 && currententity->model->name[0] != '*') - { - //float shadelight; - //shadelight = (float)R_LightPoint (currententity->origin); - //shadelight = shadelight / 128.0f; // dividing by 256 makes the brush models seem darker than the surrounding - // environment so we divide by 128, doubling the light strength - - //if(shadelight < 0.0f) - // shadelight = 0.0f; - - //if(shadelight > 1.0f) - // shadelight = 1.0f; - - // jkrige - wireframe - if (!gl_wireframe.value) - { - R_LightPoint(currententity->origin); - VectorScale(lightcolor, 1.0f / 176.0f, lightcolor); - } - else - { - lightcolor[0] = lightcolor[1] = lightcolor[2] = 1.0f; - } - // jkrige - wireframe - - //glColor4f (shadelight, shadelight, shadelight, 1.0f); - glColor4f (lightcolor[0], lightcolor[1], lightcolor[2], 1.0f); - glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); - } - else - { - glColor4f (1.0f, 1.0f, 1.0f, 1.0f); - glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); - } - // jkrige - external brushmodel lighting - - - if (fa->flags & SURF_UNDERWATER) - DrawGLWaterPoly (fa->polys); - else - DrawGLPoly (fa->polys); - - - // jkrige - luma textures - fa->luma_mark = true; - // jkrige - luma textures - - - // add the poly to the proper lightmap chain - - fa->polys->chain = lightmap_polys[fa->lightmaptexturenum]; - lightmap_polys[fa->lightmaptexturenum] = fa->polys; - - - // jkrige - overbrights (need to rebuild the lightmap if this changes) - if (fa->overbright != (qboolean)gl_overbright.value) - { - fa->overbright = (qboolean)gl_overbright.value; - goto dynamic; - } - // jkrige - overbrights - - - // check for lightmap modification - for (maps = 0 ; maps < MAXLIGHTMAPS && fa->styles[maps] != 255 ; - maps++) - if (d_lightstylevalue[fa->styles[maps]] != fa->cached_light[maps]) - goto dynamic; - - if (fa->dlightframe == r_framecount // dynamic this frame - || fa->cached_dlight) // dynamic previously - { -dynamic: - if (r_dynamic.value) - { - lightmap_modified[fa->lightmaptexturenum] = true; - theRect = &lightmap_rectchange[fa->lightmaptexturenum]; - if (fa->light_t < theRect->t) { - if (theRect->h) - theRect->h += theRect->t - fa->light_t; - theRect->t = fa->light_t; - } - if (fa->light_s < theRect->l) { - if (theRect->w) - theRect->w += theRect->l - fa->light_s; - theRect->l = fa->light_s; - } - smax = (fa->extents[0]>>4)+1; - tmax = (fa->extents[1]>>4)+1; - if ((theRect->w + theRect->l) < (fa->light_s + smax)) - theRect->w = (fa->light_s-theRect->l)+smax; - if ((theRect->h + theRect->t) < (fa->light_t + tmax)) - theRect->h = (fa->light_t-theRect->t)+tmax; - base = lightmaps + fa->lightmaptexturenum*lightmap_bytes*BLOCK_WIDTH*BLOCK_HEIGHT; - base += fa->light_t * BLOCK_WIDTH * lightmap_bytes + fa->light_s * lightmap_bytes; - R_BuildLightMap (fa, base, BLOCK_WIDTH*lightmap_bytes); - } - } -#endif // UQ_GLDEBUG -} - -/* -================ -R_RenderDynamicLightmaps -Multitexture -================ -*/ -void R_RenderDynamicLightmaps (msurface_t *fa) -{ - texture_t *t; - byte *base; - int maps; - glRect_t *theRect; - int smax, tmax; - - c_brush_polys++; - - if (fa->flags & ( SURF_DRAWSKY | SURF_DRAWTURB) ) - return; - - fa->polys->chain = lightmap_polys[fa->lightmaptexturenum]; - lightmap_polys[fa->lightmaptexturenum] = fa->polys; - - - // jkrige - overbrights (need to rebuild the lightmap if this changes) - if (fa->overbright != (qboolean)gl_overbright.value) - { - fa->overbright = (qboolean)gl_overbright.value; - goto dynamic; - } - // jkrige - overbrights - - - // check for lightmap modification - for (maps = 0 ; maps < MAXLIGHTMAPS && fa->styles[maps] != 255 ; - maps++) - if (d_lightstylevalue[fa->styles[maps]] != fa->cached_light[maps]) - goto dynamic; - - if (fa->dlightframe == r_framecount // dynamic this frame - || fa->cached_dlight) // dynamic previously - { -dynamic: - if (r_dynamic.value) - { - lightmap_modified[fa->lightmaptexturenum] = true; - theRect = &lightmap_rectchange[fa->lightmaptexturenum]; - if (fa->light_t < theRect->t) { - if (theRect->h) - theRect->h += theRect->t - fa->light_t; - theRect->t = fa->light_t; - } - if (fa->light_s < theRect->l) { - if (theRect->w) - theRect->w += theRect->l - fa->light_s; - theRect->l = fa->light_s; - } - smax = (fa->extents[0]>>4)+1; - tmax = (fa->extents[1]>>4)+1; - if ((theRect->w + theRect->l) < (fa->light_s + smax)) - theRect->w = (fa->light_s-theRect->l)+smax; - if ((theRect->h + theRect->t) < (fa->light_t + tmax)) - theRect->h = (fa->light_t-theRect->t)+tmax; - base = lightmaps + fa->lightmaptexturenum*lightmap_bytes*BLOCK_WIDTH*BLOCK_HEIGHT; - base += fa->light_t * BLOCK_WIDTH * lightmap_bytes + fa->light_s * lightmap_bytes; - R_BuildLightMap (fa, base, BLOCK_WIDTH*lightmap_bytes); - } - } -} - -/* -================ -R_MirrorChain -================ -*/ -void R_MirrorChain (msurface_t *s) -{ - if (mirror) - return; - mirror = true; - mirror_plane = s->plane; -} - - -#if 0 -/* -================ -R_DrawWaterSurfaces -================ -*/ -void R_DrawWaterSurfaces (void) -{ - int i; - msurface_t *s; - texture_t *t; - - if (r_wateralpha.value == 1.0) - return; - - // - // go back to the world matrix - // - glLoadMatrixf (r_world_matrix); - - glEnable (GL_BLEND); - glColor4f (1,1,1,r_wateralpha.value); - glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); - - for (i=0 ; inumtextures ; i++) - { - t = cl.worldmodel->textures[i]; - if (!t) - continue; - s = t->texturechain; - if (!s) - continue; - if ( !(s->flags & SURF_DRAWTURB) ) - continue; - - // set modulate mode explicitly - GL_Bind (t->gl_texturenum); - - for ( ; s ; s=s->texturechain) - R_RenderBrushPoly (s); - - t->texturechain = NULL; - } - - glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); - - glColor4f (1,1,1,1); - glDisable (GL_BLEND); -} -#else -/* -================ -R_DrawWaterSurfaces -================ -*/ -void R_DrawWaterSurfaces (void) -{ -#ifdef UQ_GLDEBUG - int i; - msurface_t *s; - texture_t *t; - - if (r_wateralpha.value == 1.0 && gl_texsort.value) - return; - - // - // go back to the world matrix - // - - glLoadMatrixf (r_world_matrix); - - if (r_wateralpha.value < 1.0) { - glEnable (GL_BLEND); - glColor4f (1,1,1,r_wateralpha.value); - glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); - } - - if (!gl_texsort.value) { - if (!waterchain) - return; - - for ( s = waterchain ; s ; s=s->texturechain) { - GL_Bind (s->texinfo->texture->gl_texturenum); - EmitWaterPolys (s); - } - - waterchain = NULL; - } else { - - for (i=0 ; inumtextures ; i++) - { - t = cl.worldmodel->textures[i]; - if (!t) - continue; - s = t->texturechain; - if (!s) - continue; - if ( !(s->flags & SURF_DRAWTURB ) ) - continue; - - // set modulate mode explicitly - - GL_Bind (t->gl_texturenum); - - for ( ; s ; s=s->texturechain) - EmitWaterPolys (s); - - t->texturechain = NULL; - } - - } - - if (r_wateralpha.value < 1.0) { - glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); - - glColor4f (1,1,1,1); - glDisable (GL_BLEND); - } -#endif // UQ_GLDEBUG -} - -#endif - -/* -================ -DrawTextureChains -================ -*/ -void DrawTextureChains (void) -{ - int i; - msurface_t *s; - texture_t *t; - - if (!gl_texsort.value) { - // jkrige - remove multitexture - //GL_DisableMultitexture(); - // jkrige - remove multitexture - - if (skychain) { - R_DrawSkyChain(skychain); - skychain = NULL; - } - - return; - } - - for (i=0 ; inumtextures ; i++) - { - t = cl.worldmodel->textures[i]; - if (!t) - continue; - s = t->texturechain; - if (!s) - continue; - if (i == skytexturenum) - R_DrawSkyChain (s); - else if (i == mirrortexturenum && r_mirroralpha.value != 1.0) - { - R_MirrorChain (s); - continue; - } - else - { - if ((s->flags & SURF_DRAWTURB) && r_wateralpha.value != 1.0) - continue; // draw translucent water later - for ( ; s ; s=s->texturechain) - R_RenderBrushPoly (s); - } - - t->texturechain = NULL; - } -} - -/* -================= -R_DrawBrushModel -================= -*/ -void R_DrawBrushModel (entity_t *e) -{ - int j, k; - vec3_t mins, maxs; - int i, numsurfaces; - msurface_t *psurf; - float dot; - mplane_t *pplane; - model_t *clmodel; - qboolean rotated; - - currententity = e; - currenttexture = -1; - - clmodel = e->model; - - if (e->angles[0] || e->angles[1] || e->angles[2]) - { - rotated = true; - for (i=0 ; i<3 ; i++) - { - mins[i] = e->origin[i] - clmodel->radius; - maxs[i] = e->origin[i] + clmodel->radius; - } - } - else - { - rotated = false; - VectorAdd (e->origin, clmodel->mins, mins); - VectorAdd (e->origin, clmodel->maxs, maxs); - } - - if (R_CullBox (mins, maxs)) - return; - - glColor3f (1,1,1); - memset (lightmap_polys, 0, sizeof(lightmap_polys)); - - VectorSubtract (r_refdef.vieworg, e->origin, modelorg); - if (rotated) - { - vec3_t temp; - vec3_t forward, right, up; - - VectorCopy (modelorg, temp); - AngleVectors (e->angles, forward, right, up); - modelorg[0] = DotProduct (temp, forward); - modelorg[1] = -DotProduct (temp, right); - modelorg[2] = DotProduct (temp, up); - } - - psurf = &clmodel->surfaces[clmodel->firstmodelsurface]; - -// calculate dynamic lighting for bmodel if it's not an -// instanced model - if (clmodel->firstmodelsurface != 0 /*&& !gl_flashblend.value*/) // jkrige - flashblend removal - { - for (k=0 ; knodes + clmodel->hulls[0].firstclipnode); - R_MarkLights (&cl_dlights[k], k, clmodel->nodes + clmodel->hulls[0].firstclipnode); - // jkrige - increase dlights - } - } - - // jkrige - brush z-fighting - glEnable(GL_POLYGON_OFFSET_FILL); - // jkrige - brush z-fighting - - glPushMatrix (); - e->angles[0] = -e->angles[0]; // stupid quake bug - R_RotateForEntity (e); - e->angles[0] = -e->angles[0]; // stupid quake bug - - // - // draw texture - // - for (i=0 ; inummodelsurfaces ; i++, psurf++) - { - // find which side of the node we are on - pplane = psurf->plane; - - dot = DotProduct (modelorg, pplane->normal) - pplane->dist; - - // draw the polygon - if (((psurf->flags & SURF_PLANEBACK) && (dot < -BACKFACE_EPSILON)) || (!(psurf->flags & SURF_PLANEBACK) && (dot > BACKFACE_EPSILON))) - { - if (gl_texsort.value) - R_RenderBrushPoly (psurf); - else - R_DrawSequentialPoly (psurf); - } - } - - - R_BlendLightmaps (); - - - // jkrige - luma textures - R_DrawLumaSurfaces (&clmodel->surfaces[clmodel->firstmodelsurface], clmodel->nummodelsurfaces); - // jkrige - luma textures - - - glPopMatrix (); - - // jkrige - brush z-fighting - glDisable(GL_POLYGON_OFFSET_FILL); - // jkrige - brush z-fighting -} - -/* -============================================================= - - WORLD MODEL - -============================================================= -*/ - -/* -================ -R_RecursiveWorldNode -================ -*/ -void R_RecursiveWorldNode (mnode_t *node) -{ - int i, c, side, *pindex; - vec3_t acceptpt, rejectpt; - mplane_t *plane; - msurface_t *surf, **mark; - mleaf_t *pleaf; - double d, dot; - vec3_t mins, maxs; - - if (node->contents == CONTENTS_SOLID) - return; // solid - - if (node->visframe != r_visframecount) - return; - if (R_CullBox (node->minmaxs, node->minmaxs+3)) - return; - -// if a leaf node, draw stuff - if (node->contents < 0) - { - pleaf = (mleaf_t *)node; - - mark = pleaf->firstmarksurface; - c = pleaf->nummarksurfaces; - - if (c) - { - do - { - (*mark)->visframe = r_framecount; - mark++; - } while (--c); - } - - // deal with model fragments in this leaf - if (pleaf->efrags) - R_StoreEfrags (&pleaf->efrags); - - return; - } - -// node is just a decision point, so go down the apropriate sides - -// find which side of the node we are on - plane = node->plane; - - switch (plane->type) - { - case PLANE_X: - dot = modelorg[0] - plane->dist; - break; - case PLANE_Y: - dot = modelorg[1] - plane->dist; - break; - case PLANE_Z: - dot = modelorg[2] - plane->dist; - break; - default: - dot = DotProduct (modelorg, plane->normal) - plane->dist; - break; - } - - if (dot >= 0) - side = 0; - else - side = 1; - -// recurse down the children, front side first - R_RecursiveWorldNode (node->children[side]); - -// draw stuff - c = node->numsurfaces; - - if (c) - { - surf = cl.worldmodel->surfaces + node->firstsurface; - - if (dot < 0 -BACKFACE_EPSILON) - side = SURF_PLANEBACK; - else if (dot > BACKFACE_EPSILON) - side = 0; - { - for ( ; c ; c--, surf++) - { - if (surf->visframe != r_framecount) - continue; - - // don't backface underwater surfaces, because they warp - if ( !(surf->flags & SURF_UNDERWATER) && ( (dot < 0) ^ !!(surf->flags & SURF_PLANEBACK)) ) - continue; // wrong side - - // if sorting by texture, just store it out - if (gl_texsort.value) - { - if (!mirror || surf->texinfo->texture != cl.worldmodel->textures[mirrortexturenum]) - { - surf->texturechain = surf->texinfo->texture->texturechain; - surf->texinfo->texture->texturechain = surf; - } - } - else if (surf->flags & SURF_DRAWSKY) - { - surf->texturechain = skychain; - skychain = surf; - } - else if (surf->flags & SURF_DRAWTURB) - { - surf->texturechain = waterchain; - waterchain = surf; - } - else - { - // jkrige - luma textures - surf->luma_mark = true; - // jkrige - luma textures - - R_DrawSequentialPoly (surf); - } - - } - } - - } - -// recurse down the back side - R_RecursiveWorldNode (node->children[!side]); -} - - - -/* -============= -R_DrawWorld -============= -*/ -void R_DrawWorld (void) -{ - entity_t ent; - int i; - - memset (&ent, 0, sizeof(ent)); - ent.model = cl.worldmodel; - - VectorCopy (r_refdef.vieworg, modelorg); - - currententity = &ent; - currenttexture = -1; - - glColor3f (1,1,1); - memset (lightmap_polys, 0, sizeof(lightmap_polys)); - -//#ifdef QUAKE2 // jkrige - skybox -// R_ClearSkyBox (); -//#endif - - // jkrige - skybox (moved upwards, disabled depth checking) - R_DrawSkyBox (); - // jkrige - skybox (moved upwards, disabled depth checking) - - R_RecursiveWorldNode (cl.worldmodel->nodes); - - DrawTextureChains (); - - R_BlendLightmaps (); - - // jkrige - luma textures - R_DrawLumaSurfaces (&cl.worldmodel->surfaces[cl.worldmodel->firstmodelsurface], cl.worldmodel->nummodelsurfaces); - // jkrige - luma textures - -//#ifdef QUAKE2 // jkrige - skybox -// R_DrawSkyBox (); -//#endif -} - - -/* -=============== -R_MarkLeaves -=============== -*/ -void R_MarkLeaves (void) -{ - byte *vis; - mnode_t *node; - int i; - byte solid[4096]; - - if (r_oldviewleaf == r_viewleaf && !r_novis.value) - return; - - if (mirror) - return; - - r_visframecount++; - r_oldviewleaf = r_viewleaf; - - if (r_novis.value) - { - vis = solid; - memset (solid, 0xff, (cl.worldmodel->numleafs+7)>>3); - } - else - vis = Mod_LeafPVS (r_viewleaf, cl.worldmodel); - - for (i=0 ; inumleafs ; i++) - { - if (vis[i>>3] & (1<<(i&7))) - { - node = (mnode_t *)&cl.worldmodel->leafs[i+1]; - do - { - if (node->visframe == r_visframecount) - break; - node->visframe = r_visframecount; - node = node->parent; - } while (node); - } - } -} - - - -/* -============================================================================= - - LIGHTMAP ALLOCATION - -============================================================================= -*/ - -// returns a texture number and the position inside it -int AllocBlock (int w, int h, int *x, int *y) -{ - int i, j; - int best, best2; - int bestx; - int texnum; - - for (texnum=0 ; texnum= best) - break; - if (allocated[texnum][i+j] > best2) - best2 = allocated[texnum][i+j]; - } - if (j == w) - { // this is a valid spot - *x = i; - *y = best = best2; - } - } - - if (best + h > BLOCK_HEIGHT) - continue; - - for (i=0 ; iedges; - lnumverts = fa->numedges; - vertpage = 0; - - // - // draw texture - // - poly = Hunk_Alloc (sizeof(glpoly_t) + (lnumverts-4) * VERTEXSIZE*sizeof(float)); - poly->next = fa->polys; - poly->flags = fa->flags; - fa->polys = poly; - poly->numverts = lnumverts; - - for (i=0 ; isurfedges[fa->firstedge + i]; - - if (lindex > 0) - { - r_pedge = &pedges[lindex]; - vec = r_pcurrentvertbase[r_pedge->v[0]].position; - } - else - { - r_pedge = &pedges[-lindex]; - vec = r_pcurrentvertbase[r_pedge->v[1]].position; - } - s = DotProduct (vec, fa->texinfo->vecs[0]) + fa->texinfo->vecs[0][3]; - s /= fa->texinfo->texture->width; - - t = DotProduct (vec, fa->texinfo->vecs[1]) + fa->texinfo->vecs[1][3]; - t /= fa->texinfo->texture->height; - - VectorCopy (vec, poly->verts[i]); - poly->verts[i][3] = s; - poly->verts[i][4] = t; - - // - // lightmap texture coordinates - // - s = DotProduct (vec, fa->texinfo->vecs[0]) + fa->texinfo->vecs[0][3]; - s -= fa->texturemins[0]; - s += fa->light_s*16; - s += 8; - s /= BLOCK_WIDTH*16; //fa->texinfo->texture->width; - - t = DotProduct (vec, fa->texinfo->vecs[1]) + fa->texinfo->vecs[1][3]; - t -= fa->texturemins[1]; - t += fa->light_t*16; - t += 8; - t /= BLOCK_HEIGHT*16; //fa->texinfo->texture->height; - - poly->verts[i][5] = s; - poly->verts[i][6] = t; - } - - // - // remove co-linear points - Ed - // - // jkrige - disabled tjunction removal - /*if (!gl_keeptjunctions.value && !(fa->flags & SURF_UNDERWATER) ) - { - for (i = 0 ; i < lnumverts ; ++i) - { - vec3_t v1, v2; - float *prev, *this, *next; - float f; - - prev = poly->verts[(i + lnumverts - 1) % lnumverts]; - this = poly->verts[i]; - next = poly->verts[(i + 1) % lnumverts]; - - VectorSubtract( this, prev, v1 ); - VectorNormalize( v1 ); - VectorSubtract( next, prev, v2 ); - VectorNormalize( v2 ); - - // skip co-linear points - #define COLINEAR_EPSILON 0.001 - if ((fabs( v1[0] - v2[0] ) <= COLINEAR_EPSILON) && - (fabs( v1[1] - v2[1] ) <= COLINEAR_EPSILON) && - (fabs( v1[2] - v2[2] ) <= COLINEAR_EPSILON)) - { - int j; - for (j = i + 1; j < lnumverts; ++j) - { - int k; - for (k = 0; k < VERTEXSIZE; ++k) - poly->verts[j - 1][k] = poly->verts[j][k]; - } - --lnumverts; - ++nColinElim; - // retry next vertex next time, which is now current vertex - --i; - } - } - }*/ - // jkrige - disabled tjunction removal - - poly->numverts = lnumverts; - -} - -/* -======================== -GL_CreateSurfaceLightmap -======================== -*/ -void GL_CreateSurfaceLightmap (msurface_t *surf) -{ - int smax, tmax, s, t, l, i; - byte *base; - - if (surf->flags & (SURF_DRAWSKY|SURF_DRAWTURB)) - return; - - smax = (surf->extents[0]>>4)+1; - tmax = (surf->extents[1]>>4)+1; - - surf->lightmaptexturenum = AllocBlock (smax, tmax, &surf->light_s, &surf->light_t); - base = lightmaps + surf->lightmaptexturenum*lightmap_bytes*BLOCK_WIDTH*BLOCK_HEIGHT; - base += (surf->light_t * BLOCK_WIDTH + surf->light_s) * lightmap_bytes; - R_BuildLightMap (surf, base, BLOCK_WIDTH*lightmap_bytes); -} - - -/* -================== -GL_BuildLightmaps - -Builds the lightmap texture -with all the surfaces from all brush models -================== -*/ -void GL_BuildLightmaps (void) -{ - int i, j; - model_t *m; - extern qboolean isPermedia; - - memset (allocated, 0, sizeof(allocated)); - - r_framecount = 1; // no dlightcache - - if (!lightmap_textures) - { - lightmap_textures = texture_extension_number; - texture_extension_number += MAX_LIGHTMAPS; - } - - // jkrige - .lit colored lights - //gl_lightmap_format = GL_LUMINANCE; - // default differently on the Permedia - //if (isPermedia) - // gl_lightmap_format = GL_RGBA; - // jkrige - .lit colored lights - - - // jkrige - .lit colored lights - /*if (COM_CheckParm ("-lm_1")) - gl_lightmap_format = GL_LUMINANCE; - if (COM_CheckParm ("-lm_a")) - gl_lightmap_format = GL_ALPHA; - if (COM_CheckParm ("-lm_i")) - gl_lightmap_format = GL_INTENSITY; - if (COM_CheckParm ("-lm_2")) - gl_lightmap_format = GL_RGBA4; - if (COM_CheckParm ("-lm_4")) - gl_lightmap_format = GL_RGBA; - - switch (gl_lightmap_format) - { - case GL_RGBA: - lightmap_bytes = 4; - break; - case GL_RGBA4: - lightmap_bytes = 2; - break; - case GL_LUMINANCE: - case GL_INTENSITY: - case GL_ALPHA: - lightmap_bytes = 1; - break; - }*/ - // jkrige - .lit colored lights - - for (j=1 ; jname[0] == '*') - continue; - r_pcurrentvertbase = m->vertexes; - currentmodel = m; - for (i=0 ; inumsurfaces ; i++) - { - GL_CreateSurfaceLightmap (m->surfaces + i); - if ( m->surfaces[i].flags & SURF_DRAWTURB ) - continue; -#ifndef QUAKE2 - if ( m->surfaces[i].flags & SURF_DRAWSKY ) - continue; -#endif - BuildSurfaceDisplayList (m->surfaces + i); - } - } - - // jkrige - remove multitexture - //if (!gl_texsort.value) - // GL_SelectTexture(TEXTURE1_SGIS); - // jkrige - remove multitexture - - // - // upload all lightmaps that were filled - // - for (i=0 ; i scr_erase_lines) - scr_erase_lines = scr_center_lines; - - scr_centertime_off -= host_frametime; - - if (scr_centertime_off <= 0 && !cl.intermission) - return; - if (key_dest != key_game) - return; - - SCR_DrawCenterString (); -} - -//============================================================================= - -/* -==================== -CalcFov -==================== -*/ -float CalcFov (float fov_x, float width, float height) -{ - float a; - float x; - - if (fov_x < 1 || fov_x > 179) - Sys_Error ("Bad fov: %f", fov_x); - - x = width/tan(fov_x/360*M_PI); - - a = atan (height/x); - a = a*360/M_PI; - - return a; -} - -// jkrige - field of view (fov) fix -float fov_width; -// jkrige - field of view (fov) fix - -/* -================= -SCR_CalcRefdef - -Must be called whenever vid changes -Internal use only -================= -*/ -static void SCR_CalcRefdef (void) -{ - vrect_t vrect; - //float size; // jkrige - scr_viewsize & statusbar - int h; - - // jkrige - field of view (fov) fix - float fov_monitor; - // jkrige - field of view (fov) fix - - - scr_fullupdate = 0; // force a background redraw - vid.recalc_refdef = 0; - - // jkrige - always draw sbar -// force the status bar to redraw - //Sbar_Changed (); - // jkrige - always draw sbar - -//======================================== - -// bound viewsize - // jkrige - scr_viewsize & statusbar - if (scr_viewsize.value < 100) - Cvar_Set ("viewsize","100"); // jkrige : was 30 - if (scr_viewsize.value > 110) - Cvar_Set ("viewsize","110"); - // jkrige - scr_viewsize & statusbar - - -// bound field of view - // jkrige - field of view (fov) fix - /*if (scr_fov.value < 10) - Cvar_Set ("fov","10"); - if (scr_fov.value > 170) - Cvar_Set ("fov","170");*/ - if (fov_width < 10) - fov_width = 10; - if (fov_width > 170) - fov_width = 170; - // jkrige - field of view (fov) fix - - -// intermission is always full screen - //if (cl.intermission) - // size = 100; - //else - // size = scr_viewsize.value; - - - // jkrige - viewsize & statusbar - if(scr_viewsize.value >= 110) - sb_lines = 24; // no inventory - else - sb_lines = 24 + 16 + 8; - - //if (size >= 110) - // sb_lines = 0; // no status bar at all - //else if (size >= 110) - // sb_lines = 24; // no inventory - //else - // sb_lines = 24 + 16 + 8; - // jkrige - viewsize & statusbar - - - if (cl.intermission) - sb_lines = 0; - - //size /= 100.0; - - - // jkrige - scale2d - if (Scale2DFactor > 1.0f) - { - /*h = modelist[(int)vid_mode.value].height - sb_lines; - r_refdef.vrect.width = modelist[(int)vid_mode.value].width * size; - if (r_refdef.vrect.width < 96) - { - size = 96.0 / modelist[(int)vid_mode.value].width; - r_refdef.vrect.width = 96; // min for icons - } - - r_refdef.vrect.height = modelist[(int)vid_mode.value].height * size; - if (r_refdef.vrect.height > modelist[(int)vid_mode.value].height - sb_lines) - r_refdef.vrect.height = modelist[(int)vid_mode.value].height - sb_lines; - if (r_refdef.vrect.height > modelist[(int)vid_mode.value].height) - r_refdef.vrect.height = modelist[(int)vid_mode.value].height; - - r_refdef.vrect.x = (modelist[(int)vid_mode.value].width - r_refdef.vrect.width)/2; - //r_refdef.vrect.y = (h - r_refdef.vrect.height)/2; - - if (full) - r_refdef.vrect.y = 0; - else - r_refdef.vrect.y = (h - r_refdef.vrect.height)/2;*/ - - - // jkrige - scr_viewsize & statusbar - r_refdef.vrect.width = modelist[(int)vid_mode.value].width; - r_refdef.vrect.height = modelist[(int)vid_mode.value].height; - r_refdef.vrect.x = 0; - r_refdef.vrect.y = 0; - - /*r_refdef.vrect.width = modelist[(int)vid_mode.value].width * size; - r_refdef.vrect.height = modelist[(int)vid_mode.value].height * size; - - r_refdef.vrect.x = (modelist[(int)vid_mode.value].width - r_refdef.vrect.width) / 2; - if(full) - r_refdef.vrect.y = 0; - else - r_refdef.vrect.y = (modelist[(int)vid_mode.value].height - r_refdef.vrect.height) / 2;*/ - // jkrige - scr_viewsize & statusbar - } - else - { - /*h = vid.height - sb_lines; - r_refdef.vrect.width = vid.width * size; - if (r_refdef.vrect.width < 96) - { - size = 96.0 / vid.width; - r_refdef.vrect.width = 96; // min for icons - } - - r_refdef.vrect.height = vid.height * size; - if (r_refdef.vrect.height > vid.height - sb_lines) - r_refdef.vrect.height = vid.height - sb_lines; - if (r_refdef.vrect.height > vid.height) - r_refdef.vrect.height = vid.height; - - r_refdef.vrect.x = (vid.width - r_refdef.vrect.width)/2; - //r_refdef.vrect.y = (h - r_refdef.vrect.height)/2; - - if (full) - r_refdef.vrect.y = 0; - else - r_refdef.vrect.y = (h - r_refdef.vrect.height)/2;*/ - - - // jkrige - scr_viewsize & statusbar - r_refdef.vrect.width = vid.width; - r_refdef.vrect.height = vid.height; - r_refdef.vrect.x = 0; - r_refdef.vrect.y = 0; - - /*r_refdef.vrect.width = vid.width * size; - r_refdef.vrect.height = vid.height * size; - - r_refdef.vrect.x = (vid.width - r_refdef.vrect.width) / 2; - if (full) - r_refdef.vrect.y = 0; - else - r_refdef.vrect.y = (vid.height - r_refdef.vrect.height) / 2;*/ - // jkrige - scr_viewsize & statusbar - } - // jkrige - scale2d - - - // jkrige - scale2d (quake original) - /*h = vid.height - sb_lines; - r_refdef.vrect.width = vid.width * size; - if (r_refdef.vrect.width < 96) - { - size = 96.0 / r_refdef.vrect.width; - r_refdef.vrect.width = 96; // min for icons - } - - r_refdef.vrect.height = vid.height * size; - if (r_refdef.vrect.height > vid.height - sb_lines) - r_refdef.vrect.height = vid.height - sb_lines; - if (r_refdef.vrect.height > vid.height) - r_refdef.vrect.height = vid.height; - r_refdef.vrect.x = (vid.width - r_refdef.vrect.width)/2; - if (full) - r_refdef.vrect.y = 0; - else - r_refdef.vrect.y = (h - r_refdef.vrect.height)/2;*/ - // jkrige - scale2d (quake original) - - - - // jkrige - field of view (fov) fix - if (r_refdef.vrect.width == 640 && r_refdef.vrect.height == 480) - r_refdef.vrect.height -= (sb_lines > 24) ? sb_lines - 24 : sb_lines - 8; - - fov_monitor = ((float)r_refdef.vrect.width / (float)r_refdef.vrect.height) / ((float)BASEWIDTH / (float)BASEHEIGHT); - //fov_monitor = ((float)vid.width / (float)vid.height) / ((float)BASEWIDTH / (float)BASEHEIGHT); - fov_width = (2 * atan(fov_monitor * tan(((float)BASEFOV / 2) * (M_PI / 180)))) * (180 / M_PI); - - if (fov_width >= floor(fov_width) + 0.5f) - fov_width = ceil(fov_width); - else - fov_width = floor(fov_width); - - - r_refdef.fov_x = fov_width; - //r_refdef.fov_x = scr_fov.value; - - //r_refdef.fov_y = CalcFov (r_refdef.fov_x, r_refdef.vrect.width, r_refdef.vrect.height); - r_refdef.fov_y = CalcFov (r_refdef.fov_x, vid.width, vid.height); - // jkrige - field of view (fov) fix - - - scr_vrect = r_refdef.vrect; -} - - -/* -================= -SCR_SizeUp_f - -Keybinding command -================= -*/ -void SCR_SizeUp_f (void) -{ - Cvar_SetValue ("viewsize",scr_viewsize.value+10); - vid.recalc_refdef = 1; -} - - -/* -================= -SCR_SizeDown_f - -Keybinding command -================= -*/ -void SCR_SizeDown_f (void) -{ - Cvar_SetValue ("viewsize",scr_viewsize.value-10); - vid.recalc_refdef = 1; -} - -//============================================================================ - -/* -================== -SCR_Init -================== -*/ -void SCR_Init (void) -{ - // jkrige - field of view (fov) fix - //Cvar_RegisterVariable (&scr_fov); - // jkrige - field of view (fov) fix - - Cvar_RegisterVariable (&scr_viewsize); - Cvar_RegisterVariable (&scr_conspeed); - Cvar_RegisterVariable (&scr_showram); - Cvar_RegisterVariable (&scr_showturtle); - Cvar_RegisterVariable (&scr_showpause); - Cvar_RegisterVariable (&scr_centertime); - Cvar_RegisterVariable (&scr_printspeed); - Cvar_RegisterVariable (&gl_triplebuffer); - -// -// register our commands -// - Cmd_AddCommand ("screenshot",SCR_ScreenShot_f); - - Cmd_AddCommand ("sizeup",SCR_SizeUp_f); - Cmd_AddCommand ("sizedown",SCR_SizeDown_f); - - scr_ram = Draw_PicFromWad ("ram"); - scr_net = Draw_PicFromWad ("net"); - scr_turtle = Draw_PicFromWad ("turtle"); - - scr_initialized = true; -} - - - -/* -============== -SCR_DrawRam -============== -*/ -void SCR_DrawRam (void) -{ - if (!scr_showram.value) - return; - - if (!r_cache_thrash) - return; - - Draw_Pic (scr_vrect.x+32, scr_vrect.y, scr_ram); -} - -/* -============== -SCR_DrawTurtle -============== -*/ -void SCR_DrawTurtle (void) -{ - static int count; - - if (!scr_showturtle.value) - return; - - if (host_frametime < 0.1) - { - count = 0; - return; - } - - count++; - if (count < 3) - return; - - Draw_Pic (scr_vrect.x, scr_vrect.y, scr_turtle); -} - -/* -============== -SCR_DrawNet -============== -*/ -void SCR_DrawNet (void) -{ - if (realtime - cl.last_received_message < 0.3) - return; - if (cls.demoplayback) - return; - - Draw_Pic (scr_vrect.x+64, scr_vrect.y, scr_net); -} - -// jkrige - fps counter -/* -============== -SCR_DrawFPS -============== -*/ - -void SCR_DrawFPS (void) -{ - extern cvar_t r_fps; - - static double lastframetime; - double t; - extern int fps_count; - static int lastfps; - int x, y; - char st[80]; - - if (!r_fps.value) - return; - - t = Sys_FloatTime (); - - if ((t - lastframetime) >= 1.0) { - lastfps = fps_count; - fps_count = 0; - lastframetime = t; - } - - sprintf(st, "%3d FPS", lastfps); - - x = vid.width - strlen(st) * 8 - 8; - y = 0 ; //vid.height - (sb_lines * (vid.height/240) )- 16; - -// Draw_TileClear(x, y, strlen(st)*16, 16); - Draw_String(x, y, st); -} -// jkrige - fps counter - -/* -============== -DrawPause -============== -*/ -void SCR_DrawPause (void) -{ - qpic_t *pic; - - if (!scr_showpause.value) // turn off for screenshots - return; - - if (!cl.paused) - return; - - pic = Draw_CachePic ("gfx/pause.lmp"); - Draw_Pic ( (vid.width - pic->width)/2, - (vid.height - 48 - pic->height)/2, pic); -} - - - -/* -============== -SCR_DrawLoading -============== -*/ -void SCR_DrawLoading (void) -{ - qpic_t *pic; - - if (!scr_drawloading) - return; - - pic = Draw_CachePic ("gfx/loading.lmp"); - Draw_Pic ( (vid.width - pic->width)/2, - (vid.height - 48 - pic->height)/2, pic); -} - - - -//============================================================================= - - -/* -================== -SCR_SetUpToDrawConsole -================== -*/ -void SCR_SetUpToDrawConsole (void) -{ - Con_CheckResize (); - - if (scr_drawloading) - return; // never a console with loading plaque - -// decide on the height of the console - con_forcedup = !cl.worldmodel || cls.signon != SIGNONS; - - if (con_forcedup) - { - scr_conlines = vid.height; // full screen - scr_con_current = scr_conlines; - } - else if (key_dest == key_console) - scr_conlines = vid.height/2; // half screen - else - scr_conlines = 0; // none visible - - if (scr_conlines < scr_con_current) - { - scr_con_current -= scr_conspeed.value*host_frametime; - if (scr_conlines > scr_con_current) - scr_con_current = scr_conlines; - - } - else if (scr_conlines > scr_con_current) - { - scr_con_current += scr_conspeed.value*host_frametime; - if (scr_conlines < scr_con_current) - scr_con_current = scr_conlines; - } - - if (clearconsole++ < vid.numpages) - { - //Sbar_Changed (); // jkrige - always draw sbar - } - else if (clearnotify++ < vid.numpages) - { - } - else - con_notifylines = 0; -} - -/* -================== -SCR_DrawConsole -================== -*/ -void SCR_DrawConsole (void) -{ - if (scr_con_current) - { - scr_copyeverything = 1; - Con_DrawConsole (scr_con_current, true); - clearconsole = 0; - } - else - { - if (key_dest == key_game || key_dest == key_message) - Con_DrawNotify (); // only draw notify in game - } -} - - -/* -============================================================================== - - SCREEN SHOTS - -============================================================================== -*/ - -typedef struct _TargaHeader { - unsigned char id_length, colormap_type, image_type; - unsigned short colormap_index, colormap_length; - unsigned char colormap_size; - unsigned short x_origin, y_origin, width, height; - unsigned char pixel_size, attributes; -} TargaHeader; - - -/* -================== -SCR_ScreenShot_f -================== -*/ -void SCR_ScreenShot_f (void) -{ - byte *buffer; - char pcxname[80]; - char checkname[MAX_OSPATH]; - int i, c, temp; - - // jkrige - "shots" directory - sprintf (checkname, "%s/shots", com_gamedir); - Sys_mkdir (checkname); - // jkrige - "shots" directory - -// -// find a file name to save it to -// - // jkrige - "shots" directory - //strcpy(pcxname,"quake00.tga"); - strcpy(pcxname,"shots/quake00.tga"); - // jkrige - "shots" directory - - for (i=0 ; i<=99 ; i++) - { - // jkrige - "shots" directory - //pcxname[5] = i/10 + '0'; - //pcxname[6] = i%10 + '0'; - pcxname[11] = i/10 + '0'; - pcxname[12] = i%10 + '0'; - // jkrige - "shots" directory - - sprintf (checkname, "%s/%s", com_gamedir, pcxname); - if (Sys_FileTime(checkname) == -1) - break; // file doesn't exist - } - if (i==100) - { - Con_Printf ("SCR_ScreenShot_f: Couldn't create a TGA file\n"); - return; - } - - - buffer = malloc(glwidth*glheight*3 + 18); - memset (buffer, 0, 18); - buffer[2] = 2; // uncompressed type - buffer[12] = glwidth&255; - buffer[13] = glwidth>>8; - buffer[14] = glheight&255; - buffer[15] = glheight>>8; - buffer[16] = 24; // pixel size - - glReadPixels (glx, gly, glwidth, glheight, GL_RGB, GL_UNSIGNED_BYTE, buffer+18 ); - - // swap rgb to bgr - c = 18+glwidth*glheight*3; - for (i=18 ; i 0 ) && deviceSupportsGamma ) - VG_GammaCorrect( buffer + 18, glwidth * glheight * 3 ); - - - COM_WriteFile (pcxname, buffer, glwidth*glheight*3 + 18 ); - - free (buffer); - Con_Printf ("Wrote %s\n", pcxname); -} - - -//============================================================================= - - -/* -=============== -SCR_BeginLoadingPlaque - -================ -*/ -void SCR_BeginLoadingPlaque (void) -{ - S_StopAllSounds (true); - - if (cls.state != ca_connected) - return; - if (cls.signon != SIGNONS) - return; - -// redraw with no console and the loading plaque - Con_ClearNotify (); - scr_centertime_off = 0; - scr_con_current = 0; - - scr_drawloading = true; - scr_fullupdate = 0; - //Sbar_Changed (); // jkrige - always draw sbar - SCR_UpdateScreen (); - scr_drawloading = false; - - scr_disabled_for_loading = true; - scr_disabled_time = realtime; - scr_fullupdate = 0; -} - -/* -=============== -SCR_EndLoadingPlaque - -================ -*/ -void SCR_EndLoadingPlaque (void) -{ - scr_disabled_for_loading = false; - scr_fullupdate = 0; - Con_ClearNotify (); -} - -//============================================================================= - -char *scr_notifystring; -qboolean scr_drawdialog; - -void SCR_DrawNotifyString (void) -{ - char *start; - int l; - int j; - int x, y; - - start = scr_notifystring; - - y = vid.height*0.35; - - do - { - // scan the width of the line - for (l=0 ; l<40 ; l++) - if (start[l] == '\n' || !start[l]) - break; - x = (vid.width - l*8)/2; - for (j=0 ; j 1.0f) - divFactor = Scale2DFactor; - else - divFactor = 1.0f; - // jkrige - scale2d - - tileX = r_refdef.vrect.x / divFactor; - tileY = r_refdef.vrect.y / divFactor; - tileWidth = r_refdef.vrect.width / divFactor; - tileHeight = r_refdef.vrect.height / divFactor; - - - if (r_refdef.vrect.x > 0) - { - Draw_TileClear (0, 0, tileX, vid.height); // left - Draw_TileClear (vid.width - tileX, 0, tileX, vid.height); // right - } - if (r_refdef.vrect.y > 0) - { - Draw_TileClear (tileX, 0, vid.width - (tileX * 2), tileY); // top - Draw_TileClear (tileX, tileY + tileHeight, vid.width - (tileX * 2), vid.height - (tileHeight + tileY)); // bottom - } -} - -/* -================== -SCR_UpdateScreen - -This is called every frame, and can also be called explicitly to flush -text to the screen. - -WARNING: be very careful calling this from elsewhere, because the refresh -needs almost the entire 256k of stack space! -================== -*/ -void SCR_UpdateScreen (void) -{ - // jkrige - scr_viewsize removal - //static float oldscr_viewsize; - // jkrige - scr_viewsize removal - - vrect_t vrect; - - if (block_drawing) - return; - - vid.numpages = 2 + gl_triplebuffer.value; - - scr_copytop = 0; - scr_copyeverything = 0; - - if (scr_disabled_for_loading) - { - if (realtime - scr_disabled_time > 60) - { - scr_disabled_for_loading = false; - Con_Printf ("load failed.\n"); - } - else - return; - } - - if (!scr_initialized || !con_initialized) - return; // not initialized yet - - - GL_BeginRendering (&glx, &gly, &glwidth, &glheight); - - // - // determine size of refresh window - // - // jkrige - field of view (fov) fix - /*if (oldfov != scr_fov.value) - { - oldfov = scr_fov.value; - vid.recalc_refdef = true; - }*/ - if (oldfov != fov_width) - { - oldfov = fov_width; - vid.recalc_refdef = true; - } - // jkrige - field of view (fov) fix - - - // jkrige - scr_viewsize removal - /*if (oldscreensize != scr_viewsize.value) - { - oldscreensize = scr_viewsize.value; - vid.recalc_refdef = true; - }*/ - // jkrige - scr_viewsize removal - - if (vid.recalc_refdef) - SCR_CalcRefdef (); - -// -// do 3D refresh drawing, and then update the screen -// - SCR_SetUpToDrawConsole (); - - V_RenderView (); - - GL_Set2D (); - - // jkrige - 2D polyblend - R_PolyBlend (); - // jkrige - 2D polyblend - - // - // draw any areas not covered by the refresh - // - SCR_TileClear (); - - - if (scr_drawdialog) - { - Sbar_Draw (); - Draw_FadeScreen (); - SCR_DrawNotifyString (); - scr_copyeverything = true; - } - else if (scr_drawloading) - { - SCR_DrawLoading (); - Sbar_Draw (); - } - else if (cl.intermission == 1 && key_dest == key_game) - { - Sbar_IntermissionOverlay (); - } - else if (cl.intermission == 2 && key_dest == key_game) - { - Sbar_FinaleOverlay (); - SCR_CheckDrawCenterString (); - } - else - { - if (crosshair.value) - { - // jkrige - scale2d - //Draw_Character (scr_vrect.x + scr_vrect.width/2, scr_vrect.y + scr_vrect.height/2, '+'); - Draw_Character ((vid.width / 2)-4, (vid.height / 2)-4, '+'); - // jkrige - scale2d - } - - SCR_DrawRam (); - SCR_DrawNet (); - SCR_DrawTurtle (); - SCR_DrawFPS (); // jkrige - fps counter - SCR_DrawPause (); - SCR_CheckDrawCenterString (); - Sbar_Draw (); - SCR_DrawConsole (); - M_Draw (); - } - - V_UpdatePalette (); - - GL_EndRendering (); - - // jkrige - texture mode - Draw_TextureMode_f(); - // jkrige - texture mode -} - diff --git a/engine/code/gl_test.c b/engine/code/gl_test.c deleted file mode 100644 index a3b1027..0000000 --- a/engine/code/gl_test.c +++ /dev/null @@ -1,182 +0,0 @@ -/* -Copyright (C) 1996-1997 Id Software, Inc. - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ - -#include "quakedef.h" - -#ifdef GLTEST - -typedef struct -{ - plane_t *plane; - vec3_t origin; - vec3_t normal; - vec3_t up; - vec3_t right; - vec3_t reflect; - float length; -} puff_t; - -#define MAX_PUFFS 64 - -puff_t puffs[MAX_PUFFS]; - - -void Test_Init (void) -{ -} - - - -plane_t junk; -plane_t *HitPlane (vec3_t start, vec3_t end) -{ - trace_t trace; - -// fill in a default trace - memset (&trace, 0, sizeof(trace_t)); - trace.fraction = 1; - trace.allsolid = true; - VectorCopy (end, trace.endpos); - - SV_RecursiveHullCheck (cl.worldmodel->hulls, 0, 0, 1, start, end, &trace); - - junk = trace.plane; - return &junk; -} - -void Test_Spawn (vec3_t origin) -{ - int i; - puff_t *p; - vec3_t temp; - vec3_t normal; - vec3_t incoming; - plane_t *plane; - float d; - - for (i=0,p=puffs ; ilength <= 0) - break; - } - if (i == MAX_PUFFS) - return; - - VectorSubtract (r_refdef.vieworg, origin, incoming); - VectorSubtract (origin, incoming, temp); - plane = HitPlane (r_refdef.vieworg, temp); - - VectorNormalize (incoming); - d = DotProduct (incoming, plane->normal); - VectorSubtract (vec3_origin, incoming, p->reflect); - VectorMA (p->reflect, d*2, plane->normal, p->reflect); - - VectorCopy (origin, p->origin); - VectorCopy (plane->normal, p->normal); - - CrossProduct (incoming, p->normal, p->up); - - CrossProduct (p->up, p->normal, p->right); - - p->length = 8; -} - -void DrawPuff (puff_t *p) -{ - vec3_t pts[2][3]; - int i, j; - float s, d; - - for (i=0 ; i<2 ; i++) - { - if (i == 1) - { - s = 6; - d = p->length; - } - else - { - s = 2; - d = 0; - } - - for (j=0 ; j<3 ; j++) - { - pts[i][0][j] = p->origin[j] + p->up[j]*s + p->reflect[j]*d; - pts[i][1][j] = p->origin[j] + p->right[j]*s + p->reflect[j]*d; - pts[i][2][j] = p->origin[j] + -p->right[j]*s + p->reflect[j]*d; - } - } - - glColor3f (1, 0, 0); - -#if 0 - glBegin (GL_LINES); - glVertex3fv (p->origin); - glVertex3f (p->origin[0] + p->length*p->reflect[0], - p->origin[1] + p->length*p->reflect[1], - p->origin[2] + p->length*p->reflect[2]); - - glVertex3fv (pts[0][0]); - glVertex3fv (pts[1][0]); - - glVertex3fv (pts[0][1]); - glVertex3fv (pts[1][1]); - - glVertex3fv (pts[0][2]); - glVertex3fv (pts[1][2]); - - glEnd (); -#endif - - glBegin (GL_QUADS); - for (i=0 ; i<3 ; i++) - { - j = (i+1)%3; - glVertex3fv (pts[0][j]); - glVertex3fv (pts[1][j]); - glVertex3fv (pts[1][i]); - glVertex3fv (pts[0][i]); - } - glEnd (); - - glBegin (GL_TRIANGLES); - glVertex3fv (pts[1][0]); - glVertex3fv (pts[1][1]); - glVertex3fv (pts[1][2]); - glEnd (); - - p->length -= host_frametime*2; -} - - -void Test_Draw (void) -{ - int i; - puff_t *p; - - for (i=0, p=puffs ; ilength > 0) - DrawPuff (p); - } -} - -#endif diff --git a/engine/code/gl_vidnt.c b/engine/code/gl_vidnt.c deleted file mode 100644 index 4db05cb..0000000 --- a/engine/code/gl_vidnt.c +++ /dev/null @@ -1,2261 +0,0 @@ -/* -Copyright (C) 1996-1997 Id Software, Inc. - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ -// gl_vidnt.c -- NT GL vid component - -#include "quakedef.h" -#include "winquake.h" -#include "resource.h" -#include - -//#define MAX_MODE_LIST 30 // jkrige - moved to winquake.h -#define VID_ROW_SIZE 3 -#define WARP_WIDTH 320 -#define WARP_HEIGHT 200 - -// jkrige - limit video modes -#define VID_MINWIDTH 320 -#define VID_MINHEIGHT 240 -// jkrige - limit video modes - -#define VID_MAXWIDTH 10000 -#define VID_MAXHEIGHT 10000 -//#define BASEWIDTH 320 // jkrige - moved to winquake.h -//#define BASEHEIGHT 200 // jkrige - moved to winquake.h - -#define MODE_WINDOWED 0 -#define NO_MODE (MODE_WINDOWED - 1) -#define MODE_FULLSCREEN_DEFAULT (MODE_WINDOWED + 1) - -// jkrige - moved to winquake.h -/*typedef struct { - modestate_t type; - int width; - int height; - int modenum; - int dib; - int fullscreen; - int bpp; - int halfscreen; - char modedesc[17]; -} vmode_t;*/ -// jkrige - moved to winquake.h - -typedef struct { - int width; - int height; -} lmode_t; - -lmode_t lowresmodes[] = { - {320, 200}, - {320, 240}, - {400, 300}, - {512, 384}, -}; - -const char *gl_vendor; -const char *gl_renderer; -const char *gl_version; -const char *gl_extensions; - -qboolean DDActive; -qboolean scr_skipupdate; - -// jkrige - scale2d -//static vmode_t modelist[MAX_MODE_LIST]; -vmode_t modelist[MAX_MODE_LIST]; -// jkrige - scale2d - -static int nummodes; -static vmode_t *pcurrentmode; -static vmode_t badmode; - -static DEVMODE gdevmode; -static qboolean vid_initialized = false; -static qboolean windowed, leavecurrentmode; -static qboolean vid_canalttab = false; -static qboolean vid_wassuspended = false; -static int windowed_mouse; -extern qboolean mouseactive; // from in_win.c -static HICON hIcon; - -int DIBWidth, DIBHeight; -RECT WindowRect; -DWORD WindowStyle, ExWindowStyle; - -HWND mainwindow, dibwindow; - -int vid_modenum = NO_MODE; -int vid_realmode; -int vid_default = MODE_WINDOWED; -static int windowed_default; -unsigned char vid_curpal[256*3]; - -// jkrige - always draw sbar -//static qboolean fullsbardraw = false; -// jkrige - always draw sbar - -static float vid_gamma = 1.0; - -HGLRC baseRC; -HDC maindc; - -glvert_t glv; - -// jkrige - changed gl_ztrick default to 0 -// this will now default to zero, because of the compatibility problems, -// Z fighting, and the fact that this doesn't necessarily give us -// any performance boost on modern hardware, where it introduces a new -// problem: if video page swaps are too frequent (130+ fps), the OpenGL -// pipeline might not keep up with changing Z test function on each -// frame update, sometimes resulting in flickering or "snow". -//cvar_t gl_ztrick = {"gl_ztrick","1"}; -cvar_t gl_ztrick = {"gl_ztrick","0"}; -// jkrige - changed gl_ztrick default to 0 - -HWND WINAPI InitializeWindow (HINSTANCE hInstance, int nCmdShow); - -viddef_t vid; // global video state - -unsigned short d_8to16table[256]; -unsigned d_8to24table[256]; -unsigned char d_15to8table[65536]; - -float gldepthmin, gldepthmax; - -modestate_t modestate = MS_UNINIT; - -void VID_MenuDraw (void); -void VID_MenuKey (int key); - -LONG WINAPI MainWndProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); -void AppActivate(BOOL fActive, BOOL minimize); -char *VID_GetModeDescription (int mode); -void ClearAllStates (void); -void VID_UpdateWindowStatus (void); -void GL_Init (void); - -// jkrige - opengl extensions -//PROC glArrayElementEXT; -//PROC glColorPointerEXT; -//PROC glTexCoordPointerEXT; -//PROC glVertexPointerEXT; -// jkrige - opengl extensions - - -// jkrige - no 8bit palette extensions -//typedef void (APIENTRY *lp3DFXFUNC) (int, int, int, int, int, const void*); -//lp3DFXFUNC glColorTableEXT; -//qboolean is8bit = false; -// jkrige - no 8bit palette extensions - -qboolean isPermedia = false; -//qboolean gl_mtexable = false; // jkrige - remove multitexture - - -// jkrige - overbrights -cvar_t gl_overbright = {"gl_overbright", "1", true}; -// jkrige - overbrights - -//==================================== - -cvar_t vid_mode = {"vid_mode","0", false}; -// Note that 0 is MODE_WINDOWED -cvar_t _vid_default_mode = {"_vid_default_mode","0", true}; -// Note that 3 is MODE_FULLSCREEN_DEFAULT -cvar_t _vid_default_mode_win = {"_vid_default_mode_win","3", true}; -cvar_t vid_wait = {"vid_wait","0"}; -cvar_t vid_nopageflip = {"vid_nopageflip","0", true}; -cvar_t _vid_wait_override = {"_vid_wait_override", "0", true}; -cvar_t vid_config_x = {"vid_config_x","800", true}; -cvar_t vid_config_y = {"vid_config_y","600", true}; -cvar_t vid_stretch_by_2 = {"vid_stretch_by_2","1", true}; -cvar_t _windowed_mouse = {"_windowed_mouse","1", true}; - -// jkrige - non power of two -cvar_t gl_texture_non_power_of_two = {"gl_texture_non_power_of_two", "1", true}; -// jkrige - non power of two - -int window_center_x, window_center_y, window_x, window_y, window_width, window_height; -RECT window_rect; - -// direct draw software compatability stuff - -void VID_HandlePause (qboolean pause) -{ -} - -void VID_ForceLockState (int lk) -{ -} - -void VID_LockBuffer (void) -{ -} - -void VID_UnlockBuffer (void) -{ -} - -int VID_ForceUnlockedAndReturnState (void) -{ - return 0; -} - -void D_BeginDirectRect (int x, int y, byte *pbitmap, int width, int height) -{ -} - -void D_EndDirectRect (int x, int y, int width, int height) -{ -} - - -void CenterWindow(HWND hWndCenter, int width, int height, BOOL lefttopjustify) -{ - RECT rect; - int CenterX, CenterY; - - CenterX = (GetSystemMetrics(SM_CXSCREEN) - width) / 2; - CenterY = (GetSystemMetrics(SM_CYSCREEN) - height) / 2; - if (CenterX > CenterY*2) - CenterX >>= 1; // dual screens - CenterX = (CenterX < 0) ? 0: CenterX; - CenterY = (CenterY < 0) ? 0: CenterY; - SetWindowPos (hWndCenter, NULL, CenterX, CenterY, 0, 0, - SWP_NOSIZE | SWP_NOZORDER | SWP_SHOWWINDOW | SWP_DRAWFRAME); -} - -qboolean VID_SetWindowedMode (int modenum) -{ - HDC hdc; - int lastmodestate, width, height; - RECT rect; - - lastmodestate = modestate; - - WindowRect.top = WindowRect.left = 0; - - WindowRect.right = modelist[modenum].width; - WindowRect.bottom = modelist[modenum].height; - - DIBWidth = modelist[modenum].width; - DIBHeight = modelist[modenum].height; - - WindowStyle = WS_OVERLAPPED | WS_BORDER | WS_CAPTION | WS_SYSMENU | - WS_MINIMIZEBOX; - ExWindowStyle = 0; - - rect = WindowRect; - AdjustWindowRectEx(&rect, WindowStyle, FALSE, 0); - - width = rect.right - rect.left; - height = rect.bottom - rect.top; - - // Create the DIB window - dibwindow = CreateWindowEx ( - ExWindowStyle, - "Quake", // jkrige - was "WinQuake" - "Quake", // jkrige - was "GLQuake" - WindowStyle, - rect.left, rect.top, - width, - height, - NULL, - NULL, - global_hInstance, - NULL); - - if (!dibwindow) - Sys_Error ("Couldn't create DIB window"); - - // Center and show the DIB window - CenterWindow(dibwindow, WindowRect.right - WindowRect.left, - WindowRect.bottom - WindowRect.top, false); - - ShowWindow (dibwindow, SW_SHOWDEFAULT); - UpdateWindow (dibwindow); - - modestate = MS_WINDOWED; - -// because we have set the background brush for the window to NULL -// (to avoid flickering when re-sizing the window on the desktop), -// we clear the window to black when created, otherwise it will be -// empty while Quake starts up. - hdc = GetDC(dibwindow); - PatBlt(hdc,0,0,WindowRect.right,WindowRect.bottom,BLACKNESS); - ReleaseDC(dibwindow, hdc); - - - // jkrige - scale2d - /*if (vid.conheight > modelist[modenum].height) - vid.conheight = modelist[modenum].height; - if (vid.conwidth > modelist[modenum].width) - vid.conwidth = modelist[modenum].width; - vid.width = vid.conwidth; - vid.height = vid.conheight;*/ - - if (Scale2DFactor > 1.0f) - { - vid.width = vid.conwidth = conback->width = Scale2DWidth; - vid.height = vid.conheight = conback->height = Scale2DHeight; - } - else - { - vid.width = vid.conwidth = conback->width = modelist[modenum].width; - vid.height = vid.conheight = conback->height = modelist[modenum].height; - } - // jkrige - scale2d - - - vid.numpages = 2; - - mainwindow = dibwindow; - - SendMessage (mainwindow, WM_SETICON, (WPARAM)TRUE, (LPARAM)hIcon); - SendMessage (mainwindow, WM_SETICON, (WPARAM)FALSE, (LPARAM)hIcon); - - return true; -} - - -qboolean VID_SetFullDIBMode (int modenum) -{ - HDC hdc; - int lastmodestate, width, height; - RECT rect; - - if (!leavecurrentmode) - { - gdevmode.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT; - gdevmode.dmBitsPerPel = modelist[modenum].bpp; - gdevmode.dmPelsWidth = modelist[modenum].width << - modelist[modenum].halfscreen; - gdevmode.dmPelsHeight = modelist[modenum].height; - gdevmode.dmSize = sizeof (gdevmode); - - if (ChangeDisplaySettings (&gdevmode, CDS_FULLSCREEN) != DISP_CHANGE_SUCCESSFUL) - Sys_Error ("Couldn't set fullscreen DIB mode"); - } - - lastmodestate = modestate; - modestate = MS_FULLDIB; - - WindowRect.top = WindowRect.left = 0; - - WindowRect.right = modelist[modenum].width; - WindowRect.bottom = modelist[modenum].height; - - DIBWidth = modelist[modenum].width; - DIBHeight = modelist[modenum].height; - - WindowStyle = WS_POPUP; - ExWindowStyle = 0; - - rect = WindowRect; - AdjustWindowRectEx(&rect, WindowStyle, FALSE, 0); - - width = rect.right - rect.left; - height = rect.bottom - rect.top; - - // Create the DIB window - dibwindow = CreateWindowEx ( - ExWindowStyle, - "Quake", // jkrige - was "WinQuake" - "Quake", // jkrige - was "GLQuake" - WindowStyle, - rect.left, rect.top, - width, - height, - NULL, - NULL, - global_hInstance, - NULL); - - if (!dibwindow) - Sys_Error ("Couldn't create DIB window"); - - ShowWindow (dibwindow, SW_SHOWDEFAULT); - UpdateWindow (dibwindow); - - // Because we have set the background brush for the window to NULL - // (to avoid flickering when re-sizing the window on the desktop), we - // clear the window to black when created, otherwise it will be - // empty while Quake starts up. - hdc = GetDC(dibwindow); - PatBlt(hdc,0,0,WindowRect.right,WindowRect.bottom,BLACKNESS); - ReleaseDC(dibwindow, hdc); - - - // jkrige - scale2d - /*if (vid.conheight > modelist[modenum].height) - vid.conheight = modelist[modenum].height; - if (vid.conwidth > modelist[modenum].width) - vid.conwidth = modelist[modenum].width; - vid.width = vid.conwidth; - vid.height = vid.conheight;*/ - - if (Scale2DFactor > 1.0f) - { - vid.width = vid.conwidth = conback->width = Scale2DWidth; - vid.height = vid.conheight = conback->height = Scale2DHeight; - } - else - { - vid.width = vid.conwidth = conback->width = modelist[modenum].width; - vid.height = vid.conheight = conback->height = modelist[modenum].height; - } - // jkrige - scale2d - - - vid.numpages = 2; - -// needed because we're not getting WM_MOVE messages fullscreen on NT - window_x = 0; - window_y = 0; - - mainwindow = dibwindow; - - SendMessage (mainwindow, WM_SETICON, (WPARAM)TRUE, (LPARAM)hIcon); - SendMessage (mainwindow, WM_SETICON, (WPARAM)FALSE, (LPARAM)hIcon); - - return true; -} - - -int VID_SetMode (int modenum, unsigned char *palette) -{ - int original_mode, temp; - qboolean stat; - MSG msg; - HDC hdc; - - if ((windowed && (modenum != 0)) || - (!windowed && (modenum < 1)) || - (!windowed && (modenum >= nummodes))) - { - Sys_Error ("Bad video mode\n"); - } - -// so Con_Printfs don't mess us up by forcing vid and snd updates - temp = scr_disabled_for_loading; - scr_disabled_for_loading = true; - - // jkrige - fmod sound system - begin -#ifdef UQE_FMOD - FMOD_MusicPause(); -#else - CDAudio_Pause(); -#endif - // jkrige - fmod sound system - end - - if (vid_modenum == NO_MODE) - original_mode = windowed_default; - else - original_mode = vid_modenum; - - // Set either the fullscreen or windowed mode - if (modelist[modenum].type == MS_WINDOWED) - { - if (_windowed_mouse.value && key_dest == key_game) - { - stat = VID_SetWindowedMode(modenum); - IN_ActivateMouse (); - IN_HideMouse (); - } - else - { - IN_DeactivateMouse (); - IN_ShowMouse (); - stat = VID_SetWindowedMode(modenum); - } - } - else if (modelist[modenum].type == MS_FULLDIB) - { - stat = VID_SetFullDIBMode(modenum); - IN_ActivateMouse (); - IN_HideMouse (); - } - else - { - Sys_Error ("VID_SetMode: Bad mode type in modelist"); - } - - window_width = DIBWidth; - window_height = DIBHeight; - VID_UpdateWindowStatus (); - - // jkrige - fmod sound system - begin -#ifdef UQE_FMOD - FMOD_MusicResume(); -#else - CDAudio_Resume(); -#endif - // jkrige - fmod sound system - end - - scr_disabled_for_loading = temp; - - if (!stat) - { - Sys_Error ("Couldn't set video mode"); - } - -// now we try to make sure we get the focus on the mode switch, because -// sometimes in some systems we don't. We grab the foreground, then -// finish setting up, pump all our messages, and sleep for a little while -// to let messages finish bouncing around the system, then we put -// ourselves at the top of the z order, then grab the foreground again, -// Who knows if it helps, but it probably doesn't hurt - SetForegroundWindow (mainwindow); - VID_SetPalette (palette); - vid_modenum = modenum; - Cvar_SetValue ("vid_mode", (float)vid_modenum); - - while (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE)) - { - TranslateMessage (&msg); - DispatchMessage (&msg); - } - - Sleep (100); - - SetWindowPos (mainwindow, HWND_TOP, 0, 0, 0, 0, - SWP_DRAWFRAME | SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW | - SWP_NOCOPYBITS); - - SetForegroundWindow (mainwindow); - -// fix the leftover Alt from any Alt-Tab or the like that switched us away - ClearAllStates (); - - if (!msg_suppress_1) - Con_SafePrintf ("Video mode %s initialized.\n", VID_GetModeDescription (vid_modenum)); - - VID_SetPalette (palette); - - vid.recalc_refdef = 1; - - return true; -} - - -/* -================ -VID_UpdateWindowStatus -================ -*/ -void VID_UpdateWindowStatus (void) -{ - - window_rect.left = window_x; - window_rect.top = window_y; - window_rect.right = window_x + window_width; - window_rect.bottom = window_y + window_height; - window_center_x = (window_rect.left + window_rect.right) / 2; - window_center_y = (window_rect.top + window_rect.bottom) / 2; - - IN_UpdateClipCursor (); -} - - -//==================================== - -BINDTEXFUNCPTR bindTexFunc; - -#define TEXTURE_EXT_STRING "GL_EXT_texture_object" - - -void CheckTextureExtensions (void) -{ - char *tmp; - qboolean texture_ext; - HINSTANCE hInstGL; - - texture_ext = FALSE; - /* check for texture extension */ - tmp = (unsigned char *)glGetString(GL_EXTENSIONS); - while (*tmp) - { - if (strncmp((const char*)tmp, TEXTURE_EXT_STRING, strlen(TEXTURE_EXT_STRING)) == 0) - texture_ext = TRUE; - tmp++; - } - - if (!texture_ext || COM_CheckParm ("-gl11") ) - { - hInstGL = LoadLibrary("opengl32.dll"); - - if (hInstGL == NULL) - Sys_Error ("Couldn't load opengl32.dll\n"); - - bindTexFunc = (void *)GetProcAddress(hInstGL,"glBindTexture"); - - if (!bindTexFunc) - Sys_Error ("No texture objects!"); - return; - } - -/* load library and get procedure adresses for texture extension API */ - if ((bindTexFunc = (BINDTEXFUNCPTR) - wglGetProcAddress((LPCSTR) "glBindTextureEXT")) == NULL) - { - Sys_Error ("GetProcAddress for BindTextureEXT failed"); - return; - } -} - -#if 0 -void CheckArrayExtensions (void) -{ - char *tmp; - - /* check for texture extension */ - tmp = (unsigned char *)glGetString(GL_EXTENSIONS); - while (*tmp) - { - if (strncmp((const char*)tmp, "GL_EXT_vertex_array", strlen("GL_EXT_vertex_array")) == 0) - { - if ( -((glArrayElementEXT = wglGetProcAddress("glArrayElementEXT")) == NULL) || -((glColorPointerEXT = wglGetProcAddress("glColorPointerEXT")) == NULL) || -((glTexCoordPointerEXT = wglGetProcAddress("glTexCoordPointerEXT")) == NULL) || -((glVertexPointerEXT = wglGetProcAddress("glVertexPointerEXT")) == NULL) ) - { - Sys_Error ("GetProcAddress for vertex extension failed"); - return; - } - return; - } - tmp++; - } - - Sys_Error ("Vertex array extension not present"); -} -#endif - -//int texture_mode = GL_NEAREST; -//int texture_mode = GL_NEAREST_MIPMAP_NEAREST; -//int texture_mode = GL_NEAREST_MIPMAP_LINEAR; -int texture_mode = GL_LINEAR; -//int texture_mode = GL_LINEAR_MIPMAP_NEAREST; -//int texture_mode = GL_LINEAR_MIPMAP_LINEAR; - -int texture_extension_number = 1; - -// jkrige - remove multitexture -/* -#ifdef _WIN32 -void CheckMultiTextureExtensions(void) -{ - if (strstr(gl_extensions, "GL_SGIS_multitexture ") && !COM_CheckParm("-nomtex")) { - Con_Printf("Multitexture extensions found.\n"); - qglMTexCoord2fSGIS = (void *) wglGetProcAddress("glMTexCoord2fSGIS"); - qglSelectTextureSGIS = (void *) wglGetProcAddress("glSelectTextureSGIS"); - gl_mtexable = true; - } -} -#else -void CheckMultiTextureExtensions(void) -{ - gl_mtexable = true; -} -#endif -*/ -// jkrige - remove multitexture - - -// jkrige - gamma -BOOL ( WINAPI * qwglGetDeviceGammaRamp3DFX)( HDC, LPVOID ); -BOOL ( WINAPI * qwglSetDeviceGammaRamp3DFX)( HDC, LPVOID ); - -void Check3DFXGammaExtensions (void) -{ - char *gl_extensions; - HINSTANCE hInstGL; - - gl_extensions = (unsigned char *)glGetString(GL_EXTENSIONS); - - // WGL_3DFX_gamma_control - qwglGetDeviceGammaRamp3DFX = NULL; - qwglSetDeviceGammaRamp3DFX = NULL; - - if ( strstr( gl_extensions, "WGL_3DFX_gamma_control" ) ) - { - //if ( !r_ignorehwgamma->integer && r_ext_gamma_control->integer ) - //{ - qwglGetDeviceGammaRamp3DFX = ( BOOL ( WINAPI * )( HDC, LPVOID ) ) wglGetProcAddress((LPCSTR) "wglGetDeviceGammaRamp3DFX" ); - qwglSetDeviceGammaRamp3DFX = ( BOOL ( WINAPI * )( HDC, LPVOID ) ) wglGetProcAddress((LPCSTR) "wglSetDeviceGammaRamp3DFX" ); - - if ( qwglGetDeviceGammaRamp3DFX && qwglSetDeviceGammaRamp3DFX ) - { - //Con_Printf("using WGL_3DFX_gamma_control\n"); - Con_Printf("WGL_3DFX_gamma_control\n"); - } - else - { - qwglGetDeviceGammaRamp3DFX = NULL; - qwglSetDeviceGammaRamp3DFX = NULL; - } - //} - //else - //{ - // ri.Printf( PRINT_ALL, "...ignoring WGL_3DFX_gamma_control\n" ); - //} - } - //else - //{ - // Con_Printf("WGL_3DFX_gamma_control not found\n"); - //} -} - - -// jkrige - anisotropic filtering -qboolean anisotropic_ext = false; -float maximumAnisotrophy = 1.0f; - -void CheckAnisotropicExtension( void ) -{ - char *tmp; - char *search; - - search = NULL; - search = "GL_EXT_texture_filter_anisotropic"; - if (!search) return; - - - tmp = ( unsigned char * )glGetString( GL_EXTENSIONS ); - while( *tmp ) - { - if (strncmp((const char*)tmp, search, strlen(search)) == 0) - { - glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &maximumAnisotrophy); - Con_Printf("GL_EXT_texture_filter_anisotropic\n"); - anisotropic_ext = true; - } - tmp++; - } - - //if(!anisotropic_ext) - // Con_Printf("GL_EXT_texture_filter_anisotropic not found\n"); -} -// jkrige - anisotropic filtering - - -// jkrige - non power of two -qboolean npow2_ext = false; - -void CheckNonPowTwoExtension( void ) -{ - unsigned char *tmp; - char *search; - - search = NULL; - search = "GL_ARB_texture_non_power_of_two"; - if (!search) return; - - - tmp = ( unsigned char * )glGetString( GL_EXTENSIONS ); - while( *tmp ) - { - if (strncmp((const char*)tmp, search, strlen(search)) == 0) - { - Con_Printf("GL_ARB_texture_non_power_of_two\n"); - npow2_ext = true; - } - tmp++; - } - - //if(!npow2_ext) - // Con_Printf("GL_ARB_texture_non_power_of_two not found\n"); -} -// jkrige - non power of two - -/* -=============== -GL_Init -=============== -*/ -void GL_Init (void) -{ - gl_vendor = glGetString (GL_VENDOR); - Con_Printf ("GL_VENDOR: %s\n", gl_vendor); - gl_renderer = glGetString (GL_RENDERER); - Con_Printf ("GL_RENDERER: %s\n", gl_renderer); - - gl_version = glGetString (GL_VERSION); - Con_Printf ("GL_VERSION: %s\n", gl_version); - - // jkrige - don't display extension list - gl_extensions = glGetString (GL_EXTENSIONS); - //Con_Printf ("GL_EXTENSIONS: %s\n", gl_extensions); - // jkrige - don't display extension list - //Con_Printf("------------------------------------\n"); - Con_Printf("\n------------- Extensions -------------\n"); - -// Con_Printf ("%s %s\n", gl_renderer, gl_version); - - // jkrige - always draw sbar - //if (strnicmp(gl_renderer,"PowerVR",7)==0) - // fullsbardraw = true; - // jkrige - always draw sbar - - if (strnicmp(gl_renderer,"Permedia",8)==0) - isPermedia = true; - - CheckTextureExtensions (); - //CheckMultiTextureExtensions (); // jkrige - remove multitexture - - Check3DFXGammaExtensions (); // jkrige - gamma - CheckNonPowTwoExtension(); // jkrige - non power of two - CheckAnisotropicExtension(); // jkrige - anisotropic filtering - - // jkrige - clear color changed to black (used to be red) - glClearColor(0.0, 0.0, 0.0, 0.0); - //glClearColor (1,0,0,0); - // jkrige - clear color changed to black (used to be red) - glCullFace(GL_FRONT); - glEnable(GL_TEXTURE_2D); - - glEnable(GL_ALPHA_TEST); - // Pa3PyX: to avoid clipping of smaller fonts/graphics - glAlphaFunc(GL_GREATER, 0.632); - //glAlphaFunc(GL_GREATER, 0.666); - - // jkrige - brush z-fighting - glPolygonOffset(0.05, 25); - // jkrige - brush z-fighting - - glPolygonMode (GL_FRONT_AND_BACK, GL_FILL); - glShadeModel (GL_FLAT); - - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); - - glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - -// glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); - glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); - -#if 0 - CheckArrayExtensions (); - - glEnable (GL_VERTEX_ARRAY_EXT); - glEnable (GL_TEXTURE_COORD_ARRAY_EXT); - glVertexPointerEXT (3, GL_FLOAT, 0, 0, &glv.x); - glTexCoordPointerEXT (2, GL_FLOAT, 0, 0, &glv.s); - glColorPointerEXT (3, GL_FLOAT, 0, 0, &glv.r); -#endif - - // jkrige - gamma - VG_CheckHardwareGamma(); - VG_SetColorMappings(); - // jkrige - gamma -} - -/* -================= -GL_BeginRendering - -================= -*/ -void GL_BeginRendering (int *x, int *y, int *width, int *height) -{ - extern cvar_t gl_clear; - - *x = *y = 0; - *width = WindowRect.right - WindowRect.left; - *height = WindowRect.bottom - WindowRect.top; - -// if (!wglMakeCurrent( maindc, baseRC )) -// Sys_Error ("wglMakeCurrent failed"); - -// glViewport (*x, *y, *width, *height); -} - - -void GL_EndRendering (void) -{ - if (!scr_skipupdate || block_drawing) - SwapBuffers(maindc); - -// handle the mouse state when windowed if that's changed - if (modestate == MS_WINDOWED) - { - if (!_windowed_mouse.value) { - if (windowed_mouse) { - IN_DeactivateMouse (); - IN_ShowMouse (); - windowed_mouse = false; - } - } else { - windowed_mouse = true; - if (key_dest == key_game && !mouseactive && ActiveApp) { - IN_ActivateMouse (); - IN_HideMouse (); - } else if (mouseactive && key_dest != key_game) { - IN_DeactivateMouse (); - IN_ShowMouse (); - } - } - } - - // jkrige - always draw sbar - //if (fullsbardraw) - // Sbar_Changed(); - // jkrige - always draw sbar -} - -void VID_SetPalette (unsigned char *palette) -{ - byte *pal; - unsigned r,g,b; - unsigned v; - int r1,g1,b1; - int j,k,l,m; - unsigned short i; - unsigned *table; - FILE *f; - char s[255]; - HWND hDlg, hProgress; - float gamma; - -// -// 8 8 8 encoding -// - pal = palette; - table = d_8to24table; - for (i=0 ; i<256 ; i++) - { - r = pal[0]; - g = pal[1]; - b = pal[2]; - pal += 3; - -// v = (255<<24) + (r<<16) + (g<<8) + (b<<0); -// v = (255<<0) + (r<<8) + (g<<16) + (b<<24); - v = (255<<24) + (r<<0) + (g<<8) + (b<<16); - *table++ = v; - } - d_8to24table[255] &= 0xffffff; // 255 is transparent - - // JACK: 3D distance calcs - k is last closest, l is the distance. - // FIXME: Precalculate this and cache to disk. - for (i=0; i < (1<<15); i++) { - /* Maps - 000000000000000 - 000000000011111 = Red = 0x1F - 000001111100000 = Blue = 0x03E0 - 111110000000000 = Grn = 0x7C00 - */ - r = ((i & 0x1F) << 3)+4; - g = ((i & 0x03E0) >> 2)+4; - b = ((i & 0x7C00) >> 7)+4; - pal = (unsigned char *)d_8to24table; - for (v=0,k=0,l=10000*10000; v<256; v++,pal+=4) { - r1 = r-pal[0]; - g1 = g-pal[1]; - b1 = b-pal[2]; - j = (r1*r1)+(g1*g1)+(b1*b1); - if (j', '?', K_SHIFT,'*', - K_ALT,' ', 0 , K_F1, K_F2, K_F3, K_F4, K_F5, // 3 - K_F6, K_F7, K_F8, K_F9, K_F10, K_PAUSE , 0 , K_HOME, - K_UPARROW,K_PGUP,'_',K_LEFTARROW,'%',K_RIGHTARROW,'+',K_END, //4 - K_DOWNARROW,K_PGDN,K_INS,K_DEL,0,0, 0, K_F11, - K_F12,0 , 0 , 0 , 0 , 0 , 0 , 0, // 5 - 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0, - 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0, // 6 - 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0, - 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 // 7 - }; -#endif - - -/* -======= -MapKey - -Map from windows to quake keynums -======= -*/ -int MapKey (int key) -{ - key = (key>>16)&255; - if (key > 127) - return 0; - if (scantokey[key] == 0) - Con_DPrintf("key 0x%02x has no translation\n", key); - return scantokey[key]; -} - -/* -=================================================================== - -MAIN WINDOW - -=================================================================== -*/ - -/* -================ -ClearAllStates -================ -*/ -void ClearAllStates (void) -{ - int i; - -// send an up event for each key, to make sure the server clears them all - for (i=0 ; i<256 ; i++) - { - Key_Event (i, false); - } - - Key_ClearStates (); - IN_ClearStates (); -} - -void AppActivate(BOOL fActive, BOOL minimize) -/**************************************************************************** -* -* Function: AppActivate -* Parameters: fActive - True if app is activating -* -* Description: If the application is activating, then swap the system -* into SYSPAL_NOSTATIC mode so that our palettes will display -* correctly. -* -****************************************************************************/ -{ - MSG msg; - HDC hdc; - int i, t; - static BOOL sound_active; - - ActiveApp = fActive; - Minimized = minimize; - -// enable/disable sound on focus gain/loss - if (!ActiveApp && sound_active) - { - // jkrige - fmod sound system - begin -#ifdef UQE_FMOD - FMOD_MusicActivate(false); -#else - CDAudio_Activate(false); -#endif - // jkrige - fmod sound system - end - - S_BlockSound (); - sound_active = false; - } - else if (ActiveApp && !sound_active) - { - // jkrige - fmod sound system - begin -#ifdef UQE_FMOD - FMOD_MusicActivate(true); -#else - CDAudio_Activate(true); -#endif - // jkrige - fmod sound system - end - - S_UnblockSound (); - sound_active = true; - } - - if (fActive) - { - if (modestate == MS_FULLDIB) - { - IN_ActivateMouse (); - IN_HideMouse (); - if (vid_canalttab && vid_wassuspended) { - vid_wassuspended = false; - ChangeDisplaySettings (&gdevmode, CDS_FULLSCREEN); - ShowWindow(mainwindow, SW_SHOWNORMAL); - } - } - else if ((modestate == MS_WINDOWED) && _windowed_mouse.value && key_dest == key_game) - { - IN_ActivateMouse (); - IN_HideMouse (); - } - } - - if (!fActive) - { - if (modestate == MS_FULLDIB) - { - IN_DeactivateMouse (); - IN_ShowMouse (); - if (vid_canalttab) { - ChangeDisplaySettings (NULL, 0); - vid_wassuspended = true; - } - } - else if ((modestate == MS_WINDOWED) && _windowed_mouse.value) - { - IN_DeactivateMouse (); - IN_ShowMouse (); - } - } -} - - -/* main window procedure */ -LONG WINAPI MainWndProc ( - HWND hWnd, - UINT uMsg, - WPARAM wParam, - LPARAM lParam) -{ - LONG lRet = 1; - int fwKeys, xPos, yPos, fActive, fMinimized, temp; - extern unsigned int uiWheelMessage; - - if ( uMsg == uiWheelMessage ) - uMsg = WM_MOUSEWHEEL; - - switch (uMsg) - { - case WM_KILLFOCUS: - if (modestate == MS_FULLDIB) - ShowWindow(mainwindow, SW_SHOWMINNOACTIVE); - break; - - case WM_CREATE: - break; - - case WM_MOVE: - window_x = (int) LOWORD(lParam); - window_y = (int) HIWORD(lParam); - VID_UpdateWindowStatus (); - break; - - case WM_KEYDOWN: - case WM_SYSKEYDOWN: - Key_Event (MapKey(lParam), true); - break; - - case WM_KEYUP: - case WM_SYSKEYUP: - Key_Event (MapKey(lParam), false); - break; - - case WM_SYSCHAR: - // keep Alt-Space from happening - break; - - // this is complicated because Win32 seems to pack multiple mouse events into - // one update sometimes, so we always check all states and look for events - case WM_LBUTTONDOWN: - case WM_LBUTTONUP: - case WM_RBUTTONDOWN: - case WM_RBUTTONUP: - case WM_MBUTTONDOWN: - case WM_MBUTTONUP: - case WM_XBUTTONDOWN: // jkrige - mouse thumb buttons - case WM_XBUTTONUP: // jkrige - mouse thumb buttons - case WM_MOUSEMOVE: - temp = 0; - - if (wParam & MK_LBUTTON) - temp |= 1; - - if (wParam & MK_RBUTTON) - temp |= 2; - - if (wParam & MK_MBUTTON) - temp |= 4; - - // jkrige - mouse thumb buttons - // intellimouse explorer - if (wParam & MK_XBUTTON1) - temp |= 8; - - if (wParam & MK_XBUTTON2) - temp |= 16; - // jkrige - mouse thumb buttons - - IN_MouseEvent (temp); - - break; - - // JACK: This is the mouse wheel with the Intellimouse - // Its delta is either positive or neg, and we generate the proper - // Event. - case WM_MOUSEWHEEL: - if ((short) HIWORD(wParam) > 0) { - Key_Event(K_MWHEELUP, true); - Key_Event(K_MWHEELUP, false); - } else { - Key_Event(K_MWHEELDOWN, true); - Key_Event(K_MWHEELDOWN, false); - } - break; - - case WM_SIZE: - break; - - case WM_CLOSE: - if (MessageBox (mainwindow, "Are you sure you want to quit?", "Confirm Exit", - MB_YESNO | MB_SETFOREGROUND | MB_ICONQUESTION) == IDYES) - { - Sys_Quit (); - } - - break; - - case WM_ACTIVATE: - fActive = LOWORD(wParam); - fMinimized = (BOOL) HIWORD(wParam); - AppActivate(!(fActive == WA_INACTIVE), fMinimized); - - // fix the leftover Alt from any Alt-Tab or the like that switched us away - ClearAllStates (); - - break; - - case WM_DESTROY: - { - if (dibwindow) - DestroyWindow (dibwindow); - - PostQuitMessage (0); - } - break; - - // jkrige - fmod sound system - begin -#ifndef UQE_FMOD_CDAUDIO - case MM_MCINOTIFY: - lRet = CDAudio_MessageHandler (hWnd, uMsg, wParam, lParam); - break; -#endif - // jkrige - fmod sound system - end - - default: - /* pass all unhandled messages to DefWindowProc */ - lRet = DefWindowProc (hWnd, uMsg, wParam, lParam); - break; - } - - /* return 1 if handled message, 0 if not */ - return lRet; -} - - -/* -================= -VID_NumModes -================= -*/ -int VID_NumModes (void) -{ - return nummodes; -} - - -/* -================= -VID_GetModePtr -================= -*/ -vmode_t *VID_GetModePtr (int modenum) -{ - - if ((modenum >= 0) && (modenum < nummodes)) - return &modelist[modenum]; - else - return &badmode; -} - - -/* -================= -VID_GetModeDescription -================= -*/ -char *VID_GetModeDescription (int mode) -{ - char *pinfo; - vmode_t *pv; - static char temp[100]; - - if ((mode < 0) || (mode >= nummodes)) - return NULL; - - if (!leavecurrentmode) - { - pv = VID_GetModePtr (mode); - pinfo = pv->modedesc; - } - else - { - sprintf (temp, "Desktop resolution (%dx%d)", modelist[MODE_FULLSCREEN_DEFAULT].width, modelist[MODE_FULLSCREEN_DEFAULT].height); - pinfo = temp; - } - - return pinfo; -} - - -// KJB: Added this to return the mode driver name in description for console - -char *VID_GetExtModeDescription (int mode) -{ - static char pinfo[100]; // jkrige - might be low - //static char pinfo[40]; - vmode_t *pv; - - if ((mode < 0) || (mode >= nummodes)) - return NULL; - - pv = VID_GetModePtr (mode); - if (modelist[mode].type == MS_FULLDIB) - { - if (!leavecurrentmode) - { - sprintf(pinfo,"%s fullscreen", pv->modedesc); - } - else - { - sprintf (pinfo, "Desktop resolution (%dx%d)", - modelist[MODE_FULLSCREEN_DEFAULT].width, - modelist[MODE_FULLSCREEN_DEFAULT].height); - } - } - else - { - if (modestate == MS_WINDOWED) - sprintf(pinfo, "%s windowed", pv->modedesc); - else - sprintf(pinfo, "windowed"); - } - - return pinfo; -} - - -/* -================= -VID_DescribeCurrentMode_f -================= -*/ -void VID_DescribeCurrentMode_f (void) -{ - Con_Printf ("%s\n", VID_GetExtModeDescription (vid_modenum)); -} - - -/* -================= -VID_NumModes_f -================= -*/ -void VID_NumModes_f (void) -{ - - if (nummodes == 1) - Con_Printf ("%d video mode is available\n", nummodes); - else - Con_Printf ("%d video modes are available\n", nummodes); -} - - -/* -================= -VID_DescribeMode_f -================= -*/ -void VID_DescribeMode_f (void) -{ - int t, modenum; - - modenum = Q_atoi (Cmd_Argv(1)); - - t = leavecurrentmode; - leavecurrentmode = 0; - - Con_Printf ("%s\n", VID_GetExtModeDescription (modenum)); - - leavecurrentmode = t; -} - - -/* -================= -VID_DescribeModes_f -================= -*/ -void VID_DescribeModes_f (void) -{ - int i, lnummodes, t; - char *pinfo; - vmode_t *pv; - - lnummodes = VID_NumModes (); - - t = leavecurrentmode; - leavecurrentmode = 0; - - for (i=1 ; i8 bpp modes - originalnummodes = nummodes; - modenum = 0; - - do - { - stat = EnumDisplaySettings (NULL, modenum, &devmode); - - // jkrige - limit video modes - //if ((devmode.dmBitsPerPel >= 15) && - /*(devmode.dmPelsWidth <= VID_MAXWIDTH) && - (devmode.dmPelsHeight <= VID_MAXHEIGHT) && - (nummodes < MAX_MODE_LIST))*/ - if ((devmode.dmBitsPerPel >= 32) && - ( - (devmode.dmPelsWidth == VID_MINWIDTH && devmode.dmPelsHeight == VID_MINHEIGHT) || (devmode.dmPelsWidth >= 1024 && devmode.dmPelsHeight >= 768) - ) && - (devmode.dmPelsWidth != 720) && - (devmode.dmPelsWidth <= VID_MAXWIDTH) && - (devmode.dmPelsHeight <= VID_MAXHEIGHT) && - (devmode.dmDisplayFrequency <= 60) && - (nummodes < MAX_MODE_LIST)) - // jkrige - limit video modes - { - devmode.dmFields = DM_BITSPERPEL | - DM_PELSWIDTH | - DM_PELSHEIGHT; - - if (ChangeDisplaySettings (&devmode, CDS_TEST | CDS_FULLSCREEN) == - DISP_CHANGE_SUCCESSFUL) - { - modelist[nummodes].type = MS_FULLDIB; - modelist[nummodes].width = devmode.dmPelsWidth; - modelist[nummodes].height = devmode.dmPelsHeight; - modelist[nummodes].modenum = 0; - modelist[nummodes].halfscreen = 0; - modelist[nummodes].dib = 1; - modelist[nummodes].fullscreen = 1; - modelist[nummodes].bpp = devmode.dmBitsPerPel; - - // jkrige - limit video modes - //sprintf (modelist[nummodes].modedesc, "%dx%dx%d", devmode.dmPelsWidth, devmode.dmPelsHeight, devmode.dmBitsPerPel); - sprintf (modelist[nummodes].modedesc, "%dx%d", devmode.dmPelsWidth, devmode.dmPelsHeight); - // jkrige - limit video modes - - - // if the width is more than twice the height, reduce it by half because this - // is probably a dual-screen monitor - if (!COM_CheckParm("-noadjustaspect")) - { - if (modelist[nummodes].width > (modelist[nummodes].height << 1)) - { - modelist[nummodes].width >>= 1; - modelist[nummodes].halfscreen = 1; - - // jkrige - limit video modes - //sprintf (modelist[nummodes].modedesc, "%dx%dx%d", modelist[nummodes].width, modelist[nummodes].height, modelist[nummodes].bpp); - sprintf (modelist[nummodes].modedesc, "%dx%d", modelist[nummodes].width, modelist[nummodes].height); - // jkrige - limit video modes - } - } - - for (i=originalnummodes, existingmode = 0 ; i 255) - inf = 255; - palette[i] = inf; - } - - memcpy (pal, palette, sizeof(palette)); -} - -/* -=================== -VID_Init -=================== -*/ -void VID_Init (unsigned char *palette) -{ - int i, existingmode; - int basenummodes, width, height, bpp, findbpp, done; - byte *ptmp; - char gldir[MAX_OSPATH]; - HDC hdc; - DEVMODE devmode; - - memset(&devmode, 0, sizeof(devmode)); - - Cvar_RegisterVariable (&vid_mode); - Cvar_RegisterVariable (&vid_wait); - Cvar_RegisterVariable (&vid_nopageflip); - Cvar_RegisterVariable (&_vid_wait_override); - Cvar_RegisterVariable (&_vid_default_mode); - Cvar_RegisterVariable (&_vid_default_mode_win); - Cvar_RegisterVariable (&vid_config_x); - Cvar_RegisterVariable (&vid_config_y); - Cvar_RegisterVariable (&vid_stretch_by_2); - Cvar_RegisterVariable (&_windowed_mouse); - Cvar_RegisterVariable (&gl_ztrick); - - // jkrige - non power of two - Cvar_RegisterVariable (&gl_texture_non_power_of_two); - // jkrige - non power of two - - // jkrige - overbrights - Cvar_RegisterVariable (&gl_overbright); - // jkrige - overbrights - - Cmd_AddCommand ("vid_nummodes", VID_NumModes_f); - Cmd_AddCommand ("vid_describecurrentmode", VID_DescribeCurrentMode_f); - Cmd_AddCommand ("vid_describemode", VID_DescribeMode_f); - Cmd_AddCommand ("vid_describemodes", VID_DescribeModes_f); - - hIcon = LoadIcon (global_hInstance, MAKEINTRESOURCE (IDI_ICON2)); - - // jkrige - disable common controls - //InitCommonControls(); - // jkrige - disable common controls - - VID_InitDIB (global_hInstance); - basenummodes = nummodes = 1; - - VID_InitFullDIB (global_hInstance); - - if (COM_CheckParm("-window")) - { - hdc = GetDC (NULL); - - if (GetDeviceCaps(hdc, RASTERCAPS) & RC_PALETTE) - { - Sys_Error ("Can't run in non-RGB mode"); - } - - ReleaseDC (NULL, hdc); - - windowed = true; - - vid_default = MODE_WINDOWED; - } - else - { - if (nummodes == 1) - Sys_Error ("No RGB fullscreen modes available"); - - windowed = false; - - if (COM_CheckParm("-mode")) - { - vid_default = Q_atoi(com_argv[COM_CheckParm("-mode")+1]); - } - else - { - if (COM_CheckParm("-current")) - { - modelist[MODE_FULLSCREEN_DEFAULT].width = GetSystemMetrics (SM_CXSCREEN); - modelist[MODE_FULLSCREEN_DEFAULT].height = GetSystemMetrics (SM_CYSCREEN); - vid_default = MODE_FULLSCREEN_DEFAULT; - leavecurrentmode = 1; - } - else - { - if (COM_CheckParm("-width")) - { - width = Q_atoi(com_argv[COM_CheckParm("-width")+1]); - } - else - { - width = 640; - } - - // jkrige - limit video modes - /*if (COM_CheckParm("-bpp")) - { - bpp = Q_atoi(com_argv[COM_CheckParm("-bpp")+1]); - findbpp = 0; - } - else - { - bpp = 15; - findbpp = 1; - }*/ - bpp = 16; - findbpp = 1; - // jkrige - limit video modes - - if (COM_CheckParm("-height")) - height = Q_atoi(com_argv[COM_CheckParm("-height")+1]); - - // if they want to force it, add the specified mode to the list - if (COM_CheckParm("-force") && (nummodes < MAX_MODE_LIST)) - { - modelist[nummodes].type = MS_FULLDIB; - modelist[nummodes].width = width; - modelist[nummodes].height = height; - modelist[nummodes].modenum = 0; - modelist[nummodes].halfscreen = 0; - modelist[nummodes].dib = 1; - modelist[nummodes].fullscreen = 1; - modelist[nummodes].bpp = bpp; - - // jkrige - limit video modes - //sprintf (modelist[nummodes].modedesc, "%dx%dx%d", devmode.dmPelsWidth, devmode.dmPelsHeight, devmode.dmBitsPerPel); - sprintf (modelist[nummodes].modedesc, "%dx%d", devmode.dmPelsWidth, devmode.dmPelsHeight); - // jkrige - limit video modes - - for (i=nummodes, existingmode = 0 ; iwidth)/2, 4, p); - - vid_wmodes = 0; - lnummodes = VID_NumModes (); - - for (i=1 ; (i 0) - { - // jkrige - limit video modes - //M_Print (2*8, 36+0*8, "Fullscreen Modes (WIDTHxHEIGHTxBPP)"); - M_Print (4*8, 36+0*8, "Fullscreen Modes (WIDTHxHEIGHT)"); - // jkrige - limit video modes - - column = 8; - row = 36+2*8; - - for (i=0 ; i"); - // jkrige - limit video modes - //M_Print (3*8, 36 + MODE_AREA_HEIGHT * 8 + 8*4, "and -bpp "); - M_Print (3*8, 36 + MODE_AREA_HEIGHT * 8 + 8*4, "and -height "); - // jkrige - limit video modes - M_Print (3*8, 36 + MODE_AREA_HEIGHT * 8 + 8*6, "Select windowed mode with -window"); -} - - -/* -================ -VID_MenuKey -================ -*/ -void VID_MenuKey (int key) -{ - switch (key) - { - case K_ESCAPE: - S_LocalSound ("misc/menu1.wav"); - M_Menu_Options_f (); - break; - - default: - break; - } -} diff --git a/engine/code/gl_warp.c b/engine/code/gl_warp.c deleted file mode 100644 index 5133f31..0000000 --- a/engine/code/gl_warp.c +++ /dev/null @@ -1,1182 +0,0 @@ -/* -Copyright (C) 1996-1997 Id Software, Inc. - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ -// gl_warp.c -- sky and water polygons - -#include "quakedef.h" - -extern model_t *loadmodel; - -int skytexturenum; - -int solidskytexture; -int alphaskytexture; -float speedscale; // for top sky and bottom sky - -msurface_t *warpface; - -// jkrige - quake2 warps -//extern cvar_t gl_subdivide_size; -#define SUBDIVIDE_SIZE 64 -// jkrige - quake2 warps - -void BoundPoly (int numverts, float *verts, vec3_t mins, vec3_t maxs) -{ - int i, j; - float *v; - - mins[0] = mins[1] = mins[2] = 9999; - maxs[0] = maxs[1] = maxs[2] = -9999; - v = verts; - for (i=0 ; i maxs[j]) - maxs[j] = *v; - } -} - -// jkrige - quake2 warps -void SubdividePolygon (int numverts, float *verts) -{ - int i, j, k; - vec3_t mins, maxs; - float m; - float *v; - vec3_t front[64], back[64]; - int f, b; - float dist[64]; - float frac; - glpoly_t *poly; - float s, t; - vec3_t total; - float total_s, total_t; - - if (numverts > 60) - Sys_Error ("numverts = %i", numverts); - - //if (numverts > 60) - // ri.Sys_Error (ERR_DROP, "numverts = %i", numverts); - - BoundPoly (numverts, verts, mins, maxs); - - for (i=0 ; i<3 ; i++) - { - m = (mins[i] + maxs[i]) * 0.5; - m = SUBDIVIDE_SIZE * floor (m/SUBDIVIDE_SIZE + 0.5); - if (maxs[i] - m < 8) - continue; - if (m - mins[i] < 8) - continue; - - // cut it - v = verts + i; - for (j=0 ; j= 0) - { - VectorCopy (v, front[f]); - f++; - } - if (dist[j] <= 0) - { - VectorCopy (v, back[b]); - b++; - } - if (dist[j] == 0 || dist[j+1] == 0) - continue; - if ( (dist[j] > 0) != (dist[j+1] > 0) ) - { - // clip point - frac = dist[j] / (dist[j] - dist[j+1]); - for (k=0 ; k<3 ; k++) - front[f][k] = back[b][k] = v[k] + frac*(v[3+k] - v[k]); - f++; - b++; - } - } - - SubdividePolygon (f, front[0]); - SubdividePolygon (b, back[0]); - return; - } - - // add a point in the center to help keep warp valid - poly = Hunk_Alloc (sizeof(glpoly_t) + ((numverts-4)+2) * VERTEXSIZE*sizeof(float)); - poly->next = warpface->polys; - warpface->polys = poly; - poly->numverts = numverts+2; - VectorClear (total); - total_s = 0; - total_t = 0; - for (i=0 ; iverts[i+1]); - s = DotProduct (verts, warpface->texinfo->vecs[0]); - t = DotProduct (verts, warpface->texinfo->vecs[1]); - - total_s += s; - total_t += t; - VectorAdd (total, verts, total); - - poly->verts[i+1][3] = s; - poly->verts[i+1][4] = t; - } - - VectorScale (total, (1.0/numverts), poly->verts[0]); - poly->verts[0][3] = total_s/numverts; - poly->verts[0][4] = total_t/numverts; - - // copy first vertex to last - memcpy (poly->verts[i+1], poly->verts[1], sizeof(poly->verts[0])); -} - -/*void SubdividePolygon (int numverts, float *verts) -{ - int i, j, k; - vec3_t mins, maxs; - float m; - float *v; - vec3_t front[64], back[64]; - int f, b; - float dist[64]; - float frac; - glpoly_t *poly; - float s, t; - - if (numverts > 60) - Sys_Error ("numverts = %i", numverts); - - BoundPoly (numverts, verts, mins, maxs); - - for (i=0 ; i<3 ; i++) - { - m = (mins[i] + maxs[i]) * 0.5; - m = gl_subdivide_size.value * floor (m/gl_subdivide_size.value + 0.5); - if (maxs[i] - m < 8) - continue; - if (m - mins[i] < 8) - continue; - - // cut it - v = verts + i; - for (j=0 ; j= 0) - { - VectorCopy (v, front[f]); - f++; - } - if (dist[j] <= 0) - { - VectorCopy (v, back[b]); - b++; - } - if (dist[j] == 0 || dist[j+1] == 0) - continue; - if ( (dist[j] > 0) != (dist[j+1] > 0) ) - { - // clip point - frac = dist[j] / (dist[j] - dist[j+1]); - for (k=0 ; k<3 ; k++) - front[f][k] = back[b][k] = v[k] + frac*(v[3+k] - v[k]); - f++; - b++; - } - } - - SubdividePolygon (f, front[0]); - SubdividePolygon (b, back[0]); - return; - } - - poly = Hunk_Alloc (sizeof(glpoly_t) + (numverts-4) * VERTEXSIZE*sizeof(float)); - poly->next = warpface->polys; - warpface->polys = poly; - poly->numverts = numverts; - for (i=0 ; iverts[i]); - s = DotProduct (verts, warpface->texinfo->vecs[0]); - t = DotProduct (verts, warpface->texinfo->vecs[1]); - poly->verts[i][3] = s; - poly->verts[i][4] = t; - } -}*/ -// jkrige - quake2 warps - -/* -================ -GL_SubdivideSurface - -Breaks a polygon up along axial 64 unit -boundaries so that turbulent and sky warps -can be done reasonably. -================ -*/ -void GL_SubdivideSurface (msurface_t *fa) -{ - vec3_t verts[64]; - int numverts; - int i; - int lindex; - float *vec; - //texture_t *t; - - warpface = fa; - - // - // convert edges back to a normal polygon - // - numverts = 0; - for (i=0 ; inumedges ; i++) - { - lindex = loadmodel->surfedges[fa->firstedge + i]; - - if (lindex > 0) - vec = loadmodel->vertexes[loadmodel->edges[lindex].v[0]].position; - else - vec = loadmodel->vertexes[loadmodel->edges[-lindex].v[1]].position; - VectorCopy (vec, verts[numverts]); - numverts++; - } - - SubdividePolygon (numverts, verts[0]); -} - -//========================================================= - - - -// speed up sin calculations - Ed -// jkrige - quake2 warps -/*float turbsin[] = -{ - #include "gl_warp_sin.h" -};*/ -// jkrige - quake2 warps -#define TURBSCALE (256.0 / (2 * M_PI)) - -/* -============= -EmitWaterPolys - -Does a water warp on the pre-fragmented glpoly_t chain -============= -*/ -// jkrige - quake2 warps -void EmitWaterPolys (msurface_t *fa) -{ - glpoly_t *p, *bp; - float *v; - int i; - float s, t, os, ot; - //float rdt = realtime; - - for (bp=fa->polys ; bp ; bp=bp->next) - { - p = bp; - - glBegin (GL_TRIANGLE_FAN); - for (i=0,v=p->verts[0] ; inumverts ; i++, v+=VERTEXSIZE) - { - os = v[3]; - ot = v[4]; - - //s = os + turbsin[(int)((ot * 0.125 + realtime) * TURBSCALE) & 255]; - s = os + sin(DEG2RAD((ot * 0.125 + realtime) * TURBSCALE)) * 3.7; - s *= (1.0/64); - - //t = ot + turbsin[(int)((os * 0.125 + realtime) * TURBSCALE) & 255]; - t = ot + sin(DEG2RAD((os * 0.125 + realtime) * TURBSCALE)) * 3.7; - t *= (1.0/64); - - glTexCoord2f (s, t); - glVertex3fv (v); - } - glEnd (); - } -} - -/*void EmitWaterPolys (msurface_t *fa) -{ - glpoly_t *p; - float *v; - int i; - float s, t, os, ot; - - - for (p=fa->polys ; p ; p=p->next) - { - glBegin (GL_POLYGON); - for (i=0,v=p->verts[0] ; inumverts ; i++, v+=VERTEXSIZE) - { - os = v[3]; - ot = v[4]; - - s = os + turbsin[(int)((ot*0.125+realtime) * TURBSCALE) & 255]; - s *= (1.0/64); - - t = ot + turbsin[(int)((os*0.125+realtime) * TURBSCALE) & 255]; - t *= (1.0/64); - - glTexCoord2f (s, t); - glVertex3fv (v); - } - glEnd (); - } -}*/ -// jkrige - quake2 warps - - - -/* -============= -EmitSkyPolys -============= -*/ -void EmitSkyPolys (msurface_t *fa) -{ - glpoly_t *p; - float *v; - int i; - float s, t; - vec3_t dir; - float length; - - // jkrige - wireframe - if (gl_wireframe.value) - return; - // jkrige - wireframe - - for (p=fa->polys ; p ; p=p->next) - { - glBegin (GL_POLYGON); - for (i=0,v=p->verts[0] ; inumverts ; i++, v+=VERTEXSIZE) - { - VectorSubtract (v, r_origin, dir); - dir[2] *= 3; // flatten the sphere - - length = dir[0]*dir[0] + dir[1]*dir[1] + dir[2]*dir[2]; - length = sqrt (length); - length = 6*63/length; - - dir[0] *= length; - dir[1] *= length; - - s = (speedscale + dir[0]) * (1.0/128); - t = (speedscale + dir[1]) * (1.0/128); - - glTexCoord2f (s, t); - glVertex3fv (v); - } - glEnd (); - } -} - -/* -=============== -EmitBothSkyLayers - -Does a sky warp on the pre-fragmented glpoly_t chain -This will be called for brushmodels, the world -will have them chained together. -=============== -*/ -void EmitBothSkyLayers (msurface_t *fa) -{ - int i; - int lindex; - float *vec; - - // jkrige - remove multitexture - //GL_DisableMultitexture(); - // jkrige - remove multitexture - - // jkrige - wireframe - if (gl_wireframe.value) - return; - // jkrige - wireframe - - GL_Bind (solidskytexture); - speedscale = realtime*8; - speedscale -= (int)speedscale & ~127 ; - - EmitSkyPolys (fa); - - glEnable (GL_BLEND); - GL_Bind (alphaskytexture); - speedscale = realtime*16; - speedscale -= (int)speedscale & ~127 ; - - EmitSkyPolys (fa); - - glDisable (GL_BLEND); -} - -#ifndef QUAKE2 -/* -================= -R_DrawSkyChain -================= -*/ -// jkrige - skybox -/*void R_DrawSkyChain (msurface_t *s) -{ - msurface_t *fa; - - // jkrige - remove multitexture - //GL_DisableMultitexture(); - // jkrige - remove multitexture - - // used when gl_texsort is on - GL_Bind(solidskytexture); - speedscale = realtime*8; - speedscale -= (int)speedscale & ~127 ; - - for (fa=s ; fa ; fa=fa->texturechain) - EmitSkyPolys (fa); - - glEnable (GL_BLEND); - GL_Bind (alphaskytexture); - speedscale = realtime*16; - speedscale -= (int)speedscale & ~127 ; - - for (fa=s ; fa ; fa=fa->texturechain) - EmitSkyPolys (fa); - - glDisable (GL_BLEND); -}*/ -// jkrige - skybox -#endif - -/* -================================================================= - - Quake 2 environment sky - -================================================================= -*/ - -//#ifdef QUAKE2 // jkrige - skybox - - -#define SKY_TEX 2560 // jkrige - skybox - -/* -================== -R_LoadSkys -================== -*/ -char *suf[6] = {"_rt", "_bk", "_lf", "_ft", "_up", "_dn"}; -// jkrige - skybox -/*void R_LoadSkys (void) -{ - int i; - FILE *f; - char name[64]; - - for (i=0 ; i<6 ; i++) - { - GL_Bind (SKY_TEX + i); - sprintf (name, "gfx/env/bkgtst%s.tga", suf[i]); - COM_FOpenFile (name, &f, false); - if (!f) - { - Con_Printf ("Couldn't load %s\n", name); - continue; - } - LoadTGA (f); -// LoadPCX (f); - - glTexImage2D (GL_TEXTURE_2D, 0, gl_solid_format, 256, 256, 0, GL_RGBA, GL_UNSIGNED_BYTE, targa_rgba); -// glTexImage2D (GL_TEXTURE_2D, 0, gl_solid_format, 256, 256, 0, GL_RGBA, GL_UNSIGNED_BYTE, pcx_rgb); - - free (targa_rgba); -// free (pcx_rgb); - - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - } -}*/ - -void R_LoadSkys (void) -{ - int i; - char name[64]; - byte *data; - - for (i=0 ; i<6 ; i++) - { - sprintf (name, "skies/%s%s", cl.skybox, suf[i]); - if (!(data = LoadImagePixels (name, true))) - { - Cvar_Set("gl_skytype", "0"); - return; - } - - GL_Bind (SKY_TEX + i); - - if(image_bits == 8) - GL_Upload8 (data, image_width, image_height, false, false); - if(image_bits == 32) - GL_Upload32 ((void*)data, image_width, image_height, false, false); - - free(data); - - // jkrige - texture mode - if(gl_texturemode.value == 0.0f) - { - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - } - else - { - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - } - // jkrige - texture mode - } - - Cvar_Set("gl_skytype", "1"); -} -// jkrige - skybox - - -vec3_t skyclip[6] = { - {1,1,0}, - {1,-1,0}, - {0,-1,1}, - {0,1,1}, - {1,0,1}, - {-1,0,1} -}; -int c_sky; - -// 1 = s, 2 = t, 3 = 2048 -int st_to_vec[6][3] = -{ - {3,-1,2}, - {-3,1,2}, - - {1,3,2}, - {-1,-3,2}, - - {-2,-1,3}, // 0 degrees yaw, look straight up - {2,-1,-3} // look straight down - -// {-1,2,3}, -// {1,2,-3} -}; - -// s = [0]/[2], t = [1]/[2] -int vec_to_st[6][3] = -{ - {-2,3,1}, - {2,3,-1}, - - {1,3,2}, - {-1,3,-2}, - - {-2,-1,3}, - {-2,1,-3} - -// {-1,2,3}, -// {1,2,-3} -}; - -#define MAX_CLIP_VERTS 64 -// jkrige - skybox (clipping) -//float skymins[2][6], skymaxs[2][6]; // jkrige - skybox - -/*void DrawSkyPolygon (int nump, vec3_t vecs) -{ - int i,j; - vec3_t v, av; - float s, t, dv; - int axis; - float *vp; - - c_sky++; -#if 0 -glBegin (GL_POLYGON); -for (i=0 ; i av[1] && av[0] > av[2]) - { - if (v[0] < 0) - axis = 1; - else - axis = 0; - } - else if (av[1] > av[2] && av[1] > av[0]) - { - if (v[1] < 0) - axis = 3; - else - axis = 2; - } - else - { - if (v[2] < 0) - axis = 5; - else - axis = 4; - } - - // project new texture coords - for (i=0 ; i 0) - dv = vecs[j - 1]; - else - dv = -vecs[-j - 1]; - - j = vec_to_st[axis][0]; - if (j < 0) - s = -vecs[-j -1] / dv; - else - s = vecs[j-1] / dv; - j = vec_to_st[axis][1]; - if (j < 0) - t = -vecs[-j -1] / dv; - else - t = vecs[j-1] / dv; - - if (s < skymins[0][axis]) - skymins[0][axis] = s; - if (t < skymins[1][axis]) - skymins[1][axis] = t; - if (s > skymaxs[0][axis]) - skymaxs[0][axis] = s; - if (t > skymaxs[1][axis]) - skymaxs[1][axis] = t; - } -} - -void ClipSkyPolygon (int nump, vec3_t vecs, int stage) -{ - float *norm; - float *v; - qboolean front, back; - float d, e; - float dists[MAX_CLIP_VERTS]; - int sides[MAX_CLIP_VERTS]; - vec3_t newv[2][MAX_CLIP_VERTS]; - int newc[2]; - int i, j; - - if (nump > MAX_CLIP_VERTS-2) - Sys_Error ("ClipSkyPolygon: MAX_CLIP_VERTS"); - if (stage == 6) - { // fully clipped, so draw it - DrawSkyPolygon (nump, vecs); - return; - } - - front = back = false; - norm = skyclip[stage]; - for (i=0, v = vecs ; i ON_EPSILON) - { - front = true; - sides[i] = SIDE_FRONT; - } - else if (d < ON_EPSILON) - { - back = true; - sides[i] = SIDE_BACK; - } - else - sides[i] = SIDE_ON; - dists[i] = d; - } - - if (!front || !back) - { // not clipped - ClipSkyPolygon (nump, vecs, stage+1); - return; - } - - // clip it - sides[i] = sides[0]; - dists[i] = dists[0]; - VectorCopy (vecs, (vecs+(i*3)) ); - newc[0] = newc[1] = 0; - - for (i=0, v = vecs ; itexturechain) - EmitSkyPolys (fa); - - glEnable (GL_BLEND); - GL_Bind (alphaskytexture); - speedscale = realtime*16; - speedscale -= (int)speedscale & ~127; - - for (fa=s ; fa ; fa=fa->texturechain) - EmitSkyPolys (fa); - - glDisable (GL_BLEND); - } -} - - -/* -============== -R_ClearSkyBox -============== -*/ -// jkrige - skybox (clipping) -/*void R_ClearSkyBox (void) -{ - int i; - - for (i=0 ; i<6 ; i++) - { - skymins[0][i] = skymins[1][i] = 9999; - skymaxs[0][i] = skymaxs[1][i] = -9999; - } -}*/ -// jkrige - skybox (clipping) - - -void MakeSkyVec (float s, float t, int axis) -{ - vec3_t v, b; - int j, k; - - // jkrige - skybox (enlarged) - /*b[0] = s*2048; - b[1] = t*2048; - b[2] = 2048;*/ - b[0] = s*2360; - b[1] = t*2360; - b[2] = 2360; - // jkrige - skybox (enlarged) - - for (j=0 ; j<3 ; j++) - { - k = st_to_vec[axis][j]; - if (k < 0) - v[j] = -b[-k - 1]; - else - v[j] = b[k - 1]; - v[j] += r_origin[j]; - } - - // avoid bilerp seam - s = (s+1)*0.5; - t = (t+1)*0.5; - - if (s < 1.0/512) - s = 1.0/512; - else if (s > 511.0/512) - s = 511.0/512; - if (t < 1.0/512) - t = 1.0/512; - else if (t > 511.0/512) - t = 511.0/512; - - t = 1.0 - t; - glTexCoord2f (s, t); - glVertex3fv (v); -} - -/* -============== -R_DrawSkyBox -============== -*/ -int skytexorder[6] = {0,2,1,3,4,5}; -void R_DrawSkyBox (void) -{ - int i, j, k; - vec3_t v; - float s, t; - - if(gl_skytype.value != 1) - return; - - // jkrige - wireframe - if (gl_wireframe.value) - return; - // jkrige - wireframe - -//#if 0 -//glEnable (GL_BLEND); -//glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); -//glColor4f (1,1,1,0.5); -glDisable (GL_DEPTH_TEST); // jkrige - skybox (disabled depth ckecking) -//#endif - - //glGetIntegerv(GL_DEPTH_FUNC, &gld); - //glDepthFunc(GL_GREATER); -//glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); -//glDisable (GL_DEPTH_TEST); - for (i=0 ; i<6 ; i++) - { - //if (skymins[0][i] >= skymaxs[0][i] - //|| skymins[1][i] >= skymaxs[1][i]) - // continue; - - GL_Bind (SKY_TEX+skytexorder[i]); - -//#if 0 // jkrige - skybox (enabled skybox with fixed mins/maxs) - //if(gl_fullskybox.value == 1) - //{ - // skymins[0][i] = -1; - // skymins[1][i] = -1; - // skymaxs[0][i] = 1; - // skymaxs[1][i] = 1; - //} -//#endif - glBegin (GL_QUADS); - MakeSkyVec (-1 /*skymins[0][i]*/, -1 /*skymins[1][i]*/, i); - MakeSkyVec (-1 /*skymins[0][i]*/, 1 /*skymaxs[1][i]*/, i); - MakeSkyVec (1 /*skymaxs[0][i]*/, 1 /*skymaxs[1][i]*/, i); - MakeSkyVec (1 /*skymaxs[0][i]*/, -1 /*skymins[1][i]*/, i); - glEnd (); - } - //glDepthFunc(gld); -//#if 0 -//glDisable (GL_BLEND); -//glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); -//glColor4f (1,1,1,0.5); -glEnable (GL_DEPTH_TEST); // jkrige - skybox (disabled depth ckecking) -//#endif -//glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); -//glEnable (GL_DEPTH_TEST); - - // jkrige - skybox test - //restore matrix and rendering state - //glPopMatrix(); - //glPopAttrib(); - // jkrige - skybox test -} - -//#endif // jkrige - skybox - - - -//=============================================================== - -/* -============= -R_InitSky - -A sky texture is 256*128, with the right side being a masked overlay -============== -*/ -void R_InitSky (texture_t *mt) -{ - int i, j, p; - byte *src; - unsigned trans[128*128]; - unsigned transpix; - int r, g, b; - unsigned *rgba; - extern int skytexturenum; - - - // jkrige - external texture loading - FILE *f2; - //qboolean ExtOK = false; - int FoundSolid = -1; - int FoundAlpha = -1; - char skytex_solid[MAX_QPATH]; - char skytex_alpha[MAX_QPATH]; - byte *skydata; - - // find solid sky texture - if(FoundSolid == -1) - { - sprintf (skytex_solid, "textures/%s/%s_solid.tga", sv.name, mt->name); - FoundSolid = COM_FOpenFile(skytex_solid, &f2); - } - if(FoundSolid == -1) - { - sprintf (skytex_solid, "textures/%s_solid.tga", mt->name); - FoundSolid = COM_FOpenFile(skytex_solid, &f2); - } - if(FoundSolid == -1) - { - sprintf (skytex_solid, "textures/%s/%s_solid.jpg", sv.name, mt->name); - FoundSolid = COM_FOpenFile(skytex_solid, &f2); - } - if(FoundSolid == -1) - { - sprintf (skytex_solid, "textures/%s_solid.jpg", mt->name); - FoundSolid = COM_FOpenFile(skytex_solid, &f2); - } - - // find alpha sky texture - if(FoundAlpha == -1) - { - sprintf (skytex_alpha, "textures/%s/%s_alpha.tga", sv.name, mt->name); - FoundAlpha = COM_FOpenFile(skytex_alpha, &f2); - } - if(FoundAlpha == -1) - { - sprintf (skytex_alpha, "textures/%s_alpha.tga", mt->name); - FoundAlpha = COM_FOpenFile(skytex_alpha, &f2); - } - if(FoundAlpha == -1) - { - sprintf (skytex_alpha, "textures/%s/%s_alpha.jpg", sv.name, mt->name); - FoundAlpha = COM_FOpenFile(skytex_alpha, &f2); - } - if(FoundAlpha == -1) - { - sprintf (skytex_alpha, "textures/%s_alpha.jpg", mt->name); - FoundAlpha = COM_FOpenFile(skytex_alpha, &f2); - } - - - if(FoundSolid != -1 && FoundAlpha != -1) - { - // load solid sky texture - if ((skydata = LoadImagePixels (skytex_solid, false))) - { - if (!solidskytexture) - solidskytexture = texture_extension_number++; - - GL_Bind (solidskytexture); - glTexImage2D (GL_TEXTURE_2D, 0, gl_solid_format, image_width, image_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, skydata); - - if(gl_texturemode.value == 0.0f) - { - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - } - else - { - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - } - - free(skydata); - } - - // load alpha sky texture - if ((skydata = LoadImagePixels (skytex_alpha, false))) - { - if (!alphaskytexture) - alphaskytexture = texture_extension_number++; - - GL_Bind(alphaskytexture); - glTexImage2D (GL_TEXTURE_2D, 0, gl_alpha_format, image_width, image_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, skydata); - - if(gl_texturemode.value == 0.0f) - { - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - } - else - { - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - } - - free(skydata); - } - - return; - } - // jkrige - external texture loading - - - src = (byte *)mt + mt->offsets[0]; - - // make an average value for the back to avoid - // a fringe on the top level - - r = g = b = 0; - for (i=0 ; i<128 ; i++) - for (j=0 ; j<128 ; j++) - { - p = src[i*256 + j + 128]; - rgba = &d_8to24table[p]; - trans[(i*128) + j] = *rgba; - r += ((byte *)rgba)[0]; - g += ((byte *)rgba)[1]; - b += ((byte *)rgba)[2]; - } - - ((byte *)&transpix)[0] = r/(128*128); - ((byte *)&transpix)[1] = g/(128*128); - ((byte *)&transpix)[2] = b/(128*128); - ((byte *)&transpix)[3] = 0; - - - if (!solidskytexture) - solidskytexture = texture_extension_number++; - GL_Bind (solidskytexture ); - glTexImage2D (GL_TEXTURE_2D, 0, gl_solid_format, 128, 128, 0, GL_RGBA, GL_UNSIGNED_BYTE, trans); - - // jkrige - texture mode - //glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - //glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - if(gl_texturemode.value == 0.0f) - { - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - } - else - { - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - } - // jkrige - texture mode - - - for (i=0 ; i<128 ; i++) - for (j=0 ; j<128 ; j++) - { - p = src[i*256 + j]; - if (p == 0) - trans[(i*128) + j] = transpix; - else - trans[(i*128) + j] = d_8to24table[p]; - } - - if (!alphaskytexture) - alphaskytexture = texture_extension_number++; - GL_Bind(alphaskytexture); - glTexImage2D (GL_TEXTURE_2D, 0, gl_alpha_format, 128, 128, 0, GL_RGBA, GL_UNSIGNED_BYTE, trans); - - // jkrige - texture mode - //glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - //glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - if(gl_texturemode.value == 0.0f) - { - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - } - else - { - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - } - // jkrige - texture mode -} - diff --git a/engine/code/gl_warp_sin.h b/engine/code/gl_warp_sin.h deleted file mode 100644 index 22976a7..0000000 --- a/engine/code/gl_warp_sin.h +++ /dev/null @@ -1,51 +0,0 @@ -/* -Copyright (C) 1996-1997 Id Software, Inc. - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ - 0, 0.19633, 0.392541, 0.588517, 0.784137, 0.979285, 1.17384, 1.3677, - 1.56072, 1.75281, 1.94384, 2.1337, 2.32228, 2.50945, 2.69512, 2.87916, - 3.06147, 3.24193, 3.42044, 3.59689, 3.77117, 3.94319, 4.11282, 4.27998, - 4.44456, 4.60647, 4.76559, 4.92185, 5.07515, 5.22538, 5.37247, 5.51632, - 5.65685, 5.79398, 5.92761, 6.05767, 6.18408, 6.30677, 6.42566, 6.54068, - 6.65176, 6.75883, 6.86183, 6.9607, 7.05537, 7.14579, 7.23191, 7.31368, - 7.39104, 7.46394, 7.53235, 7.59623, 7.65552, 7.71021, 7.76025, 7.80562, - 7.84628, 7.88222, 7.91341, 7.93984, 7.96148, 7.97832, 7.99036, 7.99759, - 8, 7.99759, 7.99036, 7.97832, 7.96148, 7.93984, 7.91341, 7.88222, - 7.84628, 7.80562, 7.76025, 7.71021, 7.65552, 7.59623, 7.53235, 7.46394, - 7.39104, 7.31368, 7.23191, 7.14579, 7.05537, 6.9607, 6.86183, 6.75883, - 6.65176, 6.54068, 6.42566, 6.30677, 6.18408, 6.05767, 5.92761, 5.79398, - 5.65685, 5.51632, 5.37247, 5.22538, 5.07515, 4.92185, 4.76559, 4.60647, - 4.44456, 4.27998, 4.11282, 3.94319, 3.77117, 3.59689, 3.42044, 3.24193, - 3.06147, 2.87916, 2.69512, 2.50945, 2.32228, 2.1337, 1.94384, 1.75281, - 1.56072, 1.3677, 1.17384, 0.979285, 0.784137, 0.588517, 0.392541, 0.19633, - 9.79717e-16, -0.19633, -0.392541, -0.588517, -0.784137, -0.979285, -1.17384, -1.3677, - -1.56072, -1.75281, -1.94384, -2.1337, -2.32228, -2.50945, -2.69512, -2.87916, - -3.06147, -3.24193, -3.42044, -3.59689, -3.77117, -3.94319, -4.11282, -4.27998, - -4.44456, -4.60647, -4.76559, -4.92185, -5.07515, -5.22538, -5.37247, -5.51632, - -5.65685, -5.79398, -5.92761, -6.05767, -6.18408, -6.30677, -6.42566, -6.54068, - -6.65176, -6.75883, -6.86183, -6.9607, -7.05537, -7.14579, -7.23191, -7.31368, - -7.39104, -7.46394, -7.53235, -7.59623, -7.65552, -7.71021, -7.76025, -7.80562, - -7.84628, -7.88222, -7.91341, -7.93984, -7.96148, -7.97832, -7.99036, -7.99759, - -8, -7.99759, -7.99036, -7.97832, -7.96148, -7.93984, -7.91341, -7.88222, - -7.84628, -7.80562, -7.76025, -7.71021, -7.65552, -7.59623, -7.53235, -7.46394, - -7.39104, -7.31368, -7.23191, -7.14579, -7.05537, -6.9607, -6.86183, -6.75883, - -6.65176, -6.54068, -6.42566, -6.30677, -6.18408, -6.05767, -5.92761, -5.79398, - -5.65685, -5.51632, -5.37247, -5.22538, -5.07515, -4.92185, -4.76559, -4.60647, - -4.44456, -4.27998, -4.11282, -3.94319, -3.77117, -3.59689, -3.42044, -3.24193, - -3.06147, -2.87916, -2.69512, -2.50945, -2.32228, -2.1337, -1.94384, -1.75281, - -1.56072, -1.3677, -1.17384, -0.979285, -0.784137, -0.588517, -0.392541, -0.19633, diff --git a/engine/code/glqnotes.txt b/engine/code/glqnotes.txt deleted file mode 100644 index 2224072..0000000 --- a/engine/code/glqnotes.txt +++ /dev/null @@ -1,171 +0,0 @@ -Glquake v0.99, Quake v1.09 release notes - -3dfx owners -- read the 3dfx.txt file. - -On a standard OpenGL system, all you should need to do to run glquake is put -glquake.exe in your quake directory, and run it from there. DO NOT install -the opengl32.dll unless you have a 3dfx! Glquake should change the screen -resolution to 640*480*32k colors and run full screen by default. - -If you are running win-95, your desktop must be set to 32k or 64k colors -before running glquake. NT can switch automatically. - -Theoretically, glquake will run on any compliant OpenGL that supports the -texture objects extensions, but unless it is very powerfull hardware that -accelerates everything needed, the game play will not be acceptable. If it -has to go through any software emulation paths, the performance will likely -by well under one frame per second. - -3dfx has provided an opengl32.dll that implements everything glquake needs, -but it is not a full opengl implementation. Other opengl applications are -very unlikely to work with it, so consider it basically a "glquake driver". -See the encluded 3dfx.txt for specific instalation notes. 3dfx can only run -full screen, but you must still have your desktop set to a 16 bit color mode -for glquake to start. - -resolution options ------------------- -We had dynamic resolution changing in glquake for a while, but every single -opengl driver I tried it on messed up in one way or another, so it is now -limited to startup time only. - -glquake -window -This will start glquake in a window on your desktop instead of switching the -screen to lower resolution and covering everything. - -glquake -width 800 -height 600 -Tries to run glquake at the specified resolution. Combined with -window, it -creates a desktop window that size, otherwise it tries to set a full screen -resolution. - -You can also specify the resolution of the console independant of the screen -resolution. - -glquake -conwidth 320 -This will specify a console resolution of 320 by 240 (the height is -automatically determined by the default 4:3 aspect ratio, you can also -specify the height directly with -conheight). - -In higher resolution modes such as 800x600 and 1024x768, glquake will default -to a 640x480 console, since the font becomes small enough at higher -resolutions to become unreadable. If do you wish to have a higher resolution -console and status bar, specify it as well, such as: -glquake -width 800 -height 600 -conwidth 800 - -texture options ---------------- -The amount of textures used in the game can have a large impact on performance. -There are several options that let you trade off visual quality for better -performance. - -There is no way to flush already loaded textures, so it is best to change -these options on the command line, or they will only take effect on some of -the textures when you change levels. - -OpenGL only allows textures to repeat on power of two boundaries (32, 64, -128, etc), but software quake had a number of textures that repeated at 24 -or 96 pixel boundaries. These need to be either stretched out to the next -higher size, or shrunk down to the next lower. By default, they are filtered -down to the smaller size, but you can cause it to use the larger size if you -really want by using: - -glquake +gl_round_down 0 -This will generally run well on a normal 4 MB 3dfx card, but for other cards -that have either worse texture management or slower texture swapping speeds, -there are some additional settings that can drastically lower the amount of -textures to be managed. - -glquake +gl_picmip 1 -This causes all textures to have one half the dimensions they otherwise would. -This makes them blurry, but very small. You can set this to 2 to make the -textures one quarter the resolution on each axis for REALLY blurry textures. - -glquake +gl_playermip 1 -This is similar to picmip, but is only used for other players in deathmatch. -Each player in a deathmatch requires an individual skin texture, so this can -be a serious problem for texture management. It wouldn't be unreasonable to -set this to 2 or even 3 if you are playing competatively (and don't care if -the other guys have smudged skins). If you change this during the game, it -will take effect as soon as a player changes their skin colors. - -GLQuake also supports the following extensions for faster texture operation: - -GL_SGIS_multitexture -Multitextures support allows certain hardware to render the world in one -pass instead of two. GLQuake uses two passes, one for the world textures -and the second for the lightmaps that are blended on the textures. On some -hardware, with a GL_SIGS_multitexture supported OpenGL implementation, this -can be done in one pass. On hardware that supports this, you will get a -60% to 100% increase in frame rate. Currently, only 3DFX dual TMU cards -(such as the Obsidian 2220) support this extension, but other hardware will -soon follow. - -This extension will be autodetected and used. If for some reason it is not -working correctly, specify the command line option "-nomtex" to disable it. - -GL_EXT_shared_texture_palette -GLQuake uses 16bit textures by default but on OpenGL implementations -that support the GL_EXT_shared_texture_palette extension, GLQuake will use -8bit textures instead. This results in using half the needed texture memory -of 16bit texture and can improve performance. This is very little difference -in visual quality due to the fact that the textures are 8bit sources to -begin with. - -run time options ----------------- -At the console, you can set these values to effect drawing. - -gl_texturemode GL_NEAREST -Sets texture mapping to point sampled, which may be faster on some GL systems -(not on 3dfx). - -gl_texturemode GL_LINEAR_MIPMAP -This is the default texture mode. - -gl_texturemode GL_LINEAR_MIPMAP_LINEAR -This is the highest quality texture mapping (trilinear), but only very high -end hardware (intergraph intense 3D / realizm) supports it. Not that big of -a deal, actually. - -gl_finish 0 -This causes the game to not issue a glFinish() call each frame, which may make -some hardware run faster. If this is cleared, the 3dfx will back up a number -of frames and not be very playable. - -gl_flashblend 0 -By default, glquake just draws a shaded ball around objects that are emiting -light. Clearing this variable will cause it to properly relight the world -like normal quake, but it can be a significant speed hit on some systems. - -gl_ztrick 0 -Glquake uses a buffering method that avoids clearing the Z buffer, but some -hardware platforms don't like it. If the status bar and console are flashing -every other frame, clear this variable. - -gl_keeptjunctions 0 -If you clear this, glquake will remove colinear vertexes when it reloads the -level. This can give a few percent speedup, but it can leave a couple stray -blinking pixels on the screen. - -novelty features ----------------- -These are some rendering tricks that were easy to do in glquake. They aren't -very robust, but they are pretty cool to look at. - -r_shadows 1 -This causes every object to cast a shadow. - -r_wateralpha 0.7 -This sets the opacity of water textures, so you can see through it in properly -processed maps. 0.3 is very faint, almost like fog. 1 is completely solid -(the default). Unfortunately, the standard quake maps don't contain any -visibility information for seeing past water surfaces, so you can't just play -quake with this turned on. If you just want to see what it looks like, you -can set "r_novis 1", but that will make things go very slow. When I get a -chance, I will probably release some maps that have been processed properly -for this. - -r_mirroralpha 0.3 -This changes one particular texture (the stained glass texture in the EASY -start hall) into a mirror. The value is the opacity of the mirror surface. - diff --git a/engine/code/glquake.h b/engine/code/glquake.h deleted file mode 100644 index 48217f1..0000000 --- a/engine/code/glquake.h +++ /dev/null @@ -1,358 +0,0 @@ -/* -Copyright (C) 1996-1997 Id Software, Inc. - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ -// disable data conversion warnings - -#pragma warning(disable : 4244) // MIPS -#pragma warning(disable : 4136) // X86 -#pragma warning(disable : 4051) // ALPHA - -#ifdef _WIN32 -#include -#endif - -#include -#include - -#include "glext.h" // jkrige - opengl extensions -#include "wglext.h" // jkrige - windows opengl extensions - - -void GL_BeginRendering (int *x, int *y, int *width, int *height); -void GL_EndRendering (void); - - -#ifdef _WIN32 -// Function prototypes for the Texture Object Extension routines -typedef GLboolean (APIENTRY *ARETEXRESFUNCPTR)(GLsizei, const GLuint *, - const GLboolean *); -typedef void (APIENTRY *BINDTEXFUNCPTR)(GLenum, GLuint); -typedef void (APIENTRY *DELTEXFUNCPTR)(GLsizei, const GLuint *); -typedef void (APIENTRY *GENTEXFUNCPTR)(GLsizei, GLuint *); -typedef GLboolean (APIENTRY *ISTEXFUNCPTR)(GLuint); -typedef void (APIENTRY *PRIORTEXFUNCPTR)(GLsizei, const GLuint *, - const GLclampf *); -typedef void (APIENTRY *TEXSUBIMAGEPTR)(int, int, int, int, int, int, int, int, void *); - -extern BINDTEXFUNCPTR bindTexFunc; -extern DELTEXFUNCPTR delTexFunc; -extern TEXSUBIMAGEPTR TexSubImage2DFunc; -#endif - - -// jkrige - moved to glquake.h -typedef struct -{ - int texnum; - - qboolean tex_luma; // jkrige - luma textures - qboolean tex_luma8bit; // jkrige - fullbright pixels - - char identifier[64]; - int width, height; - qboolean mipmap; - int lhcsum; // jkrige - memleak & texture mismatch -} gltexture_t; - -//#define MAX_GLTEXTURES 2048 -#define MAX_GLTEXTURES 4096 // jkrige - increased maximum number of opengl textures -// jkrige - moved to glquake.h - - -extern gltexture_t gltextures[MAX_GLTEXTURES]; -extern int numgltextures; - -// jkrige - luma textures -#define JK_LUMA_TEX (MAX_GLTEXTURES) -// jkrige - luma textures - -extern int texture_extension_number; -extern int texture_mode; - -extern float gldepthmin, gldepthmax; - - -// jkrige - gamma -extern BOOL ( WINAPI * qwglGetDeviceGammaRamp3DFX)( HDC, LPVOID ); -extern BOOL ( WINAPI * qwglSetDeviceGammaRamp3DFX)( HDC, LPVOID ); -// jkrige - gamma - - -// jkrige - anisotropic filtering -extern qboolean anisotropic_ext; -extern float maximumAnisotrophy; -// jkrige - anisotropic filtering - - -// jkrige - non power of two -extern qboolean npow2_ext; -// jkrige - non power of two - - -void GL_Upload32 (unsigned *data, int width, int height, qboolean mipmap, qboolean alpha); -void GL_Upload8 (byte *data, int width, int height, qboolean mipmap, qboolean alpha); - -// jkrige - bytesperpixel -//int GL_LoadTexture (char *identifier, int width, int height, byte *data, qboolean mipmap, qboolean alpha); -int GL_LoadTexture (char *identifier, char *textype, int width, int height, byte *data, int mipmap, int alpha, int bytesperpixel); -// jkrige - bytesperpixel - -int GL_FindTexture (char *identifier); - -// jkrige - .lit colored lights -void GL_SetupLightmapFmt (qboolean check_cmdline); -// jkrige - .lit colored lights - -typedef struct -{ - float x, y, z; - float s, t; - float r, g, b; -} glvert_t; - -extern glvert_t glv; - -extern int glx, gly, glwidth, glheight; - -// jkrige - opengl extensions -//#ifdef _WIN32 -//extern PROC glArrayElementEXT; -//extern PROC glColorPointerEXT; -//extern PROC glTexturePointerEXT; -//extern PROC glVertexPointerEXT; -//#endif -// jkrige - opengl extensions - -// r_local.h -- private refresh defs - -#define ALIAS_BASE_SIZE_RATIO (1.0 / 11.0) - // normalizing factor so player model works out to about - // 1 pixel per triangle -#define MAX_LBM_HEIGHT 480 - -#define TILE_SIZE 128 // size of textures generated by R_GenTiledSurf - -#define SKYSHIFT 7 -#define SKYSIZE (1 << SKYSHIFT) -#define SKYMASK (SKYSIZE - 1) - -#define BACKFACE_EPSILON 0.01 - - -void R_TimeRefresh_f (void); -void R_ReadPointFile_f (void); -texture_t *R_TextureAnimation (texture_t *base); - -typedef struct surfcache_s -{ - struct surfcache_s *next; - struct surfcache_s **owner; // NULL is an empty chunk of memory - int lightadj[MAXLIGHTMAPS]; // checked for strobe flush - int dlight; - int size; // including header - unsigned width; - unsigned height; // DEBUG only needed for debug - float mipscale; - struct texture_s *texture; // checked for animating textures - byte data[4]; // width*height elements -} surfcache_t; - - -typedef struct -{ - pixel_t *surfdat; // destination for generated surface - int rowbytes; // destination logical width in bytes - msurface_t *surf; // description for surface to generate - fixed8_t lightadj[MAXLIGHTMAPS]; - // adjust for lightmap levels for dynamic lighting - texture_t *texture; // corrected for animating textures - int surfmip; // mipmapped ratio of surface texels / world pixels - int surfwidth; // in mipmapped texels - int surfheight; // in mipmapped texels -} drawsurf_t; - - -typedef enum { - pt_static, pt_grav, pt_slowgrav, pt_fire, pt_explode, pt_explode2, pt_blob, pt_blob2 -} ptype_t; - -// !!! if this is changed, it must be changed in d_ifacea.h too !!! -typedef struct particle_s -{ -// driver-usable fields - vec3_t org; - float color; -// drivers never touch the following fields - struct particle_s *next; - vec3_t vel; - float ramp; - float die; - ptype_t type; -} particle_t; - - -//==================================================== - - -extern entity_t r_worldentity; -extern qboolean r_cache_thrash; // compatability -extern vec3_t modelorg, r_entorigin; -extern entity_t *currententity; -extern int r_visframecount; // ??? what difs? -extern int r_framecount; -extern mplane_t frustum[4]; -extern int c_brush_polys, c_alias_polys; - - -// -// view origin -// -extern vec3_t vup; -extern vec3_t vpn; -extern vec3_t vright; -extern vec3_t r_origin; - -// -// screen size info -// -extern refdef_t r_refdef; -extern mleaf_t *r_viewleaf, *r_oldviewleaf; -extern texture_t *r_notexture_mip; -extern int d_lightstylevalue[256]; // 8.8 fraction of base light value - -extern qboolean envmap; -extern int currenttexture; -extern int cnttextures[2]; - -// jkrige - texture mode -extern int particletexture_linear; -extern int particletexture_point; -// jkrige - texture mode - -extern int playertextures; - -extern int skytexturenum; // index in cl.loadmodel, not gl texture object - -extern cvar_t r_norefresh; -extern cvar_t r_drawentities; -extern cvar_t r_drawworld; -extern cvar_t r_drawviewmodel; -extern cvar_t r_speeds; -extern cvar_t r_waterwarp; -extern cvar_t r_fullbright; -extern cvar_t r_lightmap; -//extern cvar_t r_shadows; // jkrige - removed alias shadows -extern cvar_t r_mirroralpha; -extern cvar_t r_wateralpha; -extern cvar_t r_dynamic; -extern cvar_t r_novis; - -// jkrige - fix dynamic light shine through -extern cvar_t r_dynamic_sidemark; -// jkrige - fix dynamic light shine through - -extern cvar_t gl_clear; -extern cvar_t gl_cull; -extern cvar_t gl_poly; -extern cvar_t gl_texsort; -extern cvar_t gl_smoothmodels; -extern cvar_t gl_affinemodels; -extern cvar_t gl_polyblend; - -// jkrige - disabled tjunction removal -//extern cvar_t gl_keeptjunctions; -//extern cvar_t gl_reporttjunctions; -// jkrige - disabled tjunction removal - -// jkrige - flashblend removal -//extern cvar_t gl_flashblend; -// jkrige - flashblend removal - -extern cvar_t gl_nocolors; -extern cvar_t gl_skytype; // jkrige - skybox -extern cvar_t gl_doubleeyes; - -// jkrige - .lit colored lights -extern int gl_coloredstatic; -// jkrige - .lit colored lights - -extern int gl_lightmap_format; -extern int gl_solid_format; -extern int gl_alpha_format; - -extern cvar_t gl_max_size; -extern cvar_t gl_playermip; - -// jkrige - texture mode -extern cvar_t gl_texturemode; -// jkrige - texture mode - -// jkrige - wireframe -extern cvar_t gl_wireframe; -// jkrige - wireframe - -// jkrige - .lit colored lights -extern cvar_t gl_coloredlight; -extern cvar_t gl_lightmapfmt; -// jkrige - .lit colored lights - -// jkrige - luma textures -extern cvar_t gl_lumatex_render; -// jkrige - luma textures - - -extern int mirrortexturenum; // quake texturenum, not gltexturenum -extern qboolean mirror; -extern mplane_t *mirror_plane; - -extern float r_world_matrix[16]; - -extern const char *gl_vendor; -extern const char *gl_renderer; -extern const char *gl_version; -extern const char *gl_extensions; - -void R_TranslatePlayerSkin (int playernum); -void GL_Bind (int texnum); - -// Multitexture -// jkrige - remove multitexture -//#define TEXTURE0_SGIS 0x835E -//#define TEXTURE1_SGIS 0x835F -// jkrige - remove multitexture - -#ifndef _WIN32 -#define APIENTRY /* */ -#endif - -// jkrige - overbrights -extern cvar_t gl_overbright; -// jkrige - overbrights - -// jkrige - remove multitexture -/*typedef void (APIENTRY *lpMTexFUNC) (GLenum, GLfloat, GLfloat); -typedef void (APIENTRY *lpSelTexFUNC) (GLenum); -extern lpMTexFUNC qglMTexCoord2fSGIS; -extern lpSelTexFUNC qglSelectTextureSGIS; - -extern qboolean gl_mtexable; - -void GL_DisableMultitexture(void); -void GL_EnableMultitexture(void);*/ -// jkrige - remove multitexture diff --git a/engine/code/host_cmd.c b/engine/code/host_cmd.c deleted file mode 100644 index d1e55fa..0000000 --- a/engine/code/host_cmd.c +++ /dev/null @@ -1,1935 +0,0 @@ -/* -Copyright (C) 1996-1997 Id Software, Inc. - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ - -#include "quakedef.h" - -extern cvar_t pausable; - -int current_skill; - -void Mod_Print (void); - -/* -================== -Host_Quit_f -================== -*/ - -extern void M_Menu_Quit_f (void); - -void Host_Quit_f (void) -{ - if (key_dest != key_console && cls.state != ca_dedicated) - { - M_Menu_Quit_f (); - return; - } - CL_Disconnect (); - Host_ShutdownServer(false); - - Sys_Quit (); -} - - -/* -================== -Host_Status_f -================== -*/ -void Host_Status_f (void) -{ - client_t *client; - int seconds; - int minutes; - int hours = 0; - int j; - void (*print) (char *fmt, ...); - - if (cmd_source == src_command) - { - if (!sv.active) - { - Cmd_ForwardToServer (); - return; - } - print = Con_Printf; - } - else - print = SV_ClientPrintf; - - print ("host: %s\n", Cvar_VariableString ("hostname")); - print ("version: %4.2f\n", QUAKE_VERSION); - if (tcpipAvailable) - print ("tcp/ip: %s\n", my_tcpip_address); - if (ipxAvailable) - print ("ipx: %s\n", my_ipx_address); - print ("map: %s\n", sv.name); - print ("players: %i active (%i max)\n\n", net_activeconnections, svs.maxclients); - for (j=0, client = svs.clients ; jactive) - continue; - seconds = (int)(net_time - client->netconnection->connecttime); - minutes = seconds / 60; - if (minutes) - { - seconds -= (minutes * 60); - hours = minutes / 60; - if (hours) - minutes -= (hours * 60); - } - else - hours = 0; - print ("#%-2u %-16.16s %3i %2i:%02i:%02i\n", j+1, client->name, (int)client->edict->v.frags, hours, minutes, seconds); - print (" %s\n", client->netconnection->address); - } -} - - -/* -================== -Host_God_f - -Sets client to godmode -================== -*/ -void Host_God_f (void) -{ - if (cmd_source == src_command) - { - Cmd_ForwardToServer (); - return; - } - - if (pr_global_struct->deathmatch && !host_client->privileged) - return; - - sv_player->v.flags = (int)sv_player->v.flags ^ FL_GODMODE; - if (!((int)sv_player->v.flags & FL_GODMODE) ) - SV_ClientPrintf ("godmode OFF\n"); - else - SV_ClientPrintf ("godmode ON\n"); -} - -void Host_Notarget_f (void) -{ - if (cmd_source == src_command) - { - Cmd_ForwardToServer (); - return; - } - - if (pr_global_struct->deathmatch && !host_client->privileged) - return; - - sv_player->v.flags = (int)sv_player->v.flags ^ FL_NOTARGET; - if (!((int)sv_player->v.flags & FL_NOTARGET) ) - SV_ClientPrintf ("notarget OFF\n"); - else - SV_ClientPrintf ("notarget ON\n"); -} - -qboolean noclip_anglehack; - -void Host_Noclip_f (void) -{ - if (cmd_source == src_command) - { - Cmd_ForwardToServer (); - return; - } - - if (pr_global_struct->deathmatch && !host_client->privileged) - return; - - if (sv_player->v.movetype != MOVETYPE_NOCLIP) - { - noclip_anglehack = true; - sv_player->v.movetype = MOVETYPE_NOCLIP; - SV_ClientPrintf ("noclip ON\n"); - } - else - { - noclip_anglehack = false; - sv_player->v.movetype = MOVETYPE_WALK; - SV_ClientPrintf ("noclip OFF\n"); - } -} - -/* -================== -Host_Fly_f - -Sets client to flymode -================== -*/ -void Host_Fly_f (void) -{ - if (cmd_source == src_command) - { - Cmd_ForwardToServer (); - return; - } - - if (pr_global_struct->deathmatch && !host_client->privileged) - return; - - if (sv_player->v.movetype != MOVETYPE_FLY) - { - sv_player->v.movetype = MOVETYPE_FLY; - SV_ClientPrintf ("flymode ON\n"); - } - else - { - sv_player->v.movetype = MOVETYPE_WALK; - SV_ClientPrintf ("flymode OFF\n"); - } -} - - -/* -================== -Host_Ping_f - -================== -*/ -void Host_Ping_f (void) -{ - int i, j; - float total; - client_t *client; - - if (cmd_source == src_command) - { - Cmd_ForwardToServer (); - return; - } - - SV_ClientPrintf ("Client ping times:\n"); - for (i=0, client = svs.clients ; iactive) - continue; - total = 0; - for (j=0 ; jping_times[j]; - total /= NUM_PING_TIMES; - SV_ClientPrintf ("%4i %s\n", (int)(total*1000), client->name); - } -} - -/* -=============================================================================== - -SERVER TRANSITIONS - -=============================================================================== -*/ - - -/* -====================== -Host_Map_f - -handle a -map -command from the console. Active clients are kicked off. -====================== -*/ -void Host_Map_f (void) -{ - int i; - char name[MAX_QPATH]; - - if (cmd_source != src_command) - return; - - cls.demonum = -1; // stop demo loop in case this fails - - CL_Disconnect (); - Host_ShutdownServer(false); - - key_dest = key_game; // remove console or menu - SCR_BeginLoadingPlaque (); - - cls.mapstring[0] = 0; - for (i=0 ; i : continue game on a new level\n"); - return; - } - if (!sv.active || cls.demoplayback) - { - Con_Printf ("Only the server may changelevel\n"); - return; - } - - strcpy (level, Cmd_Argv(1)); - if (Cmd_Argc() == 2) - startspot = NULL; - else - { - strcpy (_startspot, Cmd_Argv(2)); - startspot = _startspot; - } - - SV_SaveSpawnparms (); - SV_SpawnServer (level, startspot); -#else - char level[MAX_QPATH]; - - if (Cmd_Argc() != 2) - { - Con_Printf ("changelevel : continue game on a new level\n"); - return; - } - if (!sv.active || cls.demoplayback) - { - Con_Printf ("Only the server may changelevel\n"); - return; - } - SV_SaveSpawnparms (); - strcpy (level, Cmd_Argv(1)); - SV_SpawnServer (level); -#endif -} - -/* -================== -Host_Restart_f - -Restarts the current server for a dead player -================== -*/ -void Host_Restart_f (void) -{ - char mapname[MAX_QPATH]; -#ifdef QUAKE2 - char startspot[MAX_QPATH]; -#endif - - if (cls.demoplayback || !sv.active) - return; - - if (cmd_source != src_command) - return; - strcpy (mapname, sv.name); // must copy out, because it gets cleared - // in sv_spawnserver -#ifdef QUAKE2 - strcpy(startspot, sv.startspot); - SV_SpawnServer (mapname, startspot); -#else - SV_SpawnServer (mapname); -#endif -} - -/* -================== -Host_Reconnect_f - -This command causes the client to wait for the signon messages again. -This is sent just before a server changes levels -================== -*/ -void Host_Reconnect_f (void) -{ - SCR_BeginLoadingPlaque (); - cls.signon = 0; // need new connection messages -} - -/* -===================== -Host_Connect_f - -User command to connect to server -===================== -*/ -void Host_Connect_f (void) -{ - char name[MAX_QPATH]; - - cls.demonum = -1; // stop demo loop in case this fails - if (cls.demoplayback) - { - CL_StopPlayback (); - CL_Disconnect (); - } - strcpy (name, Cmd_Argv(1)); - CL_EstablishConnection (name); - Host_Reconnect_f (); -} - - -/* -=============================================================================== - -LOAD / SAVE GAME - -=============================================================================== -*/ - -#define SAVEGAME_VERSION 5 - -/* -=============== -Host_SavegameComment - -Writes a SAVEGAME_COMMENT_LENGTH character comment describing the current -=============== -*/ -void Host_SavegameComment (char *text) -{ - int i; - char kills[20]; - - for (i=0 ; i : save a game\n"); - return; - } - - if (strstr(Cmd_Argv(1), "..")) - { - Con_Printf ("Relative pathnames are not allowed.\n"); - return; - } - - for (i=0 ; iv.health <= 0) ) - { - Con_Printf ("Can't savegame with a dead player\n"); - return; - } - } - - // jkrige - savegame directory - sprintf (name, "%s/saves", com_gamedir); - Sys_mkdir (name); - sprintf (name, "%s/saves/%s", com_gamedir, Cmd_Argv(1)); - //sprintf (name, "%s/%s", com_gamedir, Cmd_Argv(1)); - // jkrige - savegame directory - - COM_DefaultExtension (name, ".sav"); - - Con_Printf ("Saving game to %s...\n", name); - f = fopen (name, "w"); - if (!f) - { - Con_Printf ("ERROR: couldn't open.\n"); - return; - } - - fprintf (f, "%i\n", SAVEGAME_VERSION); - Host_SavegameComment (comment); - fprintf (f, "%s\n", comment); - for (i=0 ; ispawn_parms[i]); - fprintf (f, "%d\n", current_skill); - fprintf (f, "%s\n", sv.name); - fprintf (f, "%f\n",sv.time); - -// write the light styles - - for (i=0 ; i : load a game\n"); - return; - } - - cls.demonum = -1; // stop demo loop in case this fails - - // jkrige - savegame directory - sprintf (name, "%s/saves/%s", com_gamedir, Cmd_Argv(1)); - //sprintf (name, "%s/%s", com_gamedir, Cmd_Argv(1)); - // jkrige - savegame directory - - COM_DefaultExtension (name, ".sav"); - -// we can't call SCR_BeginLoadingPlaque, because too much stack space has -// been used. The menu calls it before stuffing loadgame command -// SCR_BeginLoadingPlaque (); - - Con_Printf ("Loading game from %s...\n", name); - f = fopen (name, "r"); - if (!f) - { - Con_Printf ("ERROR: couldn't open.\n"); - return; - } - - fscanf (f, "%i\n", &version); - if (version != SAVEGAME_VERSION) - { - fclose (f); - Con_Printf ("Savegame is version %i, not %i\n", version, SAVEGAME_VERSION); - return; - } - fscanf (f, "%s\n", str); - for (i=0 ; iv, 0, progs->entityfields * 4); - ent->free = false; - ED_ParseEdict (start, ent); - - // link it into the bsp tree - if (!ent->free) - SV_LinkEdict (ent, false); - } - - entnum++; - } - - sv.num_edicts = entnum; - sv.time = time; - - fclose (f); - - for (i=0 ; ispawn_parms[i] = spawn_parms[i]; - - if (cls.state != ca_dedicated) - { - CL_EstablishConnection ("local"); - Host_Reconnect_f (); - } -} - -#ifdef QUAKE2 -void SaveGamestate() -{ - char name[256]; - FILE *f; - int i; - char comment[SAVEGAME_COMMENT_LENGTH+1]; - edict_t *ent; - - sprintf (name, "%s/%s.gip", com_gamedir, sv.name); - - Con_Printf ("Saving game to %s...\n", name); - f = fopen (name, "w"); - if (!f) - { - Con_Printf ("ERROR: couldn't open.\n"); - return; - } - - fprintf (f, "%i\n", SAVEGAME_VERSION); - Host_SavegameComment (comment); - fprintf (f, "%s\n", comment); -// for (i=0 ; ispawn_parms[i]); - fprintf (f, "%f\n", skill.value); - fprintf (f, "%s\n", sv.name); - fprintf (f, "%f\n", sv.time); - -// write the light styles - - for (i=0 ; iv.flags & FL_ARCHIVE_OVERRIDE) - continue; - fprintf (f, "%i\n",i); - ED_Write (f, ent); - fflush (f); - } - fclose (f); - Con_Printf ("done.\n"); -} - -int LoadGamestate(char *level, char *startspot) -{ - char name[MAX_OSPATH]; - FILE *f; - char mapname[MAX_QPATH]; - float time, sk; - char str[32768], *start; - int i, r; - edict_t *ent; - int entnum; - int version; -// float spawn_parms[NUM_SPAWN_PARMS]; - - sprintf (name, "%s/%s.gip", com_gamedir, level); - - Con_Printf ("Loading game from %s...\n", name); - f = fopen (name, "r"); - if (!f) - { - Con_Printf ("ERROR: couldn't open.\n"); - return -1; - } - - fscanf (f, "%i\n", &version); - if (version != SAVEGAME_VERSION) - { - fclose (f); - Con_Printf ("Savegame is version %i, not %i\n", version, SAVEGAME_VERSION); - return -1; - } - fscanf (f, "%s\n", str); -// for (i=0 ; iv, 0, progs->entityfields * 4); - ent->free = false; - ED_ParseEdict (start, ent); - - // link it into the bsp tree - if (!ent->free) - SV_LinkEdict (ent, false); - } - -// sv.num_edicts = entnum; - sv.time = time; - fclose (f); - -// for (i=0 ; ispawn_parms[i] = spawn_parms[i]; - - return 0; -} - -// changing levels within a unit -void Host_Changelevel2_f (void) -{ - char level[MAX_QPATH]; - char _startspot[MAX_QPATH]; - char *startspot; - - if (Cmd_Argc() < 2) - { - Con_Printf ("changelevel2 : continue game on a new level in the unit\n"); - return; - } - if (!sv.active || cls.demoplayback) - { - Con_Printf ("Only the server may changelevel\n"); - return; - } - - strcpy (level, Cmd_Argv(1)); - if (Cmd_Argc() == 2) - startspot = NULL; - else - { - strcpy (_startspot, Cmd_Argv(2)); - startspot = _startspot; - } - - SV_SaveSpawnparms (); - - // save the current level's state - SaveGamestate (); - - // try to restore the new level - if (LoadGamestate (level, startspot)) - SV_SpawnServer (level, startspot); -} -#endif - - -//============================================================================ - -/* -====================== -Host_Name_f -====================== -*/ -void Host_Name_f (void) -{ - char *newName; - - if (Cmd_Argc () == 1) - { - Con_Printf ("\"name\" is \"%s\"\n", cl_name.string); - return; - } - if (Cmd_Argc () == 2) - newName = Cmd_Argv(1); - else - newName = Cmd_Args(); - newName[15] = 0; - - if (cmd_source == src_command) - { - if (Q_strcmp(cl_name.string, newName) == 0) - return; - Cvar_Set ("_cl_name", newName); - if (cls.state == ca_connected) - Cmd_ForwardToServer (); - return; - } - - if (host_client->name[0] && strcmp(host_client->name, "unconnected") ) - if (Q_strcmp(host_client->name, newName) != 0) - Con_Printf ("%s renamed to %s\n", host_client->name, newName); - Q_strcpy (host_client->name, newName); - host_client->edict->v.netname = PR_SetEngineString(host_client->name); - -// send notification to all clients - - MSG_WriteByte (&sv.reliable_datagram, svc_updatename); - MSG_WriteByte (&sv.reliable_datagram, host_client - svs.clients); - MSG_WriteString (&sv.reliable_datagram, host_client->name); -} - - -void Host_Version_f (void) -{ - Con_Printf ("Version %4.2f\n", QUAKE_VERSION); - Con_Printf ("Exe: "__TIME__" "__DATE__"\n"); -} - -#ifdef IDGODS -void Host_Please_f (void) -{ - client_t *cl; - int j; - - if (cmd_source != src_command) - return; - - if ((Cmd_Argc () == 3) && Q_strcmp(Cmd_Argv(1), "#") == 0) - { - j = Q_atof(Cmd_Argv(2)) - 1; - if (j < 0 || j >= svs.maxclients) - return; - if (!svs.clients[j].active) - return; - cl = &svs.clients[j]; - if (cl->privileged) - { - cl->privileged = false; - cl->edict->v.flags = (int)cl->edict->v.flags & ~(FL_GODMODE|FL_NOTARGET); - cl->edict->v.movetype = MOVETYPE_WALK; - noclip_anglehack = false; - } - else - cl->privileged = true; - } - - if (Cmd_Argc () != 2) - return; - - for (j=0, cl = svs.clients ; jactive) - continue; - if (Q_strcasecmp(cl->name, Cmd_Argv(1)) == 0) - { - if (cl->privileged) - { - cl->privileged = false; - cl->edict->v.flags = (int)cl->edict->v.flags & ~(FL_GODMODE|FL_NOTARGET); - cl->edict->v.movetype = MOVETYPE_WALK; - noclip_anglehack = false; - } - else - cl->privileged = true; - break; - } - } -} -#endif - - -void Host_Say(qboolean teamonly) -{ - client_t *client; - client_t *save; - int j; - char *p; - unsigned char text[64]; - qboolean fromServer = false; - - if (cmd_source == src_command) - { - if (cls.state == ca_dedicated) - { - fromServer = true; - teamonly = false; - } - else - { - Cmd_ForwardToServer (); - return; - } - } - - if (Cmd_Argc () < 2) - return; - - save = host_client; - - p = Cmd_Args(); -// remove quotes if present - if (*p == '"') - { - p++; - p[Q_strlen(p)-1] = 0; - } - -// turn on color set 1 - if (!fromServer) - sprintf (text, "%c%s: ", 1, save->name); - else - sprintf (text, "%c<%s> ", 1, hostname.string); - - j = sizeof(text) - 2 - Q_strlen(text); // -2 for /n and null terminator - if (Q_strlen(p) > j) - p[j] = 0; - - strcat (text, p); - strcat (text, "\n"); - - for (j = 0, client = svs.clients; j < svs.maxclients; j++, client++) - { - if (!client || !client->active || !client->spawned) - continue; - if (teamplay.value && teamonly && client->edict->v.team != save->edict->v.team) - continue; - host_client = client; - SV_ClientPrintf("%s", text); - } - host_client = save; - - Sys_Printf("%s", &text[1]); -} - - -void Host_Say_f(void) -{ - Host_Say(false); -} - - -void Host_Say_Team_f(void) -{ - Host_Say(true); -} - - -void Host_Tell_f(void) -{ - client_t *client; - client_t *save; - int j; - char *p; - char text[64]; - - if (cmd_source == src_command) - { - Cmd_ForwardToServer (); - return; - } - - if (Cmd_Argc () < 3) - return; - - Q_strcpy(text, host_client->name); - Q_strcat(text, ": "); - - p = Cmd_Args(); - -// remove quotes if present - if (*p == '"') - { - p++; - p[Q_strlen(p)-1] = 0; - } - -// check length & truncate if necessary - j = sizeof(text) - 2 - Q_strlen(text); // -2 for /n and null terminator - if (Q_strlen(p) > j) - p[j] = 0; - - strcat (text, p); - strcat (text, "\n"); - - save = host_client; - for (j = 0, client = svs.clients; j < svs.maxclients; j++, client++) - { - if (!client->active || !client->spawned) - continue; - if (Q_strcasecmp(client->name, Cmd_Argv(1))) - continue; - host_client = client; - SV_ClientPrintf("%s", text); - break; - } - host_client = save; -} - - -/* -================== -Host_Color_f -================== -*/ -void Host_Color_f(void) -{ - int top, bottom; - int playercolor; - - if (Cmd_Argc() == 1) - { - Con_Printf ("\"color\" is \"%i %i\"\n", ((int)cl_color.value) >> 4, ((int)cl_color.value) & 0x0f); - Con_Printf ("color <0-13> [0-13]\n"); - return; - } - - if (Cmd_Argc() == 2) - top = bottom = atoi(Cmd_Argv(1)); - else - { - top = atoi(Cmd_Argv(1)); - bottom = atoi(Cmd_Argv(2)); - } - - top &= 15; - if (top > 13) - top = 13; - bottom &= 15; - if (bottom > 13) - bottom = 13; - - playercolor = top*16 + bottom; - - if (cmd_source == src_command) - { - Cvar_SetValue ("_cl_color", playercolor); - if (cls.state == ca_connected) - Cmd_ForwardToServer (); - return; - } - - host_client->colors = playercolor; - host_client->edict->v.team = bottom + 1; - -// send notification to all clients - MSG_WriteByte (&sv.reliable_datagram, svc_updatecolors); - MSG_WriteByte (&sv.reliable_datagram, host_client - svs.clients); - MSG_WriteByte (&sv.reliable_datagram, host_client->colors); -} - -/* -================== -Host_Kill_f -================== -*/ -void Host_Kill_f (void) -{ - if (cmd_source == src_command) - { - Cmd_ForwardToServer (); - return; - } - - if (sv_player->v.health <= 0) - { - SV_ClientPrintf ("Can't suicide -- allready dead!\n"); - return; - } - - pr_global_struct->time = sv.time; - pr_global_struct->self = EDICT_TO_PROG(sv_player); - PR_ExecuteProgram (pr_global_struct->ClientKill); -} - - -/* -================== -Host_Pause_f -================== -*/ -void Host_Pause_f (void) -{ - - if (cmd_source == src_command) - { - Cmd_ForwardToServer (); - return; - } - if (!pausable.value) - SV_ClientPrintf ("Pause not allowed.\n"); - else - { - sv.paused ^= 1; - - if (sv.paused) - { - SV_BroadcastPrintf ("%s paused the game\n", PR_GetString(sv_player->v.netname)); - } - else - { - SV_BroadcastPrintf ("%s unpaused the game\n", PR_GetString(sv_player->v.netname)); - } - - // send notification to all clients - MSG_WriteByte (&sv.reliable_datagram, svc_setpause); - MSG_WriteByte (&sv.reliable_datagram, sv.paused); - } -} - -//=========================================================================== - - -/* -================== -Host_PreSpawn_f -================== -*/ -void Host_PreSpawn_f (void) -{ - if (cmd_source == src_command) - { - Con_Printf ("prespawn is not valid from the console\n"); - return; - } - - if (host_client->spawned) - { - Con_Printf ("prespawn not valid -- allready spawned\n"); - return; - } - - SZ_Write (&host_client->message, sv.signon.data, sv.signon.cursize); - MSG_WriteByte (&host_client->message, svc_signonnum); - MSG_WriteByte (&host_client->message, 2); - host_client->sendsignon = true; -} - -/* -================== -Host_Spawn_f -================== -*/ -void Host_Spawn_f (void) -{ - int i; - client_t *client; - edict_t *ent; - - if (cmd_source == src_command) - { - Con_Printf ("spawn is not valid from the console\n"); - return; - } - - if (host_client->spawned) - { - Con_Printf ("Spawn not valid -- allready spawned\n"); - return; - } - -// run the entrance script - if (sv.loadgame) - { // loaded games are fully inited allready - // if this is the last client to be connected, unpause - sv.paused = false; - } - else - { - // set up the edict - ent = host_client->edict; - - memset (&ent->v, 0, progs->entityfields * 4); - ent->v.colormap = NUM_FOR_EDICT(ent); - ent->v.team = (host_client->colors & 15) + 1; - ent->v.netname = PR_SetEngineString(host_client->name); - - // copy spawn parms out of the client_t - - for (i=0 ; i< NUM_SPAWN_PARMS ; i++) - (&pr_global_struct->parm1)[i] = host_client->spawn_parms[i]; - - // call the spawn function - - pr_global_struct->time = sv.time; - pr_global_struct->self = EDICT_TO_PROG(sv_player); - PR_ExecuteProgram (pr_global_struct->ClientConnect); - - if ((Sys_FloatTime() - host_client->netconnection->connecttime) <= sv.time) - Sys_Printf ("%s entered the game\n", host_client->name); - - PR_ExecuteProgram (pr_global_struct->PutClientInServer); - } - - -// send all current names, colors, and frag counts - SZ_Clear (&host_client->message); - -// send time of update - MSG_WriteByte (&host_client->message, svc_time); - MSG_WriteFloat (&host_client->message, sv.time); - - for (i=0, client = svs.clients ; imessage, svc_updatename); - MSG_WriteByte (&host_client->message, i); - MSG_WriteString (&host_client->message, client->name); - MSG_WriteByte (&host_client->message, svc_updatefrags); - MSG_WriteByte (&host_client->message, i); - MSG_WriteShort (&host_client->message, client->old_frags); - MSG_WriteByte (&host_client->message, svc_updatecolors); - MSG_WriteByte (&host_client->message, i); - MSG_WriteByte (&host_client->message, client->colors); - } - -// send all current light styles - for (i=0 ; imessage, svc_lightstyle); - MSG_WriteByte (&host_client->message, (char)i); - MSG_WriteString (&host_client->message, sv.lightstyles[i]); - } - -// -// send some stats -// - MSG_WriteByte (&host_client->message, svc_updatestat); - MSG_WriteByte (&host_client->message, STAT_TOTALSECRETS); - MSG_WriteLong (&host_client->message, pr_global_struct->total_secrets); - - MSG_WriteByte (&host_client->message, svc_updatestat); - MSG_WriteByte (&host_client->message, STAT_TOTALMONSTERS); - MSG_WriteLong (&host_client->message, pr_global_struct->total_monsters); - - MSG_WriteByte (&host_client->message, svc_updatestat); - MSG_WriteByte (&host_client->message, STAT_SECRETS); - MSG_WriteLong (&host_client->message, pr_global_struct->found_secrets); - - MSG_WriteByte (&host_client->message, svc_updatestat); - MSG_WriteByte (&host_client->message, STAT_MONSTERS); - MSG_WriteLong (&host_client->message, pr_global_struct->killed_monsters); - - -// -// send a fixangle -// Never send a roll angle, because savegames can catch the server -// in a state where it is expecting the client to correct the angle -// and it won't happen if the game was just loaded, so you wind up -// with a permanent head tilt - ent = EDICT_NUM( 1 + (host_client - svs.clients) ); - MSG_WriteByte (&host_client->message, svc_setangle); - for (i=0 ; i < 2 ; i++) - MSG_WriteAngle (&host_client->message, ent->v.angles[i] ); - MSG_WriteAngle (&host_client->message, 0 ); - - SV_WriteClientdataToMessage (sv_player, &host_client->message); - - MSG_WriteByte (&host_client->message, svc_signonnum); - MSG_WriteByte (&host_client->message, 3); - host_client->sendsignon = true; -} - -/* -================== -Host_Begin_f -================== -*/ -void Host_Begin_f (void) -{ - if (cmd_source == src_command) - { - Con_Printf ("begin is not valid from the console\n"); - return; - } - - host_client->spawned = true; -} - -//=========================================================================== - - -/* -================== -Host_Kick_f - -Kicks a user off of the server -================== -*/ -void Host_Kick_f (void) -{ - char *who; - char *message = NULL; - client_t *save; - int i; - qboolean byNumber = false; - - if (cmd_source == src_command) - { - if (!sv.active) - { - Cmd_ForwardToServer (); - return; - } - } - else if (pr_global_struct->deathmatch && !host_client->privileged) - return; - - save = host_client; - - if (Cmd_Argc() > 2 && Q_strcmp(Cmd_Argv(1), "#") == 0) - { - i = Q_atof(Cmd_Argv(2)) - 1; - if (i < 0 || i >= svs.maxclients) - return; - if (!svs.clients[i].active) - return; - host_client = &svs.clients[i]; - byNumber = true; - } - else - { - for (i = 0, host_client = svs.clients; i < svs.maxclients; i++, host_client++) - { - if (!host_client->active) - continue; - if (Q_strcasecmp(host_client->name, Cmd_Argv(1)) == 0) - break; - } - } - - if (i < svs.maxclients) - { - if (cmd_source == src_command) - if (cls.state == ca_dedicated) - who = "Console"; - else - who = cl_name.string; - else - who = save->name; - - // can't kick yourself! - if (host_client == save) - return; - - if (Cmd_Argc() > 2) - { - message = COM_Parse(Cmd_Args()); - if (byNumber) - { - message++; // skip the # - while (*message == ' ') // skip white space - message++; - message += Q_strlen(Cmd_Argv(2)); // skip the number - } - while (*message && *message == ' ') - message++; - } - if (message) - SV_ClientPrintf ("Kicked by %s: %s\n", who, message); - else - SV_ClientPrintf ("Kicked by %s\n", who); - SV_DropClient (false); - } - - host_client = save; -} - -/* -=============================================================================== - -DEBUGGING TOOLS - -=============================================================================== -*/ - -/* -================== -Host_Give_f -================== -*/ -void Host_Give_f (void) -{ - char *t; - int v, w; - eval_t *val; - - if (cmd_source == src_command) - { - Cmd_ForwardToServer (); - return; - } - - if (pr_global_struct->deathmatch && !host_client->privileged) - return; - - t = Cmd_Argv(1); - v = atoi (Cmd_Argv(2)); - - switch (t[0]) - { - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - // MED 01/04/97 added hipnotic give stuff - if (hipnotic) - { - if (t[0] == '6') - { - if (t[1] == 'a') - sv_player->v.items = (int)sv_player->v.items | HIT_PROXIMITY_GUN; - else - sv_player->v.items = (int)sv_player->v.items | IT_GRENADE_LAUNCHER; - } - else if (t[0] == '9') - sv_player->v.items = (int)sv_player->v.items | HIT_LASER_CANNON; - else if (t[0] == '0') - sv_player->v.items = (int)sv_player->v.items | HIT_MJOLNIR; - else if (t[0] >= '2') - sv_player->v.items = (int)sv_player->v.items | (IT_SHOTGUN << (t[0] - '2')); - } - else - { - if (t[0] >= '2') - sv_player->v.items = (int)sv_player->v.items | (IT_SHOTGUN << (t[0] - '2')); - } - break; - - case 's': - if (rogue) - { - val = GetEdictFieldValue(sv_player, "ammo_shells1"); - if (val) - val->_float = v; - } - - sv_player->v.ammo_shells = v; - break; - case 'n': - if (rogue) - { - val = GetEdictFieldValue(sv_player, "ammo_nails1"); - if (val) - { - val->_float = v; - if (sv_player->v.weapon <= IT_LIGHTNING) - sv_player->v.ammo_nails = v; - } - } - else - { - sv_player->v.ammo_nails = v; - } - break; - case 'l': - if (rogue) - { - val = GetEdictFieldValue(sv_player, "ammo_lava_nails"); - if (val) - { - val->_float = v; - if (sv_player->v.weapon > IT_LIGHTNING) - sv_player->v.ammo_nails = v; - } - } - break; - case 'r': - if (rogue) - { - val = GetEdictFieldValue(sv_player, "ammo_rockets1"); - if (val) - { - val->_float = v; - if (sv_player->v.weapon <= IT_LIGHTNING) - sv_player->v.ammo_rockets = v; - } - } - else - { - sv_player->v.ammo_rockets = v; - } - break; - case 'm': - if (rogue) - { - val = GetEdictFieldValue(sv_player, "ammo_multi_rockets"); - if (val) - { - val->_float = v; - if (sv_player->v.weapon > IT_LIGHTNING) - sv_player->v.ammo_rockets = v; - } - } - break; - case 'h': - sv_player->v.health = v; - break; - case 'c': - if (rogue) - { - val = GetEdictFieldValue(sv_player, "ammo_cells1"); - if (val) - { - val->_float = v; - if (sv_player->v.weapon <= IT_LIGHTNING) - sv_player->v.ammo_cells = v; - } - } - else - { - sv_player->v.ammo_cells = v; - } - break; - case 'p': - if (rogue) - { - val = GetEdictFieldValue(sv_player, "ammo_plasma"); - if (val) - { - val->_float = v; - if (sv_player->v.weapon > IT_LIGHTNING) - sv_player->v.ammo_cells = v; - } - } - break; - } -} - -edict_t *FindViewthing (void) -{ - int i; - edict_t *e; - - for (i=0 ; iv.classname), "viewthing") ) - return e; - } - Con_Printf ("No viewthing on map\n"); - return NULL; -} - -/* -================== -Host_Viewmodel_f -================== -*/ -void Host_Viewmodel_f (void) -{ - edict_t *e; - model_t *m; - - e = FindViewthing (); - if (!e) - return; - - m = Mod_ForName (Cmd_Argv(1), false); - if (!m) - { - Con_Printf ("Can't load %s\n", Cmd_Argv(1)); - return; - } - - e->v.frame = 0; - cl.model_precache[(int)e->v.modelindex] = m; -} - -/* -================== -Host_Viewframe_f -================== -*/ -void Host_Viewframe_f (void) -{ - edict_t *e; - int f; - model_t *m; - - e = FindViewthing (); - if (!e) - return; - m = cl.model_precache[(int)e->v.modelindex]; - - f = atoi(Cmd_Argv(1)); - if (f >= m->numframes) - f = m->numframes-1; - - e->v.frame = f; -} - - -void PrintFrameName (model_t *m, int frame) -{ - aliashdr_t *hdr; - maliasframedesc_t *pframedesc; - - hdr = (aliashdr_t *)Mod_Extradata (m); - if (!hdr) - return; - pframedesc = &hdr->frames[frame]; - - Con_Printf ("frame %i: %s\n", frame, pframedesc->name); -} - -/* -================== -Host_Viewnext_f -================== -*/ -void Host_Viewnext_f (void) -{ - edict_t *e; - model_t *m; - - e = FindViewthing (); - if (!e) - return; - m = cl.model_precache[(int)e->v.modelindex]; - - e->v.frame = e->v.frame + 1; - if (e->v.frame >= m->numframes) - e->v.frame = m->numframes - 1; - - PrintFrameName (m, e->v.frame); -} - -/* -================== -Host_Viewprev_f -================== -*/ -void Host_Viewprev_f (void) -{ - edict_t *e; - model_t *m; - - e = FindViewthing (); - if (!e) - return; - - m = cl.model_precache[(int)e->v.modelindex]; - - e->v.frame = e->v.frame - 1; - if (e->v.frame < 0) - e->v.frame = 0; - - PrintFrameName (m, e->v.frame); -} - -/* -=============================================================================== - -DEMO LOOP CONTROL - -=============================================================================== -*/ - - -/* -================== -Host_Startdemos_f -================== -*/ -void Host_Startdemos_f (void) -{ - int i, c; - - if (cls.state == ca_dedicated) - { - if (!sv.active) - Cbuf_AddText ("map start\n"); - return; - } - - c = Cmd_Argc() - 1; - if (c > MAX_DEMOS) - { - Con_Printf ("Max %i demos in demoloop\n", MAX_DEMOS); - c = MAX_DEMOS; - } - Con_Printf ("%i demo(s) in loop\n", c); - - for (i=1 ; i -#include "quakedef.h" -#include "winquake.h" -//#include "dosisms.h" // jkrige - removed - -//#define DINPUT_BUFFERSIZE 16 -//#define iDirectInputCreate(a,b,c,d) pDirectInputCreate(a,b,c,d) - -//HRESULT (WINAPI *pDirectInputCreate)(HINSTANCE hinst, DWORD dwVersion, LPDIRECTINPUT * lplpDirectInput, LPUNKNOWN punkOuter); - -// mouse variables -// jkrige - configurable fps caps -// default to filtered now, to take advantage of higher default fps cap -// for smoother gameplay -cvar_t m_filter = {"m_filter","1", true}; -//cvar_t m_filter = {"m_filter","0"}; -// jkrige - configurable fps caps - -int mouse_buttons; -int mouse_oldbuttonstate; -POINT current_pos; -int mouse_x, mouse_y, old_mouse_x, old_mouse_y, mx_accum, my_accum; - -static qboolean restore_spi; -static int originalmouseparms[3], newmouseparms[3] = {0, 0, 1}; - -unsigned int uiWheelMessage; -qboolean mouseactive; -qboolean mouseinitialized; -static qboolean mouseparmsvalid, mouseactivatetoggle; -static qboolean mouseshowtoggle = 1; -static qboolean dinput_acquired; - - -// jkrige - mouse thumb buttons -static int buttonremap[] = -{ - K_MOUSE1, - K_MOUSE2, - K_MOUSE3, - K_MOUSE4, - K_MOUSE5 -}; // do NOT include the wheel enums -#define NUM_MOUSEBUTTONS (sizeof(buttonremap) / sizeof(buttonremap[0])) -// jkrige - mouse thumb buttons - - -static unsigned int mstate_di; - -// joystick defines and variables -// where should defines be moved? -#define JOY_ABSOLUTE_AXIS 0x00000000 // control like a joystick -#define JOY_RELATIVE_AXIS 0x00000010 // control like a mouse, spinner, trackball -#define JOY_MAX_AXES 6 // X, Y, Z, R, U, V -#define JOY_AXIS_X 0 -#define JOY_AXIS_Y 1 -#define JOY_AXIS_Z 2 -#define JOY_AXIS_R 3 -#define JOY_AXIS_U 4 -#define JOY_AXIS_V 5 - -enum _ControlList -{ - AxisNada = 0, AxisForward, AxisLook, AxisSide, AxisTurn -}; - -DWORD dwAxisFlags[JOY_MAX_AXES] = -{ - JOY_RETURNX, JOY_RETURNY, JOY_RETURNZ, JOY_RETURNR, JOY_RETURNU, JOY_RETURNV -}; - -DWORD dwAxisMap[JOY_MAX_AXES]; -DWORD dwControlMap[JOY_MAX_AXES]; -PDWORD pdwRawValue[JOY_MAX_AXES]; - -// none of these cvars are saved over a session -// this means that advanced controller configuration needs to be executed -// each time. this avoids any problems with getting back to a default usage -// or when changing from one controller to another. this way at least something -// works. -cvar_t in_joystick = {"joystick","1"}; -cvar_t joy_name = {"joyname", "joystick"}; -cvar_t joy_advanced = {"joyadvanced", "0"}; -cvar_t joy_advaxisx = {"joyadvaxisx", "0"}; -cvar_t joy_advaxisy = {"joyadvaxisy", "0"}; -cvar_t joy_advaxisz = {"joyadvaxisz", "0"}; -cvar_t joy_advaxisr = {"joyadvaxisr", "0"}; -cvar_t joy_advaxisu = {"joyadvaxisu", "0"}; -cvar_t joy_advaxisv = {"joyadvaxisv", "0"}; -cvar_t joy_forwardthreshold = {"joyforwardthreshold", "0.15"}; -cvar_t joy_sidethreshold = {"joysidethreshold", "0.15"}; -cvar_t joy_pitchthreshold = {"joypitchthreshold", "0.15"}; -cvar_t joy_yawthreshold = {"joyyawthreshold", "0.15"}; -cvar_t joy_forwardsensitivity = {"joyforwardsensitivity", "-1.0"}; -cvar_t joy_sidesensitivity = {"joysidesensitivity", "-1.0"}; -cvar_t joy_pitchsensitivity = {"joypitchsensitivity", "1.0"}; -cvar_t joy_yawsensitivity = {"joyyawsensitivity", "-1.0"}; -cvar_t joy_wwhack1 = {"joywwhack1", "0.0"}; -cvar_t joy_wwhack2 = {"joywwhack2", "0.0"}; - -qboolean joy_avail, joy_advancedinit, joy_haspov; -DWORD joy_oldbuttonstate, joy_oldpovstate; - -int joy_id; -DWORD joy_flags; -DWORD joy_numbuttons; - -//static LPDIRECTINPUT g_pdi; -//static LPDIRECTINPUTDEVICE g_pMouse; - -static JOYINFOEX ji; - -//static HINSTANCE hInstDI; - -//static qboolean dinput; - -/*typedef struct MYDATA { - LONG lX; // X axis goes here - LONG lY; // Y axis goes here - LONG lZ; // Z axis goes here - BYTE bButtonA; // One button goes here - BYTE bButtonB; // Another button goes here - BYTE bButtonC; // Another button goes here - BYTE bButtonD; // Another button goes here -} MYDATA; - -static DIOBJECTDATAFORMAT rgodf[] = { - { &GUID_XAxis, FIELD_OFFSET(MYDATA, lX), DIDFT_AXIS | DIDFT_ANYINSTANCE, 0,}, - { &GUID_YAxis, FIELD_OFFSET(MYDATA, lY), DIDFT_AXIS | DIDFT_ANYINSTANCE, 0,}, - { &GUID_ZAxis, FIELD_OFFSET(MYDATA, lZ), 0x80000000 | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0,}, - { 0, FIELD_OFFSET(MYDATA, bButtonA), DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0,}, - { 0, FIELD_OFFSET(MYDATA, bButtonB), DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0,}, - { 0, FIELD_OFFSET(MYDATA, bButtonC), 0x80000000 | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0,}, - { 0, FIELD_OFFSET(MYDATA, bButtonD), 0x80000000 | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0,}, -}; - -#define NUM_OBJECTS (sizeof(rgodf) / sizeof(rgodf[0])) - -static DIDATAFORMAT df = { - sizeof(DIDATAFORMAT), // this structure - sizeof(DIOBJECTDATAFORMAT), // size of object data format - DIDF_RELAXIS, // absolute axis coordinates - sizeof(MYDATA), // device data size - NUM_OBJECTS, // number of objects - rgodf, // and here they are -};*/ - -// forward-referenced functions -void IN_StartupJoystick (void); -void Joy_AdvancedUpdate_f (void); -void IN_JoyMove (usercmd_t *cmd); - - -/* -=========== -Force_CenterView_f -=========== -*/ -void Force_CenterView_f (void) -{ - cl.viewangles[PITCH] = 0; -} - - -/* -=========== -IN_UpdateClipCursor -=========== -*/ -void IN_UpdateClipCursor (void) -{ - - if (mouseinitialized && mouseactive /*&& !dinput*/) - { - ClipCursor (&window_rect); - } -} - - -/* -=========== -IN_ShowMouse -=========== -*/ -void IN_ShowMouse (void) -{ - - if (!mouseshowtoggle) - { - ShowCursor (TRUE); - mouseshowtoggle = 1; - } -} - - -/* -=========== -IN_HideMouse -=========== -*/ -void IN_HideMouse (void) -{ - - if (mouseshowtoggle) - { - ShowCursor (FALSE); - mouseshowtoggle = 0; - } -} - - -/* -=========== -IN_ActivateMouse -=========== -*/ -void IN_ActivateMouse (void) -{ - - mouseactivatetoggle = true; - - if (mouseinitialized) - { - /*if (dinput) - { - if (g_pMouse) - { - if (!dinput_acquired) - { - IDirectInputDevice_Acquire(g_pMouse); - dinput_acquired = true; - } - } - else - { - return; - } - } - else*/ - //{ - if (mouseparmsvalid) - restore_spi = SystemParametersInfo (SPI_SETMOUSE, 0, newmouseparms, 0); - - SetCursorPos (window_center_x, window_center_y); - SetCapture (mainwindow); - ClipCursor (&window_rect); - //} - - mouseactive = true; - } -} - - -/* -=========== -IN_SetQuakeMouseState -=========== -*/ -void IN_SetQuakeMouseState (void) -{ - if (mouseactivatetoggle) - IN_ActivateMouse (); -} - - -/* -=========== -IN_DeactivateMouse -=========== -*/ -void IN_DeactivateMouse (void) -{ - - mouseactivatetoggle = false; - - if (mouseinitialized) - { - /*if (dinput) - { - if (g_pMouse) - { - if (dinput_acquired) - { - IDirectInputDevice_Unacquire(g_pMouse); - dinput_acquired = false; - } - } - } - else*/ - //{ - if (restore_spi) - SystemParametersInfo (SPI_SETMOUSE, 0, originalmouseparms, 0); - - ClipCursor (NULL); - ReleaseCapture (); - //} - - mouseactive = false; - } -} - - -/* -=========== -IN_RestoreOriginalMouseState -=========== -*/ -void IN_RestoreOriginalMouseState (void) -{ - if (mouseactivatetoggle) - { - IN_DeactivateMouse (); - mouseactivatetoggle = true; - } - -// try to redraw the cursor so it gets reinitialized, because sometimes it -// has garbage after the mode switch - ShowCursor (TRUE); - ShowCursor (FALSE); -} - - -/* -=========== -IN_InitDInput -=========== -*/ -/*qboolean IN_InitDInput (void) -{ - HRESULT hr; - DIPROPDWORD dipdw = { - { - sizeof(DIPROPDWORD), // diph.dwSize - sizeof(DIPROPHEADER), // diph.dwHeaderSize - 0, // diph.dwObj - DIPH_DEVICE, // diph.dwHow - }, - DINPUT_BUFFERSIZE, // dwData - }; - - if (!hInstDI) - { - hInstDI = LoadLibrary("dinput.dll"); - - if (hInstDI == NULL) - { - Con_SafePrintf ("Couldn't load dinput.dll\n"); - return false; - } - } - - if (!pDirectInputCreate) - { - pDirectInputCreate = (void *)GetProcAddress(hInstDI,"DirectInputCreateA"); - - if (!pDirectInputCreate) - { - Con_SafePrintf ("Couldn't get DI proc addr\n"); - return false; - } - } - -// register with DirectInput and get an IDirectInput to play with. - hr = iDirectInputCreate(global_hInstance, DIRECTINPUT_VERSION, &g_pdi, NULL); - - if (FAILED(hr)) - { - return false; - } - -// obtain an interface to the system mouse device. - hr = IDirectInput_CreateDevice(g_pdi, &GUID_SysMouse, &g_pMouse, NULL); - - if (FAILED(hr)) - { - Con_SafePrintf ("Couldn't open DI mouse device\n"); - return false; - } - -// set the data format to "mouse format". - hr = IDirectInputDevice_SetDataFormat(g_pMouse, &df); - - if (FAILED(hr)) - { - Con_SafePrintf ("Couldn't set DI mouse format\n"); - return false; - } - -// set the cooperativity level. - hr = IDirectInputDevice_SetCooperativeLevel(g_pMouse, mainwindow, - DISCL_EXCLUSIVE | DISCL_FOREGROUND); - - if (FAILED(hr)) - { - Con_SafePrintf ("Couldn't set DI coop level\n"); - return false; - } - - -// set the buffer size to DINPUT_BUFFERSIZE elements. -// the buffer size is a DWORD property associated with the device - hr = IDirectInputDevice_SetProperty(g_pMouse, DIPROP_BUFFERSIZE, &dipdw.diph); - - if (FAILED(hr)) - { - Con_SafePrintf ("Couldn't set DI buffersize\n"); - return false; - } - - return true; -}*/ - - -/* -=========== -IN_StartupMouse -=========== -*/ -void IN_StartupMouse (void) -{ - HDC hdc; - - if ( COM_CheckParm ("-nomouse") ) - return; - - mouseinitialized = true; - - /*if (COM_CheckParm ("-dinput")) - { - dinput = IN_InitDInput (); - - if (dinput) - { - Con_SafePrintf ("DirectInput initialized\n"); - } - else - { - Con_SafePrintf ("DirectInput not initialized\n"); - } - }*/ - - //if (!dinput) - //{ - mouseparmsvalid = SystemParametersInfo (SPI_GETMOUSE, 0, originalmouseparms, 0); - - if (mouseparmsvalid) - { - if ( COM_CheckParm ("-noforcemspd") ) - newmouseparms[2] = originalmouseparms[2]; - - if ( COM_CheckParm ("-noforcemaccel") ) - { - newmouseparms[0] = originalmouseparms[0]; - newmouseparms[1] = originalmouseparms[1]; - } - - if ( COM_CheckParm ("-noforcemparms") ) - { - newmouseparms[0] = originalmouseparms[0]; - newmouseparms[1] = originalmouseparms[1]; - newmouseparms[2] = originalmouseparms[2]; - } - } - //} - - mouse_buttons = 3; - -// if a fullscreen video mode was set before the mouse was initialized, -// set the mouse state appropriately - if (mouseactivatetoggle) - IN_ActivateMouse (); -} - - -/* -=========== -IN_Init -=========== -*/ -void IN_Init (void) -{ - // mouse variables - Cvar_RegisterVariable (&m_filter); - - // joystick variables - Cvar_RegisterVariable (&in_joystick); - Cvar_RegisterVariable (&joy_name); - Cvar_RegisterVariable (&joy_advanced); - Cvar_RegisterVariable (&joy_advaxisx); - Cvar_RegisterVariable (&joy_advaxisy); - Cvar_RegisterVariable (&joy_advaxisz); - Cvar_RegisterVariable (&joy_advaxisr); - Cvar_RegisterVariable (&joy_advaxisu); - Cvar_RegisterVariable (&joy_advaxisv); - Cvar_RegisterVariable (&joy_forwardthreshold); - Cvar_RegisterVariable (&joy_sidethreshold); - Cvar_RegisterVariable (&joy_pitchthreshold); - Cvar_RegisterVariable (&joy_yawthreshold); - Cvar_RegisterVariable (&joy_forwardsensitivity); - Cvar_RegisterVariable (&joy_sidesensitivity); - Cvar_RegisterVariable (&joy_pitchsensitivity); - Cvar_RegisterVariable (&joy_yawsensitivity); - Cvar_RegisterVariable (&joy_wwhack1); - Cvar_RegisterVariable (&joy_wwhack2); - - Cmd_AddCommand ("force_centerview", Force_CenterView_f); - Cmd_AddCommand ("joyadvancedupdate", Joy_AdvancedUpdate_f); - - uiWheelMessage = RegisterWindowMessage ( "MSWHEEL_ROLLMSG" ); - - IN_StartupMouse (); - IN_StartupJoystick (); -} - -/* -=========== -IN_Shutdown -=========== -*/ -void IN_Shutdown (void) -{ - - IN_DeactivateMouse (); - IN_ShowMouse (); - - /*if (g_pMouse) - { - IDirectInputDevice_Release(g_pMouse); - g_pMouse = NULL; - } - - if (g_pdi) - { - IDirectInput_Release(g_pdi); - g_pdi = NULL; - }*/ -} - - -/* -=========== -IN_MouseEvent -=========== -*/ -void IN_MouseEvent (int mstate) -{ - int i; - - if (mouseactive /*&& !dinput*/) // perform button actions - { - // jkrige - mouse thumb buttons - /*for (i=0 ; isidemove += m_side.value * mouse_x; - else - { - if (cl.time != cl.oldtime) // jkrige - mlook (don't mouselook when paused) - cl.viewangles[YAW] -= m_yaw.value * mouse_x; - } - - if (cl_mlook.value == 1.0 /*| lookspring.value == 0.0*/ /*in_mlook.state & 1*/) // jkrige - mlook cvar - V_StopPitchDrift (); - - if ( (cl_mlook.value /*in_mlook.state & 1*/) && !(in_strafe.state & 1)) // jkrige - mlook cvar - { - if (cl.time != cl.oldtime) // jkrige - mlook (don't mouselook when paused) - cl.viewangles[PITCH] += m_pitch.value * mouse_y; - - if (cl.viewangles[PITCH] > 80) - cl.viewangles[PITCH] = 80; - if (cl.viewangles[PITCH] < -70) - cl.viewangles[PITCH] = -70; - } - else - { - if ((in_strafe.state & 1) && noclip_anglehack) - cmd->upmove -= m_forward.value * mouse_y; - else - cmd->forwardmove -= m_forward.value * mouse_y; - } - -// if the mouse has moved, force it to the center, so there's room to move - if (mx || my) - { - SetCursorPos (window_center_x, window_center_y); - } -} - - -/* -=========== -IN_Move -=========== -*/ -void IN_Move (usercmd_t *cmd) -{ - - if (mouseactive) - { - IN_MouseMove (cmd); - } - - if (ActiveApp) - IN_JoyMove (cmd); - - /*if (ActiveApp && !Minimized) - { - IN_MouseMove (cmd); - IN_JoyMove (cmd); - }*/ -} - - -/* -=========== -IN_Accumulate -=========== -*/ -void IN_Accumulate (void) -{ - int mx, my; - HDC hdc; - - if (mouseactive) - { - //if (!dinput) - //{ - GetCursorPos (¤t_pos); - - mx_accum += current_pos.x - window_center_x; - my_accum += current_pos.y - window_center_y; - - // force the mouse to the center, so there's room to move - SetCursorPos (window_center_x, window_center_y); - //} - } -} - - -/* -=================== -IN_ClearStates -=================== -*/ -void IN_ClearStates (void) -{ - - if (mouseactive) - { - mx_accum = 0; - my_accum = 0; - mouse_oldbuttonstate = 0; - } -} - - -/* -=============== -IN_StartupJoystick -=============== -*/ -void IN_StartupJoystick (void) -{ - int i, numdevs; - JOYCAPS jc; - MMRESULT mmr; - - // assume no joystick - joy_avail = false; - - // abort startup if user requests no joystick - if ( COM_CheckParm ("-nojoy") ) - return; - - // verify joystick driver is present - if ((numdevs = joyGetNumDevs ()) == 0) - { - Con_Printf ("\njoystick not found -- driver not present\n\n"); - return; - } - - // cycle through the joystick ids for the first valid one - for (joy_id=0 ; joy_id 14000.0) - fTemp = 14000.0; - // restore direction information - fAxisValue = (fAxisValue > 0.0) ? fTemp : -fTemp; - } - } - - // convert range from -32768..32767 to -1..1 - fAxisValue /= 32768.0; - - switch (dwAxisMap[i]) - { - case AxisForward: - if ((joy_advanced.value == 0.0) && (cl_mlook.value /*in_mlook.state & 1*/)) // jkrige - mlook cvar - { - // user wants forward control to become look control - if (fabs(fAxisValue) > joy_pitchthreshold.value) - { - // if mouse invert is on, invert the joystick pitch value - // only absolute control support here (joy_advanced is false) - if (m_pitch.value < 0.0) - { - cl.viewangles[PITCH] -= (fAxisValue * joy_pitchsensitivity.value) * aspeed * cl_pitchspeed.value; - } - else - { - cl.viewangles[PITCH] += (fAxisValue * joy_pitchsensitivity.value) * aspeed * cl_pitchspeed.value; - } - V_StopPitchDrift(); - } - else - { - // no pitch movement - // disable pitch return-to-center unless requested by user - // *** this code can be removed when the lookspring bug is fixed - // *** the bug always has the lookspring feature on - - // jkrige - lookspring fix - //if(lookspring.value == 0.0) - // V_StopPitchDrift(); - // jkrige - lookspring fix - } - } - else - { - // user wants forward control to be forward control - if (fabs(fAxisValue) > joy_forwardthreshold.value) - { - cmd->forwardmove += (fAxisValue * joy_forwardsensitivity.value) * speed * cl_forwardspeed.value; - } - } - break; - - case AxisSide: - if (fabs(fAxisValue) > joy_sidethreshold.value) - { - cmd->sidemove += (fAxisValue * joy_sidesensitivity.value) * speed * cl_sidespeed.value; - } - break; - - case AxisTurn: - if ((in_strafe.state & 1) || (lookstrafe.value && (cl_mlook.value /*in_mlook.state & 1*/))) // jkrige - mlook cvar - { - // user wants turn control to become side control - if (fabs(fAxisValue) > joy_sidethreshold.value) - { - cmd->sidemove -= (fAxisValue * joy_sidesensitivity.value) * speed * cl_sidespeed.value; - } - } - else - { - // user wants turn control to be turn control - if (fabs(fAxisValue) > joy_yawthreshold.value) - { - if(dwControlMap[i] == JOY_ABSOLUTE_AXIS) - { - cl.viewangles[YAW] += (fAxisValue * joy_yawsensitivity.value) * aspeed * cl_yawspeed.value; - } - else - { - cl.viewangles[YAW] += (fAxisValue * joy_yawsensitivity.value) * speed * 180.0; - } - - } - } - break; - - case AxisLook: - if (cl_mlook.value /*in_mlook.state & 1*/) // jkrige - mlook cvar - { - if (fabs(fAxisValue) > joy_pitchthreshold.value) - { - // pitch movement detected and pitch movement desired by user - if(dwControlMap[i] == JOY_ABSOLUTE_AXIS) - { - cl.viewangles[PITCH] += (fAxisValue * joy_pitchsensitivity.value) * aspeed * cl_pitchspeed.value; - } - else - { - cl.viewangles[PITCH] += (fAxisValue * joy_pitchsensitivity.value) * speed * 180.0; - } - V_StopPitchDrift(); - } - else - { - // no pitch movement - // disable pitch return-to-center unless requested by user - // *** this code can be removed when the lookspring bug is fixed - // *** the bug always has the lookspring feature on - - // jkrige - lookspring fix - //if(lookspring.value == 0.0) - // V_StopPitchDrift(); - // jkrige - lookspring fix - } - } - break; - - default: - break; - } - } - - // bounds check pitch - if (cl.viewangles[PITCH] > 80.0) - cl.viewangles[PITCH] = 80.0; - if (cl.viewangles[PITCH] < -70.0) - cl.viewangles[PITCH] = -70.0; -} diff --git a/engine/code/keys.c b/engine/code/keys.c deleted file mode 100644 index 7f858e1..0000000 --- a/engine/code/keys.c +++ /dev/null @@ -1,763 +0,0 @@ -/* -Copyright (C) 1996-1997 Id Software, Inc. - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ -#include "quakedef.h" - -/* - -key up events are sent even if in console mode - -*/ - -#define MAXCMDLINE 256 -char key_lines[32][MAXCMDLINE]; -int key_linepos; -int shift_down=false; -int key_lastpress; - -int edit_line=0; -int history_line=0; - -keydest_t key_dest; - -int key_count; // incremented every key event - -char *keybindings[256]; -qboolean consolekeys[256]; // if true, can't be rebound while in console -qboolean menubound[256]; // if true, can't be rebound while in menu -int keyshift[256]; // key to map to if shift held down in console -int key_repeats[256]; // if > 1, it is autorepeating -qboolean keydown[256]; - -typedef struct -{ - char *name; - int keynum; -} keyname_t; - -keyname_t keynames[] = -{ - {"TAB", K_TAB}, - {"ENTER", K_ENTER}, - {"ESCAPE", K_ESCAPE}, - {"SPACE", K_SPACE}, - {"BACKSPACE", K_BACKSPACE}, - {"UPARROW", K_UPARROW}, - {"DOWNARROW", K_DOWNARROW}, - {"LEFTARROW", K_LEFTARROW}, - {"RIGHTARROW", K_RIGHTARROW}, - - {"ALT", K_ALT}, - {"CTRL", K_CTRL}, - {"SHIFT", K_SHIFT}, - - {"F1", K_F1}, - {"F2", K_F2}, - {"F3", K_F3}, - {"F4", K_F4}, - {"F5", K_F5}, - {"F6", K_F6}, - {"F7", K_F7}, - {"F8", K_F8}, - {"F9", K_F9}, - {"F10", K_F10}, - {"F11", K_F11}, - {"F12", K_F12}, - - {"INS", K_INS}, - {"DEL", K_DEL}, - {"PGDN", K_PGDN}, - {"PGUP", K_PGUP}, - {"HOME", K_HOME}, - {"END", K_END}, - - {"MOUSE1", K_MOUSE1}, - {"MOUSE2", K_MOUSE2}, - {"MOUSE3", K_MOUSE3}, - - {"JOY1", K_JOY1}, - {"JOY2", K_JOY2}, - {"JOY3", K_JOY3}, - {"JOY4", K_JOY4}, - - {"AUX1", K_AUX1}, - {"AUX2", K_AUX2}, - {"AUX3", K_AUX3}, - {"AUX4", K_AUX4}, - {"AUX5", K_AUX5}, - {"AUX6", K_AUX6}, - {"AUX7", K_AUX7}, - {"AUX8", K_AUX8}, - {"AUX9", K_AUX9}, - {"AUX10", K_AUX10}, - {"AUX11", K_AUX11}, - {"AUX12", K_AUX12}, - {"AUX13", K_AUX13}, - {"AUX14", K_AUX14}, - {"AUX15", K_AUX15}, - {"AUX16", K_AUX16}, - {"AUX17", K_AUX17}, - {"AUX18", K_AUX18}, - {"AUX19", K_AUX19}, - {"AUX20", K_AUX20}, - {"AUX21", K_AUX21}, - {"AUX22", K_AUX22}, - {"AUX23", K_AUX23}, - {"AUX24", K_AUX24}, - {"AUX25", K_AUX25}, - {"AUX26", K_AUX26}, - {"AUX27", K_AUX27}, - {"AUX28", K_AUX28}, - {"AUX29", K_AUX29}, - {"AUX30", K_AUX30}, - {"AUX31", K_AUX31}, - {"AUX32", K_AUX32}, - - {"PAUSE", K_PAUSE}, - - {"MWHEELUP", K_MWHEELUP}, - {"MWHEELDOWN", K_MWHEELDOWN}, - - - // jkrige - mouse thumb buttons - { "MOUSE4", K_MOUSE4 }, - { "MOUSE5", K_MOUSE5 }, - // jkrige - mouse thumb buttons - - - {"SEMICOLON", ';'}, // because a raw semicolon seperates commands - - {NULL,0} -}; - -/* -============================================================================== - - LINE TYPING INTO THE CONSOLE - -============================================================================== -*/ - -/* -==================== -Key_Console - -Interactive line editing and console scrollback -==================== -*/ -void Key_Console (int key) -{ - char *cmd; - - if (key == K_ENTER) - { - Cbuf_AddText (key_lines[edit_line]+1); // skip the > - Cbuf_AddText ("\n"); - Con_Printf ("%s\n",key_lines[edit_line]); - edit_line = (edit_line + 1) & 31; - history_line = edit_line; - key_lines[edit_line][0] = ']'; - key_linepos = 1; - if (cls.state == ca_disconnected) - SCR_UpdateScreen (); // force an update, because the command - // may take some time - return; - } - - if (key == K_TAB) - { // command completion - cmd = Cmd_CompleteCommand (key_lines[edit_line]+1); - if (!cmd) - cmd = Cvar_CompleteVariable (key_lines[edit_line]+1); - if (cmd) - { - Q_strcpy (key_lines[edit_line]+1, cmd); - key_linepos = Q_strlen(cmd)+1; - key_lines[edit_line][key_linepos] = ' '; - key_linepos++; - key_lines[edit_line][key_linepos] = 0; - return; - } - } - - if (key == K_BACKSPACE || key == K_LEFTARROW) - { - if (key_linepos > 1) - key_linepos--; - return; - } - - if (key == K_UPARROW) - { - do - { - history_line = (history_line - 1) & 31; - } while (history_line != edit_line - && !key_lines[history_line][1]); - if (history_line == edit_line) - history_line = (edit_line+1)&31; - Q_strcpy(key_lines[edit_line], key_lines[history_line]); - key_linepos = Q_strlen(key_lines[edit_line]); - return; - } - - if (key == K_DOWNARROW) - { - if (history_line == edit_line) return; - do - { - history_line = (history_line + 1) & 31; - } - while (history_line != edit_line - && !key_lines[history_line][1]); - if (history_line == edit_line) - { - key_lines[edit_line][0] = ']'; - key_linepos = 1; - } - else - { - Q_strcpy(key_lines[edit_line], key_lines[history_line]); - key_linepos = Q_strlen(key_lines[edit_line]); - } - return; - } - - if (key == K_PGUP || key==K_MWHEELUP) - { - con_backscroll += 2; - if (con_backscroll > con_totallines - (vid.height>>3) - 1) - con_backscroll = con_totallines - (vid.height>>3) - 1; - return; - } - - if (key == K_PGDN || key==K_MWHEELDOWN) - { - con_backscroll -= 2; - if (con_backscroll < 0) - con_backscroll = 0; - return; - } - - if (key == K_HOME) - { - con_backscroll = con_totallines - (vid.height>>3) - 1; - return; - } - - if (key == K_END) - { - con_backscroll = 0; - return; - } - - if (key < 32 || key > 127) - return; // non printable - - if (key_linepos < MAXCMDLINE-1) - { - key_lines[edit_line][key_linepos] = key; - key_linepos++; - key_lines[edit_line][key_linepos] = 0; - } - -} - -//============================================================================ - -char chat_buffer[32]; -qboolean team_message = false; - -void Key_Message (int key) -{ - static int chat_bufferlen = 0; - - if (key == K_ENTER) - { - if (team_message) - Cbuf_AddText ("say_team \""); - else - Cbuf_AddText ("say \""); - Cbuf_AddText(chat_buffer); - Cbuf_AddText("\"\n"); - - key_dest = key_game; - chat_bufferlen = 0; - chat_buffer[0] = 0; - return; - } - - if (key == K_ESCAPE) - { - key_dest = key_game; - chat_bufferlen = 0; - chat_buffer[0] = 0; - return; - } - - if (key < 32 || key > 127) - return; // non printable - - if (key == K_BACKSPACE) - { - if (chat_bufferlen) - { - chat_bufferlen--; - chat_buffer[chat_bufferlen] = 0; - } - return; - } - - if (chat_bufferlen == 31) - return; // all full - - chat_buffer[chat_bufferlen++] = key; - chat_buffer[chat_bufferlen] = 0; -} - -//============================================================================ - - -/* -=================== -Key_StringToKeynum - -Returns a key number to be used to index keybindings[] by looking at -the given string. Single ascii characters return themselves, while -the K_* names are matched up. -=================== -*/ -int Key_StringToKeynum (char *str) -{ - keyname_t *kn; - - if (!str || !str[0]) - return -1; - if (!str[1]) - return str[0]; - - for (kn=keynames ; kn->name ; kn++) - { - if (!Q_strcasecmp(str,kn->name)) - return kn->keynum; - } - return -1; -} - -/* -=================== -Key_KeynumToString - -Returns a string (either a single ascii char, or a K_* name) for the -given keynum. -FIXME: handle quote special (general escape sequence?) -=================== -*/ -char *Key_KeynumToString (int keynum) -{ - keyname_t *kn; - static char tinystr[2]; - - if (keynum == -1) - return ""; - if (keynum > 32 && keynum < 127) - { // printable ascii - tinystr[0] = keynum; - tinystr[1] = 0; - return tinystr; - } - - for (kn=keynames ; kn->name ; kn++) - if (keynum == kn->keynum) - return kn->name; - - return ""; -} - - -/* -=================== -Key_SetBinding -=================== -*/ -void Key_SetBinding (int keynum, char *binding) -{ - char *new; - int l; - - if (keynum == -1) - return; - -// free old bindings - if (keybindings[keynum]) - { - Z_Free (keybindings[keynum]); - keybindings[keynum] = NULL; - } - -// allocate memory for new binding - l = Q_strlen (binding); - new = Z_Malloc (l+1); - Q_strcpy (new, binding); - new[l] = 0; - keybindings[keynum] = new; -} - -/* -=================== -Key_Unbind_f -=================== -*/ -void Key_Unbind_f (void) -{ - int b; - - if (Cmd_Argc() != 2) - { - Con_Printf ("unbind : remove commands from a key\n"); - return; - } - - b = Key_StringToKeynum (Cmd_Argv(1)); - if (b==-1) - { - Con_Printf ("\"%s\" isn't a valid key\n", Cmd_Argv(1)); - return; - } - - Key_SetBinding (b, ""); -} - -void Key_Unbindall_f (void) -{ - int i; - - for (i=0 ; i<256 ; i++) - if (keybindings[i]) - Key_SetBinding (i, ""); -} - - -/* -=================== -Key_Bind_f -=================== -*/ -void Key_Bind_f (void) -{ - int i, c, b; - char cmd[1024]; - - c = Cmd_Argc(); - - if (c != 2 && c != 3) - { - Con_Printf ("bind [command] : attach a command to a key\n"); - return; - } - b = Key_StringToKeynum (Cmd_Argv(1)); - if (b==-1) - { - Con_Printf ("\"%s\" isn't a valid key\n", Cmd_Argv(1)); - return; - } - - if (c == 2) - { - if (keybindings[b]) - Con_Printf ("\"%s\" = \"%s\"\n", Cmd_Argv(1), keybindings[b] ); - else - Con_Printf ("\"%s\" is not bound\n", Cmd_Argv(1) ); - return; - } - -// copy the rest of the command line - cmd[0] = 0; // start out with a null string - for (i=2 ; i< c ; i++) - { - if (i > 2) - strcat (cmd, " "); - strcat (cmd, Cmd_Argv(i)); - } - - Key_SetBinding (b, cmd); -} - -/* -============ -Key_WriteBindings - -Writes lines containing "bind key value" -============ -*/ -void Key_WriteBindings (FILE *f) -{ - int i; - - for (i=0 ; i<256 ; i++) - if (keybindings[i]) - if (*keybindings[i]) - fprintf (f, "bind \"%s\" \"%s\"\n", Key_KeynumToString(i), keybindings[i]); -} - - -/* -=================== -Key_Init -=================== -*/ -void Key_Init (void) -{ - int i; - - for (i=0 ; i<32 ; i++) - { - key_lines[i][0] = ']'; - key_lines[i][1] = 0; - } - key_linepos = 1; - -// -// init ascii characters in console mode -// - for (i=32 ; i<128 ; i++) - consolekeys[i] = true; - consolekeys[K_ENTER] = true; - consolekeys[K_TAB] = true; - consolekeys[K_LEFTARROW] = true; - consolekeys[K_RIGHTARROW] = true; - consolekeys[K_UPARROW] = true; - consolekeys[K_DOWNARROW] = true; - consolekeys[K_BACKSPACE] = true; - consolekeys[K_PGUP] = true; - consolekeys[K_PGDN] = true; - consolekeys[K_SHIFT] = true; - consolekeys[K_MWHEELUP] = true; - consolekeys[K_MWHEELDOWN] = true; - consolekeys['`'] = false; - consolekeys['~'] = false; - - for (i=0 ; i<256 ; i++) - keyshift[i] = i; - for (i='a' ; i<='z' ; i++) - keyshift[i] = i - 'a' + 'A'; - keyshift['1'] = '!'; - keyshift['2'] = '@'; - keyshift['3'] = '#'; - keyshift['4'] = '$'; - keyshift['5'] = '%'; - keyshift['6'] = '^'; - keyshift['7'] = '&'; - keyshift['8'] = '*'; - keyshift['9'] = '('; - keyshift['0'] = ')'; - keyshift['-'] = '_'; - keyshift['='] = '+'; - keyshift[','] = '<'; - keyshift['.'] = '>'; - keyshift['/'] = '?'; - keyshift[';'] = ':'; - keyshift['\''] = '"'; - keyshift['['] = '{'; - keyshift[']'] = '}'; - keyshift['`'] = '~'; - keyshift['\\'] = '|'; - - menubound[K_ESCAPE] = true; - for (i=0 ; i<12 ; i++) - menubound[K_F1+i] = true; - -// -// register our functions -// - Cmd_AddCommand ("bind",Key_Bind_f); - Cmd_AddCommand ("unbind",Key_Unbind_f); - Cmd_AddCommand ("unbindall",Key_Unbindall_f); - - -} - -/* -=================== -Key_Event - -Called by the system between frames for both key up and key down events -Should NOT be called during an interrupt! -=================== -*/ -void Key_Event (int key, qboolean down) -{ - char *kb; - char cmd[1024]; - - keydown[key] = down; - - if (!down) - key_repeats[key] = 0; - - key_lastpress = key; - key_count++; - if (key_count <= 0) - { - return; // just catching keys for Con_NotifyBox - } - -// update auto-repeat status - if (down) - { - key_repeats[key]++; - if (key != K_BACKSPACE && key != K_PAUSE && key_repeats[key] > 1) - { - return; // ignore most autorepeats - } - - if (key >= 200 && !keybindings[key]) - Con_Printf ("%s is unbound, hit F4 to set.\n", Key_KeynumToString (key) ); - } - - if (key == K_SHIFT) - shift_down = down; - -// -// handle escape specialy, so the user can never unbind it -// - if (key == K_ESCAPE) - { - if (!down) - return; - switch (key_dest) - { - case key_message: - Key_Message (key); - break; - case key_menu: - M_Keydown (key); - break; - case key_game: - case key_console: - M_ToggleMenu_f (); - break; - default: - Sys_Error ("Bad key_dest"); - } - return; - } - -// -// key up events only generate commands if the game key binding is -// a button command (leading + sign). These will occur even in console mode, -// to keep the character from continuing an action started before a console -// switch. Button commands include the kenum as a parameter, so multiple -// downs can be matched with ups -// - if (!down) - { - kb = keybindings[key]; - if (kb && kb[0] == '+') - { - sprintf (cmd, "-%s %i\n", kb+1, key); - Cbuf_AddText (cmd); - } - if (keyshift[key] != key) - { - kb = keybindings[keyshift[key]]; - if (kb && kb[0] == '+') - { - sprintf (cmd, "-%s %i\n", kb+1, key); - Cbuf_AddText (cmd); - } - } - return; - } - -// -// during demo playback, most keys bring up the main menu -// - if (cls.demoplayback && down && consolekeys[key] && key_dest == key_game) - { - M_ToggleMenu_f (); - return; - } - -// -// if not a consolekey, send to the interpreter no matter what mode is -// - if ( (key_dest == key_menu && menubound[key]) - || (key_dest == key_console && !consolekeys[key]) - || (key_dest == key_game && ( !con_forcedup || !consolekeys[key] ) ) ) - { - kb = keybindings[key]; - if (kb) - { - if (kb[0] == '+') - { // button commands add keynum as a parm - sprintf (cmd, "%s %i\n", kb, key); - Cbuf_AddText (cmd); - } - else - { - Cbuf_AddText (kb); - Cbuf_AddText ("\n"); - } - } - return; - } - - if (!down) - return; // other systems only care about key down events - - if (shift_down) - { - key = keyshift[key]; - } - - switch (key_dest) - { - case key_message: - Key_Message (key); - break; - case key_menu: - M_Keydown (key); - break; - - case key_game: - case key_console: - Key_Console (key); - break; - default: - Sys_Error ("Bad key_dest"); - } -} - - -/* -=================== -Key_ClearStates -=================== -*/ -void Key_ClearStates (void) -{ - int i; - - for (i=0 ; i<256 ; i++) - { - keydown[i] = false; - key_repeats[i] = 0; - } -} diff --git a/engine/code/menu.h b/engine/code/menu.h deleted file mode 100644 index 616de3f..0000000 --- a/engine/code/menu.h +++ /dev/null @@ -1,38 +0,0 @@ -/* -Copyright (C) 1996-1997 Id Software, Inc. - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ - -// -// the net drivers should just set the apropriate bits in m_activenet, -// instead of having the menu code look through their internal tables -// -#define MNET_IPX 1 -#define MNET_TCP 2 - -extern int m_activenet; - -// -// menus -// -void M_Init (void); -void M_Keydown (int key); -void M_Draw (void); -void M_ToggleMenu_f (void); - - diff --git a/engine/code/net.h b/engine/code/net.h deleted file mode 100644 index af46125..0000000 --- a/engine/code/net.h +++ /dev/null @@ -1,337 +0,0 @@ -/* -Copyright (C) 1996-1997 Id Software, Inc. - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ -// net.h -- quake's interface to the networking layer - -struct qsockaddr -{ - short sa_family; - unsigned char sa_data[14]; -}; - - -#define NET_NAMELEN 64 - -#define NET_MAXMESSAGE 8192 -#define NET_HEADERSIZE (2 * sizeof(unsigned int)) -#define NET_DATAGRAMSIZE (MAX_DATAGRAM + NET_HEADERSIZE) - -// NetHeader flags -#define NETFLAG_LENGTH_MASK 0x0000ffff -#define NETFLAG_DATA 0x00010000 -#define NETFLAG_ACK 0x00020000 -#define NETFLAG_NAK 0x00040000 -#define NETFLAG_EOM 0x00080000 -#define NETFLAG_UNRELIABLE 0x00100000 -#define NETFLAG_CTL 0x80000000 - - -#define NET_PROTOCOL_VERSION 3 - -// This is the network info/connection protocol. It is used to find Quake -// servers, get info about them, and connect to them. Once connected, the -// Quake game protocol (documented elsewhere) is used. -// -// -// General notes: -// game_name is currently always "QUAKE", but is there so this same protocol -// can be used for future games as well; can you say Quake2? -// -// CCREQ_CONNECT -// string game_name "QUAKE" -// byte net_protocol_version NET_PROTOCOL_VERSION -// -// CCREQ_SERVER_INFO -// string game_name "QUAKE" -// byte net_protocol_version NET_PROTOCOL_VERSION -// -// CCREQ_PLAYER_INFO -// byte player_number -// -// CCREQ_RULE_INFO -// string rule -// -// -// -// CCREP_ACCEPT -// long port -// -// CCREP_REJECT -// string reason -// -// CCREP_SERVER_INFO -// string server_address -// string host_name -// string level_name -// byte current_players -// byte max_players -// byte protocol_version NET_PROTOCOL_VERSION -// -// CCREP_PLAYER_INFO -// byte player_number -// string name -// long colors -// long frags -// long connect_time -// string address -// -// CCREP_RULE_INFO -// string rule -// string value - -// note: -// There are two address forms used above. The short form is just a -// port number. The address that goes along with the port is defined as -// "whatever address you receive this reponse from". This lets us use -// the host OS to solve the problem of multiple host addresses (possibly -// with no routing between them); the host will use the right address -// when we reply to the inbound connection request. The long from is -// a full address and port in a string. It is used for returning the -// address of a server that is not running locally. - -#define CCREQ_CONNECT 0x01 -#define CCREQ_SERVER_INFO 0x02 -#define CCREQ_PLAYER_INFO 0x03 -#define CCREQ_RULE_INFO 0x04 - -#define CCREP_ACCEPT 0x81 -#define CCREP_REJECT 0x82 -#define CCREP_SERVER_INFO 0x83 -#define CCREP_PLAYER_INFO 0x84 -#define CCREP_RULE_INFO 0x85 - -typedef struct qsocket_s -{ - struct qsocket_s *next; - double connecttime; - double lastMessageTime; - double lastSendTime; - - qboolean disconnected; - qboolean canSend; - qboolean sendNext; - - int driver; - int landriver; - int socket; - void *driverdata; - - unsigned int ackSequence; - unsigned int sendSequence; - unsigned int unreliableSendSequence; - int sendMessageLength; - byte sendMessage [NET_MAXMESSAGE]; - - unsigned int receiveSequence; - unsigned int unreliableReceiveSequence; - int receiveMessageLength; - byte receiveMessage [NET_MAXMESSAGE]; - - struct qsockaddr addr; - char address[NET_NAMELEN]; - -} qsocket_t; - -extern qsocket_t *net_activeSockets; -extern qsocket_t *net_freeSockets; -extern int net_numsockets; - -typedef struct -{ - char *name; - qboolean initialized; - int controlSock; - int (*Init) (void); - void (*Shutdown) (void); - void (*Listen) (qboolean state); - int (*OpenSocket) (int port); - int (*CloseSocket) (int socket); - int (*Connect) (int socket, struct qsockaddr *addr); - int (*CheckNewConnections) (void); - int (*Read) (int socket, byte *buf, int len, struct qsockaddr *addr); - int (*Write) (int socket, byte *buf, int len, struct qsockaddr *addr); - int (*Broadcast) (int socket, byte *buf, int len); - char * (*AddrToString) (struct qsockaddr *addr); - int (*StringToAddr) (char *string, struct qsockaddr *addr); - int (*GetSocketAddr) (int socket, struct qsockaddr *addr); - int (*GetNameFromAddr) (struct qsockaddr *addr, char *name); - int (*GetAddrFromName) (char *name, struct qsockaddr *addr); - int (*AddrCompare) (struct qsockaddr *addr1, struct qsockaddr *addr2); - int (*GetSocketPort) (struct qsockaddr *addr); - int (*SetSocketPort) (struct qsockaddr *addr, int port); -} net_landriver_t; - -#define MAX_NET_DRIVERS 8 -extern int net_numlandrivers; -extern net_landriver_t net_landrivers[MAX_NET_DRIVERS]; - -typedef struct -{ - char *name; - qboolean initialized; - int (*Init) (void); - void (*Listen) (qboolean state); - void (*SearchForHosts) (qboolean xmit); - qsocket_t *(*Connect) (char *host); - qsocket_t *(*CheckNewConnections) (void); - int (*QGetMessage) (qsocket_t *sock); - int (*QSendMessage) (qsocket_t *sock, sizebuf_t *data); - int (*SendUnreliableMessage) (qsocket_t *sock, sizebuf_t *data); - qboolean (*CanSendMessage) (qsocket_t *sock); - qboolean (*CanSendUnreliableMessage) (qsocket_t *sock); - void (*Close) (qsocket_t *sock); - void (*Shutdown) (void); - int controlSock; -} net_driver_t; - -extern int net_numdrivers; -extern net_driver_t net_drivers[MAX_NET_DRIVERS]; - -extern int DEFAULTnet_hostport; -extern int net_hostport; - -extern int net_driverlevel; -extern cvar_t hostname; -extern char playername[]; -extern int playercolor; - -extern int messagesSent; -extern int messagesReceived; -extern int unreliableMessagesSent; -extern int unreliableMessagesReceived; - -qsocket_t *NET_NewQSocket (void); -void NET_FreeQSocket(qsocket_t *); -double SetNetTime(void); - - -#define HOSTCACHESIZE 8 - -typedef struct -{ - char name[16]; - char map[16]; - char cname[32]; - int users; - int maxusers; - int driver; - int ldriver; - struct qsockaddr addr; -} hostcache_t; - -extern int hostCacheCount; -extern hostcache_t hostcache[HOSTCACHESIZE]; - -#if !defined(_WIN32 ) && !defined (__linux__) && !defined (__sun__) -#ifndef htonl -extern unsigned long htonl (unsigned long hostlong); -#endif -#ifndef htons -extern unsigned short htons (unsigned short hostshort); -#endif -#ifndef ntohl -extern unsigned long ntohl (unsigned long netlong); -#endif -#ifndef ntohs -extern unsigned short ntohs (unsigned short netshort); -#endif -#endif - -#ifdef IDGODS -qboolean IsID(struct qsockaddr *addr); -#endif - -//============================================================================ -// -// public network functions -// -//============================================================================ - -extern double net_time; -extern sizebuf_t net_message; -extern int net_activeconnections; - -void NET_Init (void); -void NET_Shutdown (void); - -struct qsocket_s *NET_CheckNewConnections (void); -// returns a new connection number if there is one pending, else -1 - -struct qsocket_s *NET_Connect (char *host); -// called by client to connect to a host. Returns -1 if not able to - -qboolean NET_CanSendMessage (qsocket_t *sock); -// Returns true or false if the given qsocket can currently accept a -// message to be transmitted. - -int NET_GetMessage (struct qsocket_s *sock); -// returns data in net_message sizebuf -// returns 0 if no data is waiting -// returns 1 if a message was received -// returns 2 if an unreliable message was received -// returns -1 if the connection died - -int NET_SendMessage (struct qsocket_s *sock, sizebuf_t *data); -int NET_SendUnreliableMessage (struct qsocket_s *sock, sizebuf_t *data); -// returns 0 if the message connot be delivered reliably, but the connection -// is still considered valid -// returns 1 if the message was sent properly -// returns -1 if the connection died - -int NET_SendToAll(sizebuf_t *data, int blocktime); -// This is a reliable *blocking* send to all attached clients. - - -void NET_Close (struct qsocket_s *sock); -// if a dead connection is returned by a get or send function, this function -// should be called when it is convenient - -// Server calls when a client is kicked off for a game related misbehavior -// like an illegal protocal conversation. Client calls when disconnecting -// from a server. -// A netcon_t number will not be reused until this function is called for it - -void NET_Poll(void); - - -typedef struct _PollProcedure -{ - struct _PollProcedure *next; - double nextTime; - void (*procedure)(); - void *arg; -} PollProcedure; - -void SchedulePollProcedure(PollProcedure *pp, double timeOffset); - -extern qboolean serialAvailable; -extern qboolean ipxAvailable; -extern qboolean tcpipAvailable; -extern char my_ipx_address[NET_NAMELEN]; -extern char my_tcpip_address[NET_NAMELEN]; -extern void (*GetComPortConfig) (int portNumber, int *port, int *irq, int *baud, qboolean *useModem); -extern void (*SetComPortConfig) (int portNumber, int port, int irq, int baud, qboolean useModem); -extern void (*GetModemConfig) (int portNumber, char *dialType, char *clear, char *init, char *hangup); -extern void (*SetModemConfig) (int portNumber, char *dialType, char *clear, char *init, char *hangup); - -extern qboolean slistInProgress; -extern qboolean slistSilent; -extern qboolean slistLocal; - -void NET_Slist_f (void); diff --git a/engine/code/net_vcr.c b/engine/code/net_vcr.c deleted file mode 100644 index ba8f40d..0000000 --- a/engine/code/net_vcr.c +++ /dev/null @@ -1,167 +0,0 @@ -/* -Copyright (C) 1996-1997 Id Software, Inc. - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ -// net_vcr.c - -#include "quakedef.h" -#include "net_vcr.h" - -extern int vcrFile; - -// This is the playback portion of the VCR. It reads the file produced -// by the recorder and plays it back to the host. The recording contains -// everything necessary (events, timestamps, and data) to duplicate the game -// from the viewpoint of everything above the network layer. - -static struct -{ - double time; - int op; - long session; -} next; - -int VCR_Init (void) -{ - net_drivers[0].Init = VCR_Init; - - net_drivers[0].SearchForHosts = VCR_SearchForHosts; - net_drivers[0].Connect = VCR_Connect; - net_drivers[0].CheckNewConnections = VCR_CheckNewConnections; - net_drivers[0].QGetMessage = VCR_GetMessage; - net_drivers[0].QSendMessage = VCR_SendMessage; - net_drivers[0].CanSendMessage = VCR_CanSendMessage; - net_drivers[0].Close = VCR_Close; - net_drivers[0].Shutdown = VCR_Shutdown; - - Sys_FileRead(vcrFile, &next, sizeof(next)); - return 0; -} - -void VCR_ReadNext (void) -{ - if (Sys_FileRead(vcrFile, &next, sizeof(next)) == 0) - { - next.op = 255; - Sys_Error ("=== END OF PLAYBACK===\n"); - } - if (next.op < 1 || next.op > VCR_MAX_MESSAGE) - Sys_Error ("VCR_ReadNext: bad op"); -} - - -void VCR_Listen (qboolean state) -{ -} - - -void VCR_Shutdown (void) -{ -} - - -int VCR_GetMessage (qsocket_t *sock) -{ - int ret; - - if (host_time != next.time || next.op != VCR_OP_GETMESSAGE || next.session != *(long *)(&sock->driverdata)) - Sys_Error ("VCR missmatch"); - - Sys_FileRead(vcrFile, &ret, sizeof(int)); - if (ret != 1) - { - VCR_ReadNext (); - return ret; - } - - Sys_FileRead(vcrFile, &net_message.cursize, sizeof(int)); - Sys_FileRead(vcrFile, net_message.data, net_message.cursize); - - VCR_ReadNext (); - - return 1; -} - - -int VCR_SendMessage (qsocket_t *sock, sizebuf_t *data) -{ - int ret; - - if (host_time != next.time || next.op != VCR_OP_SENDMESSAGE || next.session != *(long *)(&sock->driverdata)) - Sys_Error ("VCR missmatch"); - - Sys_FileRead(vcrFile, &ret, sizeof(int)); - - VCR_ReadNext (); - - return ret; -} - - -qboolean VCR_CanSendMessage (qsocket_t *sock) -{ - qboolean ret; - - if (host_time != next.time || next.op != VCR_OP_CANSENDMESSAGE || next.session != *(long *)(&sock->driverdata)) - Sys_Error ("VCR missmatch"); - - Sys_FileRead(vcrFile, &ret, sizeof(int)); - - VCR_ReadNext (); - - return ret; -} - - -void VCR_Close (qsocket_t *sock) -{ -} - - -void VCR_SearchForHosts (qboolean xmit) -{ -} - - -qsocket_t *VCR_Connect (char *host) -{ - return NULL; -} - - -qsocket_t *VCR_CheckNewConnections (void) -{ - qsocket_t *sock; - - if (host_time != next.time || next.op != VCR_OP_CONNECT) - Sys_Error ("VCR missmatch"); - - if (!next.session) - { - VCR_ReadNext (); - return NULL; - } - - sock = NET_NewQSocket (); - *(long *)(&sock->driverdata) = next.session; - - Sys_FileRead (vcrFile, sock->address, NET_NAMELEN); - VCR_ReadNext (); - - return sock; -} diff --git a/engine/code/net_vcr.h b/engine/code/net_vcr.h deleted file mode 100644 index 95c2f34..0000000 --- a/engine/code/net_vcr.h +++ /dev/null @@ -1,37 +0,0 @@ -/* -Copyright (C) 1996-1997 Id Software, Inc. - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ -// net_vcr.h - -#define VCR_OP_CONNECT 1 -#define VCR_OP_GETMESSAGE 2 -#define VCR_OP_SENDMESSAGE 3 -#define VCR_OP_CANSENDMESSAGE 4 -#define VCR_MAX_MESSAGE 4 - -int VCR_Init (void); -void VCR_Listen (qboolean state); -void VCR_SearchForHosts (qboolean xmit); -qsocket_t *VCR_Connect (char *host); -qsocket_t *VCR_CheckNewConnections (void); -int VCR_GetMessage (qsocket_t *sock); -int VCR_SendMessage (qsocket_t *sock, sizebuf_t *data); -qboolean VCR_CanSendMessage (qsocket_t *sock); -void VCR_Close (qsocket_t *sock); -void VCR_Shutdown (void); diff --git a/engine/code/net_win.c b/engine/code/net_win.c deleted file mode 100644 index 019a9c7..0000000 --- a/engine/code/net_win.c +++ /dev/null @@ -1,120 +0,0 @@ -/* -Copyright (C) 1996-1997 Id Software, Inc. - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ -#include "quakedef.h" - -#include "net_loop.h" -#include "net_dgrm.h" -//#include "net_ser.h" - -net_driver_t net_drivers[MAX_NET_DRIVERS] = -{ - { - "Loopback", - false, - Loop_Init, - Loop_Listen, - Loop_SearchForHosts, - Loop_Connect, - Loop_CheckNewConnections, - Loop_GetMessage, - Loop_SendMessage, - Loop_SendUnreliableMessage, - Loop_CanSendMessage, - Loop_CanSendUnreliableMessage, - Loop_Close, - Loop_Shutdown - } - , - { - "Datagram", - false, - Datagram_Init, - Datagram_Listen, - Datagram_SearchForHosts, - Datagram_Connect, - Datagram_CheckNewConnections, - Datagram_GetMessage, - Datagram_SendMessage, - Datagram_SendUnreliableMessage, - Datagram_CanSendMessage, - Datagram_CanSendUnreliableMessage, - Datagram_Close, - Datagram_Shutdown - } -}; - -int net_numdrivers = 2; - - -#include "net_wins.h" -#include "net_wipx.h" - -net_landriver_t net_landrivers[MAX_NET_DRIVERS] = -{ - { - "Winsock TCPIP", - false, - 0, - WINS_Init, - WINS_Shutdown, - WINS_Listen, - WINS_OpenSocket, - WINS_CloseSocket, - WINS_Connect, - WINS_CheckNewConnections, - WINS_Read, - WINS_Write, - WINS_Broadcast, - WINS_AddrToString, - WINS_StringToAddr, - WINS_GetSocketAddr, - WINS_GetNameFromAddr, - WINS_GetAddrFromName, - WINS_AddrCompare, - WINS_GetSocketPort, - WINS_SetSocketPort - }, - { - "Winsock IPX", - false, - 0, - WIPX_Init, - WIPX_Shutdown, - WIPX_Listen, - WIPX_OpenSocket, - WIPX_CloseSocket, - WIPX_Connect, - WIPX_CheckNewConnections, - WIPX_Read, - WIPX_Write, - WIPX_Broadcast, - WIPX_AddrToString, - WIPX_StringToAddr, - WIPX_GetSocketAddr, - WIPX_GetNameFromAddr, - WIPX_GetAddrFromName, - WIPX_AddrCompare, - WIPX_GetSocketPort, - WIPX_SetSocketPort - } - -}; - -int net_numlandrivers = 2; diff --git a/engine/code/net_wins.c b/engine/code/net_wins.c deleted file mode 100644 index 1ac445b..0000000 --- a/engine/code/net_wins.c +++ /dev/null @@ -1,580 +0,0 @@ -/* -Copyright (C) 1996-1997 Id Software, Inc. - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ -// net_wins.c - -#include "quakedef.h" -#include "winquake.h" - -extern cvar_t hostname; - -#define MAXHOSTNAMELEN 256 - -static int net_acceptsocket = -1; // socket for fielding new connections -static int net_controlsocket; -static int net_broadcastsocket = 0; -static struct qsockaddr broadcastaddr; - -static unsigned long myAddr; - -qboolean winsock_lib_initialized; - -int (PASCAL FAR *pWSAStartup)(WORD wVersionRequired, LPWSADATA lpWSAData); -int (PASCAL FAR *pWSACleanup)(void); -int (PASCAL FAR *pWSAGetLastError)(void); -SOCKET (PASCAL FAR *psocket)(int af, int type, int protocol); -int (PASCAL FAR *pioctlsocket)(SOCKET s, long cmd, u_long FAR *argp); -int (PASCAL FAR *psetsockopt)(SOCKET s, int level, int optname, - const char FAR * optval, int optlen); -int (PASCAL FAR *precvfrom)(SOCKET s, char FAR * buf, int len, int flags, - struct sockaddr FAR *from, int FAR * fromlen); -int (PASCAL FAR *psendto)(SOCKET s, const char FAR * buf, int len, int flags, - const struct sockaddr FAR *to, int tolen); -int (PASCAL FAR *pclosesocket)(SOCKET s); -int (PASCAL FAR *pgethostname)(char FAR * name, int namelen); -struct hostent FAR * (PASCAL FAR *pgethostbyname)(const char FAR * name); -struct hostent FAR * (PASCAL FAR *pgethostbyaddr)(const char FAR * addr, - int len, int type); -int (PASCAL FAR *pgetsockname)(SOCKET s, struct sockaddr FAR *name, - int FAR * namelen); - -#include "net_wins.h" - -int winsock_initialized = 0; -WSADATA winsockdata; - -//============================================================================= - -static double blocktime; - -BOOL PASCAL FAR BlockingHook(void) -{ - MSG msg; - BOOL ret; - - if ((Sys_FloatTime() - blocktime) > 2.0) - { - WSACancelBlockingCall(); - return FALSE; - } - - /* get the next message, if any */ - ret = (BOOL) PeekMessage(&msg, NULL, 0, 0, PM_REMOVE); - - /* if we got one, process it */ - if (ret) { - TranslateMessage(&msg); - DispatchMessage(&msg); - } - - /* TRUE if we got a message */ - return ret; -} - - -void WINS_GetLocalAddress() -{ - struct hostent *local = NULL; - char buff[MAXHOSTNAMELEN]; - unsigned long addr; - - if (myAddr != INADDR_ANY) - return; - - if (pgethostname(buff, MAXHOSTNAMELEN) == SOCKET_ERROR) - return; - - blocktime = Sys_FloatTime(); - WSASetBlockingHook(BlockingHook); - local = pgethostbyname(buff); - WSAUnhookBlockingHook(); - if (local == NULL) - return; - - myAddr = *(int *)local->h_addr_list[0]; - - addr = ntohl(myAddr); - sprintf(my_tcpip_address, "%d.%d.%d.%d", (addr >> 24) & 0xff, (addr >> 16) & 0xff, (addr >> 8) & 0xff, addr & 0xff); -} - - -int WINS_Init (void) -{ - int i; - char buff[MAXHOSTNAMELEN]; - char *p; - int r; - WORD wVersionRequested; - HINSTANCE hInst; - -// initialize the Winsock function vectors (we do this instead of statically linking -// so we can run on Win 3.1, where there isn't necessarily Winsock) - hInst = LoadLibrary("wsock32.dll"); - - if (hInst == NULL) - { - Con_SafePrintf ("Failed to load winsock.dll\n"); - winsock_lib_initialized = false; - return -1; - } - - winsock_lib_initialized = true; - - pWSAStartup = (void *)GetProcAddress(hInst, "WSAStartup"); - pWSACleanup = (void *)GetProcAddress(hInst, "WSACleanup"); - pWSAGetLastError = (void *)GetProcAddress(hInst, "WSAGetLastError"); - psocket = (void *)GetProcAddress(hInst, "socket"); - pioctlsocket = (void *)GetProcAddress(hInst, "ioctlsocket"); - psetsockopt = (void *)GetProcAddress(hInst, "setsockopt"); - precvfrom = (void *)GetProcAddress(hInst, "recvfrom"); - psendto = (void *)GetProcAddress(hInst, "sendto"); - pclosesocket = (void *)GetProcAddress(hInst, "closesocket"); - pgethostname = (void *)GetProcAddress(hInst, "gethostname"); - pgethostbyname = (void *)GetProcAddress(hInst, "gethostbyname"); - pgethostbyaddr = (void *)GetProcAddress(hInst, "gethostbyaddr"); - pgetsockname = (void *)GetProcAddress(hInst, "getsockname"); - - if (!pWSAStartup || !pWSACleanup || !pWSAGetLastError || - !psocket || !pioctlsocket || !psetsockopt || - !precvfrom || !psendto || !pclosesocket || - !pgethostname || !pgethostbyname || !pgethostbyaddr || - !pgetsockname) - { - Con_SafePrintf ("Couldn't GetProcAddress from winsock.dll\n"); - return -1; - } - - if (COM_CheckParm ("-noudp")) - return -1; - - if (winsock_initialized == 0) - { - wVersionRequested = MAKEWORD(1, 1); - - r = pWSAStartup (MAKEWORD(1, 1), &winsockdata); - - if (r) - { - Con_SafePrintf ("Winsock initialization failed.\n"); - return -1; - } - } - winsock_initialized++; - - // determine my name - if (pgethostname(buff, MAXHOSTNAMELEN) == SOCKET_ERROR) - { - Con_DPrintf ("Winsock TCP/IP Initialization failed.\n"); - if (--winsock_initialized == 0) - pWSACleanup (); - return -1; - } - - // if the quake hostname isn't set, set it to the machine name - if (Q_strcmp(hostname.string, "UNNAMED") == 0) - { - // see if it's a text IP address (well, close enough) - for (p = buff; *p; p++) - if ((*p < '0' || *p > '9') && *p != '.') - break; - - // if it is a real name, strip off the domain; we only want the host - if (*p) - { - for (i = 0; i < 15; i++) - if (buff[i] == '.') - break; - buff[i] = 0; - } - Cvar_Set ("hostname", buff); - } - - i = COM_CheckParm ("-ip"); - if (i) - { - if (i < com_argc-1) - { - myAddr = inet_addr(com_argv[i+1]); - if (myAddr == INADDR_NONE) - Sys_Error ("%s is not a valid IP address", com_argv[i+1]); - strcpy(my_tcpip_address, com_argv[i+1]); - } - else - { - Sys_Error ("NET_Init: you must specify an IP address after -ip"); - } - } - else - { - myAddr = INADDR_ANY; - strcpy(my_tcpip_address, "INADDR_ANY"); - } - - if ((net_controlsocket = WINS_OpenSocket (0)) == -1) - { - Con_Printf("WINS_Init: Unable to open control socket\n"); - if (--winsock_initialized == 0) - pWSACleanup (); - return -1; - } - - ((struct sockaddr_in *)&broadcastaddr)->sin_family = AF_INET; - ((struct sockaddr_in *)&broadcastaddr)->sin_addr.s_addr = INADDR_BROADCAST; - ((struct sockaddr_in *)&broadcastaddr)->sin_port = htons((unsigned short)net_hostport); - - Con_Printf("Winsock TCP/IP Initialized\n"); - tcpipAvailable = true; - - return net_controlsocket; -} - -//============================================================================= - -void WINS_Shutdown (void) -{ - WINS_Listen (false); - WINS_CloseSocket (net_controlsocket); - if (--winsock_initialized == 0) - pWSACleanup (); -} - -//============================================================================= - -void WINS_Listen (qboolean state) -{ - // enable listening - if (state) - { - if (net_acceptsocket != -1) - return; - WINS_GetLocalAddress(); - if ((net_acceptsocket = WINS_OpenSocket (net_hostport)) == -1) - Sys_Error ("WINS_Listen: Unable to open accept socket\n"); - return; - } - - // disable listening - if (net_acceptsocket == -1) - return; - WINS_CloseSocket (net_acceptsocket); - net_acceptsocket = -1; -} - -//============================================================================= - -int WINS_OpenSocket (int port) -{ - int newsocket; - struct sockaddr_in address; - u_long _true = 1; - - if ((newsocket = psocket (PF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1) - return -1; - - if (pioctlsocket (newsocket, FIONBIO, &_true) == -1) - goto ErrorReturn; - - address.sin_family = AF_INET; - address.sin_addr.s_addr = myAddr; - address.sin_port = htons((unsigned short)port); - if( bind (newsocket, (void *)&address, sizeof(address)) == 0) - return newsocket; - - Sys_Error ("Unable to bind to %s", WINS_AddrToString((struct qsockaddr *)&address)); -ErrorReturn: - pclosesocket (newsocket); - return -1; -} - -//============================================================================= - -int WINS_CloseSocket (int socket) -{ - if (socket == net_broadcastsocket) - net_broadcastsocket = 0; - return pclosesocket (socket); -} - - -//============================================================================= -/* -============ -PartialIPAddress - -this lets you type only as much of the net address as required, using -the local network components to fill in the rest -============ -*/ -static int PartialIPAddress (char *in, struct qsockaddr *hostaddr) -{ - char buff[256]; - char *b; - int addr; - int num; - int mask; - int run; - int port; - - buff[0] = '.'; - b = buff; - strcpy(buff+1, in); - if (buff[1] == '.') - b++; - - addr = 0; - mask=-1; - while (*b == '.') - { - b++; - num = 0; - run = 0; - while (!( *b < '0' || *b > '9')) - { - num = num*10 + *b++ - '0'; - if (++run > 3) - return -1; - } - if ((*b < '0' || *b > '9') && *b != '.' && *b != ':' && *b != 0) - return -1; - if (num < 0 || num > 255) - return -1; - mask<<=8; - addr = (addr<<8) + num; - } - - if (*b++ == ':') - port = Q_atoi(b); - else - port = net_hostport; - - hostaddr->sa_family = AF_INET; - ((struct sockaddr_in *)hostaddr)->sin_port = htons((short)port); - ((struct sockaddr_in *)hostaddr)->sin_addr.s_addr = (myAddr & htonl(mask)) | htonl(addr); - - return 0; -} -//============================================================================= - -int WINS_Connect (int socket, struct qsockaddr *addr) -{ - return 0; -} - -//============================================================================= - -int WINS_CheckNewConnections (void) -{ - char buf[4096]; - - if (net_acceptsocket == -1) - return -1; - - if (precvfrom (net_acceptsocket, buf, sizeof(buf), MSG_PEEK, NULL, NULL) > 0) - { - return net_acceptsocket; - } - return -1; -} - -//============================================================================= - -int WINS_Read (int socket, byte *buf, int len, struct qsockaddr *addr) -{ - int addrlen = sizeof (struct qsockaddr); - int ret; - - ret = precvfrom (socket, buf, len, 0, (struct sockaddr *)addr, &addrlen); - if (ret == -1) - { - // jkrige - vs2005 - //int errno = pWSAGetLastError(); - - //if (errno == WSAEWOULDBLOCK || errno == WSAECONNREFUSED) - // return 0; - int err = pWSAGetLastError(); - - if (err == WSAEWOULDBLOCK || err == WSAECONNREFUSED) - return 0; - // jkrige - vs2005 - } - return ret; -} - -//============================================================================= - -int WINS_MakeSocketBroadcastCapable (int socket) -{ - int i = 1; - - // make this socket broadcast capable - if (psetsockopt(socket, SOL_SOCKET, SO_BROADCAST, (char *)&i, sizeof(i)) < 0) - return -1; - net_broadcastsocket = socket; - - return 0; -} - -//============================================================================= - -int WINS_Broadcast (int socket, byte *buf, int len) -{ - int ret; - - if (socket != net_broadcastsocket) - { - if (net_broadcastsocket != 0) - Sys_Error("Attempted to use multiple broadcasts sockets\n"); - WINS_GetLocalAddress(); - ret = WINS_MakeSocketBroadcastCapable (socket); - if (ret == -1) - { - Con_Printf("Unable to make socket broadcast capable\n"); - return ret; - } - } - - return WINS_Write (socket, buf, len, &broadcastaddr); -} - -//============================================================================= - -int WINS_Write (int socket, byte *buf, int len, struct qsockaddr *addr) -{ - int ret; - - ret = psendto (socket, buf, len, 0, (struct sockaddr *)addr, sizeof(struct qsockaddr)); - if (ret == -1) - if (pWSAGetLastError() == WSAEWOULDBLOCK) - return 0; - - return ret; -} - -//============================================================================= - -char *WINS_AddrToString (struct qsockaddr *addr) -{ - static char buffer[22]; - int haddr; - - haddr = ntohl(((struct sockaddr_in *)addr)->sin_addr.s_addr); - sprintf(buffer, "%d.%d.%d.%d:%d", (haddr >> 24) & 0xff, (haddr >> 16) & 0xff, (haddr >> 8) & 0xff, haddr & 0xff, ntohs(((struct sockaddr_in *)addr)->sin_port)); - return buffer; -} - -//============================================================================= - -int WINS_StringToAddr (char *string, struct qsockaddr *addr) -{ - int ha1, ha2, ha3, ha4, hp; - int ipaddr; - - sscanf(string, "%d.%d.%d.%d:%d", &ha1, &ha2, &ha3, &ha4, &hp); - ipaddr = (ha1 << 24) | (ha2 << 16) | (ha3 << 8) | ha4; - - addr->sa_family = AF_INET; - ((struct sockaddr_in *)addr)->sin_addr.s_addr = htonl(ipaddr); - ((struct sockaddr_in *)addr)->sin_port = htons((unsigned short)hp); - return 0; -} - -//============================================================================= - -int WINS_GetSocketAddr (int socket, struct qsockaddr *addr) -{ - int addrlen = sizeof(struct qsockaddr); - unsigned int a; - - Q_memset(addr, 0, sizeof(struct qsockaddr)); - pgetsockname(socket, (struct sockaddr *)addr, &addrlen); - a = ((struct sockaddr_in *)addr)->sin_addr.s_addr; - if (a == 0 || a == inet_addr("127.0.0.1")) - ((struct sockaddr_in *)addr)->sin_addr.s_addr = myAddr; - - return 0; -} - -//============================================================================= - -int WINS_GetNameFromAddr (struct qsockaddr *addr, char *name) -{ - struct hostent *hostentry; - - hostentry = pgethostbyaddr ((char *)&((struct sockaddr_in *)addr)->sin_addr, sizeof(struct in_addr), AF_INET); - if (hostentry) - { - Q_strncpy (name, (char *)hostentry->h_name, NET_NAMELEN - 1); - return 0; - } - - Q_strcpy (name, WINS_AddrToString (addr)); - return 0; -} - -//============================================================================= - -int WINS_GetAddrFromName(char *name, struct qsockaddr *addr) -{ - struct hostent *hostentry; - - if (name[0] >= '0' && name[0] <= '9') - return PartialIPAddress (name, addr); - - hostentry = pgethostbyname (name); - if (!hostentry) - return -1; - - addr->sa_family = AF_INET; - ((struct sockaddr_in *)addr)->sin_port = htons((unsigned short)net_hostport); - ((struct sockaddr_in *)addr)->sin_addr.s_addr = *(int *)hostentry->h_addr_list[0]; - - return 0; -} - -//============================================================================= - -int WINS_AddrCompare (struct qsockaddr *addr1, struct qsockaddr *addr2) -{ - if (addr1->sa_family != addr2->sa_family) - return -1; - - if (((struct sockaddr_in *)addr1)->sin_addr.s_addr != ((struct sockaddr_in *)addr2)->sin_addr.s_addr) - return -1; - - if (((struct sockaddr_in *)addr1)->sin_port != ((struct sockaddr_in *)addr2)->sin_port) - return 1; - - return 0; -} - -//============================================================================= - -int WINS_GetSocketPort (struct qsockaddr *addr) -{ - return ntohs(((struct sockaddr_in *)addr)->sin_port); -} - - -int WINS_SetSocketPort (struct qsockaddr *addr, int port) -{ - ((struct sockaddr_in *)addr)->sin_port = htons((unsigned short)port); - return 0; -} - -//============================================================================= diff --git a/engine/code/pr_exec.c b/engine/code/pr_exec.c deleted file mode 100644 index 6e3ada8..0000000 --- a/engine/code/pr_exec.c +++ /dev/null @@ -1,673 +0,0 @@ -/* -Copyright (C) 1996-1997 Id Software, Inc. - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ - -#include "quakedef.h" - - -/* - -*/ - -typedef struct -{ - int s; - dfunction_t *f; -} prstack_t; - -// jkrige - increase stack size to avoid overflows -//#define MAX_STACK_DEPTH 32 -//#define LOCALSTACK_SIZE 2048 -#define MAX_STACK_DEPTH 64 -#define LOCALSTACK_SIZE 4096 -// jkrige - increase stack size to avoid overflows - -prstack_t pr_stack[MAX_STACK_DEPTH]; -int pr_depth; - -int localstack[LOCALSTACK_SIZE]; -int localstack_used; - - -qboolean pr_trace; -dfunction_t *pr_xfunction; -int pr_xstatement; - - -int pr_argc; - -char *pr_opnames[] = -{ -"DONE", - -"MUL_F", -"MUL_V", -"MUL_FV", -"MUL_VF", - -"DIV", - -"ADD_F", -"ADD_V", - -"SUB_F", -"SUB_V", - -"EQ_F", -"EQ_V", -"EQ_S", -"EQ_E", -"EQ_FNC", - -"NE_F", -"NE_V", -"NE_S", -"NE_E", -"NE_FNC", - -"LE", -"GE", -"LT", -"GT", - -"INDIRECT", -"INDIRECT", -"INDIRECT", -"INDIRECT", -"INDIRECT", -"INDIRECT", - -"ADDRESS", - -"STORE_F", -"STORE_V", -"STORE_S", -"STORE_ENT", -"STORE_FLD", -"STORE_FNC", - -"STOREP_F", -"STOREP_V", -"STOREP_S", -"STOREP_ENT", -"STOREP_FLD", -"STOREP_FNC", - -"RETURN", - -"NOT_F", -"NOT_V", -"NOT_S", -"NOT_ENT", -"NOT_FNC", - -"IF", -"IFNOT", - -"CALL0", -"CALL1", -"CALL2", -"CALL3", -"CALL4", -"CALL5", -"CALL6", -"CALL7", -"CALL8", - -"STATE", - -"GOTO", - -"AND", -"OR", - -"BITAND", -"BITOR" -}; - -char *PR_GlobalString (int ofs); -char *PR_GlobalStringNoContents (int ofs); - - -//============================================================================= - -/* -================= -PR_PrintStatement -================= -*/ -void PR_PrintStatement (dstatement_t *s) -{ - int i; - - if ( (unsigned)s->op < sizeof(pr_opnames)/sizeof(pr_opnames[0])) - { - Con_Printf ("%s ", pr_opnames[s->op]); - i = strlen(pr_opnames[s->op]); - for ( ; i<10 ; i++) - Con_Printf (" "); - } - - if (s->op == OP_IF || s->op == OP_IFNOT) - Con_Printf ("%sbranch %i",PR_GlobalString(s->a),s->b); - else if (s->op == OP_GOTO) - { - Con_Printf ("branch %i",s->a); - } - else if ( (unsigned)(s->op - OP_STORE_F) < 6) - { - Con_Printf ("%s",PR_GlobalString(s->a)); - Con_Printf ("%s", PR_GlobalStringNoContents(s->b)); - } - else - { - if (s->a) - Con_Printf ("%s",PR_GlobalString(s->a)); - if (s->b) - Con_Printf ("%s",PR_GlobalString(s->b)); - if (s->c) - Con_Printf ("%s", PR_GlobalStringNoContents(s->c)); - } - Con_Printf ("\n"); -} - -/* -============ -PR_StackTrace -============ -*/ -void PR_StackTrace (void) -{ - dfunction_t *f; - int i; - - if (pr_depth == 0) - { - Con_Printf ("\n"); - return; - } - - pr_stack[pr_depth].f = pr_xfunction; - for (i=pr_depth ; i>=0 ; i--) - { - f = pr_stack[i].f; - - if (!f) - { - Con_Printf ("\n"); - } - else - Con_Printf ("%12s : %s\n", PR_GetString(f->s_file), PR_GetString(f->s_name)); - } -} - - -/* -============ -PR_Profile_f - -============ -*/ -void PR_Profile_f (void) -{ - dfunction_t *f, *best; - int max; - int num; - int i; - - num = 0; - do - { - max = 0; - best = NULL; - for (i=0 ; inumfunctions ; i++) - { - f = &pr_functions[i]; - if (f->profile > max) - { - max = f->profile; - best = f; - } - } - if (best) - { - if (num < 10) - Con_Printf ("%7i %s\n", best->profile, PR_GetString(best->s_name)); - num++; - best->profile = 0; - } - } while (best); -} - - -/* -============ -PR_RunError - -Aborts the currently executing function -============ -*/ -void PR_RunError (char *error, ...) -{ - va_list argptr; - char string[1024]; - - va_start (argptr,error); - vsprintf (string,error,argptr); - va_end (argptr); - - PR_PrintStatement (pr_statements + pr_xstatement); - PR_StackTrace (); - Con_Printf ("%s\n", string); - - pr_depth = 0; // dump the stack so host_error can shutdown functions - - Host_Error ("Program error"); -} - -/* -============================================================================ -PR_ExecuteProgram - -The interpretation main loop -============================================================================ -*/ - -/* -==================== -PR_EnterFunction - -Returns the new program statement counter -==================== -*/ -int PR_EnterFunction (dfunction_t *f) -{ - int i, j, c, o; - - pr_stack[pr_depth].s = pr_xstatement; - pr_stack[pr_depth].f = pr_xfunction; - pr_depth++; - if (pr_depth >= MAX_STACK_DEPTH) - PR_RunError ("stack overflow"); - -// save off any locals that the new function steps on - c = f->locals; - if (localstack_used + c > LOCALSTACK_SIZE) - PR_RunError ("PR_ExecuteProgram: locals stack overflow\n"); - - for (i=0 ; i < c ; i++) - localstack[localstack_used+i] = ((int *)pr_globals)[f->parm_start + i]; - localstack_used += c; - -// copy parameters - o = f->parm_start; - for (i=0 ; inumparms ; i++) - { - for (j=0 ; jparm_size[i] ; j++) - { - ((int *)pr_globals)[o] = ((int *)pr_globals)[OFS_PARM0+i*3+j]; - o++; - } - } - - pr_xfunction = f; - return f->first_statement - 1; // offset the s++ -} - -/* -==================== -PR_LeaveFunction -==================== -*/ -int PR_LeaveFunction (void) -{ - int i, c; - - if (pr_depth <= 0) - Sys_Error ("prog stack underflow"); - -// restore locals from the stack - c = pr_xfunction->locals; - localstack_used -= c; - if (localstack_used < 0) - PR_RunError ("PR_ExecuteProgram: locals stack underflow\n"); - - for (i=0 ; i < c ; i++) - ((int *)pr_globals)[pr_xfunction->parm_start + i] = localstack[localstack_used+i]; - -// up stack - pr_depth--; - pr_xfunction = pr_stack[pr_depth].f; - return pr_stack[pr_depth].s; -} - - -/* -==================== -PR_ExecuteProgram -==================== -*/ -void PR_ExecuteProgram (func_t fnum) -{ - eval_t *a, *b, *c; - int s; - dstatement_t *st; - dfunction_t *f, *newf; - int runaway; - int i; - edict_t *ed; - int exitdepth; - eval_t *ptr; - - if (!fnum || fnum >= progs->numfunctions) - { - if (pr_global_struct->self) - ED_Print (PROG_TO_EDICT(pr_global_struct->self)); - Host_Error ("PR_ExecuteProgram: NULL function"); - } - - f = &pr_functions[fnum]; - - runaway = 100000; - pr_trace = false; - -// make a stack frame - exitdepth = pr_depth; - - s = PR_EnterFunction (f); - -while (1) -{ - s++; // next statement - - st = &pr_statements[s]; - a = (eval_t *)&pr_globals[(unsigned short)st->a]; - b = (eval_t *)&pr_globals[(unsigned short)st->b]; - c = (eval_t *)&pr_globals[(unsigned short)st->c]; - - if (!--runaway) - PR_RunError ("runaway loop error"); - - pr_xfunction->profile++; - pr_xstatement = s; - - if (pr_trace) - PR_PrintStatement (st); - - switch (st->op) - { - case OP_ADD_F: - c->_float = a->_float + b->_float; - break; - case OP_ADD_V: - c->vector[0] = a->vector[0] + b->vector[0]; - c->vector[1] = a->vector[1] + b->vector[1]; - c->vector[2] = a->vector[2] + b->vector[2]; - break; - - case OP_SUB_F: - c->_float = a->_float - b->_float; - break; - case OP_SUB_V: - c->vector[0] = a->vector[0] - b->vector[0]; - c->vector[1] = a->vector[1] - b->vector[1]; - c->vector[2] = a->vector[2] - b->vector[2]; - break; - - case OP_MUL_F: - c->_float = a->_float * b->_float; - break; - case OP_MUL_V: - c->_float = a->vector[0]*b->vector[0] - + a->vector[1]*b->vector[1] - + a->vector[2]*b->vector[2]; - break; - case OP_MUL_FV: - c->vector[0] = a->_float * b->vector[0]; - c->vector[1] = a->_float * b->vector[1]; - c->vector[2] = a->_float * b->vector[2]; - break; - case OP_MUL_VF: - c->vector[0] = b->_float * a->vector[0]; - c->vector[1] = b->_float * a->vector[1]; - c->vector[2] = b->_float * a->vector[2]; - break; - - case OP_DIV_F: - c->_float = a->_float / b->_float; - break; - - case OP_BITAND: - c->_float = (int)a->_float & (int)b->_float; - break; - - case OP_BITOR: - c->_float = (int)a->_float | (int)b->_float; - break; - - - case OP_GE: - c->_float = a->_float >= b->_float; - break; - case OP_LE: - c->_float = a->_float <= b->_float; - break; - case OP_GT: - c->_float = a->_float > b->_float; - break; - case OP_LT: - c->_float = a->_float < b->_float; - break; - case OP_AND: - c->_float = a->_float && b->_float; - break; - case OP_OR: - c->_float = a->_float || b->_float; - break; - - case OP_NOT_F: - c->_float = !a->_float; - break; - case OP_NOT_V: - c->_float = !a->vector[0] && !a->vector[1] && !a->vector[2]; - break; - case OP_NOT_S: - c->_float = !a->string || !*PR_GetString(a->string); - break; - case OP_NOT_FNC: - c->_float = !a->function; - break; - case OP_NOT_ENT: - c->_float = (PROG_TO_EDICT(a->edict) == sv.edicts); - break; - - case OP_EQ_F: - c->_float = a->_float == b->_float; - break; - case OP_EQ_V: - c->_float = (a->vector[0] == b->vector[0]) && - (a->vector[1] == b->vector[1]) && - (a->vector[2] == b->vector[2]); - break; - case OP_EQ_S: - c->_float = !strcmp(PR_GetString(a->string), PR_GetString(b->string)); - break; - case OP_EQ_E: - c->_float = a->_int == b->_int; - break; - case OP_EQ_FNC: - c->_float = a->function == b->function; - break; - - - case OP_NE_F: - c->_float = a->_float != b->_float; - break; - case OP_NE_V: - c->_float = (a->vector[0] != b->vector[0]) || - (a->vector[1] != b->vector[1]) || - (a->vector[2] != b->vector[2]); - break; - case OP_NE_S: - c->_float = strcmp(PR_GetString(a->string), PR_GetString(b->string)); - break; - case OP_NE_E: - c->_float = a->_int != b->_int; - break; - case OP_NE_FNC: - c->_float = a->function != b->function; - break; - -//================== - case OP_STORE_F: - case OP_STORE_ENT: - case OP_STORE_FLD: // integers - case OP_STORE_S: - case OP_STORE_FNC: // pointers - b->_int = a->_int; - break; - case OP_STORE_V: - b->vector[0] = a->vector[0]; - b->vector[1] = a->vector[1]; - b->vector[2] = a->vector[2]; - break; - - case OP_STOREP_F: - case OP_STOREP_ENT: - case OP_STOREP_FLD: // integers - case OP_STOREP_S: - case OP_STOREP_FNC: // pointers - ptr = (eval_t *)((byte *)sv.edicts + b->_int); - ptr->_int = a->_int; - break; - case OP_STOREP_V: - ptr = (eval_t *)((byte *)sv.edicts + b->_int); - ptr->vector[0] = a->vector[0]; - ptr->vector[1] = a->vector[1]; - ptr->vector[2] = a->vector[2]; - break; - - case OP_ADDRESS: - ed = PROG_TO_EDICT(a->edict); -#ifdef PARANOID - NUM_FOR_EDICT(ed); // make sure it's in range -#endif - if (ed == (edict_t *)sv.edicts && sv.state == ss_active) - PR_RunError ("assignment to world entity"); - c->_int = (byte *)((int *)&ed->v + b->_int) - (byte *)sv.edicts; - break; - - case OP_LOAD_F: - case OP_LOAD_FLD: - case OP_LOAD_ENT: - case OP_LOAD_S: - case OP_LOAD_FNC: - ed = PROG_TO_EDICT(a->edict); -#ifdef PARANOID - NUM_FOR_EDICT(ed); // make sure it's in range -#endif - a = (eval_t *)((int *)&ed->v + b->_int); - c->_int = a->_int; - break; - - case OP_LOAD_V: - ed = PROG_TO_EDICT(a->edict); -#ifdef PARANOID - NUM_FOR_EDICT(ed); // make sure it's in range -#endif - a = (eval_t *)((int *)&ed->v + b->_int); - c->vector[0] = a->vector[0]; - c->vector[1] = a->vector[1]; - c->vector[2] = a->vector[2]; - break; - -//================== - - case OP_IFNOT: - if (!a->_int) - s += st->b - 1; // offset the s++ - break; - - case OP_IF: - if (a->_int) - s += st->b - 1; // offset the s++ - break; - - case OP_GOTO: - s += st->a - 1; // offset the s++ - break; - - case OP_CALL0: - case OP_CALL1: - case OP_CALL2: - case OP_CALL3: - case OP_CALL4: - case OP_CALL5: - case OP_CALL6: - case OP_CALL7: - case OP_CALL8: - pr_argc = st->op - OP_CALL0; - if (!a->function) - PR_RunError ("NULL function"); - - newf = &pr_functions[a->function]; - - if (newf->first_statement < 0) - { // negative statements are built in functions - i = -newf->first_statement; - if (i >= pr_numbuiltins) - PR_RunError ("Bad builtin call number"); - pr_builtins[i] (); - break; - } - - s = PR_EnterFunction (newf); - break; - - case OP_DONE: - case OP_RETURN: - pr_globals[OFS_RETURN] = pr_globals[st->a]; - pr_globals[OFS_RETURN+1] = pr_globals[st->a+1]; - pr_globals[OFS_RETURN+2] = pr_globals[st->a+2]; - - s = PR_LeaveFunction (); - if (pr_depth == exitdepth) - return; // all done - break; - - case OP_STATE: - ed = PROG_TO_EDICT(pr_global_struct->self); -#ifdef FPS_20 - ed->v.nextthink = pr_global_struct->time + 0.05; -#else - ed->v.nextthink = pr_global_struct->time + 0.1; -#endif - if (a->_float != ed->v.frame) - { - ed->v.frame = a->_float; - } - ed->v.think = b->function; - break; - - default: - PR_RunError ("Bad opcode %i", st->op); - } -} - -} diff --git a/engine/code/progdefs.q2 b/engine/code/progdefs.q2 deleted file mode 100644 index dc7f3be..0000000 --- a/engine/code/progdefs.q2 +++ /dev/null @@ -1,158 +0,0 @@ - -/* file generated by qcc, do not modify */ - -typedef struct -{ int pad[28]; - int self; - int other; - int world; - float time; - float frametime; - float force_retouch; - string_t mapname; - string_t startspot; - float deathmatch; - float coop; - float teamplay; - float serverflags; - float total_secrets; - float total_monsters; - float found_secrets; - float killed_monsters; - float parm1; - float parm2; - float parm3; - float parm4; - float parm5; - float parm6; - float parm7; - float parm8; - float parm9; - float parm10; - float parm11; - float parm12; - float parm13; - float parm14; - float parm15; - float parm16; - vec3_t v_forward; - vec3_t v_up; - vec3_t v_right; - float trace_allsolid; - float trace_startsolid; - float trace_fraction; - vec3_t trace_endpos; - vec3_t trace_plane_normal; - float trace_plane_dist; - int trace_ent; - float trace_inopen; - float trace_inwater; - int msg_entity; - string_t null; - func_t main; - func_t StartFrame; - func_t PlayerPreThink; - func_t PlayerPostThink; - func_t ClientKill; - func_t ClientConnect; - func_t PutClientInServer; - func_t ClientDisconnect; - func_t SetNewParms; - func_t SetChangeParms; -} globalvars_t; - -typedef struct -{ - float modelindex; - vec3_t absmin; - vec3_t absmax; - float ltime; - float movetype; - float solid; - vec3_t origin; - vec3_t oldorigin; - vec3_t velocity; - vec3_t angles; - vec3_t avelocity; - vec3_t basevelocity; - vec3_t punchangle; - string_t classname; - string_t model; - float frame; - float skin; - float effects; - float drawPercent; - float gravity; - float mass; - float light_level; - vec3_t mins; - vec3_t maxs; - vec3_t size; - func_t touch; - func_t use; - func_t think; - func_t blocked; - float nextthink; - int groundentity; - float health; - float frags; - float weapon; - string_t weaponmodel; - float weaponframe; - float currentammo; - float ammo_shells; - float ammo_nails; - float ammo_rockets; - float ammo_cells; - float items; - float items2; - float takedamage; - int chain; - float deadflag; - vec3_t view_ofs; - float button0; - float button1; - float button2; - float impulse; - float fixangle; - vec3_t v_angle; - float idealpitch; - float pitch_speed; - string_t netname; - int enemy; - float flags; - float colormap; - float team; - float max_health; - float teleport_time; - float armortype; - float armorvalue; - float waterlevel; - float watertype; - float ideal_yaw; - float yaw_speed; - int aiment; - int goalentity; - float spawnflags; - string_t target; - string_t targetname; - float dmg_take; - float dmg_save; - int dmg_inflictor; - int owner; - vec3_t movedir; - string_t message; - float sounds; - string_t noise; - string_t noise1; - string_t noise2; - string_t noise3; - float dmg; - float dmgtime; - float air_finished; - float pain_finished; - float radsuit_finished; - float speed; -} entvars_t; - -#define PROGHEADER_CRC 31586 diff --git a/engine/code/progs.h b/engine/code/progs.h deleted file mode 100644 index 16693e1..0000000 --- a/engine/code/progs.h +++ /dev/null @@ -1,137 +0,0 @@ -/* -Copyright (C) 1996-1997 Id Software, Inc. - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ - -#include "pr_comp.h" // defs shared with qcc -#include "progdefs.h" // generated by program cdefs - -typedef union eval_s -{ - string_t string; - float _float; - float vector[3]; - func_t function; - int _int; - int edict; -} eval_t; - -#define MAX_ENT_LEAFS 16 -typedef struct edict_s -{ - qboolean free; - link_t area; // linked to a division node or leaf - - int num_leafs; - short leafnums[MAX_ENT_LEAFS]; - - entity_state_t baseline; - - float freetime; // sv.time when the object was freed - entvars_t v; // C exported fields from progs -// other fields from progs come immediately after -} edict_t; -#define EDICT_FROM_AREA(l) STRUCT_FROM_LINK(l,edict_t,area) - -//============================================================================ - -extern dprograms_t *progs; -extern dfunction_t *pr_functions; -extern ddef_t *pr_globaldefs; -extern ddef_t *pr_fielddefs; -extern dstatement_t *pr_statements; -extern globalvars_t *pr_global_struct; -extern float *pr_globals; // same as pr_global_struct - -extern int pr_edict_size; // in bytes - -//============================================================================ - -void PR_Init (void); - -void PR_ExecuteProgram (func_t fnum); -void PR_LoadProgs (void); - -char *PR_GetString (int num); -int PR_SetEngineString (char *s); -int PR_AllocString (int bufferlength, char **ptr); - -void PR_Profile_f (void); - -edict_t *ED_Alloc (void); -void ED_Free (edict_t *ed); - -string_t ED_NewString (char *string); -// returns a copy of the string allocated from the server's string heap - -void ED_Print (edict_t *ed); -void ED_Write (FILE *f, edict_t *ed); -char *ED_ParseEdict (char *data, edict_t *ent); - -void ED_WriteGlobals (FILE *f); -void ED_ParseGlobals (char *data); - -void ED_LoadFromFile (char *data); - -//define EDICT_NUM(n) ((edict_t *)(sv.edicts+ (n)*pr_edict_size)) -//define NUM_FOR_EDICT(e) (((byte *)(e) - sv.edicts)/pr_edict_size) - -edict_t *EDICT_NUM(int n); -int NUM_FOR_EDICT(edict_t *e); - -#define NEXT_EDICT(e) ((edict_t *)( (byte *)e + pr_edict_size)) - -#define EDICT_TO_PROG(e) ((byte *)e - (byte *)sv.edicts) -#define PROG_TO_EDICT(e) ((edict_t *)((byte *)sv.edicts + e)) - -//============================================================================ - -#define G_FLOAT(o) (pr_globals[o]) -#define G_INT(o) (*(int *)&pr_globals[o]) -#define G_EDICT(o) ((edict_t *)((byte *)sv.edicts+ *(int *)&pr_globals[o])) -#define G_EDICTNUM(o) NUM_FOR_EDICT(G_EDICT(o)) -#define G_VECTOR(o) (&pr_globals[o]) -#define G_STRING(o) (PR_GetString(*(string_t *)&pr_globals[o])) -#define G_FUNCTION(o) (*(func_t *)&pr_globals[o]) - -#define E_FLOAT(e,o) (((float*)&e->v)[o]) -#define E_INT(e,o) (*(int *)&((float*)&e->v)[o]) -#define E_VECTOR(e,o) (&((float*)&e->v)[o]) -#define E_STRING(e,o) (PR_GetString(*(string_t *)&((float*)&e->v)[o])) - -extern int type_size[8]; - -typedef void (*builtin_t) (void); -extern builtin_t *pr_builtins; -extern int pr_numbuiltins; - -extern int pr_argc; - -extern qboolean pr_trace; -extern dfunction_t *pr_xfunction; -extern int pr_xstatement; - -extern unsigned short pr_crc; - -void PR_RunError (char *error, ...); - -void ED_PrintEdicts (void); -void ED_PrintNum (int ent); - -eval_t *GetEdictFieldValue(edict_t *ed, char *field); - diff --git a/engine/code/protocol.h b/engine/code/protocol.h deleted file mode 100644 index e1390d9..0000000 --- a/engine/code/protocol.h +++ /dev/null @@ -1,173 +0,0 @@ -/* -Copyright (C) 1996-1997 Id Software, Inc. - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ -// protocol.h -- communications protocols - -#define PROTOCOL_VERSION 15 - -// if the high bit of the servercmd is set, the low bits are fast update flags: -#define U_MOREBITS (1<<0) -#define U_ORIGIN1 (1<<1) -#define U_ORIGIN2 (1<<2) -#define U_ORIGIN3 (1<<3) -#define U_ANGLE2 (1<<4) -#define U_NOLERP (1<<5) // don't interpolate movement -#define U_FRAME (1<<6) -#define U_SIGNAL (1<<7) // just differentiates from other updates - -// svc_update can pass all of the fast update bits, plus more -#define U_ANGLE1 (1<<8) -#define U_ANGLE3 (1<<9) -#define U_MODEL (1<<10) -#define U_COLORMAP (1<<11) -#define U_SKIN (1<<12) -#define U_EFFECTS (1<<13) -#define U_LONGENTITY (1<<14) - - -#define SU_VIEWHEIGHT (1<<0) -#define SU_IDEALPITCH (1<<1) -#define SU_PUNCH1 (1<<2) -#define SU_PUNCH2 (1<<3) -#define SU_PUNCH3 (1<<4) -#define SU_VELOCITY1 (1<<5) -#define SU_VELOCITY2 (1<<6) -#define SU_VELOCITY3 (1<<7) -//define SU_AIMENT (1<<8) AVAILABLE BIT -#define SU_ITEMS (1<<9) -#define SU_ONGROUND (1<<10) // no data follows, the bit is it -#define SU_INWATER (1<<11) // no data follows, the bit is it -#define SU_WEAPONFRAME (1<<12) -#define SU_ARMOR (1<<13) -#define SU_WEAPON (1<<14) - -// a sound with no channel is a local only sound -#define SND_VOLUME (1<<0) // a byte -#define SND_ATTENUATION (1<<1) // a byte -#define SND_LOOPING (1<<2) // a long - - -// defaults for clientinfo messages -#define DEFAULT_VIEWHEIGHT 22 - - -// game types sent by serverinfo -// these determine which intermission screen plays -#define GAME_COOP 0 -#define GAME_DEATHMATCH 1 - -//================== -// note that there are some defs.qc that mirror to these numbers -// also related to svc_strings[] in cl_parse -//================== - -// -// server to client -// -#define svc_bad 0 -#define svc_nop 1 -#define svc_disconnect 2 -#define svc_updatestat 3 // [byte] [long] -#define svc_version 4 // [long] server version -#define svc_setview 5 // [short] entity number -#define svc_sound 6 // -#define svc_time 7 // [float] server time -#define svc_print 8 // [string] null terminated string -#define svc_stufftext 9 // [string] stuffed into client's console buffer - // the string should be \n terminated -#define svc_setangle 10 // [angle3] set the view angle to this absolute value - -#define svc_serverinfo 11 // [long] version - // [string] signon string - // [string]..[0]model cache - // [string]...[0]sounds cache -#define svc_lightstyle 12 // [byte] [string] -#define svc_updatename 13 // [byte] [string] -#define svc_updatefrags 14 // [byte] [short] -#define svc_clientdata 15 // -#define svc_stopsound 16 // -#define svc_updatecolors 17 // [byte] [byte] -#define svc_particle 18 // [vec3] -#define svc_damage 19 - -#define svc_spawnstatic 20 -// svc_spawnbinary 21 -#define svc_spawnbaseline 22 - -#define svc_temp_entity 23 - -#define svc_setpause 24 // [byte] on / off -#define svc_signonnum 25 // [byte] used for the signon sequence - -#define svc_centerprint 26 // [string] to put in center of the screen - -#define svc_killedmonster 27 -#define svc_foundsecret 28 - -#define svc_spawnstaticsound 29 // [coord3] [byte] samp [byte] vol [byte] aten - -#define svc_intermission 30 // [string] music -#define svc_finale 31 // [string] music [string] text - -#define svc_cdtrack 32 // [byte] track [byte] looptrack -#define svc_sellscreen 33 - -#define svc_cutscene 34 - - -// jkrige - skybox -#define svc_skybox 35 // [string] name -// jkrige - skybox - - -// -// client to server -// -#define clc_bad 0 -#define clc_nop 1 -#define clc_disconnect 2 -#define clc_move 3 // [usercmd_t] -#define clc_stringcmd 4 // [string] message - - -// -// temp entity events -// -#define TE_SPIKE 0 -#define TE_SUPERSPIKE 1 -#define TE_GUNSHOT 2 -#define TE_EXPLOSION 3 -#define TE_TAREXPLOSION 4 -#define TE_LIGHTNING1 5 -#define TE_LIGHTNING2 6 -#define TE_WIZSPIKE 7 -#define TE_KNIGHTSPIKE 8 -#define TE_LIGHTNING3 9 -#define TE_LAVASPLASH 10 -#define TE_TELEPORT 11 -#define TE_EXPLOSION2 12 - -// PGM 01/21/97 -#define TE_BEAM 13 -// PGM 01/21/97 - -#ifdef QUAKE2 -#define TE_IMPLOSION 14 -#define TE_RAILTRAIL 15 -#endif diff --git a/engine/code/quake.bmp b/engine/code/quake.bmp deleted file mode 100644 index 1d53caf..0000000 Binary files a/engine/code/quake.bmp and /dev/null differ diff --git a/engine/code/quake.ico b/engine/code/quake.ico deleted file mode 100644 index 7f26d2c..0000000 Binary files a/engine/code/quake.ico and /dev/null differ diff --git a/engine/code/quakedef.h b/engine/code/quakedef.h deleted file mode 100644 index c15c4f7..0000000 --- a/engine/code/quakedef.h +++ /dev/null @@ -1,359 +0,0 @@ -/* -Copyright (C) 1996-1997 Id Software, Inc. - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ -// quakedef.h -- primary header for client - -//#define GLTEST // experimental stuff - -#define QUAKE_GAME // as opposed to utilities - -#define QUAKE_VERSION 1.13 // jkrige - new version -//#define VERSION 1.09 -//#define GLQUAKE_VERSION 1.00 -//#define D3DQUAKE_VERSION 0.01 -//#define WINQUAKE_VERSION 0.996 -#define LINUX_VERSION 1.30 -#define X11_VERSION 1.10 - -//define PARANOID // speed sapping error checking - -#ifdef QUAKE2 -#define GAMENAME "id1" // directory to look in by default -#else -#define GAMENAME "id1" -#endif - -#include -#include -#include -#include -#include -#include - -// jkrige - pack naming convention -#include -// jkrige - pack naming convention - -#if defined(_WIN32) && !defined(WINDED) - -#if defined(_M_IX86) -#define __i386__ 1 -#endif - -void VID_LockBuffer (void); -void VID_UnlockBuffer (void); - -#else - -#define VID_LockBuffer() -#define VID_UnlockBuffer() - -#endif - -#if defined __i386__ // && !defined __sun__ -#define id386 0 // jkrige - assembly removal (was 1) -#else -#define id386 0 -#endif - -#if id386 -#define UNALIGNED_OK 1 // set to 0 if unaligned accesses are not supported -#else -#define UNALIGNED_OK 0 -#endif - -// !!! if this is changed, it must be changed in d_ifacea.h too !!! -#define CACHE_SIZE 32 // used to align key data structures - -#define UNUSED(x) (x = x) // for pesky compiler / lint warnings - -//#define MINIMUM_MEMORY 0x550000 // jkrige - memory increase: 5 570 560 bytes -#define MINIMUM_MEMORY 0xAA0000 // jkrige - memory increase: 11 141 120 bytes -#define MINIMUM_MEMORY_LEVELPAK (MINIMUM_MEMORY + 0x100000) - -#define MAX_NUM_ARGVS 50 - -// up / down -#define PITCH 0 - -// left / right -#define YAW 1 - -// fall over -#define ROLL 2 - - -#define MAX_QPATH 64 // max length of a quake game pathname -#define MAX_OSPATH 128 // max length of a filesystem pathname - -// jkrige - pk3 file support -#define MAX_ZPATH 256 // max length of a filesystem pathname, which must include a terminating zero -// jkrige - pk3 file support - - -#define ON_EPSILON 0.1 // point on plane side epsilon - -#define MAX_MSGLEN 8000 // max length of a reliable message -#define MAX_DATAGRAM 1024 // max length of unreliable message - -// -// per-level limits -// -#define MAX_EDICTS 600 // FIXME: ouch! ouch! ouch! -#define MAX_LIGHTSTYLES 64 -#define MAX_MODELS 256 // these are sent over the net as bytes -#define MAX_SOUNDS 256 // so they cannot be blindly increased - -#define SAVEGAME_COMMENT_LENGTH 39 - -#define MAX_STYLESTRING 64 - -// -// stats are integers communicated to the client by the server -// -#define MAX_CL_STATS 32 -#define STAT_HEALTH 0 -#define STAT_FRAGS 1 -#define STAT_WEAPON 2 -#define STAT_AMMO 3 -#define STAT_ARMOR 4 -#define STAT_WEAPONFRAME 5 -#define STAT_SHELLS 6 -#define STAT_NAILS 7 -#define STAT_ROCKETS 8 -#define STAT_CELLS 9 -#define STAT_ACTIVEWEAPON 10 -#define STAT_TOTALSECRETS 11 -#define STAT_TOTALMONSTERS 12 -#define STAT_SECRETS 13 // bumped on client side by svc_foundsecret -#define STAT_MONSTERS 14 // bumped by svc_killedmonster - -// stock defines - -#define IT_SHOTGUN 1 -#define IT_SUPER_SHOTGUN 2 -#define IT_NAILGUN 4 -#define IT_SUPER_NAILGUN 8 -#define IT_GRENADE_LAUNCHER 16 -#define IT_ROCKET_LAUNCHER 32 -#define IT_LIGHTNING 64 -#define IT_SUPER_LIGHTNING 128 -#define IT_SHELLS 256 -#define IT_NAILS 512 -#define IT_ROCKETS 1024 -#define IT_CELLS 2048 -#define IT_AXE 4096 -#define IT_ARMOR1 8192 -#define IT_ARMOR2 16384 -#define IT_ARMOR3 32768 -#define IT_SUPERHEALTH 65536 -#define IT_KEY1 131072 -#define IT_KEY2 262144 -#define IT_INVISIBILITY 524288 -#define IT_INVULNERABILITY 1048576 -#define IT_SUIT 2097152 -#define IT_QUAD 4194304 -#define IT_SIGIL1 (1<<28) -#define IT_SIGIL2 (1<<29) -#define IT_SIGIL3 (1<<30) -#define IT_SIGIL4 (1<<31) - -//=========================================== -//rogue changed and added defines - -#define RIT_SHELLS 128 -#define RIT_NAILS 256 -#define RIT_ROCKETS 512 -#define RIT_CELLS 1024 -#define RIT_AXE 2048 -#define RIT_LAVA_NAILGUN 4096 -#define RIT_LAVA_SUPER_NAILGUN 8192 -#define RIT_MULTI_GRENADE 16384 -#define RIT_MULTI_ROCKET 32768 -#define RIT_PLASMA_GUN 65536 -#define RIT_ARMOR1 8388608 -#define RIT_ARMOR2 16777216 -#define RIT_ARMOR3 33554432 -#define RIT_LAVA_NAILS 67108864 -#define RIT_PLASMA_AMMO 134217728 -#define RIT_MULTI_ROCKETS 268435456 -#define RIT_SHIELD 536870912 -#define RIT_ANTIGRAV 1073741824 -#define RIT_SUPERHEALTH 2147483648 - -//MED 01/04/97 added hipnotic defines -//=========================================== -//hipnotic added defines -#define HIT_PROXIMITY_GUN_BIT 16 -#define HIT_MJOLNIR_BIT 7 -#define HIT_LASER_CANNON_BIT 23 -#define HIT_PROXIMITY_GUN (1<channels - 1); - Con_Printf("%5d samples\n", shm->samples); - Con_Printf("%5d samplepos\n", shm->samplepos); - Con_Printf("%5d samplebits\n", shm->samplebits); - Con_Printf("%5d submission_chunk\n", shm->submission_chunk); - Con_Printf("%5d speed\n", shm->speed); - Con_Printf("0x%x dma buffer\n", shm->buffer); - Con_Printf("%5d total_channels\n", total_channels); -} - - -/* -================ -S_Startup -================ -*/ - -void S_Startup (void) -{ - int rc; - - if (!snd_initialized) - return; - - if (!fakedma) - { - rc = SNDDMA_Init(); - - if (!rc) - { -#ifndef _WIN32 - Con_Printf("S_Startup: SNDDMA_Init failed.\n"); -#endif - sound_started = 0; - return; - } - } - - sound_started = 1; -} - - -/* -================ -S_Init -================ -*/ -void S_Init (void) -{ - //Con_Printf("\nSound Initialization\n"); - Con_Printf("\n-------- Sound Initialization --------\n"); - - if (COM_CheckParm("-nosound")) - return; - - if (COM_CheckParm("-simsound")) - fakedma = true; - - Cmd_AddCommand("play", S_Play); - Cmd_AddCommand("playvol", S_PlayVol); - Cmd_AddCommand("stopsound", S_StopAllSoundsC); - Cmd_AddCommand("soundlist", S_SoundList); - Cmd_AddCommand("soundinfo", S_SoundInfo_f); - - Cvar_RegisterVariable(&nosound); - Cvar_RegisterVariable(&volume); - Cvar_RegisterVariable(&precache); - Cvar_RegisterVariable(&loadas8bit); - Cvar_RegisterVariable(&bgmvolume); - Cvar_RegisterVariable(&bgmbuffer); - Cvar_RegisterVariable(&ambient_level); - Cvar_RegisterVariable(&ambient_fade); - Cvar_RegisterVariable(&snd_noextraupdate); - Cvar_RegisterVariable(&snd_show); - Cvar_RegisterVariable(&_snd_mixahead); - - if (host_parms.memsize < 0x800000) - { - Cvar_Set ("loadas8bit", "1"); - Con_Printf ("loading all sounds as 8bit\n"); - } - - - - snd_initialized = true; - - S_Startup (); - - SND_InitScaletable (); - - known_sfx = Hunk_AllocName (MAX_SFX*sizeof(sfx_t), "sfx_t"); - num_sfx = 0; - -// create a piece of DMA memory - - if (fakedma) - { - shm = (void *) Hunk_AllocName(sizeof(*shm), "shm"); - shm->splitbuffer = 0; - shm->samplebits = 16; - shm->speed = 22050; - shm->channels = 2; - shm->samples = 32768; - shm->samplepos = 0; - shm->soundalive = true; - shm->gamealive = true; - shm->submission_chunk = 1; - shm->buffer = Hunk_AllocName(1<<16, "shmbuf"); - } - - Con_Printf ("Sound sampling rate: %i\n", shm->speed); - - // provides a tick sound until washed clean - -// if (shm->buffer) -// shm->buffer[4] = shm->buffer[5] = 0x7f; // force a pop for debugging - - ambient_sfx[AMBIENT_WATER] = S_PrecacheSound ("ambience/water1.wav"); - ambient_sfx[AMBIENT_SKY] = S_PrecacheSound ("ambience/wind2.wav"); - - S_StopAllSounds (true); - - // jkrige - fmod sound system - begin -#ifdef UQE_FMOD - FMOD_Init(); -#else - CDAudio_Init(); -#endif - // jkrige - fmod sound system - end - - Con_Printf("--------------------------------------\n"); -} - - -// ======================================================================= -// Shutdown sound engine -// ======================================================================= - -void S_Shutdown(void) -{ - - if (!sound_started) - return; - - if (shm) - shm->gamealive = 0; - - shm = 0; - sound_started = 0; - - if (!fakedma) - { - SNDDMA_Shutdown(); - } -} - - -// ======================================================================= -// Load a sound -// ======================================================================= - -/* -================== -S_FindName - -================== -*/ -sfx_t *S_FindName (char *name) -{ - int i; - sfx_t *sfx; - - if (!name) - Sys_Error ("S_FindName: NULL\n"); - - if (Q_strlen(name) >= MAX_QPATH) - Sys_Error ("Sound name too long: %s", name); - -// see if already loaded - for (i=0 ; i < num_sfx ; i++) - if (!Q_strcmp(known_sfx[i].name, name)) - { - return &known_sfx[i]; - } - - if (num_sfx == MAX_SFX) - Sys_Error ("S_FindName: out of sfx_t"); - - sfx = &known_sfx[i]; - strcpy (sfx->name, name); - - num_sfx++; - - return sfx; -} - - -/* -================== -S_TouchSound - -================== -*/ -void S_TouchSound (char *name) -{ - sfx_t *sfx; - - if (!sound_started) - return; - - sfx = S_FindName (name); - Cache_Check (&sfx->cache); -} - -/* -================== -S_PrecacheSound - -================== -*/ -sfx_t *S_PrecacheSound (char *name) -{ - sfx_t *sfx; - - if (!sound_started || nosound.value) - return NULL; - - sfx = S_FindName (name); - -// cache it in - if (precache.value) - S_LoadSound (sfx); - - return sfx; -} - - -//============================================================================= - -/* -================= -SND_PickChannel -================= -*/ -channel_t *SND_PickChannel(int entnum, int entchannel) -{ - int ch_idx; - int first_to_die; - int life_left; - -// Check for replacement sound, or find the best one to replace - first_to_die = -1; - life_left = 0x7fffffff; - for (ch_idx=NUM_AMBIENTS ; ch_idx < NUM_AMBIENTS + MAX_DYNAMIC_CHANNELS ; ch_idx++) - { - if (entchannel != 0 // channel 0 never overrides - && channels[ch_idx].entnum == entnum - && (channels[ch_idx].entchannel == entchannel || entchannel == -1) ) - { // allways override sound from same entity - first_to_die = ch_idx; - break; - } - - // don't let monster sounds override player sounds - if (channels[ch_idx].entnum == cl.viewentity && entnum != cl.viewentity && channels[ch_idx].sfx) - continue; - - if (channels[ch_idx].end - paintedtime < life_left) - { - life_left = channels[ch_idx].end - paintedtime; - first_to_die = ch_idx; - } - } - - if (first_to_die == -1) - return NULL; - - if (channels[first_to_die].sfx) - channels[first_to_die].sfx = NULL; - - return &channels[first_to_die]; -} - -/* -================= -SND_Spatialize -================= -*/ -void SND_Spatialize(channel_t *ch) -{ - vec_t dot; - vec_t ldist, rdist, dist; - vec_t lscale, rscale, scale; - vec3_t source_vec; - sfx_t *snd; - -// anything coming from the view entity will allways be full volume - if (ch->entnum == cl.viewentity) - { - ch->leftvol = ch->master_vol; - ch->rightvol = ch->master_vol; - return; - } - -// calculate stereo seperation and distance attenuation - - snd = ch->sfx; - VectorSubtract(ch->origin, listener_origin, source_vec); - - dist = VectorNormalize(source_vec) * ch->dist_mult; - - dot = DotProduct(listener_right, source_vec); - - if (shm->channels == 1) - { - rscale = 1.0; - lscale = 1.0; - } - else - { - rscale = 1.0 + dot; - lscale = 1.0 - dot; - } - -// add in distance effect - scale = (1.0 - dist) * rscale; - ch->rightvol = (int) (ch->master_vol * scale); - if (ch->rightvol < 0) - ch->rightvol = 0; - - scale = (1.0 - dist) * lscale; - ch->leftvol = (int) (ch->master_vol * scale); - if (ch->leftvol < 0) - ch->leftvol = 0; -} - - -// ======================================================================= -// Start a sound effect -// ======================================================================= - -void S_StartSound(int entnum, int entchannel, sfx_t *sfx, vec3_t origin, float fvol, float attenuation) -{ - channel_t *target_chan, *check; - sfxcache_t *sc; - int vol; - int ch_idx; - int skip; - - if (!sound_started) - return; - - if (!sfx) - return; - - if (nosound.value) - return; - - vol = fvol*255; - -// pick a channel to play on - target_chan = SND_PickChannel(entnum, entchannel); - if (!target_chan) - return; - -// spatialize - memset (target_chan, 0, sizeof(*target_chan)); - VectorCopy(origin, target_chan->origin); - target_chan->dist_mult = attenuation / sound_nominal_clip_dist; - target_chan->master_vol = vol; - target_chan->entnum = entnum; - target_chan->entchannel = entchannel; - SND_Spatialize(target_chan); - - if (!target_chan->leftvol && !target_chan->rightvol) - return; // not audible at all - -// new channel - sc = S_LoadSound (sfx); - if (!sc) - { - target_chan->sfx = NULL; - return; // couldn't load the sound's data - } - - target_chan->sfx = sfx; - target_chan->pos = 0.0; - target_chan->end = paintedtime + sc->length; - -// if an identical sound has also been started this frame, offset the pos -// a bit to keep it from just making the first one louder - check = &channels[NUM_AMBIENTS]; - for (ch_idx=NUM_AMBIENTS ; ch_idx < NUM_AMBIENTS + MAX_DYNAMIC_CHANNELS ; ch_idx++, check++) - { - if (check == target_chan) - continue; - if (check->sfx == sfx && !check->pos) - { - skip = rand () % (int)(0.1*shm->speed); - if (skip >= target_chan->end) - skip = target_chan->end - 1; - target_chan->pos += skip; - target_chan->end -= skip; - break; - } - - } -} - -void S_StopSound(int entnum, int entchannel) -{ - int i; - - for (i=0 ; ibuffer && !pDSBuf)) -#else - if (!sound_started || !shm || !shm->buffer) -#endif - return; - - if (shm->samplebits == 8) - clear = 0x80; - else - clear = 0; - -#ifdef _WIN32 - if (pDSBuf) - { - DWORD dwSize; - DWORD *pData; - int reps; - HRESULT hresult; - - reps = 0; - - while ((hresult = pDSBuf->lpVtbl->Lock(pDSBuf, 0, gSndBufSize, &pData, &dwSize, NULL, NULL, 0)) != DS_OK) - { - if (hresult != DSERR_BUFFERLOST) - { - Con_Printf ("S_ClearBuffer: DS::Lock Sound Buffer Failed\n"); - S_Shutdown (); - return; - } - - if (++reps > 10000) - { - Con_Printf ("S_ClearBuffer: DS: couldn't restore buffer\n"); - S_Shutdown (); - return; - } - } - - Q_memset(pData, clear, shm->samples * shm->samplebits/8); - - pDSBuf->lpVtbl->Unlock(pDSBuf, pData, dwSize, NULL, 0); - - } - else -#endif - { - Q_memset(shm->buffer, clear, shm->samples * shm->samplebits/8); - } -} - - -/* -================= -S_StaticSound -================= -*/ -void S_StaticSound (sfx_t *sfx, vec3_t origin, float vol, float attenuation) -{ - channel_t *ss; - sfxcache_t *sc; - - if (!sfx) - return; - - if (total_channels == MAX_CHANNELS) - { - Con_Printf ("total_channels == MAX_CHANNELS\n"); - return; - } - - ss = &channels[total_channels]; - total_channels++; - - sc = S_LoadSound (sfx); - if (!sc) - return; - - if (sc->loopstart == -1) - { - Con_Printf ("Sound %s not looped\n", sfx->name); - return; - } - - ss->sfx = sfx; - VectorCopy (origin, ss->origin); - ss->master_vol = vol; - ss->dist_mult = (attenuation/64) / sound_nominal_clip_dist; - ss->end = paintedtime + sc->length; - - SND_Spatialize (ss); -} - - -//============================================================================= - -/* -=================== -S_UpdateAmbientSounds -=================== -*/ -void S_UpdateAmbientSounds (void) -{ - mleaf_t *l; - float vol; - int ambient_channel; - channel_t *chan; - - if (!snd_ambient) - return; - -// calc ambient sound levels - if (!cl.worldmodel) - return; - - l = Mod_PointInLeaf (listener_origin, cl.worldmodel); - if (!l || !ambient_level.value) - { - for (ambient_channel = 0 ; ambient_channel< NUM_AMBIENTS ; ambient_channel++) - channels[ambient_channel].sfx = NULL; - return; - } - - for (ambient_channel = 0 ; ambient_channel< NUM_AMBIENTS ; ambient_channel++) - { - chan = &channels[ambient_channel]; - chan->sfx = ambient_sfx[ambient_channel]; - - vol = ambient_level.value * l->ambient_sound_level[ambient_channel]; - if (vol < 8) - vol = 0; - - // don't adjust volume too fast - if (chan->master_vol < vol) - { - chan->master_vol += host_frametime * ambient_fade.value; - if (chan->master_vol > vol) - chan->master_vol = vol; - } - else if (chan->master_vol > vol) - { - chan->master_vol -= host_frametime * ambient_fade.value; - if (chan->master_vol < vol) - chan->master_vol = vol; - } - - chan->leftvol = chan->rightvol = chan->master_vol; - } -} - - -/* -============ -S_Update - -Called once each time through the main loop -============ -*/ -void S_Update(vec3_t origin, vec3_t forward, vec3_t right, vec3_t up) -{ - int i, j; - int total; - channel_t *ch; - channel_t *combine; - - if (!sound_started || (snd_blocked > 0)) - return; - - VectorCopy(origin, listener_origin); - VectorCopy(forward, listener_forward); - VectorCopy(right, listener_right); - VectorCopy(up, listener_up); - -// update general area ambient sound sources - S_UpdateAmbientSounds (); - - combine = NULL; - -// update spatialization for static and dynamic sounds - ch = channels+NUM_AMBIENTS; - for (i=NUM_AMBIENTS ; isfx) - continue; - SND_Spatialize(ch); // respatialize channel - if (!ch->leftvol && !ch->rightvol) - continue; - - // try to combine static sounds with a previous channel of the same - // sound effect so we don't mix five torches every frame - - if (i >= MAX_DYNAMIC_CHANNELS + NUM_AMBIENTS) - { - // see if it can just use the last one - if (combine && combine->sfx == ch->sfx) - { - combine->leftvol += ch->leftvol; - combine->rightvol += ch->rightvol; - ch->leftvol = ch->rightvol = 0; - continue; - } - // search for one - combine = channels+MAX_DYNAMIC_CHANNELS + NUM_AMBIENTS; - for (j=MAX_DYNAMIC_CHANNELS + NUM_AMBIENTS ; jsfx == ch->sfx) - break; - - if (j == total_channels) - { - combine = NULL; - } - else - { - if (combine != ch) - { - combine->leftvol += ch->leftvol; - combine->rightvol += ch->rightvol; - ch->leftvol = ch->rightvol = 0; - } - continue; - } - } - - - } - -// -// debugging output -// - if (snd_show.value) - { - total = 0; - ch = channels; - for (i=0 ; isfx && (ch->leftvol || ch->rightvol) ) - { - //Con_Printf ("%3i %3i %s\n", ch->leftvol, ch->rightvol, ch->sfx->name); - total++; - } - - Con_Printf ("----(%i)----\n", total); - } - -// mix some sound - S_Update_(); -} - -void GetSoundtime(void) -{ - int samplepos; - static int buffers; - static int oldsamplepos; - int fullsamples; - - fullsamples = shm->samples / shm->channels; - -// it is possible to miscount buffers if it has wrapped twice between -// calls to S_Update. Oh well. -#ifdef __sun__ - soundtime = SNDDMA_GetSamples(); -#else - samplepos = SNDDMA_GetDMAPos(); - - - if (samplepos < oldsamplepos) - { - buffers++; // buffer wrapped - - if (paintedtime > 0x40000000) - { // time to chop things off to avoid 32 bit limits - buffers = 0; - paintedtime = fullsamples; - S_StopAllSounds (true); - } - } - oldsamplepos = samplepos; - - soundtime = buffers*fullsamples + samplepos/shm->channels; -#endif -} - -void S_ExtraUpdate (void) -{ - -#ifdef _WIN32 - IN_Accumulate (); -#endif - - if (snd_noextraupdate.value) - return; // don't pollute timings - S_Update_(); -} - -void S_Update_(void) -{ - unsigned endtime; - int samps; - - if (!sound_started || (snd_blocked > 0)) - return; - -// Updates DMA time - GetSoundtime(); - -// check to make sure that we haven't overshot - if (paintedtime < soundtime) - { - //Con_Printf ("S_Update_ : overflow\n"); - paintedtime = soundtime; - } - -// mix ahead of current position - endtime = soundtime + _snd_mixahead.value * shm->speed; - samps = shm->samples >> (shm->channels-1); - if (endtime - soundtime > samps) - endtime = soundtime + samps; - -#ifdef _WIN32 -// if the buffer was lost or stopped, restore it and/or restart it - { - DWORD dwStatus; - - if (pDSBuf) - { - if (pDSBuf->lpVtbl->GetStatus (pDSBuf, &dwStatus) != DD_OK) - Con_Printf ("Couldn't get sound buffer status\n"); - - if (dwStatus & DSBSTATUS_BUFFERLOST) - pDSBuf->lpVtbl->Restore (pDSBuf); - - if (!(dwStatus & DSBSTATUS_PLAYING)) - pDSBuf->lpVtbl->Play(pDSBuf, 0, 0, DSBPLAY_LOOPING); - } - } -#endif - - S_PaintChannels (endtime); - - SNDDMA_Submit (); -} - -/* -=============================================================================== - -console functions - -=============================================================================== -*/ - -void S_Play(void) -{ - static int hash=345; - int i; - char name[256]; - sfx_t *sfx; - - i = 1; - while (icache); - if (!sc) - continue; - size = sc->length*sc->width*(sc->stereo+1); - total += size; - if (sc->loopstart >= 0) - Con_Printf ("L"); - else - Con_Printf (" "); - Con_Printf("(%2db) %6i : %s\n",sc->width*8, size, sfx->name); - } - Con_Printf ("Total resident: %i\n", total); -} - - -void S_LocalSound (char *sound) -{ - sfx_t *sfx; - - if (nosound.value) - return; - if (!sound_started) - return; - - sfx = S_PrecacheSound (sound); - if (!sfx) - { - Con_Printf ("S_LocalSound: can't cache %s\n", sound); - return; - } - S_StartSound (cl.viewentity, -1, sfx, vec3_origin, 1, 1); -} - - -void S_ClearPrecache (void) -{ -} - - -void S_BeginPrecaching (void) -{ -} - - -void S_EndPrecaching (void) -{ -} - diff --git a/engine/code/snd_fmod.c b/engine/code/snd_fmod.c deleted file mode 100644 index 525949c..0000000 --- a/engine/code/snd_fmod.c +++ /dev/null @@ -1,730 +0,0 @@ -/* -Copyright (C) 1996-1997 Id Software, Inc. - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ -// snd_fmod.c: FMOD sound system implementation for music playback - -// Developed by Jacques Krige -// Ultimate Quake Engine -// http://www.jacqueskrige.com - - -#include "quakedef.h" - - -#ifdef _WIN32 -#include "winquake.h" -#endif - -#ifdef UQE_FMOD - -#include "../fmodcore/inc/fmod.h" -#include "../fmodcore/inc/fmod_errors.h" - -extern int sound_started; - -typedef struct -{ - void *data; - int length; - char filename[MAX_QPATH]; -} SND_File_t; - -typedef struct -{ - float volume; - FMOD_CHANNEL *channel; - int track; - char trackname[MAX_QPATH]; - qboolean inuse; - qboolean looping; - int loopcount; - qboolean paused; -} SND_Channel_t; - - -SND_File_t SND_File; -SND_Channel_t SND_MusicChannel; - -FMOD_SYSTEM *fmod_system; -FMOD_SOUND *fmod_sound; - -FMOD_CHANNELGROUP *musicChannelGroup; -FMOD_CHANNELGROUP *sfxChannelGroup; - -FMOD_RESULT fmod_result; - -qboolean SND_Initialised; - -int oldtrack; -float oldbgmvolume; - - -// forward declarations -void FMOD_Restart (void); -void FMOD_MusicStartConsole (void); -void FMOD_MusicUpdate (void); - - - -// =================================================================================== -// -// CUSTOM FMOD FILE ROUTINES TO ALLOW PAK FILE ACCESS -// -// =================================================================================== - -/* -=================== -SND_FOpen -=================== -*/ -qboolean SND_FOpen (const char *name) -{ - int len; - FILE *f; - - if ((len = COM_FOpenFile((char *)name, &f)) < 1) - { - Con_Printf("SND_FOpen: Failed to open %s, file not found\n", name); - return false; - } - - if (!SND_File.length) - { - strcpy(SND_File.filename, name); - SND_File.length = len; - SND_File.data = COM_FReadFile(f, len); - Con_DPrintf("SND_FOpen: Sucessfully opened %s\n", name); - - return true; - } - - if (f) - fclose(f); - - f = NULL; - - Con_SafePrintf("SND_FOpen: Failed to open %s, insufficient handles\n", name); - - return false; -} - -/* -=================== -SND_FClose -=================== -*/ -void SND_FClose (void) -{ - if (!SND_File.data) - return; - - SND_File.length = 0; - strcpy(SND_File.filename, "\0"); - - if (SND_File.data) - free(SND_File.data); - - SND_File.data = NULL; -} - - - -// =================================================================================== -// -// STARTUP AND SHUTDOWN ROUTINES -// -// =================================================================================== - -/* -=================== -FMOD_ERROR -=================== -*/ -void FMOD_ERROR(FMOD_RESULT result, qboolean notify, qboolean syserror) -{ - if (result != FMOD_OK) - { - if (syserror) - Sys_Error("FMOD: %s\n", FMOD_ErrorString(result)); - else if (notify) - Con_Printf("%s\n", FMOD_ErrorString(result)); - } -} - -/* -=================== -FMOD_Startup -=================== -*/ -void FMOD_Startup (void) -{ - FMOD_SPEAKERMODE speakermode; - FMOD_OUTPUTTYPE fmod_output; - unsigned int version; - int numdrivers; - char name[256]; - int SND_SoftwareChannels; - int SND_Rate; - - if (!fmod_system) - { - Con_Printf("FMOD System not set up!"); - return; - } - - fmod_result = FMOD_System_GetVersion(fmod_system, &version); - FMOD_ERROR(fmod_result, true, false); - - if (version < FMOD_VERSION) - { - Con_Printf("\nFMOD version incorrect, found v%1.2f, requires v%1.2f or newer\n", version, FMOD_VERSION); - return; - } - - fmod_result = FMOD_System_GetSoftwareChannels(fmod_system, &SND_SoftwareChannels); - FMOD_ERROR(fmod_result, true, false); - - fmod_result = FMOD_System_GetSoftwareFormat(fmod_system, &SND_Rate, &speakermode, NULL); - FMOD_ERROR(fmod_result, true, false); - - fmod_result = FMOD_System_GetOutput(fmod_system, &fmod_output); - FMOD_ERROR(fmod_result, true, false); - - fmod_result = FMOD_System_CreateChannelGroup(fmod_system, "Music", &musicChannelGroup); - FMOD_ERROR(fmod_result, true, false); - - fmod_result = FMOD_System_CreateChannelGroup(fmod_system, "SFX", &sfxChannelGroup); - FMOD_ERROR(fmod_result, true, false); - - // print all the sound information to the console - Con_Printf("\nFMOD version %01x.%02x.%02x\n", (FMOD_VERSION >> 16) & 0xff, (FMOD_VERSION >> 8) & 0xff, FMOD_VERSION & 0xff); - - switch (fmod_output) - { - case FMOD_OUTPUTTYPE_NOSOUND: - Con_Printf("using No Sound\n"); - break; - - case FMOD_OUTPUTTYPE_WASAPI: - Con_Printf("using Windows Audio Session API\n"); - break; - - case FMOD_OUTPUTTYPE_ASIO: - Con_Printf("using Low latency ASIO\n"); - break; - } - - Con_Printf(" software channels: %i\n", SND_SoftwareChannels); - Con_Printf(" %i bytes/sec\n", SND_Rate); - - switch (speakermode) - { - case FMOD_SPEAKERMODE_RAW: - Con_Printf("Speaker Output: Raw\n"); - break; - - case FMOD_SPEAKERMODE_MONO: - Con_Printf("Speaker Output: Mono\n"); - break; - - case FMOD_SPEAKERMODE_STEREO: - Con_Printf("Speaker Output: Stereo\n"); - break; - - case FMOD_SPEAKERMODE_QUAD: - Con_Printf("Speaker Output: Quad\n"); - break; - - case FMOD_SPEAKERMODE_SURROUND: - Con_Printf("Speaker Output: Surround\n"); - break; - - case FMOD_SPEAKERMODE_5POINT1: - Con_Printf("Speaker Output: 5.1\n"); - break; - - case FMOD_SPEAKERMODE_7POINT1: - Con_Printf("Speaker Output: 7.1\n"); - break; - - default: - Con_Printf("Speaker Output: Unknown\n"); - } - - oldbgmvolume = bgmvolume.value; - - SND_FClose(); - - SND_Initialised = true; - - // clear music channel - memset(&SND_MusicChannel, 0, sizeof(SND_Channel_t)); -} - -/* -=================== -FMOD_Shutdown -=================== -*/ -void FMOD_Shutdown(void) -{ - if (COM_CheckParm("-nosound")) - { - SND_Initialised = false; - return; - } - - FMOD_MusicStop(); - - SND_Initialised = false; - - // clear music channel - memset(&SND_MusicChannel, 0, sizeof(SND_Channel_t)); -} - -/* -=================== -FMOD_Init -=================== -*/ -void FMOD_Init (void) -{ - SND_Initialised = false; - - if (!sound_started) - return; - - if (COM_CheckParm("-nosound")) - return; - - FMOD_Startup(); - - Cmd_AddCommand("fmod_restart", FMOD_Restart); - Cmd_AddCommand("fmod_playmusic", FMOD_MusicStartConsole); - Cmd_AddCommand("fmod_stopmusic", FMOD_MusicStop); - Cmd_AddCommand("fmod_pausemusic", FMOD_MusicPause); - Cmd_AddCommand("fmod_resumemusic", FMOD_MusicResume); - - //Con_Printf("--------------------------------------\n"); -} - -/* -=================== -FMOD_Restart -=================== -*/ -void FMOD_Restart (void) -{ - int current_track; - char current_trackname[MAX_QPATH]; - qboolean current_inuse; - qboolean current_looping; - - if (!sound_started) - return; - - if (COM_CheckParm("-nosound")) - { - SND_Initialised = false; - return; - } - - current_inuse = SND_MusicChannel.inuse; - - // save music info - if (SND_MusicChannel.inuse == true) - { - current_track = SND_MusicChannel.track; - strcpy(current_trackname, SND_MusicChannel.trackname); - current_looping = SND_MusicChannel.looping; - FMOD_MusicStop(); - } - else - { - current_track = 0; - strcpy(current_trackname, "\0"); - current_looping = false; - } - - FMOD_Shutdown(); - FMOD_Startup(); - - // restart music if needed - if (current_inuse == true) - { - if(current_track > 0) - FMOD_MusicStart(va("%i", (int)current_track), current_looping, false); - else - FMOD_MusicStart(current_trackname, current_looping, false); - } -} - -/* -=================== -FMOD_ChannelStart -=================== -*/ -void FMOD_ChannelStart (FMOD_SOUND *sound, qboolean loop, qboolean paused) -{ - fmod_result = FMOD_System_PlaySound(fmod_system, sound, musicChannelGroup, (FMOD_BOOL)paused, &SND_MusicChannel.channel); - FMOD_ERROR(fmod_result, true, false); - - if ((SND_MusicChannel.looping = loop) == true) - { - fmod_result = FMOD_Channel_SetMode(SND_MusicChannel.channel, FMOD_LOOP_NORMAL); - FMOD_ERROR(fmod_result, true, false); - } - else - { - fmod_result = FMOD_Channel_SetMode(SND_MusicChannel.channel, FMOD_LOOP_OFF); - FMOD_ERROR(fmod_result, true, false); - - fmod_result = FMOD_Channel_SetLoopCount(SND_MusicChannel.channel, 0); - FMOD_ERROR(fmod_result, true, false); - } - - SND_MusicChannel.inuse = true; -} - -// =================================================================================== -// -// MOD AUDIO CONTROL ROUTINES (OGG / MP3 / WAV) -// -// =================================================================================== - -/* -=================== -MOD_Start -=================== -*/ -void MOD_Start (char *name, qboolean loop, qboolean notify) -{ - char file[MAX_QPATH]; - FMOD_CREATESOUNDEXINFO exinfo; - - if (SND_Initialised == false) - return; - - if (SND_MusicChannel.inuse == true) - FMOD_MusicStop(); - - if (strlen(name) == 0) - return; - - if (SND_FOpen(name) == true) - { - memset(&exinfo, 0, sizeof(FMOD_CREATESOUNDEXINFO)); - exinfo.cbsize = sizeof(FMOD_CREATESOUNDEXINFO); - exinfo.length = SND_File.length; - - fmod_result = FMOD_System_CreateSound(fmod_system, (const char *)SND_File.data, FMOD_OPENMEMORY | FMOD_2D, &exinfo, &fmod_sound); - FMOD_ERROR(fmod_result, true, false); - - strcpy(file, SND_File.filename); - SND_FClose(); - } - - if (!fmod_sound) - { - Con_Printf("Couldn't open stream %s\n", file); - return; - } - else - { - if (notify == true) - Con_Printf("Playing: %s...\n", file); - } - - if (fmod_result == FMOD_OK) - FMOD_ChannelStart(fmod_sound, loop, false); -} - -/* -=================== -MOD_Stop -=================== -*/ -void MOD_Stop (void) -{ - if (SND_Initialised == false || SND_MusicChannel.inuse == false) - return; - - if (SND_MusicChannel.channel) - { - fmod_result = FMOD_Channel_Stop(SND_MusicChannel.channel); - FMOD_ERROR(fmod_result, true, false); - } - - if (fmod_sound) - { - fmod_result = FMOD_Sound_Release(fmod_sound); - FMOD_ERROR(fmod_result, true, false); - - fmod_sound = NULL; - } - - SND_MusicChannel.inuse = false; - SND_MusicChannel.looping = false; - SND_MusicChannel.loopcount = 0; - SND_MusicChannel.paused = false; -} - -/* -=================== -MOD_Pause -=================== -*/ -void MOD_Pause (void) -{ - if (SND_Initialised == false || SND_MusicChannel.inuse == false) - return; - - if (SND_MusicChannel.paused == false) - { - fmod_result = FMOD_Channel_SetPaused(SND_MusicChannel.channel, true); - FMOD_ERROR(fmod_result, true, false); - - SND_MusicChannel.paused = true; - } - - if (SND_MusicChannel.volume == 0.0f) - SND_MusicChannel.paused = true; -} - -/* -=================== -MOD_Resume -=================== -*/ -void MOD_Resume (qboolean force) -{ - if (SND_Initialised == false || SND_MusicChannel.inuse == false) - return; - - if (SND_MusicChannel.paused == true && SND_MusicChannel.volume != 0.0f && (oldbgmvolume == 0.0f | force == true)) - { - fmod_result = FMOD_Channel_SetPaused(SND_MusicChannel.channel, false); - FMOD_ERROR(fmod_result, true, false); - - SND_MusicChannel.paused = false; - } -} - -/* -=================== -MOD_Update -=================== -*/ -void MOD_Update (void) -{ - if (SND_Initialised == false || SND_MusicChannel.inuse == false) - return; - - FMOD_System_Update(fmod_system); - SND_MusicChannel.volume = bgmvolume.value; - - if (SND_MusicChannel.volume < 0.0f) - SND_MusicChannel.volume = 0.0f; - - if (SND_MusicChannel.volume > 1.0f) - SND_MusicChannel.volume = 1.0f; - - FMOD_ChannelGroup_SetVolume(musicChannelGroup, SND_MusicChannel.volume); - - if (SND_MusicChannel.volume == 0.0f) - MOD_Pause(); - else - MOD_Resume(false); -} - - - -// =================================================================================== -// -// MAIN FMOD AUDIO CONTROL ROUTINES -// -// =================================================================================== - -/* -=================== -FMOD_MusicStart -=================== -*/ -void FMOD_MusicStart (char *name, qboolean loop, qboolean notify) -{ - int len; - char file[MAX_QPATH]; - char trackname[MAX_QPATH]; - FILE *f; - - if (!sound_started) - return; - - len = -1; - - // check for an existing audio file - if (name != NULL && strlen(name) != 0) - { - COM_StripExtension(name, file); - - sprintf(trackname, "music/%s.ogg", file); - len = COM_FOpenFile((char *)trackname, &f); - if (len < 0) - { - sprintf(trackname, "music/%s.mp3", file); - len = COM_FOpenFile((char *)trackname, &f); - } - if (len < 0) - { - sprintf(trackname, "music/%s.wav", file); - len = COM_FOpenFile((char *)trackname, &f); - } - if (len < 0) - { - sprintf(trackname, "music/track%02i.ogg", atoi(file)); - len = COM_FOpenFile((char *)trackname, &f); - } - if (len < 0) - { - sprintf(trackname, "music/track%02i.mp3", atoi(file)); - len = COM_FOpenFile((char *)trackname, &f); - } - if (len < 0) - { - sprintf(trackname, "music/track%02i.wav", atoi(file)); - len = COM_FOpenFile((char *)trackname, &f); - } - - if (f) - fclose(f); - - f = NULL; - } - - // set the new bgmtype - if (len > 0) - { - // if an audio file exists play it - SND_MusicChannel.track = atoi(file); - strcpy(SND_MusicChannel.trackname, trackname); - FMOD_MusicUpdate(); - } - - MOD_Start(SND_MusicChannel.trackname, loop, notify); -} - -/* -=================== -FMOD_MusicStartConsole -=================== -*/ -void FMOD_MusicStartConsole (void) -{ - char name[MAX_QPATH]; - char file[MAX_QPATH]; - - if (!sound_started) - return; - - if (Cmd_Argc() < 2) - { - Con_Printf ("fmod_playmusic : play an audio file\n"); - return; - } - - sprintf(name, "%s\0", Cmd_Argv(1)); - COM_StripExtension(name, file); - - MOD_Start(file, false, true); - - return; -} - -/* -=================== -FMOD_MusicStop -=================== -*/ -void FMOD_MusicStop (void) -{ - MOD_Stop(); -} - -/* -=================== -FMOD_MusicPause -=================== -*/ -void FMOD_MusicPause (void) -{ - MOD_Pause(); -} - -/* -=================== -FMOD_MusicResume -=================== -*/ -void FMOD_MusicResume (void) -{ - MOD_Resume(true); -} - -/* -=================== -FMOD_MusicUpdate -=================== -*/ -void FMOD_MusicUpdate (void) -{ - if (SND_MusicChannel.track != oldtrack) - { - MOD_Stop(); - oldtrack = SND_MusicChannel.track; - } - - MOD_Update(); - - oldbgmvolume = SND_MusicChannel.volume; -} - -/* -=================== -FMOD_MusicActivate -=================== -*/ -void FMOD_MusicActivate (qboolean active) -{ - if (active) - FMOD_MusicResume(); - else - FMOD_MusicPause(); -} - -/* -=================== -FMOD_MusicActive -=================== -*/ -qboolean FMOD_MusicActive (void) -{ - return SND_MusicChannel.inuse; -} - -#endif diff --git a/engine/code/snd_mix.c b/engine/code/snd_mix.c deleted file mode 100644 index d31f6c9..0000000 --- a/engine/code/snd_mix.c +++ /dev/null @@ -1,398 +0,0 @@ -/* -Copyright (C) 1996-1997 Id Software, Inc. - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ -// snd_mix.c -- portable code to mix sounds for snd_dma.c - -#include "quakedef.h" - -#ifdef _WIN32 -#include "winquake.h" -#else -#define DWORD unsigned long -#endif - -#define PAINTBUFFER_SIZE 512 -portable_samplepair_t paintbuffer[PAINTBUFFER_SIZE]; -int snd_scaletable[32][256]; -int *snd_p, snd_linear_count, snd_vol; -short *snd_out; - -void Snd_WriteLinearBlastStereo16 (void); - -#if !id386 -void Snd_WriteLinearBlastStereo16 (void) -{ - int i; - int val; - - for (i=0 ; i>8; - if (val > 0x7fff) - snd_out[i] = 0x7fff; - else if (val < (short)0x8000) - snd_out[i] = (short)0x8000; - else - snd_out[i] = val; - - val = (snd_p[i+1]*snd_vol)>>8; - if (val > 0x7fff) - snd_out[i+1] = 0x7fff; - else if (val < (short)0x8000) - snd_out[i+1] = (short)0x8000; - else - snd_out[i+1] = val; - } -} -#endif - -void S_TransferStereo16 (int endtime) -{ - int lpos; - int lpaintedtime; - DWORD *pbuf; -#ifdef _WIN32 - int reps; - DWORD dwSize,dwSize2; - DWORD *pbuf2; - HRESULT hresult; -#endif - - snd_vol = volume.value*256; - - snd_p = (int *) paintbuffer; - lpaintedtime = paintedtime; - -#ifdef _WIN32 - if (pDSBuf) - { - reps = 0; - - while ((hresult = pDSBuf->lpVtbl->Lock(pDSBuf, 0, gSndBufSize, &pbuf, &dwSize, - &pbuf2, &dwSize2, 0)) != DS_OK) - { - if (hresult != DSERR_BUFFERLOST) - { - Con_Printf ("S_TransferStereo16: DS::Lock Sound Buffer Failed\n"); - S_Shutdown (); - S_Startup (); - return; - } - - if (++reps > 10000) - { - Con_Printf ("S_TransferStereo16: DS: couldn't restore buffer\n"); - S_Shutdown (); - S_Startup (); - return; - } - } - } - else -#endif - { - pbuf = (DWORD *)shm->buffer; - } - - while (lpaintedtime < endtime) - { - // handle recirculating buffer issues - lpos = lpaintedtime & ((shm->samples>>1)-1); - - snd_out = (short *) pbuf + (lpos<<1); - - snd_linear_count = (shm->samples>>1) - lpos; - if (lpaintedtime + snd_linear_count > endtime) - snd_linear_count = endtime - lpaintedtime; - - snd_linear_count <<= 1; - - // write a linear blast of samples - Snd_WriteLinearBlastStereo16 (); - - snd_p += snd_linear_count; - lpaintedtime += (snd_linear_count>>1); - } - -#ifdef _WIN32 - if (pDSBuf) - pDSBuf->lpVtbl->Unlock(pDSBuf, pbuf, dwSize, NULL, 0); -#endif -} - -void S_TransferPaintBuffer(int endtime) -{ - int out_idx; - int count; - int out_mask; - int *p; - int step; - int val; - int snd_vol; - DWORD *pbuf; -#ifdef _WIN32 - int reps; - DWORD dwSize,dwSize2; - DWORD *pbuf2; - HRESULT hresult; -#endif - - if (shm->samplebits == 16 && shm->channels == 2) - { - S_TransferStereo16 (endtime); - return; - } - - p = (int *) paintbuffer; - count = (endtime - paintedtime) * shm->channels; - out_mask = shm->samples - 1; - out_idx = paintedtime * shm->channels & out_mask; - step = 3 - shm->channels; - snd_vol = volume.value*256; - -#ifdef _WIN32 - if (pDSBuf) - { - reps = 0; - - while ((hresult = pDSBuf->lpVtbl->Lock(pDSBuf, 0, gSndBufSize, &pbuf, &dwSize, - &pbuf2,&dwSize2, 0)) != DS_OK) - { - if (hresult != DSERR_BUFFERLOST) - { - Con_Printf ("S_TransferPaintBuffer: DS::Lock Sound Buffer Failed\n"); - S_Shutdown (); - S_Startup (); - return; - } - - if (++reps > 10000) - { - Con_Printf ("S_TransferPaintBuffer: DS: couldn't restore buffer\n"); - S_Shutdown (); - S_Startup (); - return; - } - } - } - else -#endif - { - pbuf = (DWORD *)shm->buffer; - } - - if (shm->samplebits == 16) - { - short *out = (short *) pbuf; - while (count--) - { - val = (*p * snd_vol) >> 8; - p+= step; - if (val > 0x7fff) - val = 0x7fff; - else if (val < (short)0x8000) - val = (short)0x8000; - out[out_idx] = val; - out_idx = (out_idx + 1) & out_mask; - } - } - else if (shm->samplebits == 8) - { - unsigned char *out = (unsigned char *) pbuf; - while (count--) - { - val = (*p * snd_vol) >> 8; - p+= step; - if (val > 0x7fff) - val = 0x7fff; - else if (val < (short)0x8000) - val = (short)0x8000; - out[out_idx] = (val>>8) + 128; - out_idx = (out_idx + 1) & out_mask; - } - } - -#ifdef _WIN32 - if (pDSBuf) { - DWORD dwNewpos, dwWrite; - int il = paintedtime; - int ir = endtime - paintedtime; - - ir += il; - - pDSBuf->lpVtbl->Unlock(pDSBuf, pbuf, dwSize, NULL, 0); - - pDSBuf->lpVtbl->GetCurrentPosition(pDSBuf, &dwNewpos, &dwWrite); - -// if ((dwNewpos >= il) && (dwNewpos <= ir)) -// Con_Printf("%d-%d p %d c\n", il, ir, dwNewpos); - } -#endif -} - - -/* -=============================================================================== - -CHANNEL MIXING - -=============================================================================== -*/ - -void SND_PaintChannelFrom8 (channel_t *ch, sfxcache_t *sc, int endtime); -void SND_PaintChannelFrom16 (channel_t *ch, sfxcache_t *sc, int endtime); - -void S_PaintChannels(int endtime) -{ - int i; - int end; - channel_t *ch; - sfxcache_t *sc; - int ltime, count; - - while (paintedtime < endtime) - { - // if paintbuffer is smaller than DMA buffer - end = endtime; - if (endtime - paintedtime > PAINTBUFFER_SIZE) - end = paintedtime + PAINTBUFFER_SIZE; - - // clear the paint buffer - Q_memset(paintbuffer, 0, (end - paintedtime) * sizeof(portable_samplepair_t)); - - // paint in the channels. - ch = channels; - for (i=0; isfx) - continue; - if (!ch->leftvol && !ch->rightvol) - continue; - sc = S_LoadSound (ch->sfx); - if (!sc) - continue; - - ltime = paintedtime; - - while (ltime < end) - { // paint up to end - if (ch->end < end) - count = ch->end - ltime; - else - count = end - ltime; - - if (count > 0) - { - if (sc->width == 1) - SND_PaintChannelFrom8(ch, sc, count); - else - SND_PaintChannelFrom16(ch, sc, count); - - ltime += count; - } - - // if at end of loop, restart - if (ltime >= ch->end) - { - if (sc->loopstart >= 0) - { - ch->pos = sc->loopstart; - ch->end = ltime + sc->length - ch->pos; - } - else - { // channel just stopped - ch->sfx = NULL; - break; - } - } - } - - } - - // transfer out according to DMA format - S_TransferPaintBuffer(end); - paintedtime = end; - } -} - -void SND_InitScaletable (void) -{ - int i, j; - - for (i=0 ; i<32 ; i++) - for (j=0 ; j<256 ; j++) - snd_scaletable[i][j] = ((signed char)j) * i * 8; -} - - -#if !id386 - -void SND_PaintChannelFrom8 (channel_t *ch, sfxcache_t *sc, int count) -{ - int data; - int *lscale, *rscale; - unsigned char *sfx; - int i; - - if (ch->leftvol > 255) - ch->leftvol = 255; - if (ch->rightvol > 255) - ch->rightvol = 255; - - lscale = snd_scaletable[ch->leftvol >> 3]; - rscale = snd_scaletable[ch->rightvol >> 3]; - sfx = (signed char *)sc->data + ch->pos; - - for (i=0 ; ipos += count; -} - -#endif // !id386 - - -void SND_PaintChannelFrom16 (channel_t *ch, sfxcache_t *sc, int count) -{ - int data; - int left, right; - int leftvol, rightvol; - signed short *sfx; - int i; - - leftvol = ch->leftvol; - rightvol = ch->rightvol; - sfx = (signed short *)sc->data + ch->pos; - - for (i=0 ; i> 8; - right = (data * rightvol) >> 8; - paintbuffer[i].left += left; - paintbuffer[i].right += right; - } - - ch->pos += count; -} - diff --git a/engine/code/snd_win.c b/engine/code/snd_win.c deleted file mode 100644 index da499b3..0000000 --- a/engine/code/snd_win.c +++ /dev/null @@ -1,737 +0,0 @@ -/* -Copyright (C) 1996-1997 Id Software, Inc. - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ -#include "quakedef.h" -#include "winquake.h" - -#define iDirectSoundCreate(a,b,c) pDirectSoundCreate(a,b,c) - -HRESULT (WINAPI *pDirectSoundCreate)(GUID FAR *lpGUID, LPDIRECTSOUND FAR *lplpDS, IUnknown FAR *pUnkOuter); - -// 64K is > 1 second at 16-bit, 22050 Hz -#define WAV_BUFFERS 64 -#define WAV_MASK 0x3F -#define WAV_BUFFER_SIZE 0x0400 -#define SECONDARY_BUFFER_SIZE 0x10000 - -typedef enum {SIS_SUCCESS, SIS_FAILURE, SIS_NOTAVAIL} sndinitstat; - -static qboolean wavonly; -static qboolean dsound_init; -static qboolean wav_init; -static qboolean snd_firsttime = true, snd_isdirect, snd_iswave; -static qboolean primary_format_set; - -static int sample16; -static int snd_sent, snd_completed; - - -/* - * Global variables. Must be visible to window-procedure function - * so it can unlock and free the data block after it has been played. - */ - -HANDLE hData; -HPSTR lpData, lpData2; - -HGLOBAL hWaveHdr; -LPWAVEHDR lpWaveHdr; - -HWAVEOUT hWaveOut; - -WAVEOUTCAPS wavecaps; - -DWORD gSndBufSize; - -MMTIME mmstarttime; - -LPDIRECTSOUND pDS; -LPDIRECTSOUNDBUFFER pDSBuf, pDSPBuf; - -HINSTANCE hInstDS; - -qboolean SNDDMA_InitDirect (void); -qboolean SNDDMA_InitWav (void); - - -/* -================== -S_BlockSound -================== -*/ -void S_BlockSound (void) -{ - -// DirectSound takes care of blocking itself - if (snd_iswave) - { - snd_blocked++; - - if (snd_blocked == 1) - { - waveOutReset (hWaveOut); - } - } -} - - -/* -================== -S_UnblockSound -================== -*/ -void S_UnblockSound (void) -{ - -// DirectSound takes care of blocking itself - if (snd_iswave) - { - snd_blocked--; - } -} - - -/* -================== -FreeSound -================== -*/ -void FreeSound (void) -{ - int i; - - if (pDSBuf) - { - pDSBuf->lpVtbl->Stop(pDSBuf); - pDSBuf->lpVtbl->Release(pDSBuf); - } - -// only release primary buffer if it's not also the mixing buffer we just released - if (pDSPBuf && (pDSBuf != pDSPBuf)) - { - pDSPBuf->lpVtbl->Release(pDSPBuf); - } - - if (pDS) - { - pDS->lpVtbl->SetCooperativeLevel (pDS, mainwindow, DSSCL_NORMAL); - pDS->lpVtbl->Release(pDS); - } - - if (hWaveOut) - { - waveOutReset (hWaveOut); - - if (lpWaveHdr) - { - for (i=0 ; i< WAV_BUFFERS ; i++) - waveOutUnprepareHeader (hWaveOut, lpWaveHdr+i, sizeof(WAVEHDR)); - } - - waveOutClose (hWaveOut); - - if (hWaveHdr) - { - GlobalUnlock(hWaveHdr); - GlobalFree(hWaveHdr); - } - - if (hData) - { - GlobalUnlock(hData); - GlobalFree(hData); - } - - } - - pDS = NULL; - pDSBuf = NULL; - pDSPBuf = NULL; - hWaveOut = 0; - hData = 0; - hWaveHdr = 0; - lpData = NULL; - lpWaveHdr = NULL; - dsound_init = false; - wav_init = false; -} - - -/* -================== -SNDDMA_InitDirect - -Direct-Sound support -================== -*/ -sndinitstat SNDDMA_InitDirect (void) -{ - DSBUFFERDESC dsbuf; - DSBCAPS dsbcaps; - DWORD dwSize, dwWrite; - DSCAPS dscaps; - WAVEFORMATEX format, pformat; - HRESULT hresult; - int reps; - - memset ((void *)&sn, 0, sizeof (sn)); - - shm = &sn; - - shm->channels = 2; - shm->samplebits = 16; - - // jkrige - change sound speed - //shm->speed = 11025; - shm->speed = 22050; - // jkrige - change sound speed - - memset (&format, 0, sizeof(format)); - format.wFormatTag = WAVE_FORMAT_PCM; - format.nChannels = shm->channels; - format.wBitsPerSample = shm->samplebits; - format.nSamplesPerSec = shm->speed; - format.nBlockAlign = format.nChannels - *format.wBitsPerSample / 8; - format.cbSize = 0; - format.nAvgBytesPerSec = format.nSamplesPerSec - *format.nBlockAlign; - - if (!hInstDS) - { - hInstDS = LoadLibrary("dsound.dll"); - - if (hInstDS == NULL) - { - Con_SafePrintf ("Couldn't load dsound.dll\n"); - return SIS_FAILURE; - } - - pDirectSoundCreate = (void *)GetProcAddress(hInstDS,"DirectSoundCreate"); - - if (!pDirectSoundCreate) - { - Con_SafePrintf ("Couldn't get DS proc addr\n"); - return SIS_FAILURE; - } - } - - while ((hresult = iDirectSoundCreate(NULL, &pDS, NULL)) != DS_OK) - { - if (hresult != DSERR_ALLOCATED) - { - Con_SafePrintf ("DirectSound create failed\n"); - return SIS_FAILURE; - } - - if (MessageBox (NULL, - "The sound hardware is in use by another app.\n\n" - "Select Retry to try to start sound again or Cancel to run Quake with no sound.", - "Sound not available", - MB_RETRYCANCEL | MB_SETFOREGROUND | MB_ICONEXCLAMATION) != IDRETRY) - { - Con_SafePrintf ("DirectSoundCreate failure\n" - " hardware already in use\n"); - return SIS_NOTAVAIL; - } - } - - dscaps.dwSize = sizeof(dscaps); - - if (DS_OK != pDS->lpVtbl->GetCaps (pDS, &dscaps)) - { - Con_SafePrintf ("Couldn't get DS caps\n"); - } - - if (dscaps.dwFlags & DSCAPS_EMULDRIVER) - { - Con_SafePrintf ("No DirectSound driver installed\n"); - FreeSound (); - return SIS_FAILURE; - } - - if (DS_OK != pDS->lpVtbl->SetCooperativeLevel (pDS, mainwindow, DSSCL_EXCLUSIVE)) - { - Con_SafePrintf ("Set coop level failed\n"); - FreeSound (); - return SIS_FAILURE; - } - -// get access to the primary buffer, if possible, so we can set the -// sound hardware format - memset (&dsbuf, 0, sizeof(dsbuf)); - dsbuf.dwSize = sizeof(DSBUFFERDESC); - dsbuf.dwFlags = DSBCAPS_PRIMARYBUFFER; - dsbuf.dwBufferBytes = 0; - dsbuf.lpwfxFormat = NULL; - - memset(&dsbcaps, 0, sizeof(dsbcaps)); - dsbcaps.dwSize = sizeof(dsbcaps); - primary_format_set = false; - - if (!COM_CheckParm ("-snoforceformat")) - { - if (DS_OK == pDS->lpVtbl->CreateSoundBuffer(pDS, &dsbuf, &pDSPBuf, NULL)) - { - pformat = format; - - if (DS_OK != pDSPBuf->lpVtbl->SetFormat (pDSPBuf, &pformat)) - { - if (snd_firsttime) - Con_SafePrintf ("Set primary sound buffer format: no\n"); - } - else - { - if (snd_firsttime) - Con_SafePrintf ("Set primary sound buffer format: yes\n"); - - primary_format_set = true; - } - } - } - - if (!primary_format_set || !COM_CheckParm ("-primarysound")) - { - // create the secondary buffer we'll actually work with - memset (&dsbuf, 0, sizeof(dsbuf)); - dsbuf.dwSize = sizeof(DSBUFFERDESC); - dsbuf.dwFlags = DSBCAPS_CTRLFREQUENCY | DSBCAPS_LOCSOFTWARE; - dsbuf.dwBufferBytes = SECONDARY_BUFFER_SIZE; - dsbuf.lpwfxFormat = &format; - - memset(&dsbcaps, 0, sizeof(dsbcaps)); - dsbcaps.dwSize = sizeof(dsbcaps); - - if (DS_OK != pDS->lpVtbl->CreateSoundBuffer(pDS, &dsbuf, &pDSBuf, NULL)) - { - Con_SafePrintf ("DS:CreateSoundBuffer Failed"); - FreeSound (); - return SIS_FAILURE; - } - - shm->channels = format.nChannels; - shm->samplebits = format.wBitsPerSample; - shm->speed = format.nSamplesPerSec; - - if (DS_OK != pDSBuf->lpVtbl->GetCaps (pDSBuf, &dsbcaps)) - { - Con_SafePrintf ("DS:GetCaps failed\n"); - FreeSound (); - return SIS_FAILURE; - } - - if (snd_firsttime) - Con_SafePrintf ("Using secondary sound buffer\n"); - } - else - { - if (DS_OK != pDS->lpVtbl->SetCooperativeLevel (pDS, mainwindow, DSSCL_WRITEPRIMARY)) - { - Con_SafePrintf ("Set coop level failed\n"); - FreeSound (); - return SIS_FAILURE; - } - - if (DS_OK != pDSPBuf->lpVtbl->GetCaps (pDSPBuf, &dsbcaps)) - { - Con_Printf ("DS:GetCaps failed\n"); - return SIS_FAILURE; - } - - pDSBuf = pDSPBuf; - Con_SafePrintf ("Using primary sound buffer\n"); - } - - // Make sure mixer is active - pDSBuf->lpVtbl->Play(pDSBuf, 0, 0, DSBPLAY_LOOPING); - - if (snd_firsttime) - Con_SafePrintf(" %d channel(s)\n" - " %d bits/sample\n" - " %d bytes/sec\n", - shm->channels, shm->samplebits, shm->speed); - - gSndBufSize = dsbcaps.dwBufferBytes; - -// initialize the buffer - reps = 0; - - while ((hresult = pDSBuf->lpVtbl->Lock(pDSBuf, 0, gSndBufSize, &lpData, &dwSize, NULL, NULL, 0)) != DS_OK) - { - if (hresult != DSERR_BUFFERLOST) - { - Con_SafePrintf ("SNDDMA_InitDirect: DS::Lock Sound Buffer Failed\n"); - FreeSound (); - return SIS_FAILURE; - } - - if (++reps > 10000) - { - Con_SafePrintf ("SNDDMA_InitDirect: DS: couldn't restore buffer\n"); - FreeSound (); - return SIS_FAILURE; - } - - } - - memset(lpData, 0, dwSize); -// lpData[4] = lpData[5] = 0x7f; // force a pop for debugging - - pDSBuf->lpVtbl->Unlock(pDSBuf, lpData, dwSize, NULL, 0); - - /* we don't want anyone to access the buffer directly w/o locking it first. */ - lpData = NULL; - - pDSBuf->lpVtbl->Stop(pDSBuf); - pDSBuf->lpVtbl->GetCurrentPosition(pDSBuf, &mmstarttime.u.sample, &dwWrite); - pDSBuf->lpVtbl->Play(pDSBuf, 0, 0, DSBPLAY_LOOPING); - - shm->soundalive = true; - shm->splitbuffer = false; - shm->samples = gSndBufSize/(shm->samplebits/8); - shm->samplepos = 0; - shm->submission_chunk = 1; - shm->buffer = (unsigned char *) lpData; - sample16 = (shm->samplebits/8) - 1; - - dsound_init = true; - - return SIS_SUCCESS; -} - - -/* -================== -SNDDM_InitWav - -Crappy windows multimedia base -================== -*/ -qboolean SNDDMA_InitWav (void) -{ - WAVEFORMATEX format; - int i; - HRESULT hr; - - snd_sent = 0; - snd_completed = 0; - - shm = &sn; - - shm->channels = 2; - shm->samplebits = 16; - - // jkrige - change sound speed - //shm->speed = 11025; - shm->speed = 22050; - // jkrige - change sound speed - - memset (&format, 0, sizeof(format)); - format.wFormatTag = WAVE_FORMAT_PCM; - format.nChannels = shm->channels; - format.wBitsPerSample = shm->samplebits; - format.nSamplesPerSec = shm->speed; - format.nBlockAlign = format.nChannels - *format.wBitsPerSample / 8; - format.cbSize = 0; - format.nAvgBytesPerSec = format.nSamplesPerSec - *format.nBlockAlign; - - /* Open a waveform device for output using window callback. */ - while ((hr = waveOutOpen((LPHWAVEOUT)&hWaveOut, WAVE_MAPPER, - &format, - 0, 0L, CALLBACK_NULL)) != MMSYSERR_NOERROR) - { - if (hr != MMSYSERR_ALLOCATED) - { - Con_SafePrintf ("waveOutOpen failed\n"); - return false; - } - - if (MessageBox (NULL, - "The sound hardware is in use by another app.\n\n" - "Select Retry to try to start sound again or Cancel to run Quake with no sound.", - "Sound not available", - MB_RETRYCANCEL | MB_SETFOREGROUND | MB_ICONEXCLAMATION) != IDRETRY) - { - Con_SafePrintf ("waveOutOpen failure;\n" - " hardware already in use\n"); - return false; - } - } - - /* - * Allocate and lock memory for the waveform data. The memory - * for waveform data must be globally allocated with - * GMEM_MOVEABLE and GMEM_SHARE flags. - - */ - gSndBufSize = WAV_BUFFERS*WAV_BUFFER_SIZE; - hData = GlobalAlloc(GMEM_MOVEABLE | GMEM_SHARE, gSndBufSize); - if (!hData) - { - Con_SafePrintf ("Sound: Out of memory.\n"); - FreeSound (); - return false; - } - lpData = GlobalLock(hData); - if (!lpData) - { - Con_SafePrintf ("Sound: Failed to lock.\n"); - FreeSound (); - return false; - } - memset (lpData, 0, gSndBufSize); - - /* - * Allocate and lock memory for the header. This memory must - * also be globally allocated with GMEM_MOVEABLE and - * GMEM_SHARE flags. - */ - hWaveHdr = GlobalAlloc(GMEM_MOVEABLE | GMEM_SHARE, - (DWORD) sizeof(WAVEHDR) * WAV_BUFFERS); - - if (hWaveHdr == NULL) - { - Con_SafePrintf ("Sound: Failed to Alloc header.\n"); - FreeSound (); - return false; - } - - lpWaveHdr = (LPWAVEHDR) GlobalLock(hWaveHdr); - - if (lpWaveHdr == NULL) - { - Con_SafePrintf ("Sound: Failed to lock header.\n"); - FreeSound (); - return false; - } - - memset (lpWaveHdr, 0, sizeof(WAVEHDR) * WAV_BUFFERS); - - /* After allocation, set up and prepare headers. */ - for (i=0 ; isoundalive = true; - shm->splitbuffer = false; - shm->samples = gSndBufSize/(shm->samplebits/8); - shm->samplepos = 0; - shm->submission_chunk = 1; - shm->buffer = (unsigned char *) lpData; - sample16 = (shm->samplebits/8) - 1; - - wav_init = true; - - return true; -} - -/* -================== -SNDDMA_Init - -Try to find a sound device to mix for. -Returns false if nothing is found. -================== -*/ - -int SNDDMA_Init(void) -{ - sndinitstat stat; - - if (COM_CheckParm ("-wavonly")) - wavonly = true; - - dsound_init = wav_init = 0; - - stat = SIS_FAILURE; // assume DirectSound won't initialize - - /* Init DirectSound */ - if (!wavonly) - { - if (snd_firsttime || snd_isdirect) - { - stat = SNDDMA_InitDirect ();; - - if (stat == SIS_SUCCESS) - { - snd_isdirect = true; - - if (snd_firsttime) - Con_SafePrintf ("DirectSound initialized\n"); - } - else - { - snd_isdirect = false; - Con_SafePrintf ("DirectSound failed to init\n"); - } - } - } - -// if DirectSound didn't succeed in initializing, try to initialize -// waveOut sound, unless DirectSound failed because the hardware is -// already allocated (in which case the user has already chosen not -// to have sound) - if (!dsound_init && (stat != SIS_NOTAVAIL)) - { - if (snd_firsttime || snd_iswave) - { - - snd_iswave = SNDDMA_InitWav (); - - if (snd_iswave) - { - if (snd_firsttime) - Con_SafePrintf ("Wave sound initialized\n"); - } - else - { - Con_SafePrintf ("Wave sound failed to init\n"); - } - } - } - - snd_firsttime = false; - - if (!dsound_init && !wav_init) - { - if (snd_firsttime) - Con_SafePrintf ("No sound device initialized\n"); - - return 0; - } - - return 1; -} - -/* -============== -SNDDMA_GetDMAPos - -return the current sample position (in mono samples read) -inside the recirculating dma buffer, so the mixing code will know -how many sample are required to fill it up. -=============== -*/ -int SNDDMA_GetDMAPos(void) -{ - MMTIME mmtime; - int s; - DWORD dwWrite; - - if (dsound_init) - { - mmtime.wType = TIME_SAMPLES; - pDSBuf->lpVtbl->GetCurrentPosition(pDSBuf, &mmtime.u.sample, &dwWrite); - s = mmtime.u.sample - mmstarttime.u.sample; - } - else if (wav_init) - { - s = snd_sent * WAV_BUFFER_SIZE; - } - - - s >>= sample16; - - s &= (shm->samples-1); - - return s; -} - -/* -============== -SNDDMA_Submit - -Send sound to device if buffer isn't really the dma buffer -=============== -*/ -void SNDDMA_Submit(void) -{ - LPWAVEHDR h; - int wResult; - - if (!wav_init) - return; - - // - // find which sound blocks have completed - // - while (1) - { - if ( snd_completed == snd_sent ) - { - Con_DPrintf ("Sound overrun\n"); - break; - } - - if ( ! (lpWaveHdr[ snd_completed & WAV_MASK].dwFlags & WHDR_DONE) ) - { - break; - } - - snd_completed++; // this buffer has been played - } - - // - // submit two new sound blocks - // - while (((snd_sent - snd_completed) >> sample16) < 4) - { - h = lpWaveHdr + ( snd_sent&WAV_MASK ); - - snd_sent++; - /* - * Now the data block can be sent to the output device. The - * waveOutWrite function returns immediately and waveform - * data is sent to the output device in the background. - */ - wResult = waveOutWrite(hWaveOut, h, sizeof(WAVEHDR)); - - if (wResult != MMSYSERR_NOERROR) - { - Con_SafePrintf ("Failed to write block to device\n"); - FreeSound (); - return; - } - } -} - -/* -============== -SNDDMA_Shutdown - -Reset the sound device for exiting -=============== -*/ -void SNDDMA_Shutdown(void) -{ - FreeSound (); -} - diff --git a/engine/code/sound.h b/engine/code/sound.h deleted file mode 100644 index 1ba08d3..0000000 --- a/engine/code/sound.h +++ /dev/null @@ -1,177 +0,0 @@ -/* -Copyright (C) 1996-1997 Id Software, Inc. - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ -// sound.h -- client sound i/o functions - -#ifndef __SOUND__ -#define __SOUND__ - -#define DEFAULT_SOUND_PACKET_VOLUME 255 -#define DEFAULT_SOUND_PACKET_ATTENUATION 1.0 - -// !!! if this is changed, it much be changed in asm_i386.h too !!! -typedef struct -{ - int left; - int right; -} portable_samplepair_t; - -typedef struct sfx_s -{ - char name[MAX_QPATH]; - cache_user_t cache; -} sfx_t; - -// !!! if this is changed, it much be changed in asm_i386.h too !!! -typedef struct -{ - int length; - int loopstart; - int speed; - int width; - int stereo; - byte data[1]; // variable sized -} sfxcache_t; - -typedef struct -{ - qboolean gamealive; - qboolean soundalive; - qboolean splitbuffer; - int channels; - int samples; // mono samples in buffer - int submission_chunk; // don't mix less than this # - int samplepos; // in mono samples - int samplebits; - int speed; - unsigned char *buffer; -} dma_t; - -// !!! if this is changed, it much be changed in asm_i386.h too !!! -typedef struct -{ - sfx_t *sfx; // sfx number - int leftvol; // 0-255 volume - int rightvol; // 0-255 volume - int end; // end time in global paintsamples - int pos; // sample position in sfx - int looping; // where to loop, -1 = no looping - int entnum; // to allow overriding a specific sound - int entchannel; // - vec3_t origin; // origin of sound effect - vec_t dist_mult; // distance multiplier (attenuation/clipK) - int master_vol; // 0-255 master volume -} channel_t; - -typedef struct -{ - int rate; - int width; - int channels; - int loopstart; - int samples; - int dataofs; // chunk starts this many bytes from file start -} wavinfo_t; - -void S_Init (void); -void S_Startup (void); -void S_Shutdown (void); -void S_StartSound (int entnum, int entchannel, sfx_t *sfx, vec3_t origin, float fvol, float attenuation); -void S_StaticSound (sfx_t *sfx, vec3_t origin, float vol, float attenuation); -void S_StopSound (int entnum, int entchannel); -void S_StopAllSounds(qboolean clear); -void S_ClearBuffer (void); -void S_Update (vec3_t origin, vec3_t v_forward, vec3_t v_right, vec3_t v_up); -void S_ExtraUpdate (void); - -sfx_t *S_PrecacheSound (char *sample); -void S_TouchSound (char *sample); -void S_ClearPrecache (void); -void S_BeginPrecaching (void); -void S_EndPrecaching (void); -void S_PaintChannels(int endtime); -void S_InitPaintChannels (void); - -// picks a channel based on priorities, empty slots, number of channels -channel_t *SND_PickChannel(int entnum, int entchannel); - -// spatializes a channel -void SND_Spatialize(channel_t *ch); - -// initializes cycling through a DMA buffer and returns information on it -qboolean SNDDMA_Init(void); - -// gets the current DMA position -int SNDDMA_GetDMAPos(void); - -// shutdown the DMA xfer. -void SNDDMA_Shutdown(void); - -// ==================================================================== -// User-setable variables -// ==================================================================== - -#define MAX_CHANNELS 128 -#define MAX_DYNAMIC_CHANNELS 8 - - -extern channel_t channels[MAX_CHANNELS]; -// 0 to MAX_DYNAMIC_CHANNELS-1 = normal entity sounds -// MAX_DYNAMIC_CHANNELS to MAX_DYNAMIC_CHANNELS + NUM_AMBIENTS -1 = water, etc -// MAX_DYNAMIC_CHANNELS + NUM_AMBIENTS to total_channels = static sounds - -extern int total_channels; - -// -// Fake dma is a synchronous faking of the DMA progress used for -// isolating performance in the renderer. The fakedma_updates is -// number of times S_Update() is called per second. -// - -extern qboolean fakedma; -extern int fakedma_updates; -extern int paintedtime; -extern vec3_t listener_origin; -extern vec3_t listener_forward; -extern vec3_t listener_right; -extern vec3_t listener_up; -extern volatile dma_t *shm; -extern volatile dma_t sn; -extern vec_t sound_nominal_clip_dist; - -extern cvar_t loadas8bit; -extern cvar_t bgmvolume; -extern cvar_t volume; - -extern qboolean snd_initialized; - -extern int snd_blocked; - -void S_LocalSound (char *s); -sfxcache_t *S_LoadSound (sfx_t *s); - -wavinfo_t GetWavinfo (char *name, byte *wav, int wavlength); - -void SND_InitScaletable (void); -void SNDDMA_Submit(void); - -void S_AmbientOff (void); -void S_AmbientOn (void); - -#endif diff --git a/engine/code/sys.h b/engine/code/sys.h deleted file mode 100644 index ec0a6eb..0000000 --- a/engine/code/sys.h +++ /dev/null @@ -1,89 +0,0 @@ -/* -Copyright (C) 1996-1997 Id Software, Inc. - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ -// sys.h -- non-portable functions - -// -// file IO -// - -// returns the file size -// return -1 if file is not present -// the file should be in BINARY mode for stupid OSs that care -int Sys_FileOpenRead (char *path, int *hndl); - -int Sys_FileOpenWrite (char *path); -void Sys_FileClose (int handle); -void Sys_FileSeek (int handle, int position); - -// jkrige - pk3 file support -// jkrige - increased max number of file handles -//#define MAX_HANDLES 10 -#define MAX_HANDLES 25 -// jkrige - increased max number of file handles -extern FILE *sys_handles[MAX_HANDLES]; -extern unzFile sys_zhandles[MAX_HANDLES]; -//long Sys_FileTell (int handle); -int Sys_FFileRead (FILE *f, void *dest, int count); -void Sys_FFileClose (FILE *f); -int findhandle (qboolean zip); -// jkrige - pk3 file support - -int Sys_FileRead (int handle, void *dest, int count); -int Sys_FileWrite (int handle, void *data, int count); -int Sys_FileTime (char *path); -void Sys_mkdir (char *path); - -// -// memory protection -// -void Sys_MakeCodeWriteable (uintptr_t startaddr, size_t length); - -// -// system IO -// -void Sys_DebugLog(char *file, char *fmt, ...); - -void Sys_Error (char *error, ...); -// an error will cause the entire program to exit - -void Sys_Printf (char *fmt, ...); -// send text to the console - -void Sys_Quit (void); - -double Sys_FloatTime (void); - -char *Sys_ConsoleInput (void); - -void Sys_Sleep (void); -// called to yield for a little bit so as -// not to hog cpu when paused or debugging - -// Pa3PyX: Same as above, but time in milliseconds can be specified -#define Sys_LongSleep(time_len) (Sleep(time_len)) - -void Sys_SendKeyEvents (void); -// Perform Key_Event () callbacks until the input que is empty - -// jkrige - assembly removal -//void Sys_LowFPPrecision (void); -//void Sys_HighFPPrecision (void); -//void Sys_SetFPCW (void); -// jkrige - assembly removal diff --git a/engine/code/sys_win.c b/engine/code/sys_win.c deleted file mode 100644 index f599b14..0000000 --- a/engine/code/sys_win.c +++ /dev/null @@ -1,1007 +0,0 @@ -/* -Copyright (C) 1996-1997 Id Software, Inc. - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ -// sys_win.c -- Win32 system interface code - -#include "quakedef.h" -#include "winquake.h" -#include "errno.h" -#include "resource.h" -#include "conproc.h" - -//#define MINIMUM_WIN_MEMORY 0x0880000 -//#define MAXIMUM_WIN_MEMORY 0x1000000 -#define MINIMUM_WIN_MEMORY 0x2000000 // jkrige - memory increase: 33 554 432 bytes (32MB) -#define MAXIMUM_WIN_MEMORY 0x4000000 // jkrige - memory increase: 67 108 864 bytes (64MB) - -#define CONSOLE_ERROR_TIMEOUT 60.0 // # of seconds to wait on Sys_Error running - // dedicated before exiting -#define PAUSE_SLEEP 50 // sleep time on pause or minimization -#define NOT_FOCUS_SLEEP 20 // sleep time when not focus - -int starttime; -qboolean ActiveApp, Minimized; -//qboolean WinNT; // jkrige - remove windows version check - -static double pfreq; -static double curtime = 0.0; -static double lastcurtime = 0.0; -static int lowshift; -qboolean isDedicated; -static qboolean sc_return_on_enter = false; -HANDLE hinput, houtput; - -static char *tracking_tag = "Clams & Mooses"; - -static HANDLE tevent; -static HANDLE hFile; -static HANDLE heventParent; -static HANDLE heventChild; - -void Sys_InitFloatTime(void); - -// jkrige - assembly removal -//void Sys_PushFPCW_SetHigh (void); -//void Sys_PopFPCW (void); -//void MaskExceptions(void); -// jkrige - assembly removal - -volatile int sys_checksum; - - -/* -================ -Sys_PageIn -================ -*/ -void Sys_PageIn (void *ptr, int size) -{ - byte *x; - int j, m, n; - -// touch all the memory to make sure it's there. The 16-page skip is to -// keep Win 95 from thinking we're trying to page ourselves in (we are -// doing that, of course, but there's no reason we shouldn't) - x = (byte *)ptr; - - for (n=0 ; n<4 ; n++) - { - for (m=0 ; m<(size - 16 * 0x1000) ; m += 4) - { - sys_checksum += *(int *)&x[m]; - sys_checksum += *(int *)&x[m + 16 * 0x1000]; - } - } -} - - -/* -=============================================================================== - -FILE IO - -=============================================================================== -*/ - -// jkrige - pk3 file support -//#define MAX_HANDLES 10 -unzFile sys_zhandles[MAX_HANDLES]; -// jkrige - pk3 file support - -FILE *sys_handles[MAX_HANDLES]; - -// jkrige - pk3 file support -/*int findhandle (void) -{ - int i; - - for (i=1 ; i 2000000.0)) - { - lowshift++; - lowpart >>= 1; - lowpart |= (highpart & 1) << 31; - highpart >>= 1; - } - - pfreq = 1.0 / (double)lowpart; - - Sys_InitFloatTime (); - - // jkrige - remove windows version check - begin - /* - vinfo.dwOSVersionInfoSize = sizeof(vinfo); - - if (!GetVersionEx (&vinfo)) - Sys_Error ("Couldn't get OS info"); - - if ((vinfo.dwMajorVersion < 4) || - (vinfo.dwPlatformId == VER_PLATFORM_WIN32s)) - { - Sys_Error ("WinQuake requires at least Win95 or NT 4.0"); - } - - if (vinfo.dwPlatformId == VER_PLATFORM_WIN32_NT) - WinNT = true; - else - WinNT = false; - */ - // jkrige - remove windows version check - end -} - - -void Sys_Error_Obsolete (char *error, ...) -{ - va_list argptr; - char text[1024], text2[1024]; - char *text3 = "Press Enter to exit\n"; - char *text4 = "***********************************\n"; - char *text5 = "\n"; - DWORD dummy; - double starttime; - static int in_sys_error0 = 0; - static int in_sys_error1 = 0; - static int in_sys_error2 = 0; - static int in_sys_error3 = 0; - - if (!in_sys_error3) - { - in_sys_error3 = 1; - VID_ForceUnlockedAndReturnState (); - } - - va_start (argptr, error); - vsprintf (text, error, argptr); - va_end (argptr); - - if (isDedicated) - { - va_start (argptr, error); - vsprintf (text, error, argptr); - va_end (argptr); - - sprintf (text2, "ERROR: %s\n", text); - WriteFile (houtput, text5, strlen (text5), &dummy, NULL); - WriteFile (houtput, text4, strlen (text4), &dummy, NULL); - WriteFile (houtput, text2, strlen (text2), &dummy, NULL); - WriteFile (houtput, text3, strlen (text3), &dummy, NULL); - WriteFile (houtput, text4, strlen (text4), &dummy, NULL); - - - starttime = Sys_FloatTime (); - sc_return_on_enter = true; // so Enter will get us out of here - - while (!Sys_ConsoleInput () && - ((Sys_FloatTime () - starttime) < CONSOLE_ERROR_TIMEOUT)) - { - } - } - else - { - // switch to windowed so the message box is visible, unless we already - // tried that and failed - if (!in_sys_error0) - { - in_sys_error0 = 1; - VID_SetDefaultMode (); - MessageBox(NULL, text, "Quake Error", - MB_OK | MB_SETFOREGROUND | MB_ICONSTOP); - } - else - { - MessageBox(NULL, text, "Double Quake Error", - MB_OK | MB_SETFOREGROUND | MB_ICONSTOP); - } - } - - if (!in_sys_error1) - { - in_sys_error1 = 1; - Host_Shutdown (); - } - -// shut down QHOST hooks if necessary - if (!in_sys_error2) - { - in_sys_error2 = 1; - DeinitConProc (); - } - - exit (1); -} - -void Sys_Printf_Obsolete (char *fmt, ...) -{ - va_list argptr; - char text[1024]; - DWORD dummy; - - if (isDedicated) - { - va_start (argptr,fmt); - vsprintf (text, fmt, argptr); - va_end (argptr); - - WriteFile(houtput, text, strlen (text), &dummy, NULL); - } -} - -void Sys_Quit_Obsolete (void) -{ - - VID_ForceUnlockedAndReturnState (); - - Host_Shutdown(); - - if (tevent) - CloseHandle (tevent); - - if (isDedicated) - FreeConsole (); - -// shut down QHOST hooks if necessary - DeinitConProc (); - - exit (0); -} - - -/* -================ -Sys_FloatTime -================ -*/ -double Sys_FloatTime_Win (void) // TODO: obsolete -{ - static int sametimecount; - static unsigned int oldtime; - static int first = 1; - LARGE_INTEGER PerformanceCount; - unsigned int temp, t2; - double time; - - // jkrige - assembly removal - //Sys_PushFPCW_SetHigh (); - // jkrige - assembly removal - - QueryPerformanceCounter (&PerformanceCount); - - temp = ((unsigned int)PerformanceCount.LowPart >> lowshift) | - ((unsigned int)PerformanceCount.HighPart << (32 - lowshift)); - - if (first) - { - oldtime = temp; - first = 0; - } - else - { - // check for turnover or backward time - if ((temp <= oldtime) && ((oldtime - temp) < 0x10000000)) - { - oldtime = temp; // so we can't get stuck - } - else - { - t2 = temp - oldtime; - - time = (double)t2 * pfreq; - oldtime = temp; - - curtime += time; - - if (curtime == lastcurtime) - { - sametimecount++; - - if (sametimecount > 100000) - { - curtime += 1.0; - sametimecount = 0; - } - } - else - { - sametimecount = 0; - } - - lastcurtime = curtime; - } - } - - // jkrige - assembly removal - //Sys_PopFPCW (); - // jkrige - assembly removal - - return curtime; -} - - -/* -================ -Sys_InitFloatTime -================ -*/ -void Sys_InitFloatTime (void) -{ - int j; - - Sys_FloatTime (); - - j = COM_CheckParm("-starttime"); - - if (j) - { - curtime = (double) (Q_atof(com_argv[j+1])); - } - else - { - curtime = 0.0; - } - - lastcurtime = curtime; -} - - -char *Sys_ConsoleInput (void) -{ - static char text[256]; - static int len; - INPUT_RECORD recs[1024]; - int count; - int i, dummy; - int ch, numread, numevents; - - if (!isDedicated) - return NULL; - - - for ( ;; ) - { - if (!GetNumberOfConsoleInputEvents (hinput, &numevents)) - Sys_Error ("Error getting # of console events"); - - if (numevents <= 0) - break; - - if (!ReadConsoleInput(hinput, recs, 1, &numread)) - Sys_Error ("Error reading console input"); - - if (numread != 1) - Sys_Error ("Couldn't read console input"); - - if (recs[0].EventType == KEY_EVENT) - { - if (!recs[0].Event.KeyEvent.bKeyDown) - { - ch = recs[0].Event.KeyEvent.uChar.AsciiChar; - - switch (ch) - { - case '\r': - WriteFile(houtput, "\r\n", 2, &dummy, NULL); - - if (len) - { - text[len] = 0; - len = 0; - return text; - } - else if (sc_return_on_enter) - { - // special case to allow exiting from the error handler on Enter - text[0] = '\r'; - len = 0; - return text; - } - - break; - - case '\b': - WriteFile(houtput, "\b \b", 3, &dummy, NULL); - if (len) - { - len--; - } - break; - - default: - if (ch >= ' ') - { - WriteFile(houtput, &ch, 1, &dummy, NULL); - text[len] = ch; - len = (len + 1) & 0xff; - } - - break; - - } - } - } - } - - return NULL; -} - -void Sys_Sleep (void) -{ - Sleep (1); -} - - -void Sys_SendKeyEvents (void) -{ - MSG msg; - - while (PeekMessage (&msg, NULL, 0, 0, PM_NOREMOVE)) - { - // we always update if there are any event, even if we're paused - scr_skipupdate = 0; - - if (!GetMessage (&msg, NULL, 0, 0)) - Sys_Quit (); - - TranslateMessage (&msg); - DispatchMessage (&msg); - } -} - - -/* -============================================================================== - - WINDOWS CRAP - -============================================================================== -*/ - - -/* -================== -WinMain -================== -*/ -void SleepUntilInput (int time) -{ - - MsgWaitForMultipleObjects(1, &tevent, FALSE, time, QS_ALLINPUT); -} - - -/* -================== -WinMain -================== -*/ -HINSTANCE global_hInstance; -int global_nCmdShow; -char *argv[MAX_NUM_ARGVS]; -static char *empty_string = ""; -HWND hwnd_dialog; - - -int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) -{ - MSG msg; - quakeparms_t parms; - double time, oldtime, newtime; - MEMORYSTATUS lpBuffer; - static char cwd[1024]; - int t; - RECT rect; - - /* previous instances do not exist in Win32 */ - if (hPrevInstance) - return 0; - - global_hInstance = hInstance; - global_nCmdShow = nCmdShow; - - lpBuffer.dwLength = sizeof(MEMORYSTATUS); - GlobalMemoryStatus (&lpBuffer); - - if (!GetCurrentDirectory (sizeof(cwd), cwd)) - Sys_Error ("Couldn't determine current directory"); - - if (cwd[Q_strlen(cwd)-1] == '/') - cwd[Q_strlen(cwd)-1] = 0; - - parms.basedir = cwd; - parms.cachedir = NULL; - - parms.argc = 1; - argv[0] = empty_string; - - while (*lpCmdLine && (parms.argc < MAX_NUM_ARGVS)) - { - while (*lpCmdLine && ((*lpCmdLine <= 32) || (*lpCmdLine > 126))) - lpCmdLine++; - - if (*lpCmdLine) - { - argv[parms.argc] = lpCmdLine; - parms.argc++; - - while (*lpCmdLine && ((*lpCmdLine > 32) && (*lpCmdLine <= 126))) - lpCmdLine++; - - if (*lpCmdLine) - { - *lpCmdLine = 0; - lpCmdLine++; - } - - } - } - - parms.argv = argv; - - COM_InitArgv (parms.argc, parms.argv); - - parms.argc = com_argc; - parms.argv = com_argv; - - isDedicated = (COM_CheckParm ("-dedicated") != 0); - - if (!isDedicated) - { - hwnd_dialog = CreateDialog(hInstance, MAKEINTRESOURCE(IDD_DIALOG1), NULL, NULL); - - if (hwnd_dialog) - { - if (GetWindowRect (hwnd_dialog, &rect)) - { - if (rect.left > (rect.top * 2)) - { - SetWindowPos (hwnd_dialog, 0, - (rect.left / 2) - ((rect.right - rect.left) / 2), - rect.top, 0, 0, - SWP_NOZORDER | SWP_NOSIZE); - } - } - - ShowWindow (hwnd_dialog, SW_SHOWDEFAULT); - UpdateWindow (hwnd_dialog); - SetForegroundWindow (hwnd_dialog); - } - } - -// take the greater of all the available memory or half the total memory, -// but at least 8 Mb and no more than 16 Mb, unless they explicitly -// request otherwise - parms.memsize = lpBuffer.dwAvailPhys; - - if (parms.memsize < MINIMUM_WIN_MEMORY) - parms.memsize = MINIMUM_WIN_MEMORY; - - if (parms.memsize < (lpBuffer.dwTotalPhys >> 1)) - parms.memsize = lpBuffer.dwTotalPhys >> 1; - - if (parms.memsize > MAXIMUM_WIN_MEMORY) - parms.memsize = MAXIMUM_WIN_MEMORY; - - if (COM_CheckParm ("-heapsize")) - { - t = COM_CheckParm("-heapsize") + 1; - - if (t < com_argc) - parms.memsize = Q_atoi (com_argv[t]) * 1024; - } - - parms.membase = malloc (parms.memsize); - - if (!parms.membase) - Sys_Error ("Not enough memory free; check disk space\n"); - - Sys_PageIn (parms.membase, parms.memsize); - - tevent = CreateEvent(NULL, FALSE, FALSE, NULL); - - if (!tevent) - Sys_Error ("Couldn't create event"); - - if (isDedicated) - { - if (!AllocConsole ()) - { - Sys_Error ("Couldn't create dedicated server console"); - } - - hinput = GetStdHandle (STD_INPUT_HANDLE); - houtput = GetStdHandle (STD_OUTPUT_HANDLE); - - // give QHOST a chance to hook into the console - if ((t = COM_CheckParm ("-HFILE")) > 0) - { - if (t < com_argc) - hFile = (HANDLE)Q_atoi (com_argv[t+1]); - } - - if ((t = COM_CheckParm ("-HPARENT")) > 0) - { - if (t < com_argc) - heventParent = (HANDLE)Q_atoi (com_argv[t+1]); - } - - if ((t = COM_CheckParm ("-HCHILD")) > 0) - { - if (t < com_argc) - heventChild = (HANDLE)Q_atoi (com_argv[t+1]); - } - - InitConProc (hFile, heventParent, heventChild); - } - - Sys_Init (); - -// because sound is off until we become active - S_BlockSound (); - - Sys_Printf ("Host_Init\n"); - Host_Init (&parms); - - oldtime = Sys_FloatTime (); - - /* main window message loop */ - while (1) - { - if (isDedicated) - { - newtime = Sys_FloatTime (); - time = newtime - oldtime; - - while (time < sys_ticrate.value ) - { - Sys_Sleep(); - newtime = Sys_FloatTime (); - time = newtime - oldtime; - } - } - else - { - // yield the CPU for a little while when paused, minimized, or not the focus - if ((cl.paused && (!ActiveApp && !DDActive)) || Minimized || block_drawing) - { - SleepUntilInput (PAUSE_SLEEP); - scr_skipupdate = 1; // no point in bothering to draw - } - else if (!ActiveApp && !DDActive) - { - SleepUntilInput (NOT_FOCUS_SLEEP); - } - - newtime = Sys_FloatTime (); - time = newtime - oldtime; - } - - Host_Frame (time); - oldtime = newtime; - } - - /* return success of application */ - return TRUE; -} - diff --git a/engine/code/unzip.c b/engine/code/unzip.c deleted file mode 100644 index 295f254..0000000 --- a/engine/code/unzip.c +++ /dev/null @@ -1,4321 +0,0 @@ -/***************************************************************************** - * name: unzip.c - * - * desc: IO on .zip files using portions of zlib - * - * $Archive: /MissionPack/code/qcommon/unzip.c $ - * - *****************************************************************************/ - -//#include "../client/client.h" -#include "quakedef.h" -//#include "unzip.h" - -/* unzip.h -- IO for uncompress .zip files using zlib - Version 0.15 beta, Mar 19th, 1998, - - Copyright (C) 1998 Gilles Vollant - - This unzip package allow extract file from .ZIP file, compatible with PKZip 2.04g - WinZip, InfoZip tools and compatible. - Encryption and multi volume ZipFile (span) are not supported. - Old compressions used by old PKZip 1.x are not supported - - THIS IS AN ALPHA VERSION. AT THIS STAGE OF DEVELOPPEMENT, SOMES API OR STRUCTURE - CAN CHANGE IN FUTURE VERSION !! - I WAIT FEEDBACK at mail info@winimage.com - Visit also http://www.winimage.com/zLibDll/unzip.htm for evolution - - Condition of use and distribution are the same than zlib : - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - -*/ -/* for more info about .ZIP format, see - ftp://ftp.cdrom.com/pub/infozip/doc/appnote-970311-iz.zip - PkWare has also a specification at : - ftp://ftp.pkware.com/probdesc.zip */ - -/* zlib.h -- interface of the 'zlib' general purpose compression library - version 1.1.3, July 9th, 1998 - - Copyright (C) 1995-1998 Jean-loup Gailly and Mark Adler - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - Jean-loup Gailly Mark Adler - jloup@gzip.org madler@alumni.caltech.edu - - - The data format used by the zlib library is described by RFCs (Request for - Comments) 1950 to 1952 in the files ftp://ds.internic.net/rfc/rfc1950.txt - (zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format). -*/ - -/* zconf.h -- configuration of the zlib compression library - * Copyright (C) 1995-1998 Jean-loup Gailly. - * For conditions of distribution and use, see copyright notice in zlib.h - */ - - -#ifndef _ZCONF_H -#define _ZCONF_H - -/* Maximum value for memLevel in deflateInit2 */ -#ifndef MAX_MEM_LEVEL -# ifdef MAXSEG_64K -# define MAX_MEM_LEVEL 8 -# else -# define MAX_MEM_LEVEL 9 -# endif -#endif - -/* Maximum value for windowBits in deflateInit2 and inflateInit2. - * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files - * created by gzip. (Files created by minigzip can still be extracted by - * gzip.) - */ -#ifndef MAX_WBITS -# define MAX_WBITS 15 /* 32K LZ77 window */ -#endif - -/* The memory requirements for deflate are (in bytes): - (1 << (windowBits+2)) + (1 << (memLevel+9)) - that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values) - plus a few kilobytes for small objects. For example, if you want to reduce - the default memory requirements from 256K to 128K, compile with - make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7" - Of course this will generally degrade compression (there's no free lunch). - - The memory requirements for inflate are (in bytes) 1 << windowBits - that is, 32K for windowBits=15 (default value) plus a few kilobytes - for small objects. -*/ - - /* Type declarations */ - -#ifndef OF /* function prototypes */ -#define OF(args) args -#endif - -typedef unsigned char Byte; /* 8 bits */ -typedef unsigned int uInt; /* 16 bits or more */ -typedef unsigned long uLong; /* 32 bits or more */ -typedef Byte *voidp; - -#ifndef SEEK_SET -# define SEEK_SET 0 /* Seek from beginning of file. */ -# define SEEK_CUR 1 /* Seek from current position. */ -# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */ -#endif - -#endif /* _ZCONF_H */ - -#define ZLIB_VERSION "1.1.3" - -/* - The 'zlib' compression library provides in-memory compression and - decompression functions, including integrity checks of the uncompressed - data. This version of the library supports only one compression method - (deflation) but other algorithms will be added later and will have the same - stream interface. - - Compression can be done in a single step if the buffers are large - enough (for example if an input file is mmap'ed), or can be done by - repeated calls of the compression function. In the latter case, the - application must provide more input and/or consume the output - (providing more output space) before each call. - - The library also supports reading and writing files in gzip (.gz) format - with an interface similar to that of stdio. - - The library does not install any signal handler. The decoder checks - the consistency of the compressed data, so the library should never - crash even in case of corrupted input. -*/ - -/* - The application must update next_in and avail_in when avail_in has - dropped to zero. It must update next_out and avail_out when avail_out - has dropped to zero. The application must initialize zalloc, zfree and - opaque before calling the init function. All other fields are set by the - compression library and must not be updated by the application. - - The opaque value provided by the application will be passed as the first - parameter for calls of zalloc and zfree. This can be useful for custom - memory management. The compression library attaches no meaning to the - opaque value. - - zalloc must return Z_NULL if there is not enough memory for the object. - If zlib is used in a multi-threaded application, zalloc and zfree must be - thread safe. - - On 16-bit systems, the functions zalloc and zfree must be able to allocate - exactly 65536 bytes, but will not be required to allocate more than this - if the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS, - pointers returned by zalloc for objects of exactly 65536 bytes *must* - have their offset normalized to zero. The default allocation function - provided by this library ensures this (see zutil.c). To reduce memory - requirements and avoid any allocation of 64K objects, at the expense of - compression ratio, compile the library with -DMAX_WBITS=14 (see zconf.h). - - The fields total_in and total_out can be used for statistics or - progress reports. After compression, total_in holds the total size of - the uncompressed data and may be saved for use in the decompressor - (particularly if the decompressor wants to decompress everything in - a single step). -*/ - - /* constants */ - -#define Z_NO_FLUSH 0 -#define Z_PARTIAL_FLUSH 1 /* will be removed, use Z_SYNC_FLUSH instead */ -#define Z_SYNC_FLUSH 2 -#define Z_FULL_FLUSH 3 -#define Z_FINISH 4 -/* Allowed flush values; see deflate() below for details */ - -#define Z_OK 0 -#define Z_STREAM_END 1 -#define Z_NEED_DICT 2 -#define Z_ERRNO (-1) -#define Z_STREAM_ERROR (-2) -#define Z_DATA_ERROR (-3) -#define Z_MEM_ERROR (-4) -#define Z_BUF_ERROR (-5) -#define Z_VERSION_ERROR (-6) -/* Return codes for the compression/decompression functions. Negative - * values are errors, positive values are used for special but normal events. - */ - -#define Z_NO_COMPRESSION 0 -#define Z_BEST_SPEED 1 -#define Z_BEST_COMPRESSION 9 -#define Z_DEFAULT_COMPRESSION (-1) -/* compression levels */ - -#define Z_FILTERED 1 -#define Z_HUFFMAN_ONLY 2 -#define Z_DEFAULT_STRATEGY 0 -/* compression strategy; see deflateInit2() below for details */ - -#define Z_BINARY 0 -#define Z_ASCII 1 -#define Z_UNKNOWN 2 -/* Possible values of the data_type field */ - -#define Z_DEFLATED 8 -/* The deflate compression method (the only one supported in this version) */ - -#define Z_NULL 0 /* for initializing zalloc, zfree, opaque */ - -#define zlib_version zlibVersion() -/* for compatibility with versions < 1.0.2 */ - - /* basic functions */ - -// static const char * zlibVersion OF((void)); -/* The application can compare zlibVersion and ZLIB_VERSION for consistency. - If the first character differs, the library code actually used is - not compatible with the zlib.h header file used by the application. - This check is automatically made by deflateInit and inflateInit. - */ - -/* -int deflateInit OF((z_streamp strm, int level)); - - Initializes the internal stream state for compression. The fields - zalloc, zfree and opaque must be initialized before by the caller. - If zalloc and zfree are set to Z_NULL, deflateInit updates them to - use default allocation functions. - - The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9: - 1 gives best speed, 9 gives best compression, 0 gives no compression at - all (the input data is simply copied a block at a time). - Z_DEFAULT_COMPRESSION requests a default compromise between speed and - compression (currently equivalent to level 6). - - deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not - enough memory, Z_STREAM_ERROR if level is not a valid compression level, - Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible - with the version assumed by the caller (ZLIB_VERSION). - msg is set to null if there is no error message. deflateInit does not - perform any compression: this will be done by deflate(). -*/ - - -// static int deflate OF((z_streamp strm, int flush)); -/* - deflate compresses as much data as possible, and stops when the input - buffer becomes empty or the output buffer becomes full. It may introduce some - output latency (reading input without producing any output) except when - forced to flush. - - The detailed semantics are as follows. deflate performs one or both of the - following actions: - - - Compress more input starting at next_in and update next_in and avail_in - accordingly. If not all input can be processed (because there is not - enough room in the output buffer), next_in and avail_in are updated and - processing will resume at this point for the next call of deflate(). - - - Provide more output starting at next_out and update next_out and avail_out - accordingly. This action is forced if the parameter flush is non zero. - Forcing flush frequently degrades the compression ratio, so this parameter - should be set only when necessary (in interactive applications). - Some output may be provided even if flush is not set. - - Before the call of deflate(), the application should ensure that at least - one of the actions is possible, by providing more input and/or consuming - more output, and updating avail_in or avail_out accordingly; avail_out - should never be zero before the call. The application can consume the - compressed output when it wants, for example when the output buffer is full - (avail_out == 0), or after each call of deflate(). If deflate returns Z_OK - and with zero avail_out, it must be called again after making room in the - output buffer because there might be more output pending. - - If the parameter flush is set to Z_SYNC_FLUSH, all pending output is - flushed to the output buffer and the output is aligned on a byte boundary, so - that the decompressor can get all input data available so far. (In particular - avail_in is zero after the call if enough output space has been provided - before the call.) Flushing may degrade compression for some compression - algorithms and so it should be used only when necessary. - - If flush is set to Z_FULL_FLUSH, all output is flushed as with - Z_SYNC_FLUSH, and the compression state is reset so that decompression can - restart from this point if previous compressed data has been damaged or if - random access is desired. Using Z_FULL_FLUSH too often can seriously degrade - the compression. - - If deflate returns with avail_out == 0, this function must be called again - with the same value of the flush parameter and more output space (updated - avail_out), until the flush is complete (deflate returns with non-zero - avail_out). - - If the parameter flush is set to Z_FINISH, pending input is processed, - pending output is flushed and deflate returns with Z_STREAM_END if there - was enough output space; if deflate returns with Z_OK, this function must be - called again with Z_FINISH and more output space (updated avail_out) but no - more input data, until it returns with Z_STREAM_END or an error. After - deflate has returned Z_STREAM_END, the only possible operations on the - stream are deflateReset or deflateEnd. - - Z_FINISH can be used immediately after deflateInit if all the compression - is to be done in a single step. In this case, avail_out must be at least - 0.1% larger than avail_in plus 12 bytes. If deflate does not return - Z_STREAM_END, then it must be called again as described above. - - deflate() sets strm->adler to the adler32 checksum of all input read - so (that is, total_in bytes). - - deflate() may update data_type if it can make a good guess about - the input data type (Z_ASCII or Z_BINARY). In doubt, the data is considered - binary. This field is only for information purposes and does not affect - the compression algorithm in any manner. - - deflate() returns Z_OK if some progress has been made (more input - processed or more output produced), Z_STREAM_END if all input has been - consumed and all output has been produced (only when flush is set to - Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example - if next_in or next_out was NULL), Z_BUF_ERROR if no progress is possible - (for example avail_in or avail_out was zero). -*/ - - -// static int deflateEnd OF((z_streamp strm)); -/* - All dynamically allocated data structures for this stream are freed. - This function discards any unprocessed input and does not flush any - pending output. - - deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the - stream state was inconsistent, Z_DATA_ERROR if the stream was freed - prematurely (some input or output was discarded). In the error case, - msg may be set but then points to a static string (which must not be - deallocated). -*/ - - -/* -int inflateInit OF((z_streamp strm)); - - Initializes the internal stream state for decompression. The fields - next_in, avail_in, zalloc, zfree and opaque must be initialized before by - the caller. If next_in is not Z_NULL and avail_in is large enough (the exact - value depends on the compression method), inflateInit determines the - compression method from the zlib header and allocates all data structures - accordingly; otherwise the allocation will be deferred to the first call of - inflate. If zalloc and zfree are set to Z_NULL, inflateInit updates them to - use default allocation functions. - - inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough - memory, Z_VERSION_ERROR if the zlib library version is incompatible with the - version assumed by the caller. msg is set to null if there is no error - message. inflateInit does not perform any decompression apart from reading - the zlib header if present: this will be done by inflate(). (So next_in and - avail_in may be modified, but next_out and avail_out are unchanged.) -*/ - - -static int inflate OF((z_streamp strm, int flush)); -/* - inflate decompresses as much data as possible, and stops when the input - buffer becomes empty or the output buffer becomes full. It may some - introduce some output latency (reading input without producing any output) - except when forced to flush. - - The detailed semantics are as follows. inflate performs one or both of the - following actions: - - - Decompress more input starting at next_in and update next_in and avail_in - accordingly. If not all input can be processed (because there is not - enough room in the output buffer), next_in is updated and processing - will resume at this point for the next call of inflate(). - - - Provide more output starting at next_out and update next_out and avail_out - accordingly. inflate() provides as much output as possible, until there - is no more input data or no more space in the output buffer (see below - about the flush parameter). - - Before the call of inflate(), the application should ensure that at least - one of the actions is possible, by providing more input and/or consuming - more output, and updating the next_* and avail_* values accordingly. - The application can consume the uncompressed output when it wants, for - example when the output buffer is full (avail_out == 0), or after each - call of inflate(). If inflate returns Z_OK and with zero avail_out, it - must be called again after making room in the output buffer because there - might be more output pending. - - If the parameter flush is set to Z_SYNC_FLUSH, inflate flushes as much - output as possible to the output buffer. The flushing behavior of inflate is - not specified for values of the flush parameter other than Z_SYNC_FLUSH - and Z_FINISH, but the current implementation actually flushes as much output - as possible anyway. - - inflate() should normally be called until it returns Z_STREAM_END or an - error. However if all decompression is to be performed in a single step - (a single call of inflate), the parameter flush should be set to - Z_FINISH. In this case all pending input is processed and all pending - output is flushed; avail_out must be large enough to hold all the - uncompressed data. (The size of the uncompressed data may have been saved - by the compressor for this purpose.) The next operation on this stream must - be inflateEnd to deallocate the decompression state. The use of Z_FINISH - is never required, but can be used to inform inflate that a faster routine - may be used for the single inflate() call. - - If a preset dictionary is needed at this point (see inflateSetDictionary - below), inflate sets strm-adler to the adler32 checksum of the - dictionary chosen by the compressor and returns Z_NEED_DICT; otherwise - it sets strm->adler to the adler32 checksum of all output produced - so (that is, total_out bytes) and returns Z_OK, Z_STREAM_END or - an error code as described below. At the end of the stream, inflate() - checks that its computed adler32 checksum is equal to that saved by the - compressor and returns Z_STREAM_END only if the checksum is correct. - - inflate() returns Z_OK if some progress has been made (more input processed - or more output produced), Z_STREAM_END if the end of the compressed data has - been reached and all uncompressed output has been produced, Z_NEED_DICT if a - preset dictionary is needed at this point, Z_DATA_ERROR if the input data was - corrupted (input stream not conforming to the zlib format or incorrect - adler32 checksum), Z_STREAM_ERROR if the stream structure was inconsistent - (for example if next_in or next_out was NULL), Z_MEM_ERROR if there was not - enough memory, Z_BUF_ERROR if no progress is possible or if there was not - enough room in the output buffer when Z_FINISH is used. In the Z_DATA_ERROR - case, the application may then call inflateSync to look for a good - compression block. -*/ - - -static int inflateEnd OF((z_streamp strm)); -/* - All dynamically allocated data structures for this stream are freed. - This function discards any unprocessed input and does not flush any - pending output. - - inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state - was inconsistent. In the error case, msg may be set but then points to a - static string (which must not be deallocated). -*/ - - /* Advanced functions */ - -/* - The following functions are needed only in some special applications. -*/ - -/* -int deflateInit2 OF((z_streamp strm, - int level, - int method, - int windowBits, - int memLevel, - int strategy)); - - This is another version of deflateInit with more compression options. The - fields next_in, zalloc, zfree and opaque must be initialized before by - the caller. - - The method parameter is the compression method. It must be Z_DEFLATED in - this version of the library. - - The windowBits parameter is the base two logarithm of the window size - (the size of the history buffer). It should be in the range 8..15 for this - version of the library. Larger values of this parameter result in better - compression at the expense of memory usage. The default value is 15 if - deflateInit is used instead. - - The memLevel parameter specifies how much memory should be allocated - for the internal compression state. memLevel=1 uses minimum memory but - is slow and reduces compression ratio; memLevel=9 uses maximum memory - for optimal speed. The default value is 8. See zconf.h for total memory - usage as a function of windowBits and memLevel. - - The strategy parameter is used to tune the compression algorithm. Use the - value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a - filter (or predictor), or Z_HUFFMAN_ONLY to force Huffman encoding only (no - string match). Filtered data consists mostly of small values with a - somewhat random distribution. In this case, the compression algorithm is - tuned to compress them better. The effect of Z_FILTERED is to force more - Huffman coding and less string matching; it is somewhat intermediate - between Z_DEFAULT and Z_HUFFMAN_ONLY. The strategy parameter only affects - the compression ratio but not the correctness of the compressed output even - if it is not set appropriately. - - deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough - memory, Z_STREAM_ERROR if a parameter is invalid (such as an invalid - method). msg is set to null if there is no error message. deflateInit2 does - not perform any compression: this will be done by deflate(). -*/ - -/* -static int deflateSetDictionary OF((z_streamp strm, - const Byte *dictionary, - uInt dictLength)); -*/ -/* - Initializes the compression dictionary from the given byte sequence - without producing any compressed output. This function must be called - immediately after deflateInit, deflateInit2 or deflateReset, before any - call of deflate. The compressor and decompressor must use exactly the same - dictionary (see inflateSetDictionary). - - The dictionary should consist of strings (byte sequences) that are likely - to be encountered later in the data to be compressed, with the most commonly - used strings preferably put towards the end of the dictionary. Using a - dictionary is most useful when the data to be compressed is short and can be - predicted with good accuracy; the data can then be compressed better than - with the default empty dictionary. - - Depending on the size of the compression data structures selected by - deflateInit or deflateInit2, a part of the dictionary may in effect be - discarded, for example if the dictionary is larger than the window size in - deflate or deflate2. Thus the strings most likely to be useful should be - put at the end of the dictionary, not at the front. - - Upon return of this function, strm->adler is set to the Adler32 value - of the dictionary; the decompressor may later use this value to determine - which dictionary has been used by the compressor. (The Adler32 value - applies to the whole dictionary even if only a subset of the dictionary is - actually used by the compressor.) - - deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a - parameter is invalid (such as NULL dictionary) or the stream state is - inconsistent (for example if deflate has already been called for this stream - or if the compression method is bsort). deflateSetDictionary does not - perform any compression: this will be done by deflate(). -*/ - -/* -static int deflateCopy OF((z_streamp dest, - z_streamp source)); -*/ -/* - Sets the destination stream as a complete copy of the source stream. - - This function can be useful when several compression strategies will be - tried, for example when there are several ways of pre-processing the input - data with a filter. The streams that will be discarded should then be freed - by calling deflateEnd. Note that deflateCopy duplicates the internal - compression state which can be quite large, so this strategy is slow and - can consume lots of memory. - - deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not - enough memory, Z_STREAM_ERROR if the source stream state was inconsistent - (such as zalloc being NULL). msg is left unchanged in both source and - destination. -*/ - -// static int deflateReset OF((z_streamp strm)); -/* - This function is equivalent to deflateEnd followed by deflateInit, - but does not free and reallocate all the internal compression state. - The stream will keep the same compression level and any other attributes - that may have been set by deflateInit2. - - deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source - stream state was inconsistent (such as zalloc or state being NULL). -*/ - -/* -static int deflateParams OF((z_streamp strm, - int level, - int strategy)); -*/ -/* - Dynamically update the compression level and compression strategy. The - interpretation of level and strategy is as in deflateInit2. This can be - used to switch between compression and straight copy of the input data, or - to switch to a different kind of input data requiring a different - strategy. If the compression level is changed, the input available so far - is compressed with the old level (and may be flushed); the new level will - take effect only at the next call of deflate(). - - Before the call of deflateParams, the stream state must be set as for - a call of deflate(), since the currently available input may have to - be compressed and flushed. In particular, strm->avail_out must be non-zero. - - deflateParams returns Z_OK if success, Z_STREAM_ERROR if the source - stream state was inconsistent or if a parameter was invalid, Z_BUF_ERROR - if strm->avail_out was zero. -*/ - -/* -int inflateInit2 OF((z_streamp strm, - int windowBits)); - - This is another version of inflateInit with an extra parameter. The - fields next_in, avail_in, zalloc, zfree and opaque must be initialized - before by the caller. - - The windowBits parameter is the base two logarithm of the maximum window - size (the size of the history buffer). It should be in the range 8..15 for - this version of the library. The default value is 15 if inflateInit is used - instead. If a compressed stream with a larger window size is given as - input, inflate() will return with the error code Z_DATA_ERROR instead of - trying to allocate a larger window. - - inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough - memory, Z_STREAM_ERROR if a parameter is invalid (such as a negative - memLevel). msg is set to null if there is no error message. inflateInit2 - does not perform any decompression apart from reading the zlib header if - present: this will be done by inflate(). (So next_in and avail_in may be - modified, but next_out and avail_out are unchanged.) -*/ - -/* -static int inflateSetDictionary OF((z_streamp strm, - const Byte *dictionary, - uInt dictLength)); -*/ -/* - Initializes the decompression dictionary from the given uncompressed byte - sequence. This function must be called immediately after a call of inflate - if this call returned Z_NEED_DICT. The dictionary chosen by the compressor - can be determined from the Adler32 value returned by this call of - inflate. The compressor and decompressor must use exactly the same - dictionary (see deflateSetDictionary). - - inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a - parameter is invalid (such as NULL dictionary) or the stream state is - inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the - expected one (incorrect Adler32 value). inflateSetDictionary does not - perform any decompression: this will be done by subsequent calls of - inflate(). -*/ - -// static int inflateSync OF((z_streamp strm)); -/* - Skips invalid compressed data until a full flush point (see above the - description of deflate with Z_FULL_FLUSH) can be found, or until all - available input is skipped. No output is provided. - - inflateSync returns Z_OK if a full flush point has been found, Z_BUF_ERROR - if no more input was provided, Z_DATA_ERROR if no flush point has been found, - or Z_STREAM_ERROR if the stream structure was inconsistent. In the success - case, the application may save the current current value of total_in which - indicates where valid compressed data was found. In the error case, the - application may repeatedly call inflateSync, providing more input each time, - until success or end of the input data. -*/ - -static int inflateReset OF((z_streamp strm)); -/* - This function is equivalent to inflateEnd followed by inflateInit, - but does not free and reallocate all the internal decompression state. - The stream will keep attributes that may have been set by inflateInit2. - - inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source - stream state was inconsistent (such as zalloc or state being NULL). -*/ - - - /* utility functions */ - -/* - The following utility functions are implemented on top of the - basic stream-oriented functions. To simplify the interface, some - default options are assumed (compression level and memory usage, - standard memory allocation functions). The source code of these - utility functions can easily be modified if you need special options. -*/ - -/* -static int compress OF((Byte *dest, uLong *destLen, - const Byte *source, uLong sourceLen)); -*/ -/* - Compresses the source buffer into the destination buffer. sourceLen is - the byte length of the source buffer. Upon entry, destLen is the total - size of the destination buffer, which must be at least 0.1% larger than - sourceLen plus 12 bytes. Upon exit, destLen is the actual size of the - compressed buffer. - This function can be used to compress a whole file at once if the - input file is mmap'ed. - compress returns Z_OK if success, Z_MEM_ERROR if there was not - enough memory, Z_BUF_ERROR if there was not enough room in the output - buffer. -*/ - -/* -static int compress2 OF((Byte *dest, uLong *destLen, - const Byte *source, uLong sourceLen, - int level)); -*/ -/* - Compresses the source buffer into the destination buffer. The level - parameter has the same meaning as in deflateInit. sourceLen is the byte - length of the source buffer. Upon entry, destLen is the total size of the - destination buffer, which must be at least 0.1% larger than sourceLen plus - 12 bytes. Upon exit, destLen is the actual size of the compressed buffer. - - compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough - memory, Z_BUF_ERROR if there was not enough room in the output buffer, - Z_STREAM_ERROR if the level parameter is invalid. -*/ - -/* -static int uncompress OF((Byte *dest, uLong *destLen, - const Byte *source, uLong sourceLen)); -*/ -/* - Decompresses the source buffer into the destination buffer. sourceLen is - the byte length of the source buffer. Upon entry, destLen is the total - size of the destination buffer, which must be large enough to hold the - entire uncompressed data. (The size of the uncompressed data must have - been saved previously by the compressor and transmitted to the decompressor - by some mechanism outside the scope of this compression library.) - Upon exit, destLen is the actual size of the compressed buffer. - This function can be used to decompress a whole file at once if the - input file is mmap'ed. - - uncompress returns Z_OK if success, Z_MEM_ERROR if there was not - enough memory, Z_BUF_ERROR if there was not enough room in the output - buffer, or Z_DATA_ERROR if the input data was corrupted. -*/ - - -typedef voidp gzFile; - -gzFile gzopen OF((const char *path, const char *mode)); -/* - Opens a gzip (.gz) file for reading or writing. The mode parameter - is as in fopen ("rb" or "wb") but can also include a compression level - ("wb9") or a strategy: 'f' for filtered data as in "wb6f", 'h' for - Huffman only compression as in "wb1h". (See the description - of deflateInit2 for more information about the strategy parameter.) - - gzopen can be used to read a file which is not in gzip format; in this - case gzread will directly read from the file without decompression. - - gzopen returns NULL if the file could not be opened or if there was - insufficient memory to allocate the (de)compression state; errno - can be checked to distinguish the two cases (if errno is zero, the - zlib error is Z_MEM_ERROR). */ - -gzFile gzdopen OF((int fd, const char *mode)); -/* - gzdopen() associates a gzFile with the file descriptor fd. File - descriptors are obtained from calls like open, dup, creat, pipe or - fileno (in the file has been previously opened with fopen). - The mode parameter is as in gzopen. - The next call of gzclose on the returned gzFile will also close the - file descriptor fd, just like fclose(fdopen(fd), mode) closes the file - descriptor fd. If you want to keep fd open, use gzdopen(dup(fd), mode). - gzdopen returns NULL if there was insufficient memory to allocate - the (de)compression state. -*/ - -int gzsetparams OF((gzFile file, int level, int strategy)); -/* - Dynamically update the compression level or strategy. See the description - of deflateInit2 for the meaning of these parameters. - gzsetparams returns Z_OK if success, or Z_STREAM_ERROR if the file was not - opened for writing. -*/ - -int gzread OF((gzFile file, voidp buf, unsigned len)); -/* - Reads the given number of uncompressed bytes from the compressed file. - If the input file was not in gzip format, gzread copies the given number - of bytes into the buffer. - gzread returns the number of uncompressed bytes actually read (0 for - end of file, -1 for error). */ - -int gzwrite OF((gzFile file, - const voidp buf, unsigned len)); -/* - Writes the given number of uncompressed bytes into the compressed file. - gzwrite returns the number of uncompressed bytes actually written - (0 in case of error). -*/ - -//int QDECL gzprintf OF((gzFile file, const char *format, ...)); jkrige -/* - Converts, formats, and writes the args to the compressed file under - control of the format string, as in fprintf. gzprintf returns the number of - uncompressed bytes actually written (0 in case of error). -*/ - -int gzputs OF((gzFile file, const char *s)); -/* - Writes the given null-terminated string to the compressed file, excluding - the terminating null character. - gzputs returns the number of characters written, or -1 in case of error. -*/ - -char * gzgets OF((gzFile file, char *buf, int len)); -/* - Reads bytes from the compressed file until len-1 characters are read, or - a newline character is read and transferred to buf, or an end-of-file - condition is encountered. The string is then terminated with a null - character. - gzgets returns buf, or Z_NULL in case of error. -*/ - -int gzputc OF((gzFile file, int c)); -/* - Writes c, converted to an unsigned char, into the compressed file. - gzputc returns the value that was written, or -1 in case of error. -*/ - -int gzgetc OF((gzFile file)); -/* - Reads one byte from the compressed file. gzgetc returns this byte - or -1 in case of end of file or error. -*/ - -int gzflush OF((gzFile file, int flush)); -/* - Flushes all pending output into the compressed file. The parameter - flush is as in the deflate() function. The return value is the zlib - error number (see function gzerror below). gzflush returns Z_OK if - the flush parameter is Z_FINISH and all output could be flushed. - gzflush should be called only when strictly necessary because it can - degrade compression. -*/ - -long gzseek OF((gzFile file, - long offset, int whence)); -/* - Sets the starting position for the next gzread or gzwrite on the - given compressed file. The offset represents a number of bytes in the - uncompressed data stream. The whence parameter is defined as in lseek(2); - the value SEEK_END is not supported. - If the file is opened for reading, this function is emulated but can be - extremely slow. If the file is opened for writing, only forward seeks are - supported; gzseek then compresses a sequence of zeroes up to the new - starting position. - - gzseek returns the resulting offset location as measured in bytes from - the beginning of the uncompressed stream, or -1 in case of error, in - particular if the file is opened for writing and the new starting position - would be before the current position. -*/ - -int gzrewind OF((gzFile file)); -/* - Rewinds the given file. This function is supported only for reading. - - gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET) -*/ - -long gztell OF((gzFile file)); -/* - Returns the starting position for the next gzread or gzwrite on the - given compressed file. This position represents a number of bytes in the - uncompressed data stream. - - gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR) -*/ - -int gzeof OF((gzFile file)); -/* - Returns 1 when EOF has previously been detected reading the given - input stream, otherwise zero. -*/ - -int gzclose OF((gzFile file)); -/* - Flushes all pending output if necessary, closes the compressed file - and deallocates all the (de)compression state. The return value is the zlib - error number (see function gzerror below). -*/ - -// static const char * gzerror OF((gzFile file, int *errnum)); -/* - Returns the error message for the last error which occurred on the - given compressed file. errnum is set to zlib error number. If an - error occurred in the file system and not in the compression library, - errnum is set to Z_ERRNO and the application may consult errno - to get the exact error code. -*/ - - /* checksum functions */ - -/* - These functions are not related to compression but are exported - anyway because they might be useful in applications using the - compression library. -*/ - -static uLong adler32 OF((uLong adler, const Byte *buf, uInt len)); - -/* - Update a running Adler-32 checksum with the bytes buf[0..len-1] and - return the updated checksum. If buf is NULL, this function returns - the required initial value for the checksum. - An Adler-32 checksum is almost as reliable as a CRC32 but can be computed - much faster. Usage example: - - uLong adler = adler32(0L, Z_NULL, 0); - - while (read_buffer(buffer, length) != EOF) { - adler = adler32(adler, buffer, length); - } - if (adler != original_adler) error(); -*/ - - /* various hacks, don't look :) */ - -/* deflateInit and inflateInit are macros to allow checking the zlib version - * and the compiler's view of z_stream: - */ -/* -static int deflateInit_ OF((z_streamp strm, int level, - const char *version, int stream_size)); -static int inflateInit_ OF((z_streamp strm, - const char *version, int stream_size)); -static int deflateInit2_ OF((z_streamp strm, int level, int method, - int windowBits, int memLevel, - int strategy, const char *version, - int stream_size)); -*/ -static int inflateInit2_ OF((z_streamp strm, int windowBits, - const char *version, int stream_size)); - -#define deflateInit(strm, level) \ - deflateInit_((strm), (level), ZLIB_VERSION, sizeof(z_stream)) -#define inflateInit(strm) \ - inflateInit_((strm), ZLIB_VERSION, sizeof(z_stream)) -#define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \ - deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\ - (strategy), ZLIB_VERSION, sizeof(z_stream)) -#define inflateInit2(strm, windowBits) \ - inflateInit2_((strm), (windowBits), ZLIB_VERSION, sizeof(z_stream)) - - -// static const char * zError OF((int err)); -// static int inflateSyncPoint OF((z_streamp z)); -// static const uLong * get_crc_table OF((void)); - -typedef unsigned char uch; -typedef unsigned short ush; -typedef unsigned long ulg; - -// static const char *z_errmsg[10]; /* indexed by 2-zlib_error */ -/* (size given to avoid silly warnings with Visual C++) */ - -#define ERR_MSG(err) z_errmsg[Z_NEED_DICT-(err)] - -#define ERR_RETURN(strm,err) \ - return (strm->msg = (char*)ERR_MSG(err), (err)) -/* To be used only when the state is known to be valid */ - - /* common constants */ - -#ifndef DEF_WBITS -# define DEF_WBITS MAX_WBITS -#endif -/* default windowBits for decompression. MAX_WBITS is for compression only */ - -#if MAX_MEM_LEVEL >= 8 -# define DEF_MEM_LEVEL 8 -#else -# define DEF_MEM_LEVEL MAX_MEM_LEVEL -#endif -/* default memLevel */ - -#define STORED_BLOCK 0 -#define STATIC_TREES 1 -#define DYN_TREES 2 -/* The three kinds of block type */ - -#define MIN_MATCH 3 -#define MAX_MATCH 258 -/* The minimum and maximum match lengths */ - -#define PRESET_DICT 0x20 /* preset dictionary flag in zlib header */ - - /* target dependencies */ - - /* Common defaults */ - -#ifndef OS_CODE -# define OS_CODE 0x03 /* assume Unix */ -#endif - -#ifndef F_OPEN -# define F_OPEN(name, mode) fopen((name), (mode)) -#endif - - /* functions */ - -#ifdef HAVE_STRERROR - extern char *strerror OF((int)); -# define zstrerror(errnum) strerror(errnum) -#else -# define zstrerror(errnum) "" -#endif - -// jkrige -//#define zmemcpy Com_Memcpy -#define zmemcpy memcpy -// jkrige - -#define zmemcmp memcmp -#define zmemzero(dest, len) Com_Memset(dest, 0, len) - -/* Diagnostic functions */ -#ifdef _ZIP_DEBUG_ - int z_verbose = 0; -# define Assert(cond,msg) assert(cond); - //{if(!(cond)) Sys_Error(msg);} -# define Trace(x) {if (z_verbose>=0) Sys_Error x ;} -# define Tracev(x) {if (z_verbose>0) Sys_Error x ;} -# define Tracevv(x) {if (z_verbose>1) Sys_Error x ;} -# define Tracec(c,x) {if (z_verbose>0 && (c)) Sys_Error x ;} -# define Tracecv(c,x) {if (z_verbose>1 && (c)) Sys_Error x ;} -#else -# define Assert(cond,msg) -# define Trace(x) -# define Tracev(x) -# define Tracevv(x) -# define Tracec(c,x) -# define Tracecv(c,x) -#endif - - -typedef uLong (*check_func) OF((uLong check, const Byte *buf, uInt len)); -static voidp zcalloc OF((voidp opaque, unsigned items, unsigned size)); -static void zcfree OF((voidp opaque, voidp ptr)); - -#define ZALLOC(strm, items, size) \ - (*((strm)->zalloc))((strm)->opaque, (items), (size)) -#define ZFREE(strm, addr) (*((strm)->zfree))((strm)->opaque, (voidp)(addr)) -#define TRY_FREE(s, p) {if (p) ZFREE(s, p);} - - -#if !defined(unix) && !defined(CASESENSITIVITYDEFAULT_YES) && \ - !defined(CASESENSITIVITYDEFAULT_NO) -#define CASESENSITIVITYDEFAULT_NO -#endif - - -#ifndef UNZ_BUFSIZE -#define UNZ_BUFSIZE (65536) -#endif - -#ifndef UNZ_MAXFILENAMEINZIP -#define UNZ_MAXFILENAMEINZIP (256) -#endif - -#ifndef ALLOC -// jkrige - pk3 file support -//# define ALLOC(size) (Z_Malloc(size)) -# define ALLOC(size) (malloc(size)) -// jkrige - pk3 file support -#endif -#ifndef TRYFREE -// jkrige - pk3 file support -//# define TRYFREE(p) {if (p) Z_Free(p);} -# define TRYFREE(p) {if (p) free(p);} -// jkrige - pk3 file support -#endif - -#define SIZECENTRALDIRITEM (0x2e) -#define SIZEZIPLOCALHEADER (0x1e) - - - -/* =========================================================================== - Read a byte from a gz_stream; update next_in and avail_in. Return EOF - for end of file. - IN assertion: the stream s has been sucessfully opened for reading. -*/ - -/* -static int unzlocal_getByte(FILE *fin,int *pi) -{ - unsigned char c; - int err = fread(&c, 1, 1, fin); - if (err==1) - { - *pi = (int)c; - return UNZ_OK; - } - else - { - if (ferror(fin)) - return UNZ_ERRNO; - else - return UNZ_EOF; - } -} -*/ - -/* =========================================================================== - Reads a long in LSB order from the given gz_stream. Sets -*/ -static int unzlocal_getShort (FILE* fin, uLong *pX) -{ - short v; - - fread( &v, sizeof(v), 1, fin ); - - *pX = LittleShort( v); - return UNZ_OK; - -/* - uLong x ; - int i; - int err; - - err = unzlocal_getByte(fin,&i); - x = (uLong)i; - - if (err==UNZ_OK) - err = unzlocal_getByte(fin,&i); - x += ((uLong)i)<<8; - - if (err==UNZ_OK) - *pX = x; - else - *pX = 0; - return err; -*/ -} - -static int unzlocal_getLong (FILE *fin, uLong *pX) -{ - int v; - - fread( &v, sizeof(v), 1, fin ); - - *pX = LittleLong( v); - return UNZ_OK; - -/* - uLong x ; - int i; - int err; - - err = unzlocal_getByte(fin,&i); - x = (uLong)i; - - if (err==UNZ_OK) - err = unzlocal_getByte(fin,&i); - x += ((uLong)i)<<8; - - if (err==UNZ_OK) - err = unzlocal_getByte(fin,&i); - x += ((uLong)i)<<16; - - if (err==UNZ_OK) - err = unzlocal_getByte(fin,&i); - x += ((uLong)i)<<24; - - if (err==UNZ_OK) - *pX = x; - else - *pX = 0; - return err; -*/ -} - - -/* My own strcmpi / strcasecmp */ -static int strcmpcasenosensitive_internal (const char* fileName1,const char* fileName2) -{ - for (;;) - { - char c1=*(fileName1++); - char c2=*(fileName2++); - if ((c1>='a') && (c1<='z')) - c1 -= 0x20; - if ((c2>='a') && (c2<='z')) - c2 -= 0x20; - if (c1=='\0') - return ((c2=='\0') ? 0 : -1); - if (c2=='\0') - return 1; - if (c1c2) - return 1; - } -} - - -#ifdef CASESENSITIVITYDEFAULT_NO -#define CASESENSITIVITYDEFAULTVALUE 2 -#else -#define CASESENSITIVITYDEFAULTVALUE 1 -#endif - -#ifndef STRCMPCASENOSENTIVEFUNCTION -#define STRCMPCASENOSENTIVEFUNCTION strcmpcasenosensitive_internal -#endif - -/* - Compare two filename (fileName1,fileName2). - If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp) - If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi - or strcasecmp) - If iCaseSenisivity = 0, case sensitivity is defaut of your operating system - (like 1 on Unix, 2 on Windows) - -*/ -extern int unzStringFileNameCompare (const char* fileName1,const char* fileName2,int iCaseSensitivity) -{ - if (iCaseSensitivity==0) - iCaseSensitivity=CASESENSITIVITYDEFAULTVALUE; - - if (iCaseSensitivity==1) - return strcmp(fileName1,fileName2); - - return STRCMPCASENOSENTIVEFUNCTION(fileName1,fileName2); -} - -#define BUFREADCOMMENT (0x400) - -/* - Locate the Central directory of a zipfile (at the end, just before - the global comment) -*/ -extern uLong unzlocal_SearchCentralDir(FILE *fin) -{ - unsigned char* buf; - uLong uSizeFile; - uLong uBackRead; - uLong uMaxBack=0xffff; /* maximum size of global comment */ - uLong uPosFound=0; - - if (fseek(fin,0,SEEK_END) != 0) - return 0; - - - uSizeFile = ftell( fin ); - - if (uMaxBack>uSizeFile) - uMaxBack = uSizeFile; - - buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4); - if (buf==NULL) - return 0; - - uBackRead = 4; - while (uBackReaduMaxBack) - uBackRead = uMaxBack; - else - uBackRead+=BUFREADCOMMENT; - uReadPos = uSizeFile-uBackRead ; - - uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ? - (BUFREADCOMMENT+4) : (uSizeFile-uReadPos); - if (fseek(fin,uReadPos,SEEK_SET)!=0) - break; - - if (fread(buf,(uInt)uReadSize,1,fin)!=1) - break; - - for (i=(int)uReadSize-3; (i--)>0;) - if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) && - ((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06)) - { - uPosFound = uReadPos+i; - break; - } - - if (uPosFound!=0) - break; - } - TRYFREE(buf); - return uPosFound; -} - -extern unzFile unzReOpen (const char* path, unzFile file) -{ - unz_s *s; - FILE * fin; - - fin=fopen(path,"rb"); - if (fin==NULL) - return NULL; - - s=(unz_s*)ALLOC(sizeof(unz_s)); - - // jkrige - //Com_Memcpy(s, (unz_s*)file, sizeof(unz_s)); - memcpy(s, (unz_s*)file, sizeof(unz_s)); - // jkrige - - s->file = fin; - return (unzFile)s; -} - -/* - Open a Zip file. path contain the full pathname (by example, - on a Windows NT computer "c:\\test\\zlib109.zip" or on an Unix computer - "zlib/zlib109.zip". - If the zipfile cannot be opened (file don't exist or in not valid), the - return value is NULL. - Else, the return value is a unzFile Handle, usable with other function - of this unzip package. -*/ -extern unzFile unzOpen (const char* path) -{ - unz_s us; - unz_s *s; - uLong central_pos,uL; - FILE * fin ; - - uLong number_disk; /* number of the current dist, used for - spaning ZIP, unsupported, always 0*/ - uLong number_disk_with_CD; /* number the the disk with central dir, used - for spaning ZIP, unsupported, always 0*/ - uLong number_entry_CD; /* total number of entries in - the central dir - (same than number_entry on nospan) */ - - int err=UNZ_OK; - - fin=fopen(path,"rb"); - if (fin==NULL) - return NULL; - - central_pos = unzlocal_SearchCentralDir(fin); - if (central_pos==0) - err=UNZ_ERRNO; - - if (fseek(fin,central_pos,SEEK_SET)!=0) - err=UNZ_ERRNO; - - /* the signature, already checked */ - if (unzlocal_getLong(fin,&uL)!=UNZ_OK) - err=UNZ_ERRNO; - - /* number of this disk */ - if (unzlocal_getShort(fin,&number_disk)!=UNZ_OK) - err=UNZ_ERRNO; - - /* number of the disk with the start of the central directory */ - if (unzlocal_getShort(fin,&number_disk_with_CD)!=UNZ_OK) - err=UNZ_ERRNO; - - /* total number of entries in the central dir on this disk */ - if (unzlocal_getShort(fin,&us.gi.number_entry)!=UNZ_OK) - err=UNZ_ERRNO; - - /* total number of entries in the central dir */ - if (unzlocal_getShort(fin,&number_entry_CD)!=UNZ_OK) - err=UNZ_ERRNO; - - if ((number_entry_CD!=us.gi.number_entry) || - (number_disk_with_CD!=0) || - (number_disk!=0)) - err=UNZ_BADZIPFILE; - - /* size of the central directory */ - if (unzlocal_getLong(fin,&us.size_central_dir)!=UNZ_OK) - err=UNZ_ERRNO; - - /* offset of start of central directory with respect to the - starting disk number */ - if (unzlocal_getLong(fin,&us.offset_central_dir)!=UNZ_OK) - err=UNZ_ERRNO; - - /* zipfile comment length */ - if (unzlocal_getShort(fin,&us.gi.size_comment)!=UNZ_OK) - err=UNZ_ERRNO; - - if ((central_pospfile_in_zip_read!=NULL) - unzCloseCurrentFile(file); - - fclose(s->file); - TRYFREE(s); - return UNZ_OK; -} - - -/* - Write info about the ZipFile in the *pglobal_info structure. - No preparation of the structure is needed - return UNZ_OK if there is no problem. */ -extern int unzGetGlobalInfo (unzFile file,unz_global_info *pglobal_info) -{ - unz_s* s; - if (file==NULL) - return UNZ_PARAMERROR; - s=(unz_s*)file; - *pglobal_info=s->gi; - return UNZ_OK; -} - - -/* - Translate date/time from Dos format to tm_unz (readable more easilty) -*/ -static void unzlocal_DosDateToTmuDate (uLong ulDosDate, tm_unz* ptm) -{ - uLong uDate; - uDate = (uLong)(ulDosDate>>16); - ptm->tm_mday = (uInt)(uDate&0x1f) ; - ptm->tm_mon = (uInt)((((uDate)&0x1E0)/0x20)-1) ; - ptm->tm_year = (uInt)(((uDate&0x0FE00)/0x0200)+1980) ; - - ptm->tm_hour = (uInt) ((ulDosDate &0xF800)/0x800); - ptm->tm_min = (uInt) ((ulDosDate&0x7E0)/0x20) ; - ptm->tm_sec = (uInt) (2*(ulDosDate&0x1f)) ; -} - -/* - Get Info about the current file in the zipfile, with internal only info -*/ -static int unzlocal_GetCurrentFileInfoInternal (unzFile file, - unz_file_info *pfile_info, - unz_file_info_internal - *pfile_info_internal, - char *szFileName, - uLong fileNameBufferSize, - void *extraField, - uLong extraFieldBufferSize, - char *szComment, - uLong commentBufferSize) -{ - unz_s* s; - unz_file_info file_info; - unz_file_info_internal file_info_internal; - int err=UNZ_OK; - uLong uMagic; - long lSeek=0; - - if (file==NULL) - return UNZ_PARAMERROR; - s=(unz_s*)file; - if (fseek(s->file,s->pos_in_central_dir+s->byte_before_the_zipfile,SEEK_SET)!=0) - err=UNZ_ERRNO; - - - /* we check the magic */ - if (err==UNZ_OK) { - if (unzlocal_getLong(s->file,&uMagic) != UNZ_OK) - err=UNZ_ERRNO; - else if (uMagic!=0x02014b50) - err=UNZ_BADZIPFILE; - } - if (unzlocal_getShort(s->file,&file_info.version) != UNZ_OK) - err=UNZ_ERRNO; - - if (unzlocal_getShort(s->file,&file_info.version_needed) != UNZ_OK) - err=UNZ_ERRNO; - - if (unzlocal_getShort(s->file,&file_info.flag) != UNZ_OK) - err=UNZ_ERRNO; - - if (unzlocal_getShort(s->file,&file_info.compression_method) != UNZ_OK) - err=UNZ_ERRNO; - - if (unzlocal_getLong(s->file,&file_info.dosDate) != UNZ_OK) - err=UNZ_ERRNO; - - unzlocal_DosDateToTmuDate(file_info.dosDate,&file_info.tmu_date); - - if (unzlocal_getLong(s->file,&file_info.crc) != UNZ_OK) - err=UNZ_ERRNO; - - if (unzlocal_getLong(s->file,&file_info.compressed_size) != UNZ_OK) - err=UNZ_ERRNO; - - if (unzlocal_getLong(s->file,&file_info.uncompressed_size) != UNZ_OK) - err=UNZ_ERRNO; - - if (unzlocal_getShort(s->file,&file_info.size_filename) != UNZ_OK) - err=UNZ_ERRNO; - - if (unzlocal_getShort(s->file,&file_info.size_file_extra) != UNZ_OK) - err=UNZ_ERRNO; - - if (unzlocal_getShort(s->file,&file_info.size_file_comment) != UNZ_OK) - err=UNZ_ERRNO; - - if (unzlocal_getShort(s->file,&file_info.disk_num_start) != UNZ_OK) - err=UNZ_ERRNO; - - if (unzlocal_getShort(s->file,&file_info.internal_fa) != UNZ_OK) - err=UNZ_ERRNO; - - if (unzlocal_getLong(s->file,&file_info.external_fa) != UNZ_OK) - err=UNZ_ERRNO; - - if (unzlocal_getLong(s->file,&file_info_internal.offset_curfile) != UNZ_OK) - err=UNZ_ERRNO; - - lSeek+=file_info.size_filename; - if ((err==UNZ_OK) && (szFileName!=NULL)) - { - uLong uSizeRead ; - if (file_info.size_filename0) && (fileNameBufferSize>0)) - if (fread(szFileName,(uInt)uSizeRead,1,s->file)!=1) - err=UNZ_ERRNO; - lSeek -= uSizeRead; - } - - - if ((err==UNZ_OK) && (extraField!=NULL)) - { - uLong uSizeRead ; - if (file_info.size_file_extrafile,lSeek,SEEK_CUR)==0) - lSeek=0; - else - err=UNZ_ERRNO; - } - if ((file_info.size_file_extra>0) && (extraFieldBufferSize>0)) { - if (fread(extraField,(uInt)uSizeRead,1,s->file)!=1) - err=UNZ_ERRNO; - } - lSeek += file_info.size_file_extra - uSizeRead; - } - else - lSeek+=file_info.size_file_extra; - - - if ((err==UNZ_OK) && (szComment!=NULL)) - { - uLong uSizeRead ; - if (file_info.size_file_commentfile,lSeek,SEEK_CUR)==0) - lSeek=0; - else - err=UNZ_ERRNO; - } - if ((file_info.size_file_comment>0) && (commentBufferSize>0)) { - if (fread(szComment,(uInt)uSizeRead,1,s->file)!=1) - err=UNZ_ERRNO; - } - lSeek+=file_info.size_file_comment - uSizeRead; - } - else - lSeek+=file_info.size_file_comment; - - if ((err==UNZ_OK) && (pfile_info!=NULL)) - *pfile_info=file_info; - - if ((err==UNZ_OK) && (pfile_info_internal!=NULL)) - *pfile_info_internal=file_info_internal; - - return err; -} - - - -/* - Write info about the ZipFile in the *pglobal_info structure. - No preparation of the structure is needed - return UNZ_OK if there is no problem. -*/ -extern int unzGetCurrentFileInfo ( unzFile file, unz_file_info *pfile_info, - char *szFileName, uLong fileNameBufferSize, - void *extraField, uLong extraFieldBufferSize, - char *szComment, uLong commentBufferSize) -{ - return unzlocal_GetCurrentFileInfoInternal(file,pfile_info,NULL, - szFileName,fileNameBufferSize, - extraField,extraFieldBufferSize, - szComment,commentBufferSize); -} - -/* - Set the current file of the zipfile to the first file. - return UNZ_OK if there is no problem -*/ -extern int unzGoToFirstFile (unzFile file) -{ - int err=UNZ_OK; - unz_s* s; - if (file==NULL) - return UNZ_PARAMERROR; - s=(unz_s*)file; - s->pos_in_central_dir=s->offset_central_dir; - s->num_file=0; - err=unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info, - &s->cur_file_info_internal, - NULL,0,NULL,0,NULL,0); - s->current_file_ok = (err == UNZ_OK); - return err; -} - - -/* - Set the current file of the zipfile to the next file. - return UNZ_OK if there is no problem - return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest. -*/ -extern int unzGoToNextFile (unzFile file) -{ - unz_s* s; - int err; - - if (file==NULL) - return UNZ_PARAMERROR; - s=(unz_s*)file; - if (!s->current_file_ok) - return UNZ_END_OF_LIST_OF_FILE; - if (s->num_file+1==s->gi.number_entry) - return UNZ_END_OF_LIST_OF_FILE; - - s->pos_in_central_dir += SIZECENTRALDIRITEM + s->cur_file_info.size_filename + - s->cur_file_info.size_file_extra + s->cur_file_info.size_file_comment ; - s->num_file++; - err = unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info, - &s->cur_file_info_internal, - NULL,0,NULL,0,NULL,0); - s->current_file_ok = (err == UNZ_OK); - return err; -} - -/* - Get the position of the info of the current file in the zip. - return UNZ_OK if there is no problem -*/ -extern int unzGetCurrentFileInfoPosition (unzFile file, unsigned long *pos ) -{ - unz_s* s; - - if (file==NULL) - return UNZ_PARAMERROR; - s=(unz_s*)file; - - *pos = s->pos_in_central_dir; - return UNZ_OK; -} - -/* - Set the position of the info of the current file in the zip. - return UNZ_OK if there is no problem -*/ -extern int unzSetCurrentFileInfoPosition (unzFile file, unsigned long pos ) -{ - unz_s* s; - int err; - - if (file==NULL) - return UNZ_PARAMERROR; - s=(unz_s*)file; - - s->pos_in_central_dir = pos; - err = unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info, - &s->cur_file_info_internal, - NULL,0,NULL,0,NULL,0); - s->current_file_ok = (err == UNZ_OK); - return UNZ_OK; -} - -/* - Try locate the file szFileName in the zipfile. - For the iCaseSensitivity signification, see unzipStringFileNameCompare - - return value : - UNZ_OK if the file is found. It becomes the current file. - UNZ_END_OF_LIST_OF_FILE if the file is not found -*/ -extern int unzLocateFile (unzFile file, const char *szFileName, int iCaseSensitivity) -{ - unz_s* s; - int err; - - - uLong num_fileSaved; - uLong pos_in_central_dirSaved; - - - if (file==NULL) - return UNZ_PARAMERROR; - - if (strlen(szFileName)>=UNZ_MAXFILENAMEINZIP) - return UNZ_PARAMERROR; - - s=(unz_s*)file; - if (!s->current_file_ok) - return UNZ_END_OF_LIST_OF_FILE; - - num_fileSaved = s->num_file; - pos_in_central_dirSaved = s->pos_in_central_dir; - - err = unzGoToFirstFile(file); - - while (err == UNZ_OK) - { - char szCurrentFileName[UNZ_MAXFILENAMEINZIP+1]; - unzGetCurrentFileInfo(file,NULL, - szCurrentFileName,sizeof(szCurrentFileName)-1, - NULL,0,NULL,0); - if (unzStringFileNameCompare(szCurrentFileName, - szFileName,iCaseSensitivity)==0) - return UNZ_OK; - err = unzGoToNextFile(file); - } - - s->num_file = num_fileSaved ; - s->pos_in_central_dir = pos_in_central_dirSaved ; - return err; -} - - -/* - Read the static header of the current zipfile - Check the coherency of the static header and info in the end of central - directory about this file - store in *piSizeVar the size of extra info in static header - (filename and size of extra field data) -*/ -static int unzlocal_CheckCurrentFileCoherencyHeader (unz_s* s, uInt* piSizeVar, - uLong *poffset_local_extrafield, - uInt *psize_local_extrafield) -{ - uLong uMagic,uData,uFlags; - uLong size_filename; - uLong size_extra_field; - int err=UNZ_OK; - - *piSizeVar = 0; - *poffset_local_extrafield = 0; - *psize_local_extrafield = 0; - - if (fseek(s->file,s->cur_file_info_internal.offset_curfile + - s->byte_before_the_zipfile,SEEK_SET)!=0) - return UNZ_ERRNO; - - - if (err==UNZ_OK) { - if (unzlocal_getLong(s->file,&uMagic) != UNZ_OK) - err=UNZ_ERRNO; - else if (uMagic!=0x04034b50) - err=UNZ_BADZIPFILE; - } - if (unzlocal_getShort(s->file,&uData) != UNZ_OK) - err=UNZ_ERRNO; -/* - else if ((err==UNZ_OK) && (uData!=s->cur_file_info.wVersion)) - err=UNZ_BADZIPFILE; -*/ - if (unzlocal_getShort(s->file,&uFlags) != UNZ_OK) - err=UNZ_ERRNO; - - if (unzlocal_getShort(s->file,&uData) != UNZ_OK) - err=UNZ_ERRNO; - else if ((err==UNZ_OK) && (uData!=s->cur_file_info.compression_method)) - err=UNZ_BADZIPFILE; - - if ((err==UNZ_OK) && (s->cur_file_info.compression_method!=0) && - (s->cur_file_info.compression_method!=Z_DEFLATED)) - err=UNZ_BADZIPFILE; - - if (unzlocal_getLong(s->file,&uData) != UNZ_OK) /* date/time */ - err=UNZ_ERRNO; - - if (unzlocal_getLong(s->file,&uData) != UNZ_OK) /* crc */ - err=UNZ_ERRNO; - else if ((err==UNZ_OK) && (uData!=s->cur_file_info.crc) && - ((uFlags & 8)==0)) - err=UNZ_BADZIPFILE; - - if (unzlocal_getLong(s->file,&uData) != UNZ_OK) /* size compr */ - err=UNZ_ERRNO; - else if ((err==UNZ_OK) && (uData!=s->cur_file_info.compressed_size) && - ((uFlags & 8)==0)) - err=UNZ_BADZIPFILE; - - if (unzlocal_getLong(s->file,&uData) != UNZ_OK) /* size uncompr */ - err=UNZ_ERRNO; - else if ((err==UNZ_OK) && (uData!=s->cur_file_info.uncompressed_size) && - ((uFlags & 8)==0)) - err=UNZ_BADZIPFILE; - - - if (unzlocal_getShort(s->file,&size_filename) != UNZ_OK) - err=UNZ_ERRNO; - else if ((err==UNZ_OK) && (size_filename!=s->cur_file_info.size_filename)) - err=UNZ_BADZIPFILE; - - *piSizeVar += (uInt)size_filename; - - if (unzlocal_getShort(s->file,&size_extra_field) != UNZ_OK) - err=UNZ_ERRNO; - *poffset_local_extrafield= s->cur_file_info_internal.offset_curfile + - SIZEZIPLOCALHEADER + size_filename; - *psize_local_extrafield = (uInt)size_extra_field; - - *piSizeVar += (uInt)size_extra_field; - - return err; -} - -/* - Open for reading data the current file in the zipfile. - If there is no error and the file is opened, the return value is UNZ_OK. -*/ -extern int unzOpenCurrentFile (unzFile file) -{ - int err=UNZ_OK; - int Store; - uInt iSizeVar; - unz_s* s; - file_in_zip_read_info_s* pfile_in_zip_read_info; - uLong offset_local_extrafield; /* offset of the static extra field */ - uInt size_local_extrafield; /* size of the static extra field */ - - if (file==NULL) - return UNZ_PARAMERROR; - s=(unz_s*)file; - if (!s->current_file_ok) - return UNZ_PARAMERROR; - - if (s->pfile_in_zip_read != NULL) - unzCloseCurrentFile(file); - - if (unzlocal_CheckCurrentFileCoherencyHeader(s,&iSizeVar, - &offset_local_extrafield,&size_local_extrafield)!=UNZ_OK) - return UNZ_BADZIPFILE; - - pfile_in_zip_read_info = (file_in_zip_read_info_s*)ALLOC(sizeof(file_in_zip_read_info_s)); - if (pfile_in_zip_read_info==NULL) - return UNZ_INTERNALERROR; - - pfile_in_zip_read_info->read_buffer=(char*)ALLOC(UNZ_BUFSIZE); - pfile_in_zip_read_info->offset_local_extrafield = offset_local_extrafield; - pfile_in_zip_read_info->size_local_extrafield = size_local_extrafield; - pfile_in_zip_read_info->pos_local_extrafield=0; - - if (pfile_in_zip_read_info->read_buffer==NULL) - { - TRYFREE(pfile_in_zip_read_info); - return UNZ_INTERNALERROR; - } - - pfile_in_zip_read_info->stream_initialised=0; - - if ((s->cur_file_info.compression_method!=0) && - (s->cur_file_info.compression_method!=Z_DEFLATED)) - err=UNZ_BADZIPFILE; - Store = s->cur_file_info.compression_method==0; - - pfile_in_zip_read_info->crc32_wait=s->cur_file_info.crc; - pfile_in_zip_read_info->crc32=0; - pfile_in_zip_read_info->compression_method = - s->cur_file_info.compression_method; - pfile_in_zip_read_info->file=s->file; - pfile_in_zip_read_info->byte_before_the_zipfile=s->byte_before_the_zipfile; - - pfile_in_zip_read_info->stream.total_out = 0; - - if (!Store) - { - pfile_in_zip_read_info->stream.zalloc = (alloc_func)0; - pfile_in_zip_read_info->stream.zfree = (free_func)0; - pfile_in_zip_read_info->stream.opaque = (voidp)0; - - err=inflateInit2(&pfile_in_zip_read_info->stream, -MAX_WBITS); - if (err == Z_OK) - pfile_in_zip_read_info->stream_initialised=1; - /* windowBits is passed < 0 to tell that there is no zlib header. - * Note that in this case inflate *requires* an extra "dummy" byte - * after the compressed stream in order to complete decompression and - * return Z_STREAM_END. - * In unzip, i don't wait absolutely Z_STREAM_END because I known the - * size of both compressed and uncompressed data - */ - } - pfile_in_zip_read_info->rest_read_compressed = - s->cur_file_info.compressed_size ; - pfile_in_zip_read_info->rest_read_uncompressed = - s->cur_file_info.uncompressed_size ; - - - pfile_in_zip_read_info->pos_in_zipfile = - s->cur_file_info_internal.offset_curfile + SIZEZIPLOCALHEADER + - iSizeVar; - - pfile_in_zip_read_info->stream.avail_in = (uInt)0; - - - s->pfile_in_zip_read = pfile_in_zip_read_info; - return UNZ_OK; -} - - -/* - Read bytes from the current file. - buf contain buffer where data must be copied - len the size of buf. - - return the number of byte copied if somes bytes are copied - return 0 if the end of file was reached - return <0 with error code if there is an error - (UNZ_ERRNO for IO error, or zLib error for uncompress error) -*/ -extern int unzReadCurrentFile (unzFile file, void *buf, unsigned len) -{ - int err=UNZ_OK; - uInt iRead = 0; - unz_s* s; - file_in_zip_read_info_s* pfile_in_zip_read_info; - if (file==NULL) - return UNZ_PARAMERROR; - s=(unz_s*)file; - pfile_in_zip_read_info=s->pfile_in_zip_read; - - if (pfile_in_zip_read_info==NULL) - return UNZ_PARAMERROR; - - - if ((pfile_in_zip_read_info->read_buffer == NULL)) - return UNZ_END_OF_LIST_OF_FILE; - if (len==0) - return 0; - - pfile_in_zip_read_info->stream.next_out = (Byte*)buf; - - pfile_in_zip_read_info->stream.avail_out = (uInt)len; - - if (len>pfile_in_zip_read_info->rest_read_uncompressed) - pfile_in_zip_read_info->stream.avail_out = - (uInt)pfile_in_zip_read_info->rest_read_uncompressed; - - while (pfile_in_zip_read_info->stream.avail_out>0) - { - if ((pfile_in_zip_read_info->stream.avail_in==0) && - (pfile_in_zip_read_info->rest_read_compressed>0)) - { - uInt uReadThis = UNZ_BUFSIZE; - if (pfile_in_zip_read_info->rest_read_compressedrest_read_compressed; - if (uReadThis == 0) - return UNZ_EOF; - if (s->cur_file_info.compressed_size == pfile_in_zip_read_info->rest_read_compressed) - if (fseek(pfile_in_zip_read_info->file, - pfile_in_zip_read_info->pos_in_zipfile + - pfile_in_zip_read_info->byte_before_the_zipfile,SEEK_SET)!=0) - return UNZ_ERRNO; - if (fread(pfile_in_zip_read_info->read_buffer,uReadThis,1, - pfile_in_zip_read_info->file)!=1) - return UNZ_ERRNO; - pfile_in_zip_read_info->pos_in_zipfile += uReadThis; - - pfile_in_zip_read_info->rest_read_compressed-=uReadThis; - - pfile_in_zip_read_info->stream.next_in = - (Byte*)pfile_in_zip_read_info->read_buffer; - pfile_in_zip_read_info->stream.avail_in = (uInt)uReadThis; - } - - if (pfile_in_zip_read_info->compression_method==0) - { - uInt uDoCopy,i ; - if (pfile_in_zip_read_info->stream.avail_out < - pfile_in_zip_read_info->stream.avail_in) - uDoCopy = pfile_in_zip_read_info->stream.avail_out ; - else - uDoCopy = pfile_in_zip_read_info->stream.avail_in ; - - for (i=0;istream.next_out+i) = - *(pfile_in_zip_read_info->stream.next_in+i); - -// pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32, -// pfile_in_zip_read_info->stream.next_out, -// uDoCopy); - pfile_in_zip_read_info->rest_read_uncompressed-=uDoCopy; - pfile_in_zip_read_info->stream.avail_in -= uDoCopy; - pfile_in_zip_read_info->stream.avail_out -= uDoCopy; - pfile_in_zip_read_info->stream.next_out += uDoCopy; - pfile_in_zip_read_info->stream.next_in += uDoCopy; - pfile_in_zip_read_info->stream.total_out += uDoCopy; - iRead += uDoCopy; - } - else - { - uLong uTotalOutBefore,uTotalOutAfter; - const Byte *bufBefore; - uLong uOutThis; - int flush=Z_SYNC_FLUSH; - - uTotalOutBefore = pfile_in_zip_read_info->stream.total_out; - bufBefore = pfile_in_zip_read_info->stream.next_out; - - /* - if ((pfile_in_zip_read_info->rest_read_uncompressed == - pfile_in_zip_read_info->stream.avail_out) && - (pfile_in_zip_read_info->rest_read_compressed == 0)) - flush = Z_FINISH; - */ - err=inflate(&pfile_in_zip_read_info->stream,flush); - - uTotalOutAfter = pfile_in_zip_read_info->stream.total_out; - uOutThis = uTotalOutAfter-uTotalOutBefore; - -// pfile_in_zip_read_info->crc32 = -// crc32(pfile_in_zip_read_info->crc32,bufBefore, -// (uInt)(uOutThis)); - - pfile_in_zip_read_info->rest_read_uncompressed -= - uOutThis; - - iRead += (uInt)(uTotalOutAfter - uTotalOutBefore); - - if (err==Z_STREAM_END) - return (iRead==0) ? UNZ_EOF : iRead; - if (err!=Z_OK) - break; - } - } - - if (err==Z_OK) - return iRead; - return err; -} - - -/* - Give the current position in uncompressed data -*/ -extern long unztell (unzFile file) -{ - unz_s* s; - file_in_zip_read_info_s* pfile_in_zip_read_info; - if (file==NULL) - return UNZ_PARAMERROR; - s=(unz_s*)file; - pfile_in_zip_read_info=s->pfile_in_zip_read; - - if (pfile_in_zip_read_info==NULL) - return UNZ_PARAMERROR; - - return (long)pfile_in_zip_read_info->stream.total_out; -} - - -/* - return 1 if the end of file was reached, 0 elsewhere -*/ -extern int unzeof (unzFile file) -{ - unz_s* s; - file_in_zip_read_info_s* pfile_in_zip_read_info; - if (file==NULL) - return UNZ_PARAMERROR; - s=(unz_s*)file; - pfile_in_zip_read_info=s->pfile_in_zip_read; - - if (pfile_in_zip_read_info==NULL) - return UNZ_PARAMERROR; - - if (pfile_in_zip_read_info->rest_read_uncompressed == 0) - return 1; - else - return 0; -} - - - -/* - Read extra field from the current file (opened by unzOpenCurrentFile) - This is the static-header version of the extra field (sometimes, there is - more info in the static-header version than in the central-header) - - if buf==NULL, it return the size of the static extra field that can be read - - if buf!=NULL, len is the size of the buffer, the extra header is copied in - buf. - the return value is the number of bytes copied in buf, or (if <0) - the error code -*/ -extern int unzGetLocalExtrafield (unzFile file,void *buf,unsigned len) -{ - unz_s* s; - file_in_zip_read_info_s* pfile_in_zip_read_info; - uInt read_now; - uLong size_to_read; - - if (file==NULL) - return UNZ_PARAMERROR; - s=(unz_s*)file; - pfile_in_zip_read_info=s->pfile_in_zip_read; - - if (pfile_in_zip_read_info==NULL) - return UNZ_PARAMERROR; - - size_to_read = (pfile_in_zip_read_info->size_local_extrafield - - pfile_in_zip_read_info->pos_local_extrafield); - - if (buf==NULL) - return (int)size_to_read; - - if (len>size_to_read) - read_now = (uInt)size_to_read; - else - read_now = (uInt)len ; - - if (read_now==0) - return 0; - - if (fseek(pfile_in_zip_read_info->file, - pfile_in_zip_read_info->offset_local_extrafield + - pfile_in_zip_read_info->pos_local_extrafield,SEEK_SET)!=0) - return UNZ_ERRNO; - - if (fread(buf,(uInt)size_to_read,1,pfile_in_zip_read_info->file)!=1) - return UNZ_ERRNO; - - return (int)read_now; -} - -/* - Close the file in zip opened with unzipOpenCurrentFile - Return UNZ_CRCERROR if all the file was read but the CRC is not good -*/ -extern int unzCloseCurrentFile (unzFile file) -{ - int err=UNZ_OK; - - unz_s* s; - file_in_zip_read_info_s* pfile_in_zip_read_info; - if (file==NULL) - return UNZ_PARAMERROR; - s=(unz_s*)file; - pfile_in_zip_read_info=s->pfile_in_zip_read; - - if (pfile_in_zip_read_info==NULL) - return UNZ_PARAMERROR; - -/* - if (pfile_in_zip_read_info->rest_read_uncompressed == 0) - { - if (pfile_in_zip_read_info->crc32 != pfile_in_zip_read_info->crc32_wait) - err=UNZ_CRCERROR; - } -*/ - - TRYFREE(pfile_in_zip_read_info->read_buffer); - pfile_in_zip_read_info->read_buffer = NULL; - if (pfile_in_zip_read_info->stream_initialised) - inflateEnd(&pfile_in_zip_read_info->stream); - - pfile_in_zip_read_info->stream_initialised = 0; - TRYFREE(pfile_in_zip_read_info); - - s->pfile_in_zip_read=NULL; - - return err; -} - - -/* - Get the global comment string of the ZipFile, in the szComment buffer. - uSizeBuf is the size of the szComment buffer. - return the number of byte copied or an error code <0 -*/ -extern int unzGetGlobalComment (unzFile file, char *szComment, uLong uSizeBuf) -{ - unz_s* s; - uLong uReadThis ; - if (file==NULL) - return UNZ_PARAMERROR; - s=(unz_s*)file; - - uReadThis = uSizeBuf; - if (uReadThis>s->gi.size_comment) - uReadThis = s->gi.size_comment; - - if (fseek(s->file,s->central_pos+22,SEEK_SET)!=0) - return UNZ_ERRNO; - - if (uReadThis>0) - { - *szComment='\0'; - if (fread(szComment,(uInt)uReadThis,1,s->file)!=1) - return UNZ_ERRNO; - } - - if ((szComment != NULL) && (uSizeBuf > s->gi.size_comment)) - *(szComment+s->gi.size_comment)='\0'; - return (int)uReadThis; -} - -/* infblock.h -- header to use infblock.c - * Copyright (C) 1995-1998 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* WARNING: this file should *not* be used by applications. It is - part of the implementation of the compression library and is - subject to change. Applications should only use zlib.h. - */ - -struct inflate_blocks_state; -typedef struct inflate_blocks_state inflate_blocks_statef; - -static inflate_blocks_statef * inflate_blocks_new OF(( - z_streamp z, - check_func c, /* check function */ - uInt w)); /* window size */ - -static int inflate_blocks OF(( - inflate_blocks_statef *, - z_streamp , - int)); /* initial return code */ - -static void inflate_blocks_reset OF(( - inflate_blocks_statef *, - z_streamp , - uLong *)); /* check value on output */ - -static int inflate_blocks_free OF(( - inflate_blocks_statef *, - z_streamp)); - -#if 0 -static void inflate_set_dictionary OF(( - inflate_blocks_statef *s, - const Byte *d, /* dictionary */ - uInt n)); /* dictionary length */ - -static int inflate_blocks_sync_point OF(( - inflate_blocks_statef *s)); -#endif - -/* simplify the use of the inflate_huft type with some defines */ -#define exop word.what.Exop -#define bits word.what.Bits - -/* Table for deflate from PKZIP's appnote.txt. */ -static const uInt border[] = { /* Order of the bit length code lengths */ - 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; - -/* inftrees.h -- header to use inftrees.c - * Copyright (C) 1995-1998 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* WARNING: this file should *not* be used by applications. It is - part of the implementation of the compression library and is - subject to change. Applications should only use zlib.h. - */ - -/* Huffman code lookup table entry--this entry is four bytes for machines - that have 16-bit pointers (e.g. PC's in the small or medium model). */ - -typedef struct inflate_huft_s inflate_huft; - -struct inflate_huft_s { - union { - struct { - Byte Exop; /* number of extra bits or operation */ - Byte Bits; /* number of bits in this code or subcode */ - } what; - uInt pad; /* pad structure to a power of 2 (4 bytes for */ - } word; /* 16-bit, 8 bytes for 32-bit int's) */ - uInt base; /* literal, length base, distance base, - or table offset */ -}; - -/* Maximum size of dynamic tree. The maximum found in a long but non- - exhaustive search was 1004 huft structures (850 for length/literals - and 154 for distances, the latter actually the result of an - exhaustive search). The actual maximum is not known, but the - value below is more than safe. */ -#define MANY 1440 - -static int inflate_trees_bits OF(( - uInt *, /* 19 code lengths */ - uInt *, /* bits tree desired/actual depth */ - inflate_huft * *, /* bits tree result */ - inflate_huft *, /* space for trees */ - z_streamp)); /* for messages */ - -static int inflate_trees_dynamic OF(( - uInt, /* number of literal/length codes */ - uInt, /* number of distance codes */ - uInt *, /* that many (total) code lengths */ - uInt *, /* literal desired/actual bit depth */ - uInt *, /* distance desired/actual bit depth */ - inflate_huft * *, /* literal/length tree result */ - inflate_huft * *, /* distance tree result */ - inflate_huft *, /* space for trees */ - z_streamp)); /* for messages */ - -static int inflate_trees_fixed OF(( - uInt *, /* literal desired/actual bit depth */ - uInt *, /* distance desired/actual bit depth */ - inflate_huft * *, /* literal/length tree result */ - inflate_huft * *, /* distance tree result */ - z_streamp)); /* for memory allocation */ - - -/* infcodes.h -- header to use infcodes.c - * Copyright (C) 1995-1998 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* WARNING: this file should *not* be used by applications. It is - part of the implementation of the compression library and is - subject to change. Applications should only use zlib.h. - */ - -struct inflate_codes_state; -typedef struct inflate_codes_state inflate_codes_statef; - -static inflate_codes_statef *inflate_codes_new OF(( - uInt, uInt, - inflate_huft *, inflate_huft *, - z_streamp )); - -static int inflate_codes OF(( - inflate_blocks_statef *, - z_streamp , - int)); - -static void inflate_codes_free OF(( - inflate_codes_statef *, - z_streamp )); - -/* infutil.h -- types and macros common to blocks and codes - * Copyright (C) 1995-1998 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* WARNING: this file should *not* be used by applications. It is - part of the implementation of the compression library and is - subject to change. Applications should only use zlib.h. - */ - -#ifndef _INFUTIL_H -#define _INFUTIL_H - -typedef enum { - TYPE, /* get type bits (3, including end bit) */ - LENS, /* get lengths for stored */ - STORED, /* processing stored block */ - TABLE, /* get table lengths */ - BTREE, /* get bit lengths tree for a dynamic block */ - DTREE, /* get length, distance trees for a dynamic block */ - CODES, /* processing fixed or dynamic block */ - DRY, /* output remaining window bytes */ - DONE, /* finished last block, done */ - BAD} /* got a data error--stuck here */ -inflate_block_mode; - -/* inflate blocks semi-private state */ -struct inflate_blocks_state { - - /* mode */ - inflate_block_mode mode; /* current inflate_block mode */ - - /* mode dependent information */ - union { - uInt left; /* if STORED, bytes left to copy */ - struct { - uInt table; /* table lengths (14 bits) */ - uInt index; /* index into blens (or border) */ - uInt *blens; /* bit lengths of codes */ - uInt bb; /* bit length tree depth */ - inflate_huft *tb; /* bit length decoding tree */ - } trees; /* if DTREE, decoding info for trees */ - struct { - inflate_codes_statef - *codes; - } decode; /* if CODES, current state */ - } sub; /* submode */ - uInt last; /* true if this block is the last block */ - - /* mode independent information */ - uInt bitk; /* bits in bit buffer */ - uLong bitb; /* bit buffer */ - inflate_huft *hufts; /* single malloc for tree space */ - Byte *window; /* sliding window */ - Byte *end; /* one byte after sliding window */ - Byte *read; /* window read pointer */ - Byte *write; /* window write pointer */ - check_func checkfn; /* check function */ - uLong check; /* check on output */ - -}; - - -/* defines for inflate input/output */ -/* update pointers and return */ -#define UPDBITS {s->bitb=b;s->bitk=k;} -#define UPDIN {z->avail_in=n;z->total_in+=p-z->next_in;z->next_in=p;} -#define UPDOUT {s->write=q;} -#define UPDATE {UPDBITS UPDIN UPDOUT} -#define LEAVE {UPDATE return inflate_flush(s,z,r);} -/* get bytes and bits */ -#define LOADIN {p=z->next_in;n=z->avail_in;b=s->bitb;k=s->bitk;} -#define NEEDBYTE {if(n)r=Z_OK;else LEAVE} -#define NEXTBYTE (n--,*p++) -#define NEEDBITS(j) {while(k<(j)){NEEDBYTE;b|=((uLong)NEXTBYTE)<>=(j);k-=(j);} -/* output bytes */ -#define WAVAIL (uInt)(qread?s->read-q-1:s->end-q) -#define LOADOUT {q=s->write;m=(uInt)WAVAIL;} -#define WRAP {if(q==s->end&&s->read!=s->window){q=s->window;m=(uInt)WAVAIL;}} -#define FLUSH {UPDOUT r=inflate_flush(s,z,r); LOADOUT} -#define NEEDOUT {if(m==0){WRAP if(m==0){FLUSH WRAP if(m==0) LEAVE}}r=Z_OK;} -#define OUTBYTE(a) {*q++=(Byte)(a);m--;} -/* load static pointers */ -#define LOAD {LOADIN LOADOUT} - -/* masks for lower bits (size given to avoid silly warnings with Visual C++) */ -static uInt inflate_mask[17]; - -/* copy as much as possible from the sliding window to the output area */ -static int inflate_flush OF(( - inflate_blocks_statef *, - z_streamp , - int)); - -#endif - - -/* - Notes beyond the 1.93a appnote.txt: - - 1. Distance pointers never point before the beginning of the output - stream. - 2. Distance pointers can point back across blocks, up to 32k away. - 3. There is an implied maximum of 7 bits for the bit length table and - 15 bits for the actual data. - 4. If only one code exists, then it is encoded using one bit. (Zero - would be more efficient, but perhaps a little confusing.) If two - codes exist, they are coded using one bit each (0 and 1). - 5. There is no way of sending zero distance codes--a dummy must be - sent if there are none. (History: a pre 2.0 version of PKZIP would - store blocks with no distance codes, but this was discovered to be - too harsh a criterion.) Valid only for 1.93a. 2.04c does allow - zero distance codes, which is sent as one code of zero bits in - length. - 6. There are up to 286 literal/length codes. Code 256 represents the - end-of-block. Note however that the static length tree defines - 288 codes just to fill out the Huffman codes. Codes 286 and 287 - cannot be used though, since there is no length base or extra bits - defined for them. Similarily, there are up to 30 distance codes. - However, static trees define 32 codes (all 5 bits) to fill out the - Huffman codes, but the last two had better not show up in the data. - 7. Unzip can check dynamic Huffman blocks for complete code sets. - The exception is that a single code would not be complete (see #4). - 8. The five bits following the block type is really the number of - literal codes sent minus 257. - 9. Length codes 8,16,16 are interpreted as 13 length codes of 8 bits - (1+6+6). Therefore, to output three times the length, you output - three codes (1+1+1), whereas to output four times the same length, - you only need two codes (1+3). Hmm. - 10. In the tree reconstruction algorithm, Code = Code + Increment - only if BitLength(i) is not zero. (Pretty obvious.) - 11. Correction: 4 Bits: # of Bit Length codes - 4 (4 - 19) - 12. Note: length code 284 can represent 227-258, but length code 285 - really is 258. The last length deserves its own, short code - since it gets used a lot in very redundant files. The length - 258 is special since 258 - 3 (the min match length) is 255. - 13. The literal/length and distance code bit lengths are read as a - single stream of lengths. It is possible (and advantageous) for - a repeat code (16, 17, or 18) to go across the boundary between - the two sets of lengths. - */ - - -void inflate_blocks_reset(inflate_blocks_statef *s, z_streamp z, uLong *c) -{ - if (c != Z_NULL) - *c = s->check; - if (s->mode == BTREE || s->mode == DTREE) - ZFREE(z, s->sub.trees.blens); - if (s->mode == CODES) - inflate_codes_free(s->sub.decode.codes, z); - s->mode = TYPE; - s->bitk = 0; - s->bitb = 0; - s->read = s->write = s->window; - if (s->checkfn != Z_NULL) - z->adler = s->check = (*s->checkfn)(0L, (const Byte *)Z_NULL, 0); - Tracev(("inflate: blocks reset\n")); -} - - -inflate_blocks_statef *inflate_blocks_new(z_streamp z, check_func c, uInt w) -{ - inflate_blocks_statef *s; - - if ((s = (inflate_blocks_statef *)ZALLOC - (z,1,sizeof(struct inflate_blocks_state))) == Z_NULL) - return s; - if ((s->hufts = - (inflate_huft *)ZALLOC(z, sizeof(inflate_huft), MANY)) == Z_NULL) - { - ZFREE(z, s); - return Z_NULL; - } - if ((s->window = (Byte *)ZALLOC(z, 1, w)) == Z_NULL) - { - ZFREE(z, s->hufts); - ZFREE(z, s); - return Z_NULL; - } - s->end = s->window + w; - s->checkfn = c; - s->mode = TYPE; - Tracev(("inflate: blocks allocated\n")); - inflate_blocks_reset(s, z, Z_NULL); - return s; -} - - -int inflate_blocks(inflate_blocks_statef *s, z_streamp z, int r) -{ - uInt t; /* temporary storage */ - uLong b; /* bit buffer */ - uInt k; /* bits in bit buffer */ - Byte *p; /* input data pointer */ - uInt n; /* bytes available there */ - Byte *q; /* output window write pointer */ - uInt m; /* bytes to end of window or read pointer */ - - /* copy input/output information to locals (UPDATE macro restores) */ - LOAD - - /* process input based on current state */ - while (1) switch (s->mode) - { - case TYPE: - NEEDBITS(3) - t = (uInt)b & 7; - s->last = t & 1; - switch (t >> 1) - { - case 0: /* stored */ - Tracev(("inflate: stored block%s\n", - s->last ? " (last)" : "")); - DUMPBITS(3) - t = k & 7; /* go to byte boundary */ - DUMPBITS(t) - s->mode = LENS; /* get length of stored block */ - break; - case 1: /* fixed */ - Tracev(("inflate: fixed codes block%s\n", - s->last ? " (last)" : "")); - { - uInt bl, bd; - inflate_huft *tl, *td; - inflate_trees_fixed(&bl, &bd, &tl, &td, z); - s->sub.decode.codes = inflate_codes_new(bl, bd, tl, td, z); - if (s->sub.decode.codes == Z_NULL) - { - r = Z_MEM_ERROR; - LEAVE - } - } - DUMPBITS(3) - s->mode = CODES; - break; - case 2: /* dynamic */ - Tracev(("inflate: dynamic codes block%s\n", - s->last ? " (last)" : "")); - DUMPBITS(3) - s->mode = TABLE; - break; - case 3: /* illegal */ - DUMPBITS(3) - s->mode = BAD; - z->msg = (char*)"invalid block type"; - r = Z_DATA_ERROR; - LEAVE - } - break; - case LENS: - NEEDBITS(32) - if ((((~b) >> 16) & 0xffff) != (b & 0xffff)) - { - s->mode = BAD; - z->msg = (char*)"invalid stored block lengths"; - r = Z_DATA_ERROR; - LEAVE - } - s->sub.left = (uInt)b & 0xffff; - b = k = 0; /* dump bits */ - Tracev(("inflate: stored length %u\n", s->sub.left)); - s->mode = s->sub.left ? STORED : (s->last ? DRY : TYPE); - break; - case STORED: - if (n == 0) - LEAVE - NEEDOUT - t = s->sub.left; - if (t > n) t = n; - if (t > m) t = m; - zmemcpy(q, p, t); - p += t; n -= t; - q += t; m -= t; - if ((s->sub.left -= t) != 0) - break; - Tracev(("inflate: stored end, %lu total out\n", - z->total_out + (q >= s->read ? q - s->read : - (s->end - s->read) + (q - s->window)))); - s->mode = s->last ? DRY : TYPE; - break; - case TABLE: - NEEDBITS(14) - s->sub.trees.table = t = (uInt)b & 0x3fff; -#ifndef PKZIP_BUG_WORKAROUND - if ((t & 0x1f) > 29 || ((t >> 5) & 0x1f) > 29) - { - s->mode = BAD; - z->msg = (char*)"too many length or distance symbols"; - r = Z_DATA_ERROR; - LEAVE - } -#endif - t = 258 + (t & 0x1f) + ((t >> 5) & 0x1f); - if ((s->sub.trees.blens = (uInt*)ZALLOC(z, t, sizeof(uInt))) == Z_NULL) - { - r = Z_MEM_ERROR; - LEAVE - } - DUMPBITS(14) - s->sub.trees.index = 0; - Tracev(("inflate: table sizes ok\n")); - s->mode = BTREE; - case BTREE: - while (s->sub.trees.index < 4 + (s->sub.trees.table >> 10)) - { - NEEDBITS(3) - s->sub.trees.blens[border[s->sub.trees.index++]] = (uInt)b & 7; - DUMPBITS(3) - } - while (s->sub.trees.index < 19) - s->sub.trees.blens[border[s->sub.trees.index++]] = 0; - s->sub.trees.bb = 7; - t = inflate_trees_bits(s->sub.trees.blens, &s->sub.trees.bb, - &s->sub.trees.tb, s->hufts, z); - if (t != Z_OK) - { - ZFREE(z, s->sub.trees.blens); - r = t; - if (r == Z_DATA_ERROR) - s->mode = BAD; - LEAVE - } - s->sub.trees.index = 0; - Tracev(("inflate: bits tree ok\n")); - s->mode = DTREE; - case DTREE: - while (t = s->sub.trees.table, - s->sub.trees.index < 258 + (t & 0x1f) + ((t >> 5) & 0x1f)) - { - inflate_huft *h; - uInt i, j, c; - - t = s->sub.trees.bb; - NEEDBITS(t) - h = s->sub.trees.tb + ((uInt)b & inflate_mask[t]); - t = h->bits; - c = h->base; - if (c < 16) - { - DUMPBITS(t) - s->sub.trees.blens[s->sub.trees.index++] = c; - } - else /* c == 16..18 */ - { - i = c == 18 ? 7 : c - 14; - j = c == 18 ? 11 : 3; - NEEDBITS(t + i) - DUMPBITS(t) - j += (uInt)b & inflate_mask[i]; - DUMPBITS(i) - i = s->sub.trees.index; - t = s->sub.trees.table; - if (i + j > 258 + (t & 0x1f) + ((t >> 5) & 0x1f) || - (c == 16 && i < 1)) - { - ZFREE(z, s->sub.trees.blens); - s->mode = BAD; - z->msg = (char*)"invalid bit length repeat"; - r = Z_DATA_ERROR; - LEAVE - } - c = c == 16 ? s->sub.trees.blens[i - 1] : 0; - do { - s->sub.trees.blens[i++] = c; - } while (--j); - s->sub.trees.index = i; - } - } - s->sub.trees.tb = Z_NULL; - { - uInt bl, bd; - inflate_huft *tl, *td; - inflate_codes_statef *c; - - tl = NULL; - td = NULL; - bl = 9; /* must be <= 9 for lookahead assumptions */ - bd = 6; /* must be <= 9 for lookahead assumptions */ - t = s->sub.trees.table; - t = inflate_trees_dynamic(257 + (t & 0x1f), 1 + ((t >> 5) & 0x1f), - s->sub.trees.blens, &bl, &bd, &tl, &td, - s->hufts, z); - ZFREE(z, s->sub.trees.blens); - if (t != Z_OK) - { - if (t == (uInt)Z_DATA_ERROR) - s->mode = BAD; - r = t; - LEAVE - } - Tracev(("inflate: trees ok\n")); - if ((c = inflate_codes_new(bl, bd, tl, td, z)) == Z_NULL) - { - r = Z_MEM_ERROR; - LEAVE - } - s->sub.decode.codes = c; - } - s->mode = CODES; - case CODES: - UPDATE - if ((r = inflate_codes(s, z, r)) != Z_STREAM_END) - return inflate_flush(s, z, r); - r = Z_OK; - inflate_codes_free(s->sub.decode.codes, z); - LOAD - Tracev(("inflate: codes end, %lu total out\n", - z->total_out + (q >= s->read ? q - s->read : - (s->end - s->read) + (q - s->window)))); - if (!s->last) - { - s->mode = TYPE; - break; - } - s->mode = DRY; - case DRY: - FLUSH - if (s->read != s->write) - LEAVE - s->mode = DONE; - case DONE: - r = Z_STREAM_END; - LEAVE - case BAD: - r = Z_DATA_ERROR; - LEAVE - default: - r = Z_STREAM_ERROR; - LEAVE - } -} - - -int inflate_blocks_free(inflate_blocks_statef *s, z_streamp z) -{ - inflate_blocks_reset(s, z, Z_NULL); - ZFREE(z, s->window); - ZFREE(z, s->hufts); - ZFREE(z, s); - Tracev(("inflate: blocks freed\n")); - return Z_OK; -} - -#if 0 -void inflate_set_dictionary(inflate_blocks_statef *s, const Byte *d, uInt n) -{ - zmemcpy(s->window, d, n); - s->read = s->write = s->window + n; -} - -/* Returns true if inflate is currently at the end of a block generated - * by Z_SYNC_FLUSH or Z_FULL_FLUSH. - * IN assertion: s != Z_NULL - */ -int inflate_blocks_sync_point(inflate_blocks_statef *s) -{ - return s->mode == LENS; -} -#endif - - -/* And'ing with mask[n] masks the lower n bits */ -static uInt inflate_mask[17] = { - 0x0000, - 0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff, - 0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff -}; - - -/* copy as much as possible from the sliding window to the output area */ -int inflate_flush(inflate_blocks_statef *s, z_streamp z, int r) -{ - uInt n; - Byte *p; - Byte *q; - - /* static copies of source and destination pointers */ - p = z->next_out; - q = s->read; - - /* compute number of bytes to copy as as end of window */ - n = (uInt)((q <= s->write ? s->write : s->end) - q); - if (n > z->avail_out) n = z->avail_out; - if (n && r == Z_BUF_ERROR) r = Z_OK; - - /* update counters */ - z->avail_out -= n; - z->total_out += n; - - /* update check information */ - if (s->checkfn != Z_NULL) - z->adler = s->check = (*s->checkfn)(s->check, q, n); - - /* copy as as end of window */ - zmemcpy(p, q, n); - p += n; - q += n; - - /* see if more to copy at beginning of window */ - if (q == s->end) - { - /* wrap pointers */ - q = s->window; - if (s->write == s->end) - s->write = s->window; - - /* compute bytes to copy */ - n = (uInt)(s->write - q); - if (n > z->avail_out) n = z->avail_out; - if (n && r == Z_BUF_ERROR) r = Z_OK; - - /* update counters */ - z->avail_out -= n; - z->total_out += n; - - /* update check information */ - if (s->checkfn != Z_NULL) - z->adler = s->check = (*s->checkfn)(s->check, q, n); - - /* copy */ - zmemcpy(p, q, n); - p += n; - q += n; - } - - /* update pointers */ - z->next_out = p; - s->read = q; - - /* done */ - return r; -} - -/* inftrees.c -- generate Huffman trees for efficient decoding - * Copyright (C) 1995-1998 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -static const char inflate_copyright[] = - " inflate 1.1.3 Copyright 1995-1998 Mark Adler "; -/* - If you use the zlib library in a product, an acknowledgment is welcome - in the documentation of your product. If for some reason you cannot - include such an acknowledgment, I would appreciate that you keep this - copyright string in the executable of your product. - */ - -/* simplify the use of the inflate_huft type with some defines */ -#define exop word.what.Exop -#define bits word.what.Bits - - -static int huft_build OF(( - uInt *, /* code lengths in bits */ - uInt, /* number of codes */ - uInt, /* number of "simple" codes */ - const uInt *, /* list of base values for non-simple codes */ - const uInt *, /* list of extra bits for non-simple codes */ - inflate_huft **, /* result: starting table */ - uInt *, /* maximum lookup bits (returns actual) */ - inflate_huft *, /* space for trees */ - uInt *, /* hufts used in space */ - uInt * )); /* space for values */ - -/* Tables for deflate from PKZIP's appnote.txt. */ -static const uInt cplens[31] = { /* Copy lengths for literal codes 257..285 */ - 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, - 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0}; - /* see note #13 above about 258 */ -static const uInt cplext[31] = { /* Extra bits for literal codes 257..285 */ - 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, - 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 112, 112}; /* 112==invalid */ -static const uInt cpdist[30] = { /* Copy offsets for distance codes 0..29 */ - 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, - 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, - 8193, 12289, 16385, 24577}; -static const uInt cpdext[30] = { /* Extra bits for distance codes */ - 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, - 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, - 12, 12, 13, 13}; - -/* - Huffman code decoding is performed using a multi-level table lookup. - The fastest way to decode is to simply build a lookup table whose - size is determined by the longest code. However, the time it takes - to build this table can also be a factor if the data being decoded - is not very long. The most common codes are necessarily the - shortest codes, so those codes dominate the decoding time, and hence - the speed. The idea is you can have a shorter table that decodes the - shorter, more probable codes, and then point to subsidiary tables for - the longer codes. The time it costs to decode the longer codes is - then traded against the time it takes to make longer tables. - - This results of this trade are in the variables lbits and dbits - below. lbits is the number of bits the first level table for literal/ - length codes can decode in one step, and dbits is the same thing for - the distance codes. Subsequent tables are also less than or equal to - those sizes. These values may be adjusted either when all of the - codes are shorter than that, in which case the longest code length in - bits is used, or when the shortest code is *longer* than the requested - table size, in which case the length of the shortest code in bits is - used. - - There are two different values for the two tables, since they code a - different number of possibilities each. The literal/length table - codes 286 possible values, or in a flat code, a little over eight - bits. The distance table codes 30 possible values, or a little less - than five bits, flat. The optimum values for speed end up being - about one bit more than those, so lbits is 8+1 and dbits is 5+1. - The optimum values may differ though from machine to machine, and - possibly even between compilers. Your mileage may vary. - */ - - -/* If BMAX needs to be larger than 16, then h and x[] should be uLong. */ -#define BMAX 15 /* maximum bit length of any code */ - -static int huft_build(uInt *b, uInt n, uInt s, const uInt *d, const uInt *e, inflate_huft ** t, uInt *m, inflate_huft *hp, uInt *hn, uInt *v) -//uInt *b; /* code lengths in bits (all assumed <= BMAX) */ -//uInt n; /* number of codes (assumed <= 288) */ -//uInt s; /* number of simple-valued codes (0..s-1) */ -//const uInt *d; /* list of base values for non-simple codes */ -//const uInt *e; /* list of extra bits for non-simple codes */ -//inflate_huft ** t; /* result: starting table */ -//uInt *m; /* maximum lookup bits, returns actual */ -//inflate_huft *hp; /* space for trees */ -//uInt *hn; /* hufts used in space */ -//uInt *v; /* working area: values in order of bit length */ -/* Given a list of code lengths and a maximum table size, make a set of - tables to decode that set of codes. Return Z_OK on success, Z_BUF_ERROR - if the given code set is incomplete (the tables are still built in this - case), Z_DATA_ERROR if the input is invalid (an over-subscribed set of - lengths), or Z_MEM_ERROR if not enough memory. */ -{ - - uInt a; /* counter for codes of length k */ - uInt c[BMAX+1]; /* bit length count table */ - uInt f; /* i repeats in table every f entries */ - int g; /* maximum code length */ - int h; /* table level */ - register uInt i; /* counter, current code */ - register uInt j; /* counter */ - register int k; /* number of bits in current code */ - int l; /* bits per table (returned in m) */ - uInt mask; /* (1 << w) - 1, to avoid cc -O bug on HP */ - register uInt *p; /* pointer into c[], b[], or v[] */ - inflate_huft *q; /* points to current table */ - struct inflate_huft_s r; /* table entry for structure assignment */ - inflate_huft *u[BMAX]; /* table stack */ - register int w; /* bits before this table == (l * h) */ - uInt x[BMAX+1]; /* bit offsets, then code stack */ - uInt *xp; /* pointer into x */ - int y; /* number of dummy codes added */ - uInt z; /* number of entries in current table */ - - - /* Generate counts for each bit length */ - p = c; -#define C0 *p++ = 0; -#define C2 C0 C0 C0 C0 -#define C4 C2 C2 C2 C2 - C4 /* clear c[]--assume BMAX+1 is 16 */ - p = b; i = n; - do { - c[*p++]++; /* assume all entries <= BMAX */ - } while (--i); - if (c[0] == n) /* null input--all zero length codes */ - { - *t = (inflate_huft *)Z_NULL; - *m = 0; - return Z_OK; - } - - - /* Find minimum and maximum length, bound *m by those */ - l = *m; - for (j = 1; j <= BMAX; j++) - if (c[j]) - break; - k = j; /* minimum code length */ - if ((uInt)l < j) - l = j; - for (i = BMAX; i; i--) - if (c[i]) - break; - g = i; /* maximum code length */ - if ((uInt)l > i) - l = i; - *m = l; - - - /* Adjust last length count to fill out codes, if needed */ - for (y = 1 << j; j < i; j++, y <<= 1) - if ((y -= c[j]) < 0) - return Z_DATA_ERROR; - if ((y -= c[i]) < 0) - return Z_DATA_ERROR; - c[i] += y; - - - /* Generate starting offsets into the value table for each length */ - x[1] = j = 0; - p = c + 1; xp = x + 2; - while (--i) { /* note that i == g from above */ - *xp++ = (j += *p++); - } - - - /* Make a table of values in order of bit lengths */ - p = b; i = 0; - do { - if ((j = *p++) != 0) - v[x[j]++] = i; - } while (++i < n); - n = x[g]; /* set n to length of v */ - - - /* Generate the Huffman codes and for each, make the table entries */ - x[0] = i = 0; /* first Huffman code is zero */ - p = v; /* grab values in bit order */ - h = -1; /* no tables yet--level -1 */ - w = -l; /* bits decoded == (l * h) */ - u[0] = (inflate_huft *)Z_NULL; /* just to keep compilers happy */ - q = (inflate_huft *)Z_NULL; /* ditto */ - z = 0; /* ditto */ - - /* go through the bit lengths (k already is bits in shortest code) */ - for (; k <= g; k++) - { - a = c[k]; - while (a--) - { - /* here i is the Huffman code of length k bits for value *p */ - /* make tables up to required level */ - while (k > w + l) - { - h++; - w += l; /* previous table always l bits */ - - /* compute minimum size table less than or equal to l bits */ - z = g - w; - z = z > (uInt)l ? l : z; /* table size upper limit */ - if ((f = 1 << (j = k - w)) > a + 1) /* try a k-w bit table */ - { /* too few codes for k-w bit table */ - f -= a + 1; /* deduct codes from patterns left */ - xp = c + k; - if (j < z) - while (++j < z) /* try smaller tables up to z bits */ - { - if ((f <<= 1) <= *++xp) - break; /* enough codes to use up j bits */ - f -= *xp; /* else deduct codes from patterns */ - } - } - z = 1 << j; /* table entries for j-bit table */ - - /* allocate new table */ - if (*hn + z > MANY) /* (note: doesn't matter for fixed) */ - return Z_MEM_ERROR; /* not enough memory */ - u[h] = q = hp + *hn; - *hn += z; - - /* connect to last table, if there is one */ - if (h) - { - x[h] = i; /* save pattern for backing up */ - r.bits = (Byte)l; /* bits to dump before this table */ - r.exop = (Byte)j; /* bits in this table */ - j = i >> (w - l); - r.base = (uInt)(q - u[h-1] - j); /* offset to this table */ - u[h-1][j] = r; /* connect to last table */ - } - else - *t = q; /* first table is returned result */ - } - - /* set up table entry in r */ - r.bits = (Byte)(k - w); - if (p >= v + n) - r.exop = 128 + 64; /* out of values--invalid code */ - else if (*p < s) - { - r.exop = (Byte)(*p < 256 ? 0 : 32 + 64); /* 256 is end-of-block */ - r.base = *p++; /* simple code is just the value */ - } - else - { - r.exop = (Byte)(e[*p - s] + 16 + 64);/* non-simple--look up in lists */ - r.base = d[*p++ - s]; - } - - /* fill code-like entries with r */ - f = 1 << (k - w); - for (j = i >> w; j < z; j += f) - q[j] = r; - - /* backwards increment the k-bit code i */ - for (j = 1 << (k - 1); i & j; j >>= 1) - i ^= j; - i ^= j; - - /* backup over finished tables */ - mask = (1 << w) - 1; /* needed on HP, cc -O bug */ - while ((i & mask) != x[h]) - { - h--; /* don't need to update q */ - w -= l; - mask = (1 << w) - 1; - } - } - } - - - /* Return Z_BUF_ERROR if we were given an incomplete table */ - return y != 0 && g != 1 ? Z_BUF_ERROR : Z_OK; -} - - -int inflate_trees_bits(uInt *c, uInt *bb, inflate_huft * *tb, inflate_huft *hp, z_streamp z) -//uInt *c; /* 19 code lengths */ -//uInt *bb; /* bits tree desired/actual depth */ -//inflate_huft * *tb; /* bits tree result */ -//inflate_huft *hp; /* space for trees */ -//z_streamp z; /* for messages */ -{ - int r; - uInt hn = 0; /* hufts used in space */ - uInt *v; /* work area for huft_build */ - - if ((v = (uInt*)ZALLOC(z, 19, sizeof(uInt))) == Z_NULL) - return Z_MEM_ERROR; - r = huft_build(c, 19, 19, (uInt*)Z_NULL, (uInt*)Z_NULL, - tb, bb, hp, &hn, v); - if (r == Z_DATA_ERROR) - z->msg = (char*)"oversubscribed dynamic bit lengths tree"; - else if (r == Z_BUF_ERROR || *bb == 0) - { - z->msg = (char*)"incomplete dynamic bit lengths tree"; - r = Z_DATA_ERROR; - } - ZFREE(z, v); - return r; -} - - -int inflate_trees_dynamic(uInt nl, uInt nd, uInt *c, uInt *bl, uInt *bd, inflate_huft * *tl, inflate_huft * *td, inflate_huft *hp, z_streamp z) -//uInt nl; /* number of literal/length codes */ -//uInt nd; /* number of distance codes */ -//uInt *c; /* that many (total) code lengths */ -//uInt *bl; /* literal desired/actual bit depth */ -//uInt *bd; /* distance desired/actual bit depth */ -//inflate_huft * *tl; /* literal/length tree result */ -//inflate_huft * *td; /* distance tree result */ -//inflate_huft *hp; /* space for trees */ -//z_streamp z; /* for messages */ -{ - int r; - uInt hn = 0; /* hufts used in space */ - uInt *v; /* work area for huft_build */ - - /* allocate work area */ - if ((v = (uInt*)ZALLOC(z, 288, sizeof(uInt))) == Z_NULL) - return Z_MEM_ERROR; - - /* build literal/length tree */ - r = huft_build(c, nl, 257, cplens, cplext, tl, bl, hp, &hn, v); - if (r != Z_OK || *bl == 0) - { - if (r == Z_DATA_ERROR) - z->msg = (char*)"oversubscribed literal/length tree"; - else if (r != Z_MEM_ERROR) - { - z->msg = (char*)"incomplete literal/length tree"; - r = Z_DATA_ERROR; - } - ZFREE(z, v); - return r; - } - - /* build distance tree */ - r = huft_build(c + nl, nd, 0, cpdist, cpdext, td, bd, hp, &hn, v); - if (r != Z_OK || (*bd == 0 && nl > 257)) - { - if (r == Z_DATA_ERROR) - z->msg = (char*)"oversubscribed distance tree"; - else if (r == Z_BUF_ERROR) { -#ifdef PKZIP_BUG_WORKAROUND - r = Z_OK; - } -#else - z->msg = (char*)"incomplete distance tree"; - r = Z_DATA_ERROR; - } - else if (r != Z_MEM_ERROR) - { - z->msg = (char*)"empty distance tree with lengths"; - r = Z_DATA_ERROR; - } - ZFREE(z, v); - return r; -#endif - } - - /* done */ - ZFREE(z, v); - return Z_OK; -} - -/* inffixed.h -- table for decoding fixed codes - * Generated automatically by the maketree.c program - */ - -/* WARNING: this file should *not* be used by applications. It is - part of the implementation of the compression library and is - subject to change. Applications should only use zlib.h. - */ - -static uInt fixed_bl = 9; -static uInt fixed_bd = 5; -static inflate_huft fixed_tl[] = { - {{{96,7}},256}, {{{0,8}},80}, {{{0,8}},16}, {{{84,8}},115}, - {{{82,7}},31}, {{{0,8}},112}, {{{0,8}},48}, {{{0,9}},192}, - {{{80,7}},10}, {{{0,8}},96}, {{{0,8}},32}, {{{0,9}},160}, - {{{0,8}},0}, {{{0,8}},128}, {{{0,8}},64}, {{{0,9}},224}, - {{{80,7}},6}, {{{0,8}},88}, {{{0,8}},24}, {{{0,9}},144}, - {{{83,7}},59}, {{{0,8}},120}, {{{0,8}},56}, {{{0,9}},208}, - {{{81,7}},17}, {{{0,8}},104}, {{{0,8}},40}, {{{0,9}},176}, - {{{0,8}},8}, {{{0,8}},136}, {{{0,8}},72}, {{{0,9}},240}, - {{{80,7}},4}, {{{0,8}},84}, {{{0,8}},20}, {{{85,8}},227}, - {{{83,7}},43}, {{{0,8}},116}, {{{0,8}},52}, {{{0,9}},200}, - {{{81,7}},13}, {{{0,8}},100}, {{{0,8}},36}, {{{0,9}},168}, - {{{0,8}},4}, {{{0,8}},132}, {{{0,8}},68}, {{{0,9}},232}, - {{{80,7}},8}, {{{0,8}},92}, {{{0,8}},28}, {{{0,9}},152}, - {{{84,7}},83}, {{{0,8}},124}, {{{0,8}},60}, {{{0,9}},216}, - {{{82,7}},23}, {{{0,8}},108}, {{{0,8}},44}, {{{0,9}},184}, - {{{0,8}},12}, {{{0,8}},140}, {{{0,8}},76}, {{{0,9}},248}, - {{{80,7}},3}, {{{0,8}},82}, {{{0,8}},18}, {{{85,8}},163}, - {{{83,7}},35}, {{{0,8}},114}, {{{0,8}},50}, {{{0,9}},196}, - {{{81,7}},11}, {{{0,8}},98}, {{{0,8}},34}, {{{0,9}},164}, - {{{0,8}},2}, {{{0,8}},130}, {{{0,8}},66}, {{{0,9}},228}, - {{{80,7}},7}, {{{0,8}},90}, {{{0,8}},26}, {{{0,9}},148}, - {{{84,7}},67}, {{{0,8}},122}, {{{0,8}},58}, {{{0,9}},212}, - {{{82,7}},19}, {{{0,8}},106}, {{{0,8}},42}, {{{0,9}},180}, - {{{0,8}},10}, {{{0,8}},138}, {{{0,8}},74}, {{{0,9}},244}, - {{{80,7}},5}, {{{0,8}},86}, {{{0,8}},22}, {{{192,8}},0}, - {{{83,7}},51}, {{{0,8}},118}, {{{0,8}},54}, {{{0,9}},204}, - {{{81,7}},15}, {{{0,8}},102}, {{{0,8}},38}, {{{0,9}},172}, - {{{0,8}},6}, {{{0,8}},134}, {{{0,8}},70}, {{{0,9}},236}, - {{{80,7}},9}, {{{0,8}},94}, {{{0,8}},30}, {{{0,9}},156}, - {{{84,7}},99}, {{{0,8}},126}, {{{0,8}},62}, {{{0,9}},220}, - {{{82,7}},27}, {{{0,8}},110}, {{{0,8}},46}, {{{0,9}},188}, - {{{0,8}},14}, {{{0,8}},142}, {{{0,8}},78}, {{{0,9}},252}, - {{{96,7}},256}, {{{0,8}},81}, {{{0,8}},17}, {{{85,8}},131}, - {{{82,7}},31}, {{{0,8}},113}, {{{0,8}},49}, {{{0,9}},194}, - {{{80,7}},10}, {{{0,8}},97}, {{{0,8}},33}, {{{0,9}},162}, - {{{0,8}},1}, {{{0,8}},129}, {{{0,8}},65}, {{{0,9}},226}, - {{{80,7}},6}, {{{0,8}},89}, {{{0,8}},25}, {{{0,9}},146}, - {{{83,7}},59}, {{{0,8}},121}, {{{0,8}},57}, {{{0,9}},210}, - {{{81,7}},17}, {{{0,8}},105}, {{{0,8}},41}, {{{0,9}},178}, - {{{0,8}},9}, {{{0,8}},137}, {{{0,8}},73}, {{{0,9}},242}, - {{{80,7}},4}, {{{0,8}},85}, {{{0,8}},21}, {{{80,8}},258}, - {{{83,7}},43}, {{{0,8}},117}, {{{0,8}},53}, {{{0,9}},202}, - {{{81,7}},13}, {{{0,8}},101}, {{{0,8}},37}, {{{0,9}},170}, - {{{0,8}},5}, {{{0,8}},133}, {{{0,8}},69}, {{{0,9}},234}, - {{{80,7}},8}, {{{0,8}},93}, {{{0,8}},29}, {{{0,9}},154}, - {{{84,7}},83}, {{{0,8}},125}, {{{0,8}},61}, {{{0,9}},218}, - {{{82,7}},23}, {{{0,8}},109}, {{{0,8}},45}, {{{0,9}},186}, - {{{0,8}},13}, {{{0,8}},141}, {{{0,8}},77}, {{{0,9}},250}, - {{{80,7}},3}, {{{0,8}},83}, {{{0,8}},19}, {{{85,8}},195}, - {{{83,7}},35}, {{{0,8}},115}, {{{0,8}},51}, {{{0,9}},198}, - {{{81,7}},11}, {{{0,8}},99}, {{{0,8}},35}, {{{0,9}},166}, - {{{0,8}},3}, {{{0,8}},131}, {{{0,8}},67}, {{{0,9}},230}, - {{{80,7}},7}, {{{0,8}},91}, {{{0,8}},27}, {{{0,9}},150}, - {{{84,7}},67}, {{{0,8}},123}, {{{0,8}},59}, {{{0,9}},214}, - {{{82,7}},19}, {{{0,8}},107}, {{{0,8}},43}, {{{0,9}},182}, - {{{0,8}},11}, {{{0,8}},139}, {{{0,8}},75}, {{{0,9}},246}, - {{{80,7}},5}, {{{0,8}},87}, {{{0,8}},23}, {{{192,8}},0}, - {{{83,7}},51}, {{{0,8}},119}, {{{0,8}},55}, {{{0,9}},206}, - {{{81,7}},15}, {{{0,8}},103}, {{{0,8}},39}, {{{0,9}},174}, - {{{0,8}},7}, {{{0,8}},135}, {{{0,8}},71}, {{{0,9}},238}, - {{{80,7}},9}, {{{0,8}},95}, {{{0,8}},31}, {{{0,9}},158}, - {{{84,7}},99}, {{{0,8}},127}, {{{0,8}},63}, {{{0,9}},222}, - {{{82,7}},27}, {{{0,8}},111}, {{{0,8}},47}, {{{0,9}},190}, - {{{0,8}},15}, {{{0,8}},143}, {{{0,8}},79}, {{{0,9}},254}, - {{{96,7}},256}, {{{0,8}},80}, {{{0,8}},16}, {{{84,8}},115}, - {{{82,7}},31}, {{{0,8}},112}, {{{0,8}},48}, {{{0,9}},193}, - {{{80,7}},10}, {{{0,8}},96}, {{{0,8}},32}, {{{0,9}},161}, - {{{0,8}},0}, {{{0,8}},128}, {{{0,8}},64}, {{{0,9}},225}, - {{{80,7}},6}, {{{0,8}},88}, {{{0,8}},24}, {{{0,9}},145}, - {{{83,7}},59}, {{{0,8}},120}, {{{0,8}},56}, {{{0,9}},209}, - {{{81,7}},17}, {{{0,8}},104}, {{{0,8}},40}, {{{0,9}},177}, - {{{0,8}},8}, {{{0,8}},136}, {{{0,8}},72}, {{{0,9}},241}, - {{{80,7}},4}, {{{0,8}},84}, {{{0,8}},20}, {{{85,8}},227}, - {{{83,7}},43}, {{{0,8}},116}, {{{0,8}},52}, {{{0,9}},201}, - {{{81,7}},13}, {{{0,8}},100}, {{{0,8}},36}, {{{0,9}},169}, - {{{0,8}},4}, {{{0,8}},132}, {{{0,8}},68}, {{{0,9}},233}, - {{{80,7}},8}, {{{0,8}},92}, {{{0,8}},28}, {{{0,9}},153}, - {{{84,7}},83}, {{{0,8}},124}, {{{0,8}},60}, {{{0,9}},217}, - {{{82,7}},23}, {{{0,8}},108}, {{{0,8}},44}, {{{0,9}},185}, - {{{0,8}},12}, {{{0,8}},140}, {{{0,8}},76}, {{{0,9}},249}, - {{{80,7}},3}, {{{0,8}},82}, {{{0,8}},18}, {{{85,8}},163}, - {{{83,7}},35}, {{{0,8}},114}, {{{0,8}},50}, {{{0,9}},197}, - {{{81,7}},11}, {{{0,8}},98}, {{{0,8}},34}, {{{0,9}},165}, - {{{0,8}},2}, {{{0,8}},130}, {{{0,8}},66}, {{{0,9}},229}, - {{{80,7}},7}, {{{0,8}},90}, {{{0,8}},26}, {{{0,9}},149}, - {{{84,7}},67}, {{{0,8}},122}, {{{0,8}},58}, {{{0,9}},213}, - {{{82,7}},19}, {{{0,8}},106}, {{{0,8}},42}, {{{0,9}},181}, - {{{0,8}},10}, {{{0,8}},138}, {{{0,8}},74}, {{{0,9}},245}, - {{{80,7}},5}, {{{0,8}},86}, {{{0,8}},22}, {{{192,8}},0}, - {{{83,7}},51}, {{{0,8}},118}, {{{0,8}},54}, {{{0,9}},205}, - {{{81,7}},15}, {{{0,8}},102}, {{{0,8}},38}, {{{0,9}},173}, - {{{0,8}},6}, {{{0,8}},134}, {{{0,8}},70}, {{{0,9}},237}, - {{{80,7}},9}, {{{0,8}},94}, {{{0,8}},30}, {{{0,9}},157}, - {{{84,7}},99}, {{{0,8}},126}, {{{0,8}},62}, {{{0,9}},221}, - {{{82,7}},27}, {{{0,8}},110}, {{{0,8}},46}, {{{0,9}},189}, - {{{0,8}},14}, {{{0,8}},142}, {{{0,8}},78}, {{{0,9}},253}, - {{{96,7}},256}, {{{0,8}},81}, {{{0,8}},17}, {{{85,8}},131}, - {{{82,7}},31}, {{{0,8}},113}, {{{0,8}},49}, {{{0,9}},195}, - {{{80,7}},10}, {{{0,8}},97}, {{{0,8}},33}, {{{0,9}},163}, - {{{0,8}},1}, {{{0,8}},129}, {{{0,8}},65}, {{{0,9}},227}, - {{{80,7}},6}, {{{0,8}},89}, {{{0,8}},25}, {{{0,9}},147}, - {{{83,7}},59}, {{{0,8}},121}, {{{0,8}},57}, {{{0,9}},211}, - {{{81,7}},17}, {{{0,8}},105}, {{{0,8}},41}, {{{0,9}},179}, - {{{0,8}},9}, {{{0,8}},137}, {{{0,8}},73}, {{{0,9}},243}, - {{{80,7}},4}, {{{0,8}},85}, {{{0,8}},21}, {{{80,8}},258}, - {{{83,7}},43}, {{{0,8}},117}, {{{0,8}},53}, {{{0,9}},203}, - {{{81,7}},13}, {{{0,8}},101}, {{{0,8}},37}, {{{0,9}},171}, - {{{0,8}},5}, {{{0,8}},133}, {{{0,8}},69}, {{{0,9}},235}, - {{{80,7}},8}, {{{0,8}},93}, {{{0,8}},29}, {{{0,9}},155}, - {{{84,7}},83}, {{{0,8}},125}, {{{0,8}},61}, {{{0,9}},219}, - {{{82,7}},23}, {{{0,8}},109}, {{{0,8}},45}, {{{0,9}},187}, - {{{0,8}},13}, {{{0,8}},141}, {{{0,8}},77}, {{{0,9}},251}, - {{{80,7}},3}, {{{0,8}},83}, {{{0,8}},19}, {{{85,8}},195}, - {{{83,7}},35}, {{{0,8}},115}, {{{0,8}},51}, {{{0,9}},199}, - {{{81,7}},11}, {{{0,8}},99}, {{{0,8}},35}, {{{0,9}},167}, - {{{0,8}},3}, {{{0,8}},131}, {{{0,8}},67}, {{{0,9}},231}, - {{{80,7}},7}, {{{0,8}},91}, {{{0,8}},27}, {{{0,9}},151}, - {{{84,7}},67}, {{{0,8}},123}, {{{0,8}},59}, {{{0,9}},215}, - {{{82,7}},19}, {{{0,8}},107}, {{{0,8}},43}, {{{0,9}},183}, - {{{0,8}},11}, {{{0,8}},139}, {{{0,8}},75}, {{{0,9}},247}, - {{{80,7}},5}, {{{0,8}},87}, {{{0,8}},23}, {{{192,8}},0}, - {{{83,7}},51}, {{{0,8}},119}, {{{0,8}},55}, {{{0,9}},207}, - {{{81,7}},15}, {{{0,8}},103}, {{{0,8}},39}, {{{0,9}},175}, - {{{0,8}},7}, {{{0,8}},135}, {{{0,8}},71}, {{{0,9}},239}, - {{{80,7}},9}, {{{0,8}},95}, {{{0,8}},31}, {{{0,9}},159}, - {{{84,7}},99}, {{{0,8}},127}, {{{0,8}},63}, {{{0,9}},223}, - {{{82,7}},27}, {{{0,8}},111}, {{{0,8}},47}, {{{0,9}},191}, - {{{0,8}},15}, {{{0,8}},143}, {{{0,8}},79}, {{{0,9}},255} - }; -static inflate_huft fixed_td[] = { - {{{80,5}},1}, {{{87,5}},257}, {{{83,5}},17}, {{{91,5}},4097}, - {{{81,5}},5}, {{{89,5}},1025}, {{{85,5}},65}, {{{93,5}},16385}, - {{{80,5}},3}, {{{88,5}},513}, {{{84,5}},33}, {{{92,5}},8193}, - {{{82,5}},9}, {{{90,5}},2049}, {{{86,5}},129}, {{{192,5}},24577}, - {{{80,5}},2}, {{{87,5}},385}, {{{83,5}},25}, {{{91,5}},6145}, - {{{81,5}},7}, {{{89,5}},1537}, {{{85,5}},97}, {{{93,5}},24577}, - {{{80,5}},4}, {{{88,5}},769}, {{{84,5}},49}, {{{92,5}},12289}, - {{{82,5}},13}, {{{90,5}},3073}, {{{86,5}},193}, {{{192,5}},24577} - }; - -int inflate_trees_fixed(uInt *bl, uInt *bd, inflate_huft * *tl, inflate_huft * *td, z_streamp z) -//uInt *bl; /* literal desired/actual bit depth */ -//uInt *bd; /* distance desired/actual bit depth */ -//inflate_huft * *tl; /* literal/length tree result */ -//inflate_huft * *td; /* distance tree result */ -//z_streamp z; /* for memory allocation */ -{ - *bl = fixed_bl; - *bd = fixed_bd; - *tl = fixed_tl; - *td = fixed_td; - return Z_OK; -} - -/* simplify the use of the inflate_huft type with some defines */ -#define exop word.what.Exop -#define bits word.what.Bits - -/* macros for bit input with no checking and for returning unused bytes */ -#define GRABBITS(j) {while(k<(j)){b|=((uLong)NEXTBYTE)<avail_in-n;c=(k>>3)>3:c;n+=c;p-=c;k-=c<<3;} - -/* Called with number of bytes left to write in window at least 258 - (the maximum string length) and number of input bytes available - at least ten. The ten bytes are six bytes for the longest length/ - distance pair plus four bytes for overloading the bit buffer. */ - -static int inflate_fast(uInt bl, uInt bd, inflate_huft *tl, inflate_huft *td, inflate_blocks_statef *s, z_streamp z) -{ - inflate_huft *t; /* temporary pointer */ - uInt e; /* extra bits or operation */ - uLong b; /* bit buffer */ - uInt k; /* bits in bit buffer */ - Byte *p; /* input data pointer */ - uInt n; /* bytes available there */ - Byte *q; /* output window write pointer */ - uInt m; /* bytes to end of window or read pointer */ - uInt ml; /* mask for literal/length tree */ - uInt md; /* mask for distance tree */ - uInt c; /* bytes to copy */ - uInt d; /* distance back to copy from */ - Byte *r; /* copy source pointer */ - - /* load input, output, bit values */ - LOAD - - /* initialize masks */ - ml = inflate_mask[bl]; - md = inflate_mask[bd]; - - /* do until not enough input or output space for fast loop */ - do { /* assume called with m >= 258 && n >= 10 */ - /* get literal/length code */ - GRABBITS(20) /* max bits for literal/length code */ - if ((e = (t = tl + ((uInt)b & ml))->exop) == 0) - { - DUMPBITS(t->bits) - Tracevv((t->base >= 0x20 && t->base < 0x7f ? - "inflate: * literal '%c'\n" : - "inflate: * literal 0x%02x\n", t->base)); - *q++ = (Byte)t->base; - m--; - continue; - } - do { - DUMPBITS(t->bits) - if (e & 16) - { - /* get extra bits for length */ - e &= 15; - c = t->base + ((uInt)b & inflate_mask[e]); - DUMPBITS(e) - Tracevv(("inflate: * length %u\n", c)); - - /* decode distance base of block to copy */ - GRABBITS(15); /* max bits for distance code */ - e = (t = td + ((uInt)b & md))->exop; - do { - DUMPBITS(t->bits) - if (e & 16) - { - /* get extra bits to add to distance base */ - e &= 15; - GRABBITS(e) /* get extra bits (up to 13) */ - d = t->base + ((uInt)b & inflate_mask[e]); - DUMPBITS(e) - Tracevv(("inflate: * distance %u\n", d)); - - /* do the copy */ - m -= c; - if ((uInt)(q - s->window) >= d) /* offset before dest */ - { /* just copy */ - r = q - d; - *q++ = *r++; c--; /* minimum count is three, */ - *q++ = *r++; c--; /* so unroll loop a little */ - } - else /* else offset after destination */ - { - e = d - (uInt)(q - s->window); /* bytes from offset to end */ - r = s->end - e; /* pointer to offset */ - if (c > e) /* if source crosses, */ - { - c -= e; /* copy to end of window */ - do { - *q++ = *r++; - } while (--e); - r = s->window; /* copy rest from start of window */ - } - } - do { /* copy all or what's left */ - *q++ = *r++; - } while (--c); - break; - } - else if ((e & 64) == 0) - { - t += t->base; - e = (t += ((uInt)b & inflate_mask[e]))->exop; - } - else - { - z->msg = (char*)"invalid distance code"; - UNGRAB - UPDATE - return Z_DATA_ERROR; - } - } while (1); - break; - } - if ((e & 64) == 0) - { - t += t->base; - if ((e = (t += ((uInt)b & inflate_mask[e]))->exop) == 0) - { - DUMPBITS(t->bits) - Tracevv((t->base >= 0x20 && t->base < 0x7f ? - "inflate: * literal '%c'\n" : - "inflate: * literal 0x%02x\n", t->base)); - *q++ = (Byte)t->base; - m--; - break; - } - } - else if (e & 32) - { - Tracevv(("inflate: * end of block\n")); - UNGRAB - UPDATE - return Z_STREAM_END; - } - else - { - z->msg = (char*)"invalid literal/length code"; - UNGRAB - UPDATE - return Z_DATA_ERROR; - } - } while (1); - } while (m >= 258 && n >= 10); - - /* not enough input or output--restore pointers and return */ - UNGRAB - UPDATE - return Z_OK; -} - -/* infcodes.c -- process literals and length/distance pairs - * Copyright (C) 1995-1998 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* simplify the use of the inflate_huft type with some defines */ -#define exop word.what.Exop -#define bits word.what.Bits - -typedef enum { /* waiting for "i:"=input, "o:"=output, "x:"=nothing */ - START, /* x: set up for LEN */ - LEN, /* i: get length/literal/eob next */ - LENEXT, /* i: getting length extra (have base) */ - DIST, /* i: get distance next */ - DISTEXT, /* i: getting distance extra */ - COPY, /* o: copying bytes in window, waiting for space */ - LIT, /* o: got literal, waiting for output space */ - WASH, /* o: got eob, possibly still output waiting */ - END, /* x: got eob and all data flushed */ - BADCODE} /* x: got error */ -inflate_codes_mode; - -/* inflate codes private state */ -struct inflate_codes_state { - - /* mode */ - inflate_codes_mode mode; /* current inflate_codes mode */ - - /* mode dependent information */ - uInt len; - union { - struct { - inflate_huft *tree; /* pointer into tree */ - uInt need; /* bits needed */ - } code; /* if LEN or DIST, where in tree */ - uInt lit; /* if LIT, literal */ - struct { - uInt get; /* bits to get for extra */ - uInt dist; /* distance back to copy from */ - } copy; /* if EXT or COPY, where and how much */ - } sub; /* submode */ - - /* mode independent information */ - Byte lbits; /* ltree bits decoded per branch */ - Byte dbits; /* dtree bits decoder per branch */ - inflate_huft *ltree; /* literal/length/eob tree */ - inflate_huft *dtree; /* distance tree */ - -}; - - -inflate_codes_statef *inflate_codes_new(uInt bl, uInt bd, inflate_huft *tl, inflate_huft *td, z_streamp z) -{ - inflate_codes_statef *c; - - if ((c = (inflate_codes_statef *) - ZALLOC(z,1,sizeof(struct inflate_codes_state))) != Z_NULL) - { - c->mode = START; - c->lbits = (Byte)bl; - c->dbits = (Byte)bd; - c->ltree = tl; - c->dtree = td; - Tracev(("inflate: codes new\n")); - } - return c; -} - - -int inflate_codes(inflate_blocks_statef *s, z_streamp z, int r) -{ - uInt j; /* temporary storage */ - inflate_huft *t; /* temporary pointer */ - uInt e; /* extra bits or operation */ - uLong b; /* bit buffer */ - uInt k; /* bits in bit buffer */ - Byte *p; /* input data pointer */ - uInt n; /* bytes available there */ - Byte *q; /* output window write pointer */ - uInt m; /* bytes to end of window or read pointer */ - Byte *f; /* pointer to copy strings from */ - inflate_codes_statef *c = s->sub.decode.codes; /* codes state */ - - /* copy input/output information to locals (UPDATE macro restores) */ - LOAD - - /* process input and output based on current state */ - while (1) switch (c->mode) - { /* waiting for "i:"=input, "o:"=output, "x:"=nothing */ - case START: /* x: set up for LEN */ -#ifndef SLOW - if (m >= 258 && n >= 10) - { - UPDATE - r = inflate_fast(c->lbits, c->dbits, c->ltree, c->dtree, s, z); - LOAD - if (r != Z_OK) - { - c->mode = r == Z_STREAM_END ? WASH : BADCODE; - break; - } - } -#endif /* !SLOW */ - c->sub.code.need = c->lbits; - c->sub.code.tree = c->ltree; - c->mode = LEN; - case LEN: /* i: get length/literal/eob next */ - j = c->sub.code.need; - NEEDBITS(j) - t = c->sub.code.tree + ((uInt)b & inflate_mask[j]); - DUMPBITS(t->bits) - e = (uInt)(t->exop); - if (e == 0) /* literal */ - { - c->sub.lit = t->base; - Tracevv((t->base >= 0x20 && t->base < 0x7f ? - "inflate: literal '%c'\n" : - "inflate: literal 0x%02x\n", t->base)); - c->mode = LIT; - break; - } - if (e & 16) /* length */ - { - c->sub.copy.get = e & 15; - c->len = t->base; - c->mode = LENEXT; - break; - } - if ((e & 64) == 0) /* next table */ - { - c->sub.code.need = e; - c->sub.code.tree = t + t->base; - break; - } - if (e & 32) /* end of block */ - { - Tracevv(("inflate: end of block\n")); - c->mode = WASH; - break; - } - c->mode = BADCODE; /* invalid code */ - z->msg = (char*)"invalid literal/length code"; - r = Z_DATA_ERROR; - LEAVE - case LENEXT: /* i: getting length extra (have base) */ - j = c->sub.copy.get; - NEEDBITS(j) - c->len += (uInt)b & inflate_mask[j]; - DUMPBITS(j) - c->sub.code.need = c->dbits; - c->sub.code.tree = c->dtree; - Tracevv(("inflate: length %u\n", c->len)); - c->mode = DIST; - case DIST: /* i: get distance next */ - j = c->sub.code.need; - NEEDBITS(j) - t = c->sub.code.tree + ((uInt)b & inflate_mask[j]); - DUMPBITS(t->bits) - e = (uInt)(t->exop); - if (e & 16) /* distance */ - { - c->sub.copy.get = e & 15; - c->sub.copy.dist = t->base; - c->mode = DISTEXT; - break; - } - if ((e & 64) == 0) /* next table */ - { - c->sub.code.need = e; - c->sub.code.tree = t + t->base; - break; - } - c->mode = BADCODE; /* invalid code */ - z->msg = (char*)"invalid distance code"; - r = Z_DATA_ERROR; - LEAVE - case DISTEXT: /* i: getting distance extra */ - j = c->sub.copy.get; - NEEDBITS(j) - c->sub.copy.dist += (uInt)b & inflate_mask[j]; - DUMPBITS(j) - Tracevv(("inflate: distance %u\n", c->sub.copy.dist)); - c->mode = COPY; - case COPY: /* o: copying bytes in window, waiting for space */ -#ifndef __TURBOC__ /* Turbo C bug for following expression */ - f = (uInt)(q - s->window) < c->sub.copy.dist ? - s->end - (c->sub.copy.dist - (q - s->window)) : - q - c->sub.copy.dist; -#else - f = q - c->sub.copy.dist; - if ((uInt)(q - s->window) < c->sub.copy.dist) - f = s->end - (c->sub.copy.dist - (uInt)(q - s->window)); -#endif - while (c->len) - { - NEEDOUT - OUTBYTE(*f++) - if (f == s->end) - f = s->window; - c->len--; - } - c->mode = START; - break; - case LIT: /* o: got literal, waiting for output space */ - NEEDOUT - OUTBYTE(c->sub.lit) - c->mode = START; - break; - case WASH: /* o: got eob, possibly more output */ - if (k > 7) /* return unused byte, if any */ - { - Assert(k < 16, "inflate_codes grabbed too many bytes") - k -= 8; - n++; - p--; /* can always return one */ - } - FLUSH - if (s->read != s->write) - LEAVE - c->mode = END; - case END: - r = Z_STREAM_END; - LEAVE - case BADCODE: /* x: got error */ - r = Z_DATA_ERROR; - LEAVE - default: - r = Z_STREAM_ERROR; - LEAVE - } -#ifdef NEED_DUMMY_RETURN - return Z_STREAM_ERROR; /* Some dumb compilers complain without this */ -#endif -} - - -void inflate_codes_free(inflate_codes_statef *c, z_streamp z) -{ - ZFREE(z, c); - Tracev(("inflate: codes free\n")); -} - -/* adler32.c -- compute the Adler-32 checksum of a data stream - * Copyright (C) 1995-1998 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -#define BASE 65521L /* largest prime smaller than 65536 */ -#define NMAX 5552 -/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */ - -#undef DO1 -#undef DO2 -#undef DO4 -#undef DO8 - -#define DO1(buf,i) {s1 += buf[i]; s2 += s1;} -#define DO2(buf,i) DO1(buf,i); DO1(buf,i+1); -#define DO4(buf,i) DO2(buf,i); DO2(buf,i+2); -#define DO8(buf,i) DO4(buf,i); DO4(buf,i+4); -#define DO16(buf) DO8(buf,0); DO8(buf,8); - -/* ========================================================================= */ -static uLong adler32(uLong adler, const Byte *buf, uInt len) -{ - unsigned long s1 = adler & 0xffff; - unsigned long s2 = (adler >> 16) & 0xffff; - int k; - - if (buf == Z_NULL) return 1L; - - while (len > 0) { - k = len < NMAX ? len : NMAX; - len -= k; - while (k >= 16) { - DO16(buf); - buf += 16; - k -= 16; - } - if (k != 0) do { - s1 += *buf++; - s2 += s1; - } while (--k); - s1 %= BASE; - s2 %= BASE; - } - return (s2 << 16) | s1; -} - - -/* infblock.h -- header to use infblock.c - * Copyright (C) 1995-1998 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* WARNING: this file should *not* be used by applications. It is - part of the implementation of the compression library and is - subject to change. Applications should only use zlib.h. - */ - -static inflate_blocks_statef * inflate_blocks_new OF(( - z_streamp z, - check_func c, /* check function */ - uInt w)); /* window size */ - -static int inflate_blocks OF(( - inflate_blocks_statef *, - z_streamp , - int)); /* initial return code */ - -static void inflate_blocks_reset OF(( - inflate_blocks_statef *, - z_streamp , - uLong *)); /* check value on output */ - -static int inflate_blocks_free OF(( - inflate_blocks_statef *, - z_streamp)); - -#if 0 -static void inflate_set_dictionary OF(( - inflate_blocks_statef *s, - const Byte *d, /* dictionary */ - uInt n)); /* dictionary length */ - -static int inflate_blocks_sync_point OF(( - inflate_blocks_statef *s)); -#endif - -typedef enum { - imMETHOD, /* waiting for method byte */ - imFLAG, /* waiting for flag byte */ - imDICT4, /* four dictionary check bytes to go */ - imDICT3, /* three dictionary check bytes to go */ - imDICT2, /* two dictionary check bytes to go */ - imDICT1, /* one dictionary check byte to go */ - imDICT0, /* waiting for inflateSetDictionary */ - imBLOCKS, /* decompressing blocks */ - imCHECK4, /* four check bytes to go */ - imCHECK3, /* three check bytes to go */ - imCHECK2, /* two check bytes to go */ - imCHECK1, /* one check byte to go */ - imDONE, /* finished check, done */ - imBAD} /* got an error--stay here */ -inflate_mode; - -/* inflate private state */ -struct internal_state { - - /* mode */ - inflate_mode mode; /* current inflate mode */ - - /* mode dependent information */ - union { - uInt method; /* if FLAGS, method byte */ - struct { - uLong was; /* computed check value */ - uLong need; /* stream check value */ - } check; /* if CHECK, check values to compare */ - uInt marker; /* if BAD, inflateSync's marker bytes count */ - } sub; /* submode */ - - /* mode independent information */ - int nowrap; /* flag for no wrapper */ - uInt wbits; /* log2(window size) (8..15, defaults to 15) */ - inflate_blocks_statef - *blocks; /* current inflate_blocks state */ - -}; - - -int inflateReset(z_streamp z) -{ - if (z == Z_NULL || z->state == Z_NULL) - return Z_STREAM_ERROR; - z->total_in = z->total_out = 0; - z->msg = Z_NULL; - z->state->mode = z->state->nowrap ? imBLOCKS : imMETHOD; - inflate_blocks_reset(z->state->blocks, z, Z_NULL); - Tracev(("inflate: reset\n")); - return Z_OK; -} - - -int inflateEnd(z_streamp z) -{ - if (z == Z_NULL || z->state == Z_NULL || z->zfree == Z_NULL) - return Z_STREAM_ERROR; - if (z->state->blocks != Z_NULL) - inflate_blocks_free(z->state->blocks, z); - ZFREE(z, z->state); - z->state = Z_NULL; - Tracev(("inflate: end\n")); - return Z_OK; -} - - - -int inflateInit2_(z_streamp z, int w, const char *version, int stream_size) -{ - if (version == Z_NULL || version[0] != ZLIB_VERSION[0] || - stream_size != sizeof(z_stream)) - return Z_VERSION_ERROR; - - /* initialize state */ - if (z == Z_NULL) - return Z_STREAM_ERROR; - z->msg = Z_NULL; - if (z->zalloc == Z_NULL) - { - z->zalloc = (void *(*)(void *, unsigned, unsigned))zcalloc; - z->opaque = (voidp)0; - } - if (z->zfree == Z_NULL) z->zfree = (void (*)(void *, void *))zcfree; - if ((z->state = (struct internal_state *) - ZALLOC(z,1,sizeof(struct internal_state))) == Z_NULL) - return Z_MEM_ERROR; - z->state->blocks = Z_NULL; - - /* handle undocumented nowrap option (no zlib header or check) */ - z->state->nowrap = 0; - if (w < 0) - { - w = - w; - z->state->nowrap = 1; - } - - /* set window size */ - if (w < 8 || w > 15) - { - inflateEnd(z); - return Z_STREAM_ERROR; - } - z->state->wbits = (uInt)w; - - /* create inflate_blocks state */ - if ((z->state->blocks = - inflate_blocks_new(z, z->state->nowrap ? Z_NULL : adler32, (uInt)1 << w)) - == Z_NULL) - { - inflateEnd(z); - return Z_MEM_ERROR; - } - Tracev(("inflate: allocated\n")); - - /* reset state */ - inflateReset(z); - return Z_OK; -} - -#if 0 -int inflateInit_(z_streamp z, const char *version, int stream_size) -{ - return inflateInit2_(z, DEF_WBITS, version, stream_size); -} -#endif - -#define iNEEDBYTE {if(z->avail_in==0)return r;r=f;} -#define iNEXTBYTE (z->avail_in--,z->total_in++,*z->next_in++) - -int inflate(z_streamp z, int f) -{ - int r; - uInt b; - - if (z == Z_NULL || z->state == Z_NULL || z->next_in == Z_NULL) - return Z_STREAM_ERROR; - f = f == Z_FINISH ? Z_BUF_ERROR : Z_OK; - r = Z_BUF_ERROR; - while (1) switch (z->state->mode) - { - case imMETHOD: - iNEEDBYTE - if (((z->state->sub.method = iNEXTBYTE) & 0xf) != Z_DEFLATED) - { - z->state->mode = imBAD; - z->msg = (char*)"unknown compression method"; - z->state->sub.marker = 5; /* can't try inflateSync */ - break; - } - if ((z->state->sub.method >> 4) + 8 > z->state->wbits) - { - z->state->mode = imBAD; - z->msg = (char*)"invalid window size"; - z->state->sub.marker = 5; /* can't try inflateSync */ - break; - } - z->state->mode = imFLAG; - case imFLAG: - iNEEDBYTE - b = iNEXTBYTE; - if (((z->state->sub.method << 8) + b) % 31) - { - z->state->mode = imBAD; - z->msg = (char*)"incorrect header check"; - z->state->sub.marker = 5; /* can't try inflateSync */ - break; - } - Tracev(("inflate: zlib header ok\n")); - if (!(b & PRESET_DICT)) - { - z->state->mode = imBLOCKS; - break; - } - z->state->mode = imDICT4; - case imDICT4: - iNEEDBYTE - z->state->sub.check.need = (uLong)iNEXTBYTE << 24; - z->state->mode = imDICT3; - case imDICT3: - iNEEDBYTE - z->state->sub.check.need += (uLong)iNEXTBYTE << 16; - z->state->mode = imDICT2; - case imDICT2: - iNEEDBYTE - z->state->sub.check.need += (uLong)iNEXTBYTE << 8; - z->state->mode = imDICT1; - case imDICT1: - iNEEDBYTE - z->state->sub.check.need += (uLong)iNEXTBYTE; - z->adler = z->state->sub.check.need; - z->state->mode = imDICT0; - return Z_NEED_DICT; - case imDICT0: - z->state->mode = imBAD; - z->msg = (char*)"need dictionary"; - z->state->sub.marker = 0; /* can try inflateSync */ - return Z_STREAM_ERROR; - case imBLOCKS: - r = inflate_blocks(z->state->blocks, z, r); - if (r == Z_DATA_ERROR) - { - z->state->mode = imBAD; - z->state->sub.marker = 0; /* can try inflateSync */ - break; - } - if (r == Z_OK) - r = f; - if (r != Z_STREAM_END) - return r; - r = f; - inflate_blocks_reset(z->state->blocks, z, &z->state->sub.check.was); - if (z->state->nowrap) - { - z->state->mode = imDONE; - break; - } - z->state->mode = imCHECK4; - case imCHECK4: - iNEEDBYTE - z->state->sub.check.need = (uLong)iNEXTBYTE << 24; - z->state->mode = imCHECK3; - case imCHECK3: - iNEEDBYTE - z->state->sub.check.need += (uLong)iNEXTBYTE << 16; - z->state->mode = imCHECK2; - case imCHECK2: - iNEEDBYTE - z->state->sub.check.need += (uLong)iNEXTBYTE << 8; - z->state->mode = imCHECK1; - case imCHECK1: - iNEEDBYTE - z->state->sub.check.need += (uLong)iNEXTBYTE; - - if (z->state->sub.check.was != z->state->sub.check.need) - { - z->state->mode = imBAD; - z->msg = (char*)"incorrect data check"; - z->state->sub.marker = 5; /* can't try inflateSync */ - break; - } - Tracev(("inflate: zlib check ok\n")); - z->state->mode = imDONE; - case imDONE: - return Z_STREAM_END; - case imBAD: - return Z_DATA_ERROR; - default: - return Z_STREAM_ERROR; - } -#ifdef NEED_DUMMY_RETURN - return Z_STREAM_ERROR; /* Some dumb compilers complain without this */ -#endif -} - -// defined but not used -#if 0 -int inflateSetDictionary(z_streamp z, const Byte *dictionary, uInt dictLength) -{ - uInt length = dictLength; - - if (z == Z_NULL || z->state == Z_NULL || z->state->mode != imDICT0) - return Z_STREAM_ERROR; - - if (adler32(1L, dictionary, dictLength) != z->adler) return Z_DATA_ERROR; - z->adler = 1L; - - if (length >= ((uInt)1<state->wbits)) - { - length = (1<state->wbits)-1; - dictionary += dictLength - length; - } - inflate_set_dictionary(z->state->blocks, dictionary, length); - z->state->mode = imBLOCKS; - return Z_OK; -} - -int inflateSync(z_streamp z) -{ - uInt n; /* number of bytes to look at */ - Byte *p; /* pointer to bytes */ - uInt m; /* number of marker bytes found in a row */ - uLong r, w; /* temporaries to save total_in and total_out */ - - /* set up */ - if (z == Z_NULL || z->state == Z_NULL) - return Z_STREAM_ERROR; - if (z->state->mode != imBAD) - { - z->state->mode = imBAD; - z->state->sub.marker = 0; - } - if ((n = z->avail_in) == 0) - return Z_BUF_ERROR; - p = z->next_in; - m = z->state->sub.marker; - - /* search */ - while (n && m < 4) - { - static const Byte mark[4] = {0, 0, 0xff, 0xff}; - if (*p == mark[m]) - m++; - else if (*p) - m = 0; - else - m = 4 - m; - p++, n--; - } - - /* restore */ - z->total_in += p - z->next_in; - z->next_in = p; - z->avail_in = n; - z->state->sub.marker = m; - - /* return no joy or set up to restart on a new block */ - if (m != 4) - return Z_DATA_ERROR; - r = z->total_in; w = z->total_out; - inflateReset(z); - z->total_in = r; z->total_out = w; - z->state->mode = imBLOCKS; - return Z_OK; -} - -/* Returns true if inflate is currently at the end of a block generated - * by Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP - * implementation to provide an additional safety check. PPP uses Z_SYNC_FLUSH - * but removes the length bytes of the resulting empty stored block. When - * decompressing, PPP checks that at the end of input packet, inflate is - * waiting for these length bytes. - */ -int inflateSyncPoint(z_streamp z) -{ - if (z == Z_NULL || z->state == Z_NULL || z->state->blocks == Z_NULL) - return Z_STREAM_ERROR; - return inflate_blocks_sync_point(z->state->blocks); -} -#endif - -voidp zcalloc (voidp opaque, unsigned items, unsigned size) -{ - if (opaque) items += size - size; /* make compiler happy */ - - // jkrige - pk3 file support - //return (voidp)Z_Malloc(items*size); - return (voidp)malloc(items*size); - // jkrige - pk3 file support -} - -void zcfree (voidp opaque, voidp ptr) -{ - // jkrige - pk3 file support - //Z_Free(ptr); - free(ptr); - // jkrige - pk3 file support - - if (opaque) return; /* make compiler happy */ -} - - diff --git a/engine/code/unzip.h b/engine/code/unzip.h deleted file mode 100644 index 2c31298..0000000 --- a/engine/code/unzip.h +++ /dev/null @@ -1,336 +0,0 @@ -/* -=========================================================================== -Copyright (C) 1999-2005 Id Software, Inc. - -This file is part of Quake III Arena source code. - -Quake III Arena source code is free software; you can redistribute it -and/or modify it under the terms of the GNU General Public License as -published by the Free Software Foundation; either version 2 of the License, -or (at your option) any later version. - -Quake III Arena source code is distributed in the hope that it will be -useful, but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with Foobar; if not, write to the Free Software -Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -=========================================================================== -*/ - -#if defined(STRICTUNZIP) || defined(STRICTZIPUNZIP) -/* like the STRICT of WIN32, we define a pointer that cannot be converted - from (void*) without cast */ -typedef struct TagunzFile__ { int unused; } unzFile__; -typedef unzFile__ *unzFile; -#else -typedef void* unzFile; -#endif - -/* tm_unz contain date/time info */ -typedef struct tm_unz_s -{ - unsigned int tm_sec; /* seconds after the minute - [0,59] */ - unsigned int tm_min; /* minutes after the hour - [0,59] */ - unsigned int tm_hour; /* hours since midnight - [0,23] */ - unsigned int tm_mday; /* day of the month - [1,31] */ - unsigned int tm_mon; /* months since January - [0,11] */ - unsigned int tm_year; /* years - [1980..2044] */ -} tm_unz; - -/* unz_global_info structure contain global data about the ZIPfile - These data comes from the end of central dir */ -typedef struct unz_global_info_s -{ - unsigned long number_entry; /* total number of entries in the central dir on this disk */ - unsigned long size_comment; /* size of the global comment of the zipfile */ -} unz_global_info; - - -/* unz_file_info contain information about a file in the zipfile */ -typedef struct unz_file_info_s -{ - unsigned long version; /* version made by 2 unsigned chars */ - unsigned long version_needed; /* version needed to extract 2 unsigned chars */ - unsigned long flag; /* general purpose bit flag 2 unsigned chars */ - unsigned long compression_method; /* compression method 2 unsigned chars */ - unsigned long dosDate; /* last mod file date in Dos fmt 4 unsigned chars */ - unsigned long crc; /* crc-32 4 unsigned chars */ - unsigned long compressed_size; /* compressed size 4 unsigned chars */ - unsigned long uncompressed_size; /* uncompressed size 4 unsigned chars */ - unsigned long size_filename; /* filename length 2 unsigned chars */ - unsigned long size_file_extra; /* extra field length 2 unsigned chars */ - unsigned long size_file_comment; /* file comment length 2 unsigned chars */ - - unsigned long disk_num_start; /* disk number start 2 unsigned chars */ - unsigned long internal_fa; /* internal file attributes 2 unsigned chars */ - unsigned long external_fa; /* external file attributes 4 unsigned chars */ - - tm_unz tmu_date; -} unz_file_info; - -/* unz_file_info_interntal contain internal info about a file in zipfile*/ -typedef struct unz_file_info_internal_s -{ - unsigned long offset_curfile;/* relative offset of static header 4 unsigned chars */ -} unz_file_info_internal; - -typedef void* (*alloc_func) (void* opaque, unsigned int items, unsigned int size); -typedef void (*free_func) (void* opaque, void* address); - -struct internal_state; - -typedef struct z_stream_s { - unsigned char *next_in; /* next input unsigned char */ - unsigned int avail_in; /* number of unsigned chars available at next_in */ - unsigned long total_in; /* total nb of input unsigned chars read so */ - - unsigned char *next_out; /* next output unsigned char should be put there */ - unsigned int avail_out; /* remaining free space at next_out */ - unsigned long total_out; /* total nb of unsigned chars output so */ - - char *msg; /* last error message, NULL if no error */ - struct internal_state *state; /* not visible by applications */ - - alloc_func zalloc; /* used to allocate the internal state */ - free_func zfree; /* used to free the internal state */ - unsigned char* opaque; /* private data object passed to zalloc and zfree */ - - int data_type; /* best guess about the data type: ascii or binary */ - unsigned long adler; /* adler32 value of the uncompressed data */ - unsigned long reserved; /* reserved for future use */ -} z_stream; - -typedef z_stream *z_streamp; - - -/* file_in_zip_read_info_s contain internal information about a file in zipfile, - when reading and decompress it */ -typedef struct -{ - char *read_buffer; /* internal buffer for compressed data */ - z_stream stream; /* zLib stream structure for inflate */ - - unsigned long pos_in_zipfile; /* position in unsigned char on the zipfile, for fseek*/ - unsigned long stream_initialised; /* flag set if stream structure is initialised*/ - - unsigned long offset_local_extrafield;/* offset of the static extra field */ - unsigned int size_local_extrafield;/* size of the static extra field */ - unsigned long pos_local_extrafield; /* position in the static extra field in read*/ - - unsigned long crc32; /* crc32 of all data uncompressed */ - unsigned long crc32_wait; /* crc32 we must obtain after decompress all */ - unsigned long rest_read_compressed; /* number of unsigned char to be decompressed */ - unsigned long rest_read_uncompressed;/*number of unsigned char to be obtained after decomp*/ - FILE* file; /* io structore of the zipfile */ - unsigned long compression_method; /* compression method (0==store) */ - unsigned long byte_before_the_zipfile;/* unsigned char before the zipfile, (>0 for sfx)*/ -} file_in_zip_read_info_s; - - -/* unz_s contain internal information about the zipfile -*/ -typedef struct -{ - FILE* file; /* io structore of the zipfile */ - unz_global_info gi; /* public global information */ - unsigned long byte_before_the_zipfile;/* unsigned char before the zipfile, (>0 for sfx)*/ - unsigned long num_file; /* number of the current file in the zipfile*/ - unsigned long pos_in_central_dir; /* pos of the current file in the central dir*/ - unsigned long current_file_ok; /* flag about the usability of the current file*/ - unsigned long central_pos; /* position of the beginning of the central dir*/ - - unsigned long size_central_dir; /* size of the central directory */ - unsigned long offset_central_dir; /* offset of start of central directory with - respect to the starting disk number */ - - unz_file_info cur_file_info; /* public info about the current file in zip*/ - unz_file_info_internal cur_file_info_internal; /* private info about it*/ - file_in_zip_read_info_s* pfile_in_zip_read; /* structure about the current - file if we are decompressing it */ - unsigned char* tmpFile; - int tmpPos,tmpSize; -} unz_s; - -#define UNZ_OK (0) -#define UNZ_END_OF_LIST_OF_FILE (-100) -#define UNZ_ERRNO (Z_ERRNO) -#define UNZ_EOF (0) -#define UNZ_PARAMERROR (-102) -#define UNZ_BADZIPFILE (-103) -#define UNZ_INTERNALERROR (-104) -#define UNZ_CRCERROR (-105) - -#define UNZ_CASESENSITIVE 1 -#define UNZ_NOTCASESENSITIVE 2 -#define UNZ_OSDEFAULTCASE 0 - -extern int unzStringFileNameCompare (const char* fileName1, const char* fileName2, int iCaseSensitivity); - -/* - Compare two filename (fileName1,fileName2). - If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp) - If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi - or strcasecmp) - If iCaseSenisivity = 0, case sensitivity is defaut of your operating system - (like 1 on Unix, 2 on Windows) -*/ - -extern unzFile unzOpen (const char *path); -extern unzFile unzReOpen (const char* path, unzFile file); - -/* - Open a Zip file. path contain the full pathname (by example, - on a Windows NT computer "c:\\zlib\\zlib111.zip" or on an Unix computer - "zlib/zlib111.zip". - If the zipfile cannot be opened (file don't exist or in not valid), the - return value is NULL. - Else, the return value is a unzFile Handle, usable with other function - of this unzip package. -*/ - -extern int unzClose (unzFile file); - -/* - Close a ZipFile opened with unzipOpen. - If there is files inside the .Zip opened with unzOpenCurrentFile (see later), - these files MUST be closed with unzipCloseCurrentFile before call unzipClose. - return UNZ_OK if there is no problem. */ - -extern int unzGetGlobalInfo (unzFile file, unz_global_info *pglobal_info); - -/* - Write info about the ZipFile in the *pglobal_info structure. - No preparation of the structure is needed - return UNZ_OK if there is no problem. */ - - -extern int unzGetGlobalComment (unzFile file, char *szComment, unsigned long uSizeBuf); - -/* - Get the global comment string of the ZipFile, in the szComment buffer. - uSizeBuf is the size of the szComment buffer. - return the number of unsigned char copied or an error code <0 -*/ - - -/***************************************************************************/ -/* Unzip package allow you browse the directory of the zipfile */ - -extern int unzGoToFirstFile (unzFile file); - -/* - Set the current file of the zipfile to the first file. - return UNZ_OK if there is no problem -*/ - -extern int unzGoToNextFile (unzFile file); - -/* - Set the current file of the zipfile to the next file. - return UNZ_OK if there is no problem - return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest. -*/ - -extern int unzGetCurrentFileInfoPosition (unzFile file, unsigned long *pos ); - -/* - Get the position of the info of the current file in the zip. - return UNZ_OK if there is no problem -*/ - -extern int unzSetCurrentFileInfoPosition (unzFile file, unsigned long pos ); - -/* - Set the position of the info of the current file in the zip. - return UNZ_OK if there is no problem -*/ - -extern int unzLocateFile (unzFile file, const char *szFileName, int iCaseSensitivity); - -/* - Try locate the file szFileName in the zipfile. - For the iCaseSensitivity signification, see unzStringFileNameCompare - - return value : - UNZ_OK if the file is found. It becomes the current file. - UNZ_END_OF_LIST_OF_FILE if the file is not found -*/ - - -extern int unzGetCurrentFileInfo (unzFile file, unz_file_info *pfile_info, char *szFileName, unsigned long fileNameBufferSize, void *extraField, unsigned long extraFieldBufferSize, char *szComment, unsigned long commentBufferSize); - -/* - Get Info about the current file - if pfile_info!=NULL, the *pfile_info structure will contain somes info about - the current file - if szFileName!=NULL, the filemane string will be copied in szFileName - (fileNameBufferSize is the size of the buffer) - if extraField!=NULL, the extra field information will be copied in extraField - (extraFieldBufferSize is the size of the buffer). - This is the Central-header version of the extra field - if szComment!=NULL, the comment string of the file will be copied in szComment - (commentBufferSize is the size of the buffer) -*/ - -/***************************************************************************/ -/* for reading the content of the current zipfile, you can open it, read data - from it, and close it (you can close it before reading all the file) - */ - -extern int unzOpenCurrentFile (unzFile file); - -/* - Open for reading data the current file in the zipfile. - If there is no error, the return value is UNZ_OK. -*/ - -extern int unzCloseCurrentFile (unzFile file); - -/* - Close the file in zip opened with unzOpenCurrentFile - Return UNZ_CRCERROR if all the file was read but the CRC is not good -*/ - - -extern int unzReadCurrentFile (unzFile file, void* buf, unsigned len); - -/* - Read unsigned chars from the current file (opened by unzOpenCurrentFile) - buf contain buffer where data must be copied - len the size of buf. - - return the number of unsigned char copied if somes unsigned chars are copied - return 0 if the end of file was reached - return <0 with error code if there is an error - (UNZ_ERRNO for IO error, or zLib error for uncompress error) -*/ - -extern long unztell(unzFile file); - -/* - Give the current position in uncompressed data -*/ - -extern int unzeof (unzFile file); - -/* - return 1 if the end of file was reached, 0 elsewhere -*/ - -extern int unzGetLocalExtrafield (unzFile file, void* buf, unsigned len); - -/* - Read extra field from the current file (opened by unzOpenCurrentFile) - This is the local-header version of the extra field (sometimes, there is - more info in the local-header version than in the central-header) - - if buf==NULL, it return the size of the local extra field - - if buf!=NULL, len is the size of the buffer, the extra header is copied in - buf. - the return value is the number of unsigned chars copied in buf, or (if <0) - the error code -*/ diff --git a/engine/code/vid.h b/engine/code/vid.h deleted file mode 100644 index 1708ba8..0000000 --- a/engine/code/vid.h +++ /dev/null @@ -1,85 +0,0 @@ -/* -Copyright (C) 1996-1997 Id Software, Inc. - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ -// vid.h -- video driver defs - -#define VID_CBITS 6 -#define VID_GRADES (1 << VID_CBITS) - -// a pixel can be one, two, or four bytes -typedef byte pixel_t; - -typedef struct vrect_s -{ - int x,y,width,height; - struct vrect_s *pnext; -} vrect_t; - -typedef struct -{ - pixel_t *buffer; // invisible buffer - pixel_t *colormap; // 256 * VID_GRADES size - unsigned short *colormap16; // 256 * VID_GRADES size - int fullbright; // index of first fullbright color - unsigned rowbytes; // may be > width if displayed in a window - unsigned width; - unsigned height; - float aspect; // width / height -- < 0 is taller than wide - int numpages; - int recalc_refdef; // if true, recalc vid-based stuff - pixel_t *conbuffer; - int conrowbytes; - unsigned conwidth; - unsigned conheight; - int maxwarpwidth; - int maxwarpheight; - pixel_t *direct; // direct drawing to framebuffer, if not - // NULL -} viddef_t; - -extern viddef_t vid; // global video state -extern unsigned short d_8to16table[256]; -extern unsigned d_8to24table[256]; -extern void (*vid_menudrawfn)(void); -extern void (*vid_menukeyfn)(int key); - -void VID_SetPalette (unsigned char *palette); -// called at startup and after any gamma correction - -void VID_ShiftPalette (unsigned char *palette); -// called for bonus and pain flashes, and for underwater color changes - -void VID_Init (unsigned char *palette); -// Called at startup to set up translation tables, takes 256 8 bit RGB values -// the palette data will go away after the call, so it must be copied off if -// the video driver will need it again - -void VID_Shutdown (void); -// Called at shutdown - -void VID_Update (vrect_t *rects); -// flushes the given rectangles from the view buffer to the screen - -int VID_SetMode (int modenum, unsigned char *palette); -// sets the mode; only used by the Quake engine for resetting to mode 0 (the -// base mode) on memory allocation failures - -void VID_HandlePause (qboolean pause); -// called only on Win32, when pause happens, so the mouse can be released - diff --git a/engine/code/vid_gamma.c b/engine/code/vid_gamma.c deleted file mode 100644 index d8c603a..0000000 --- a/engine/code/vid_gamma.c +++ /dev/null @@ -1,308 +0,0 @@ -/* -=========================================================================== -Copyright (C) 1999-2005 Id Software, Inc. - -This file is part of Quake III Arena source code. - -Quake III Arena source code is free software; you can redistribute it -and/or modify it under the terms of the GNU General Public License as -published by the Free Software Foundation; either version 2 of the License, -or (at your option) any later version. - -Quake III Arena source code is distributed in the hope that it will be -useful, but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with Foobar; if not, write to the Free Software -Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -=========================================================================== -*/ -/* -** VID_GAMMA.C -*/ - -#include "quakedef.h" - -#ifdef _WIN32 -#include "winquake.h" -#endif - -static unsigned char gl_gammatable[256]; - -static int overbrightBits; -static unsigned short oldHardwareGamma[3][256]; -qboolean deviceSupportsGamma = false; -qboolean deviceSupportsGamma3DFX = false; - -/* -** VG_CheckHardwareGamma -** -** Determines if the underlying hardware supports the Win32 gamma correction API. -*/ -void VG_CheckHardwareGamma( void ) -{ - HDC hDC; - - deviceSupportsGamma = false; - deviceSupportsGamma3DFX = false; - - if ( qwglSetDeviceGammaRamp3DFX ) - { - deviceSupportsGamma3DFX = true; - - hDC = GetDC( GetDesktopWindow() ); - deviceSupportsGamma3DFX = qwglGetDeviceGammaRamp3DFX( hDC, oldHardwareGamma ); - ReleaseDC( GetDesktopWindow(), hDC ); - - return; - } - - if ( !deviceSupportsGamma3DFX ) - { - hDC = GetDC( GetDesktopWindow() ); - deviceSupportsGamma = GetDeviceGammaRamp( hDC, oldHardwareGamma ); - ReleaseDC( GetDesktopWindow(), hDC ); - - if ( deviceSupportsGamma ) - { - // do a sanity check on the gamma values - if ( ( HIBYTE( oldHardwareGamma[0][255] ) <= HIBYTE( oldHardwareGamma[0][0] ) ) || - ( HIBYTE( oldHardwareGamma[1][255] ) <= HIBYTE( oldHardwareGamma[1][0] ) ) || - ( HIBYTE( oldHardwareGamma[2][255] ) <= HIBYTE( oldHardwareGamma[2][0] ) ) ) - { - deviceSupportsGamma = false; - Con_Printf("Device has broken gamma support\n"); - } - - // make sure that we didn't have a prior crash in the game, and if so we need to - // restore the gamma values to at least a linear value - if ( ( HIBYTE( oldHardwareGamma[0][181] ) == 255 ) ) - { - int g; - - Con_Printf("Suspicious gamma tables, using linear ramp for restoration\n"); - - for ( g = 0; g < 255; g++ ) - { - oldHardwareGamma[0][g] = g << 8; - oldHardwareGamma[1][g] = g << 8; - oldHardwareGamma[2][g] = g << 8; - } - } - } - } -} - -/* -** VG_SetGamma -** -** This routine should only be called if deviceSupportsGamma is TRUE -*/ -void VG_SetGamma( unsigned char red[256], unsigned char green[256], unsigned char blue[256] ) -{ - unsigned short table[3][256]; - int i, j; - int ret; - //OSVERSIONINFO vinfo; // jkrige - remove windows version check - HDC hDC; - - hDC = GetDC( GetDesktopWindow() ); - - if ( (!deviceSupportsGamma && !deviceSupportsGamma3DFX) || !hDC ) - return; - - for ( i = 0; i < 256; i++ ) { - table[0][i] = ( ( ( unsigned short ) red[i] ) << 8 ) | red[i]; - table[1][i] = ( ( ( unsigned short ) green[i] ) << 8 ) | green[i]; - table[2][i] = ( ( ( unsigned short ) blue[i] ) << 8 ) | blue[i]; - } - - // jkrige - remove windows version check - begin - // Win2K puts this odd restriction on gamma ramps... - /*vinfo.dwOSVersionInfoSize = sizeof(vinfo); - GetVersionEx( &vinfo ); - if ( vinfo.dwMajorVersion == 5 && vinfo.dwPlatformId == VER_PLATFORM_WIN32_NT ) - { - Con_DPrintf("performing Windows 2000 gamma clamp.\n"); - for ( j = 0 ; j < 3 ; j++ ) { - for ( i = 0 ; i < 128 ; i++ ) { - if ( table[j][i] > ( (128+i) << 8 ) ) { - table[j][i] = (128+i) << 8; - } - } - if ( table[j][127] > 254<<8 ) { - table[j][127] = 254<<8; - } - } - } - else - { - Con_DPrintf("skipping Windows 2000 gamma clamp.\n"); - }*/ - // jkrige - remove windows version check - end - - // enforce constantly increasing - for ( j = 0 ; j < 3 ; j++ ) { - for ( i = 1 ; i < 256 ; i++ ) { - if ( table[j][i] < table[j][i-1] ) { - table[j][i] = table[j][i-1]; - } - } - } - - if ( qwglSetDeviceGammaRamp3DFX ) - { - qwglSetDeviceGammaRamp3DFX( hDC, table ); - } - else - { - ret = SetDeviceGammaRamp( hDC, table ); - if ( !ret ) - Con_Printf("SetDeviceGammaRamp failed.\n"); - } - ReleaseDC( GetDesktopWindow(), hDC ); -} - -/* -** VG_RestoreGamma -*/ -void VG_RestoreGamma( void ) -{ - HDC hDC; - - hDC = GetDC( GetDesktopWindow() ); - - if ( deviceSupportsGamma ) - { - if ( qwglSetDeviceGammaRamp3DFX ) - { - qwglSetDeviceGammaRamp3DFX( hDC, oldHardwareGamma ); - } - else - { - SetDeviceGammaRamp( hDC, oldHardwareGamma ); - } - } - - ReleaseDC( GetDesktopWindow(), hDC ); -} - -/* -=============== -VG_GammaCorrect -=============== -*/ -void VG_GammaCorrect( byte *buffer, int bufSize ) { - int i; - - for ( i = 0; i < bufSize; i++ ) { - buffer[i] = gl_gammatable[buffer[i]]; - } -} - -/* -=============== -VG_SetColorMappings -=============== -*/ -void VG_SetColorMappings( void ) -{ - int i, j; - float g; - int inf; - int shift; - - // setup the overbright lighting - overbrightBits = (int)gl_overbrightbits.value; - - if ( !deviceSupportsGamma ) - overbrightBits = 0; // need hardware gamma for overbright - - // never overbright in windowed mode - if ( modestate != MS_FULLSCREEN && modestate != MS_FULLDIB ) - overbrightBits = 0; - - // allow 2 overbright bits in 24 bit, but only 1 in 16 bit - - // jkrige - no 16bit mode - //if ( vid.bpp > 16 ) - //{ - if ( overbrightBits > 2 ) - overbrightBits = 2; - //} - //else - //{ - // if ( overbrightBits > 1 ) - // overbrightBits = 1; - //} - // jkrige - no 16bit mode - - - if ( overbrightBits < 0 ) - overbrightBits = 0; - - if ( gl_gamma.value < 0.5f ) - { - Cvar_SetValue ("gamma", 0.5f); - return; - } - else if ( gl_gamma.value > 2.75f ) - { - Cvar_SetValue ("gamma", 2.75f); - return; - } - - g = 3.0f - gl_gamma.value; - - // jkrige - quake 3 - //if ( r_intensity->value <= 1 ) { - // ri.Cvar_Set( "r_intensity", "1" ); - //} - // jkrige - quake 3 - - if ( gl_overbrightbits.value < 0.0f ) - { - Cvar_SetValue ("gl_overbrightbits", 0.0f); - return; - } - else if ( gl_overbrightbits.value > (float)overbrightBits ) - { - Cvar_SetValue ("gl_overbrightbits", (float)overbrightBits); - return; - } - - shift = (int)gl_overbrightbits.value; - - for ( i = 0; i < 256; i++ ) { - if ( g == 1 ) { - inf = i; - } else { - inf = 255 * pow ( i/255.0f, 1.0f / g ) + 0.5f; - } - inf <<= shift; - if (inf < 0) { - inf = 0; - } - if (inf > 255) { - inf = 255; - } - gl_gammatable[i] = inf; - } - - // jkrige - quake 3 - /*for (i=0 ; i<256 ; i++) { - j = i * r_intensity->value; - if (j > 255) { - j = 255; - } - s_intensitytable[i] = j; - }*/ - // jkrige - quake 3 - - if ( deviceSupportsGamma ) - { - VG_SetGamma( gl_gammatable, gl_gammatable, gl_gammatable ); - } -} \ No newline at end of file diff --git a/engine/code/vid_gamma.h b/engine/code/vid_gamma.h deleted file mode 100644 index c1e1951..0000000 --- a/engine/code/vid_gamma.h +++ /dev/null @@ -1,28 +0,0 @@ -/* -=========================================================================== -Copyright (C) 1999-2005 Id Software, Inc. - -This file is part of Quake III Arena source code. - -Quake III Arena source code is free software; you can redistribute it -and/or modify it under the terms of the GNU General Public License as -published by the Free Software Foundation; either version 2 of the License, -or (at your option) any later version. - -Quake III Arena source code is distributed in the hope that it will be -useful, but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with Foobar; if not, write to the Free Software -Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -=========================================================================== -*/ - -extern qboolean deviceSupportsGamma; - -void VG_SetColorMappings( void ); -void VG_CheckHardwareGamma( void ); -void VG_RestoreGamma( void ); -void VG_GammaCorrect( byte *buffer, int bufSize ); \ No newline at end of file diff --git a/engine/code/wglext.h b/engine/code/wglext.h deleted file mode 100644 index 9193948..0000000 --- a/engine/code/wglext.h +++ /dev/null @@ -1,840 +0,0 @@ -#ifndef __wglext_h_ -#define __wglext_h_ 1 - -#ifdef __cplusplus -extern "C" { -#endif - -/* -** Copyright (c) 2013-2016 The Khronos Group Inc. -** -** Permission is hereby granted, free of charge, to any person obtaining a -** copy of this software and/or associated documentation files (the -** "Materials"), to deal in the Materials without restriction, including -** without limitation the rights to use, copy, modify, merge, publish, -** distribute, sublicense, and/or sell copies of the Materials, and to -** permit persons to whom the Materials are furnished to do so, subject to -** the following conditions: -** -** The above copyright notice and this permission notice shall be included -** in all copies or substantial portions of the Materials. -** -** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. -*/ -/* -** This header is generated from the Khronos OpenGL / OpenGL ES XML -** API Registry. The current version of the Registry, generator scripts -** used to make the header, and the header can be found at -** http://www.opengl.org/registry/ -** -** Khronos $Revision: 32433 $ on $Date: 2016-02-10 02:02:08 -0500 (Wed, 10 Feb 2016) $ -*/ - -#if defined(_WIN32) && !defined(APIENTRY) && !defined(__CYGWIN__) && !defined(__SCITECH_SNAP__) -#define WIN32_LEAN_AND_MEAN 1 -#include -#endif - -#define WGL_WGLEXT_VERSION 20160209 - -/* Generated C header for: - * API: wgl - * Versions considered: .* - * Versions emitted: _nomatch_^ - * Default extensions included: wgl - * Additional extensions included: _nomatch_^ - * Extensions removed: _nomatch_^ - */ - -#ifndef WGL_ARB_buffer_region -#define WGL_ARB_buffer_region 1 -#define WGL_FRONT_COLOR_BUFFER_BIT_ARB 0x00000001 -#define WGL_BACK_COLOR_BUFFER_BIT_ARB 0x00000002 -#define WGL_DEPTH_BUFFER_BIT_ARB 0x00000004 -#define WGL_STENCIL_BUFFER_BIT_ARB 0x00000008 -typedef HANDLE (WINAPI * PFNWGLCREATEBUFFERREGIONARBPROC) (HDC hDC, int iLayerPlane, UINT uType); -typedef VOID (WINAPI * PFNWGLDELETEBUFFERREGIONARBPROC) (HANDLE hRegion); -typedef BOOL (WINAPI * PFNWGLSAVEBUFFERREGIONARBPROC) (HANDLE hRegion, int x, int y, int width, int height); -typedef BOOL (WINAPI * PFNWGLRESTOREBUFFERREGIONARBPROC) (HANDLE hRegion, int x, int y, int width, int height, int xSrc, int ySrc); -#ifdef WGL_WGLEXT_PROTOTYPES -HANDLE WINAPI wglCreateBufferRegionARB (HDC hDC, int iLayerPlane, UINT uType); -VOID WINAPI wglDeleteBufferRegionARB (HANDLE hRegion); -BOOL WINAPI wglSaveBufferRegionARB (HANDLE hRegion, int x, int y, int width, int height); -BOOL WINAPI wglRestoreBufferRegionARB (HANDLE hRegion, int x, int y, int width, int height, int xSrc, int ySrc); -#endif -#endif /* WGL_ARB_buffer_region */ - -#ifndef WGL_ARB_context_flush_control -#define WGL_ARB_context_flush_control 1 -#define WGL_CONTEXT_RELEASE_BEHAVIOR_ARB 0x2097 -#define WGL_CONTEXT_RELEASE_BEHAVIOR_NONE_ARB 0 -#define WGL_CONTEXT_RELEASE_BEHAVIOR_FLUSH_ARB 0x2098 -#endif /* WGL_ARB_context_flush_control */ - -#ifndef WGL_ARB_create_context -#define WGL_ARB_create_context 1 -#define WGL_CONTEXT_DEBUG_BIT_ARB 0x00000001 -#define WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x00000002 -#define WGL_CONTEXT_MAJOR_VERSION_ARB 0x2091 -#define WGL_CONTEXT_MINOR_VERSION_ARB 0x2092 -#define WGL_CONTEXT_LAYER_PLANE_ARB 0x2093 -#define WGL_CONTEXT_FLAGS_ARB 0x2094 -#define ERROR_INVALID_VERSION_ARB 0x2095 -typedef HGLRC (WINAPI * PFNWGLCREATECONTEXTATTRIBSARBPROC) (HDC hDC, HGLRC hShareContext, const int *attribList); -#ifdef WGL_WGLEXT_PROTOTYPES -HGLRC WINAPI wglCreateContextAttribsARB (HDC hDC, HGLRC hShareContext, const int *attribList); -#endif -#endif /* WGL_ARB_create_context */ - -#ifndef WGL_ARB_create_context_profile -#define WGL_ARB_create_context_profile 1 -#define WGL_CONTEXT_PROFILE_MASK_ARB 0x9126 -#define WGL_CONTEXT_CORE_PROFILE_BIT_ARB 0x00000001 -#define WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB 0x00000002 -#define ERROR_INVALID_PROFILE_ARB 0x2096 -#endif /* WGL_ARB_create_context_profile */ - -#ifndef WGL_ARB_create_context_robustness -#define WGL_ARB_create_context_robustness 1 -#define WGL_CONTEXT_ROBUST_ACCESS_BIT_ARB 0x00000004 -#define WGL_LOSE_CONTEXT_ON_RESET_ARB 0x8252 -#define WGL_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB 0x8256 -#define WGL_NO_RESET_NOTIFICATION_ARB 0x8261 -#endif /* WGL_ARB_create_context_robustness */ - -#ifndef WGL_ARB_extensions_string -#define WGL_ARB_extensions_string 1 -typedef const char *(WINAPI * PFNWGLGETEXTENSIONSSTRINGARBPROC) (HDC hdc); -#ifdef WGL_WGLEXT_PROTOTYPES -const char *WINAPI wglGetExtensionsStringARB (HDC hdc); -#endif -#endif /* WGL_ARB_extensions_string */ - -#ifndef WGL_ARB_framebuffer_sRGB -#define WGL_ARB_framebuffer_sRGB 1 -#define WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB 0x20A9 -#endif /* WGL_ARB_framebuffer_sRGB */ - -#ifndef WGL_ARB_make_current_read -#define WGL_ARB_make_current_read 1 -#define ERROR_INVALID_PIXEL_TYPE_ARB 0x2043 -#define ERROR_INCOMPATIBLE_DEVICE_CONTEXTS_ARB 0x2054 -typedef BOOL (WINAPI * PFNWGLMAKECONTEXTCURRENTARBPROC) (HDC hDrawDC, HDC hReadDC, HGLRC hglrc); -typedef HDC (WINAPI * PFNWGLGETCURRENTREADDCARBPROC) (void); -#ifdef WGL_WGLEXT_PROTOTYPES -BOOL WINAPI wglMakeContextCurrentARB (HDC hDrawDC, HDC hReadDC, HGLRC hglrc); -HDC WINAPI wglGetCurrentReadDCARB (void); -#endif -#endif /* WGL_ARB_make_current_read */ - -#ifndef WGL_ARB_multisample -#define WGL_ARB_multisample 1 -#define WGL_SAMPLE_BUFFERS_ARB 0x2041 -#define WGL_SAMPLES_ARB 0x2042 -#endif /* WGL_ARB_multisample */ - -#ifndef WGL_ARB_pbuffer -#define WGL_ARB_pbuffer 1 -DECLARE_HANDLE(HPBUFFERARB); -#define WGL_DRAW_TO_PBUFFER_ARB 0x202D -#define WGL_MAX_PBUFFER_PIXELS_ARB 0x202E -#define WGL_MAX_PBUFFER_WIDTH_ARB 0x202F -#define WGL_MAX_PBUFFER_HEIGHT_ARB 0x2030 -#define WGL_PBUFFER_LARGEST_ARB 0x2033 -#define WGL_PBUFFER_WIDTH_ARB 0x2034 -#define WGL_PBUFFER_HEIGHT_ARB 0x2035 -#define WGL_PBUFFER_LOST_ARB 0x2036 -typedef HPBUFFERARB (WINAPI * PFNWGLCREATEPBUFFERARBPROC) (HDC hDC, int iPixelFormat, int iWidth, int iHeight, const int *piAttribList); -typedef HDC (WINAPI * PFNWGLGETPBUFFERDCARBPROC) (HPBUFFERARB hPbuffer); -typedef int (WINAPI * PFNWGLRELEASEPBUFFERDCARBPROC) (HPBUFFERARB hPbuffer, HDC hDC); -typedef BOOL (WINAPI * PFNWGLDESTROYPBUFFERARBPROC) (HPBUFFERARB hPbuffer); -typedef BOOL (WINAPI * PFNWGLQUERYPBUFFERARBPROC) (HPBUFFERARB hPbuffer, int iAttribute, int *piValue); -#ifdef WGL_WGLEXT_PROTOTYPES -HPBUFFERARB WINAPI wglCreatePbufferARB (HDC hDC, int iPixelFormat, int iWidth, int iHeight, const int *piAttribList); -HDC WINAPI wglGetPbufferDCARB (HPBUFFERARB hPbuffer); -int WINAPI wglReleasePbufferDCARB (HPBUFFERARB hPbuffer, HDC hDC); -BOOL WINAPI wglDestroyPbufferARB (HPBUFFERARB hPbuffer); -BOOL WINAPI wglQueryPbufferARB (HPBUFFERARB hPbuffer, int iAttribute, int *piValue); -#endif -#endif /* WGL_ARB_pbuffer */ - -#ifndef WGL_ARB_pixel_format -#define WGL_ARB_pixel_format 1 -#define WGL_NUMBER_PIXEL_FORMATS_ARB 0x2000 -#define WGL_DRAW_TO_WINDOW_ARB 0x2001 -#define WGL_DRAW_TO_BITMAP_ARB 0x2002 -#define WGL_ACCELERATION_ARB 0x2003 -#define WGL_NEED_PALETTE_ARB 0x2004 -#define WGL_NEED_SYSTEM_PALETTE_ARB 0x2005 -#define WGL_SWAP_LAYER_BUFFERS_ARB 0x2006 -#define WGL_SWAP_METHOD_ARB 0x2007 -#define WGL_NUMBER_OVERLAYS_ARB 0x2008 -#define WGL_NUMBER_UNDERLAYS_ARB 0x2009 -#define WGL_TRANSPARENT_ARB 0x200A -#define WGL_TRANSPARENT_RED_VALUE_ARB 0x2037 -#define WGL_TRANSPARENT_GREEN_VALUE_ARB 0x2038 -#define WGL_TRANSPARENT_BLUE_VALUE_ARB 0x2039 -#define WGL_TRANSPARENT_ALPHA_VALUE_ARB 0x203A -#define WGL_TRANSPARENT_INDEX_VALUE_ARB 0x203B -#define WGL_SHARE_DEPTH_ARB 0x200C -#define WGL_SHARE_STENCIL_ARB 0x200D -#define WGL_SHARE_ACCUM_ARB 0x200E -#define WGL_SUPPORT_GDI_ARB 0x200F -#define WGL_SUPPORT_OPENGL_ARB 0x2010 -#define WGL_DOUBLE_BUFFER_ARB 0x2011 -#define WGL_STEREO_ARB 0x2012 -#define WGL_PIXEL_TYPE_ARB 0x2013 -#define WGL_COLOR_BITS_ARB 0x2014 -#define WGL_RED_BITS_ARB 0x2015 -#define WGL_RED_SHIFT_ARB 0x2016 -#define WGL_GREEN_BITS_ARB 0x2017 -#define WGL_GREEN_SHIFT_ARB 0x2018 -#define WGL_BLUE_BITS_ARB 0x2019 -#define WGL_BLUE_SHIFT_ARB 0x201A -#define WGL_ALPHA_BITS_ARB 0x201B -#define WGL_ALPHA_SHIFT_ARB 0x201C -#define WGL_ACCUM_BITS_ARB 0x201D -#define WGL_ACCUM_RED_BITS_ARB 0x201E -#define WGL_ACCUM_GREEN_BITS_ARB 0x201F -#define WGL_ACCUM_BLUE_BITS_ARB 0x2020 -#define WGL_ACCUM_ALPHA_BITS_ARB 0x2021 -#define WGL_DEPTH_BITS_ARB 0x2022 -#define WGL_STENCIL_BITS_ARB 0x2023 -#define WGL_AUX_BUFFERS_ARB 0x2024 -#define WGL_NO_ACCELERATION_ARB 0x2025 -#define WGL_GENERIC_ACCELERATION_ARB 0x2026 -#define WGL_FULL_ACCELERATION_ARB 0x2027 -#define WGL_SWAP_EXCHANGE_ARB 0x2028 -#define WGL_SWAP_COPY_ARB 0x2029 -#define WGL_SWAP_UNDEFINED_ARB 0x202A -#define WGL_TYPE_RGBA_ARB 0x202B -#define WGL_TYPE_COLORINDEX_ARB 0x202C -typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBIVARBPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int *piAttributes, int *piValues); -typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBFVARBPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int *piAttributes, FLOAT *pfValues); -typedef BOOL (WINAPI * PFNWGLCHOOSEPIXELFORMATARBPROC) (HDC hdc, const int *piAttribIList, const FLOAT *pfAttribFList, UINT nMaxFormats, int *piFormats, UINT *nNumFormats); -#ifdef WGL_WGLEXT_PROTOTYPES -BOOL WINAPI wglGetPixelFormatAttribivARB (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int *piAttributes, int *piValues); -BOOL WINAPI wglGetPixelFormatAttribfvARB (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int *piAttributes, FLOAT *pfValues); -BOOL WINAPI wglChoosePixelFormatARB (HDC hdc, const int *piAttribIList, const FLOAT *pfAttribFList, UINT nMaxFormats, int *piFormats, UINT *nNumFormats); -#endif -#endif /* WGL_ARB_pixel_format */ - -#ifndef WGL_ARB_pixel_format_float -#define WGL_ARB_pixel_format_float 1 -#define WGL_TYPE_RGBA_FLOAT_ARB 0x21A0 -#endif /* WGL_ARB_pixel_format_float */ - -#ifndef WGL_ARB_render_texture -#define WGL_ARB_render_texture 1 -#define WGL_BIND_TO_TEXTURE_RGB_ARB 0x2070 -#define WGL_BIND_TO_TEXTURE_RGBA_ARB 0x2071 -#define WGL_TEXTURE_FORMAT_ARB 0x2072 -#define WGL_TEXTURE_TARGET_ARB 0x2073 -#define WGL_MIPMAP_TEXTURE_ARB 0x2074 -#define WGL_TEXTURE_RGB_ARB 0x2075 -#define WGL_TEXTURE_RGBA_ARB 0x2076 -#define WGL_NO_TEXTURE_ARB 0x2077 -#define WGL_TEXTURE_CUBE_MAP_ARB 0x2078 -#define WGL_TEXTURE_1D_ARB 0x2079 -#define WGL_TEXTURE_2D_ARB 0x207A -#define WGL_MIPMAP_LEVEL_ARB 0x207B -#define WGL_CUBE_MAP_FACE_ARB 0x207C -#define WGL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB 0x207D -#define WGL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB 0x207E -#define WGL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB 0x207F -#define WGL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB 0x2080 -#define WGL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB 0x2081 -#define WGL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB 0x2082 -#define WGL_FRONT_LEFT_ARB 0x2083 -#define WGL_FRONT_RIGHT_ARB 0x2084 -#define WGL_BACK_LEFT_ARB 0x2085 -#define WGL_BACK_RIGHT_ARB 0x2086 -#define WGL_AUX0_ARB 0x2087 -#define WGL_AUX1_ARB 0x2088 -#define WGL_AUX2_ARB 0x2089 -#define WGL_AUX3_ARB 0x208A -#define WGL_AUX4_ARB 0x208B -#define WGL_AUX5_ARB 0x208C -#define WGL_AUX6_ARB 0x208D -#define WGL_AUX7_ARB 0x208E -#define WGL_AUX8_ARB 0x208F -#define WGL_AUX9_ARB 0x2090 -typedef BOOL (WINAPI * PFNWGLBINDTEXIMAGEARBPROC) (HPBUFFERARB hPbuffer, int iBuffer); -typedef BOOL (WINAPI * PFNWGLRELEASETEXIMAGEARBPROC) (HPBUFFERARB hPbuffer, int iBuffer); -typedef BOOL (WINAPI * PFNWGLSETPBUFFERATTRIBARBPROC) (HPBUFFERARB hPbuffer, const int *piAttribList); -#ifdef WGL_WGLEXT_PROTOTYPES -BOOL WINAPI wglBindTexImageARB (HPBUFFERARB hPbuffer, int iBuffer); -BOOL WINAPI wglReleaseTexImageARB (HPBUFFERARB hPbuffer, int iBuffer); -BOOL WINAPI wglSetPbufferAttribARB (HPBUFFERARB hPbuffer, const int *piAttribList); -#endif -#endif /* WGL_ARB_render_texture */ - -#ifndef WGL_ARB_robustness_application_isolation -#define WGL_ARB_robustness_application_isolation 1 -#define WGL_CONTEXT_RESET_ISOLATION_BIT_ARB 0x00000008 -#endif /* WGL_ARB_robustness_application_isolation */ - -#ifndef WGL_ARB_robustness_share_group_isolation -#define WGL_ARB_robustness_share_group_isolation 1 -#endif /* WGL_ARB_robustness_share_group_isolation */ - -#ifndef WGL_3DFX_multisample -#define WGL_3DFX_multisample 1 -#define WGL_SAMPLE_BUFFERS_3DFX 0x2060 -#define WGL_SAMPLES_3DFX 0x2061 -#endif /* WGL_3DFX_multisample */ - -#ifndef WGL_3DL_stereo_control -#define WGL_3DL_stereo_control 1 -#define WGL_STEREO_EMITTER_ENABLE_3DL 0x2055 -#define WGL_STEREO_EMITTER_DISABLE_3DL 0x2056 -#define WGL_STEREO_POLARITY_NORMAL_3DL 0x2057 -#define WGL_STEREO_POLARITY_INVERT_3DL 0x2058 -typedef BOOL (WINAPI * PFNWGLSETSTEREOEMITTERSTATE3DLPROC) (HDC hDC, UINT uState); -#ifdef WGL_WGLEXT_PROTOTYPES -BOOL WINAPI wglSetStereoEmitterState3DL (HDC hDC, UINT uState); -#endif -#endif /* WGL_3DL_stereo_control */ - -#ifndef WGL_AMD_gpu_association -#define WGL_AMD_gpu_association 1 -#define WGL_GPU_VENDOR_AMD 0x1F00 -#define WGL_GPU_RENDERER_STRING_AMD 0x1F01 -#define WGL_GPU_OPENGL_VERSION_STRING_AMD 0x1F02 -#define WGL_GPU_FASTEST_TARGET_GPUS_AMD 0x21A2 -#define WGL_GPU_RAM_AMD 0x21A3 -#define WGL_GPU_CLOCK_AMD 0x21A4 -#define WGL_GPU_NUM_PIPES_AMD 0x21A5 -#define WGL_GPU_NUM_SIMD_AMD 0x21A6 -#define WGL_GPU_NUM_RB_AMD 0x21A7 -#define WGL_GPU_NUM_SPI_AMD 0x21A8 -typedef UINT (WINAPI * PFNWGLGETGPUIDSAMDPROC) (UINT maxCount, UINT *ids); -typedef INT (WINAPI * PFNWGLGETGPUINFOAMDPROC) (UINT id, int property, GLenum dataType, UINT size, void *data); -typedef UINT (WINAPI * PFNWGLGETCONTEXTGPUIDAMDPROC) (HGLRC hglrc); -typedef HGLRC (WINAPI * PFNWGLCREATEASSOCIATEDCONTEXTAMDPROC) (UINT id); -typedef HGLRC (WINAPI * PFNWGLCREATEASSOCIATEDCONTEXTATTRIBSAMDPROC) (UINT id, HGLRC hShareContext, const int *attribList); -typedef BOOL (WINAPI * PFNWGLDELETEASSOCIATEDCONTEXTAMDPROC) (HGLRC hglrc); -typedef BOOL (WINAPI * PFNWGLMAKEASSOCIATEDCONTEXTCURRENTAMDPROC) (HGLRC hglrc); -typedef HGLRC (WINAPI * PFNWGLGETCURRENTASSOCIATEDCONTEXTAMDPROC) (void); -typedef VOID (WINAPI * PFNWGLBLITCONTEXTFRAMEBUFFERAMDPROC) (HGLRC dstCtx, GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); -#ifdef WGL_WGLEXT_PROTOTYPES -UINT WINAPI wglGetGPUIDsAMD (UINT maxCount, UINT *ids); -INT WINAPI wglGetGPUInfoAMD (UINT id, int property, GLenum dataType, UINT size, void *data); -UINT WINAPI wglGetContextGPUIDAMD (HGLRC hglrc); -HGLRC WINAPI wglCreateAssociatedContextAMD (UINT id); -HGLRC WINAPI wglCreateAssociatedContextAttribsAMD (UINT id, HGLRC hShareContext, const int *attribList); -BOOL WINAPI wglDeleteAssociatedContextAMD (HGLRC hglrc); -BOOL WINAPI wglMakeAssociatedContextCurrentAMD (HGLRC hglrc); -HGLRC WINAPI wglGetCurrentAssociatedContextAMD (void); -VOID WINAPI wglBlitContextFramebufferAMD (HGLRC dstCtx, GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); -#endif -#endif /* WGL_AMD_gpu_association */ - -#ifndef WGL_ATI_pixel_format_float -#define WGL_ATI_pixel_format_float 1 -#define WGL_TYPE_RGBA_FLOAT_ATI 0x21A0 -#endif /* WGL_ATI_pixel_format_float */ - -#ifndef WGL_EXT_create_context_es2_profile -#define WGL_EXT_create_context_es2_profile 1 -#define WGL_CONTEXT_ES2_PROFILE_BIT_EXT 0x00000004 -#endif /* WGL_EXT_create_context_es2_profile */ - -#ifndef WGL_EXT_create_context_es_profile -#define WGL_EXT_create_context_es_profile 1 -#define WGL_CONTEXT_ES_PROFILE_BIT_EXT 0x00000004 -#endif /* WGL_EXT_create_context_es_profile */ - -#ifndef WGL_EXT_depth_float -#define WGL_EXT_depth_float 1 -#define WGL_DEPTH_FLOAT_EXT 0x2040 -#endif /* WGL_EXT_depth_float */ - -#ifndef WGL_EXT_display_color_table -#define WGL_EXT_display_color_table 1 -typedef GLboolean (WINAPI * PFNWGLCREATEDISPLAYCOLORTABLEEXTPROC) (GLushort id); -typedef GLboolean (WINAPI * PFNWGLLOADDISPLAYCOLORTABLEEXTPROC) (const GLushort *table, GLuint length); -typedef GLboolean (WINAPI * PFNWGLBINDDISPLAYCOLORTABLEEXTPROC) (GLushort id); -typedef VOID (WINAPI * PFNWGLDESTROYDISPLAYCOLORTABLEEXTPROC) (GLushort id); -#ifdef WGL_WGLEXT_PROTOTYPES -GLboolean WINAPI wglCreateDisplayColorTableEXT (GLushort id); -GLboolean WINAPI wglLoadDisplayColorTableEXT (const GLushort *table, GLuint length); -GLboolean WINAPI wglBindDisplayColorTableEXT (GLushort id); -VOID WINAPI wglDestroyDisplayColorTableEXT (GLushort id); -#endif -#endif /* WGL_EXT_display_color_table */ - -#ifndef WGL_EXT_extensions_string -#define WGL_EXT_extensions_string 1 -typedef const char *(WINAPI * PFNWGLGETEXTENSIONSSTRINGEXTPROC) (void); -#ifdef WGL_WGLEXT_PROTOTYPES -const char *WINAPI wglGetExtensionsStringEXT (void); -#endif -#endif /* WGL_EXT_extensions_string */ - -#ifndef WGL_EXT_framebuffer_sRGB -#define WGL_EXT_framebuffer_sRGB 1 -#define WGL_FRAMEBUFFER_SRGB_CAPABLE_EXT 0x20A9 -#endif /* WGL_EXT_framebuffer_sRGB */ - -#ifndef WGL_EXT_make_current_read -#define WGL_EXT_make_current_read 1 -#define ERROR_INVALID_PIXEL_TYPE_EXT 0x2043 -typedef BOOL (WINAPI * PFNWGLMAKECONTEXTCURRENTEXTPROC) (HDC hDrawDC, HDC hReadDC, HGLRC hglrc); -typedef HDC (WINAPI * PFNWGLGETCURRENTREADDCEXTPROC) (void); -#ifdef WGL_WGLEXT_PROTOTYPES -BOOL WINAPI wglMakeContextCurrentEXT (HDC hDrawDC, HDC hReadDC, HGLRC hglrc); -HDC WINAPI wglGetCurrentReadDCEXT (void); -#endif -#endif /* WGL_EXT_make_current_read */ - -#ifndef WGL_EXT_multisample -#define WGL_EXT_multisample 1 -#define WGL_SAMPLE_BUFFERS_EXT 0x2041 -#define WGL_SAMPLES_EXT 0x2042 -#endif /* WGL_EXT_multisample */ - -#ifndef WGL_EXT_pbuffer -#define WGL_EXT_pbuffer 1 -DECLARE_HANDLE(HPBUFFEREXT); -#define WGL_DRAW_TO_PBUFFER_EXT 0x202D -#define WGL_MAX_PBUFFER_PIXELS_EXT 0x202E -#define WGL_MAX_PBUFFER_WIDTH_EXT 0x202F -#define WGL_MAX_PBUFFER_HEIGHT_EXT 0x2030 -#define WGL_OPTIMAL_PBUFFER_WIDTH_EXT 0x2031 -#define WGL_OPTIMAL_PBUFFER_HEIGHT_EXT 0x2032 -#define WGL_PBUFFER_LARGEST_EXT 0x2033 -#define WGL_PBUFFER_WIDTH_EXT 0x2034 -#define WGL_PBUFFER_HEIGHT_EXT 0x2035 -typedef HPBUFFEREXT (WINAPI * PFNWGLCREATEPBUFFEREXTPROC) (HDC hDC, int iPixelFormat, int iWidth, int iHeight, const int *piAttribList); -typedef HDC (WINAPI * PFNWGLGETPBUFFERDCEXTPROC) (HPBUFFEREXT hPbuffer); -typedef int (WINAPI * PFNWGLRELEASEPBUFFERDCEXTPROC) (HPBUFFEREXT hPbuffer, HDC hDC); -typedef BOOL (WINAPI * PFNWGLDESTROYPBUFFEREXTPROC) (HPBUFFEREXT hPbuffer); -typedef BOOL (WINAPI * PFNWGLQUERYPBUFFEREXTPROC) (HPBUFFEREXT hPbuffer, int iAttribute, int *piValue); -#ifdef WGL_WGLEXT_PROTOTYPES -HPBUFFEREXT WINAPI wglCreatePbufferEXT (HDC hDC, int iPixelFormat, int iWidth, int iHeight, const int *piAttribList); -HDC WINAPI wglGetPbufferDCEXT (HPBUFFEREXT hPbuffer); -int WINAPI wglReleasePbufferDCEXT (HPBUFFEREXT hPbuffer, HDC hDC); -BOOL WINAPI wglDestroyPbufferEXT (HPBUFFEREXT hPbuffer); -BOOL WINAPI wglQueryPbufferEXT (HPBUFFEREXT hPbuffer, int iAttribute, int *piValue); -#endif -#endif /* WGL_EXT_pbuffer */ - -#ifndef WGL_EXT_pixel_format -#define WGL_EXT_pixel_format 1 -#define WGL_NUMBER_PIXEL_FORMATS_EXT 0x2000 -#define WGL_DRAW_TO_WINDOW_EXT 0x2001 -#define WGL_DRAW_TO_BITMAP_EXT 0x2002 -#define WGL_ACCELERATION_EXT 0x2003 -#define WGL_NEED_PALETTE_EXT 0x2004 -#define WGL_NEED_SYSTEM_PALETTE_EXT 0x2005 -#define WGL_SWAP_LAYER_BUFFERS_EXT 0x2006 -#define WGL_SWAP_METHOD_EXT 0x2007 -#define WGL_NUMBER_OVERLAYS_EXT 0x2008 -#define WGL_NUMBER_UNDERLAYS_EXT 0x2009 -#define WGL_TRANSPARENT_EXT 0x200A -#define WGL_TRANSPARENT_VALUE_EXT 0x200B -#define WGL_SHARE_DEPTH_EXT 0x200C -#define WGL_SHARE_STENCIL_EXT 0x200D -#define WGL_SHARE_ACCUM_EXT 0x200E -#define WGL_SUPPORT_GDI_EXT 0x200F -#define WGL_SUPPORT_OPENGL_EXT 0x2010 -#define WGL_DOUBLE_BUFFER_EXT 0x2011 -#define WGL_STEREO_EXT 0x2012 -#define WGL_PIXEL_TYPE_EXT 0x2013 -#define WGL_COLOR_BITS_EXT 0x2014 -#define WGL_RED_BITS_EXT 0x2015 -#define WGL_RED_SHIFT_EXT 0x2016 -#define WGL_GREEN_BITS_EXT 0x2017 -#define WGL_GREEN_SHIFT_EXT 0x2018 -#define WGL_BLUE_BITS_EXT 0x2019 -#define WGL_BLUE_SHIFT_EXT 0x201A -#define WGL_ALPHA_BITS_EXT 0x201B -#define WGL_ALPHA_SHIFT_EXT 0x201C -#define WGL_ACCUM_BITS_EXT 0x201D -#define WGL_ACCUM_RED_BITS_EXT 0x201E -#define WGL_ACCUM_GREEN_BITS_EXT 0x201F -#define WGL_ACCUM_BLUE_BITS_EXT 0x2020 -#define WGL_ACCUM_ALPHA_BITS_EXT 0x2021 -#define WGL_DEPTH_BITS_EXT 0x2022 -#define WGL_STENCIL_BITS_EXT 0x2023 -#define WGL_AUX_BUFFERS_EXT 0x2024 -#define WGL_NO_ACCELERATION_EXT 0x2025 -#define WGL_GENERIC_ACCELERATION_EXT 0x2026 -#define WGL_FULL_ACCELERATION_EXT 0x2027 -#define WGL_SWAP_EXCHANGE_EXT 0x2028 -#define WGL_SWAP_COPY_EXT 0x2029 -#define WGL_SWAP_UNDEFINED_EXT 0x202A -#define WGL_TYPE_RGBA_EXT 0x202B -#define WGL_TYPE_COLORINDEX_EXT 0x202C -typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBIVEXTPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, int *piAttributes, int *piValues); -typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBFVEXTPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, int *piAttributes, FLOAT *pfValues); -typedef BOOL (WINAPI * PFNWGLCHOOSEPIXELFORMATEXTPROC) (HDC hdc, const int *piAttribIList, const FLOAT *pfAttribFList, UINT nMaxFormats, int *piFormats, UINT *nNumFormats); -#ifdef WGL_WGLEXT_PROTOTYPES -BOOL WINAPI wglGetPixelFormatAttribivEXT (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, int *piAttributes, int *piValues); -BOOL WINAPI wglGetPixelFormatAttribfvEXT (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, int *piAttributes, FLOAT *pfValues); -BOOL WINAPI wglChoosePixelFormatEXT (HDC hdc, const int *piAttribIList, const FLOAT *pfAttribFList, UINT nMaxFormats, int *piFormats, UINT *nNumFormats); -#endif -#endif /* WGL_EXT_pixel_format */ - -#ifndef WGL_EXT_pixel_format_packed_float -#define WGL_EXT_pixel_format_packed_float 1 -#define WGL_TYPE_RGBA_UNSIGNED_FLOAT_EXT 0x20A8 -#endif /* WGL_EXT_pixel_format_packed_float */ - -#ifndef WGL_EXT_swap_control -#define WGL_EXT_swap_control 1 -typedef BOOL (WINAPI * PFNWGLSWAPINTERVALEXTPROC) (int interval); -typedef int (WINAPI * PFNWGLGETSWAPINTERVALEXTPROC) (void); -#ifdef WGL_WGLEXT_PROTOTYPES -BOOL WINAPI wglSwapIntervalEXT (int interval); -int WINAPI wglGetSwapIntervalEXT (void); -#endif -#endif /* WGL_EXT_swap_control */ - -#ifndef WGL_EXT_swap_control_tear -#define WGL_EXT_swap_control_tear 1 -#endif /* WGL_EXT_swap_control_tear */ - -#ifndef WGL_I3D_digital_video_control -#define WGL_I3D_digital_video_control 1 -#define WGL_DIGITAL_VIDEO_CURSOR_ALPHA_FRAMEBUFFER_I3D 0x2050 -#define WGL_DIGITAL_VIDEO_CURSOR_ALPHA_VALUE_I3D 0x2051 -#define WGL_DIGITAL_VIDEO_CURSOR_INCLUDED_I3D 0x2052 -#define WGL_DIGITAL_VIDEO_GAMMA_CORRECTED_I3D 0x2053 -typedef BOOL (WINAPI * PFNWGLGETDIGITALVIDEOPARAMETERSI3DPROC) (HDC hDC, int iAttribute, int *piValue); -typedef BOOL (WINAPI * PFNWGLSETDIGITALVIDEOPARAMETERSI3DPROC) (HDC hDC, int iAttribute, const int *piValue); -#ifdef WGL_WGLEXT_PROTOTYPES -BOOL WINAPI wglGetDigitalVideoParametersI3D (HDC hDC, int iAttribute, int *piValue); -BOOL WINAPI wglSetDigitalVideoParametersI3D (HDC hDC, int iAttribute, const int *piValue); -#endif -#endif /* WGL_I3D_digital_video_control */ - -#ifndef WGL_I3D_gamma -#define WGL_I3D_gamma 1 -#define WGL_GAMMA_TABLE_SIZE_I3D 0x204E -#define WGL_GAMMA_EXCLUDE_DESKTOP_I3D 0x204F -typedef BOOL (WINAPI * PFNWGLGETGAMMATABLEPARAMETERSI3DPROC) (HDC hDC, int iAttribute, int *piValue); -typedef BOOL (WINAPI * PFNWGLSETGAMMATABLEPARAMETERSI3DPROC) (HDC hDC, int iAttribute, const int *piValue); -typedef BOOL (WINAPI * PFNWGLGETGAMMATABLEI3DPROC) (HDC hDC, int iEntries, USHORT *puRed, USHORT *puGreen, USHORT *puBlue); -typedef BOOL (WINAPI * PFNWGLSETGAMMATABLEI3DPROC) (HDC hDC, int iEntries, const USHORT *puRed, const USHORT *puGreen, const USHORT *puBlue); -#ifdef WGL_WGLEXT_PROTOTYPES -BOOL WINAPI wglGetGammaTableParametersI3D (HDC hDC, int iAttribute, int *piValue); -BOOL WINAPI wglSetGammaTableParametersI3D (HDC hDC, int iAttribute, const int *piValue); -BOOL WINAPI wglGetGammaTableI3D (HDC hDC, int iEntries, USHORT *puRed, USHORT *puGreen, USHORT *puBlue); -BOOL WINAPI wglSetGammaTableI3D (HDC hDC, int iEntries, const USHORT *puRed, const USHORT *puGreen, const USHORT *puBlue); -#endif -#endif /* WGL_I3D_gamma */ - -#ifndef WGL_I3D_genlock -#define WGL_I3D_genlock 1 -#define WGL_GENLOCK_SOURCE_MULTIVIEW_I3D 0x2044 -#define WGL_GENLOCK_SOURCE_EXTERNAL_SYNC_I3D 0x2045 -#define WGL_GENLOCK_SOURCE_EXTERNAL_FIELD_I3D 0x2046 -#define WGL_GENLOCK_SOURCE_EXTERNAL_TTL_I3D 0x2047 -#define WGL_GENLOCK_SOURCE_DIGITAL_SYNC_I3D 0x2048 -#define WGL_GENLOCK_SOURCE_DIGITAL_FIELD_I3D 0x2049 -#define WGL_GENLOCK_SOURCE_EDGE_FALLING_I3D 0x204A -#define WGL_GENLOCK_SOURCE_EDGE_RISING_I3D 0x204B -#define WGL_GENLOCK_SOURCE_EDGE_BOTH_I3D 0x204C -typedef BOOL (WINAPI * PFNWGLENABLEGENLOCKI3DPROC) (HDC hDC); -typedef BOOL (WINAPI * PFNWGLDISABLEGENLOCKI3DPROC) (HDC hDC); -typedef BOOL (WINAPI * PFNWGLISENABLEDGENLOCKI3DPROC) (HDC hDC, BOOL *pFlag); -typedef BOOL (WINAPI * PFNWGLGENLOCKSOURCEI3DPROC) (HDC hDC, UINT uSource); -typedef BOOL (WINAPI * PFNWGLGETGENLOCKSOURCEI3DPROC) (HDC hDC, UINT *uSource); -typedef BOOL (WINAPI * PFNWGLGENLOCKSOURCEEDGEI3DPROC) (HDC hDC, UINT uEdge); -typedef BOOL (WINAPI * PFNWGLGETGENLOCKSOURCEEDGEI3DPROC) (HDC hDC, UINT *uEdge); -typedef BOOL (WINAPI * PFNWGLGENLOCKSAMPLERATEI3DPROC) (HDC hDC, UINT uRate); -typedef BOOL (WINAPI * PFNWGLGETGENLOCKSAMPLERATEI3DPROC) (HDC hDC, UINT *uRate); -typedef BOOL (WINAPI * PFNWGLGENLOCKSOURCEDELAYI3DPROC) (HDC hDC, UINT uDelay); -typedef BOOL (WINAPI * PFNWGLGETGENLOCKSOURCEDELAYI3DPROC) (HDC hDC, UINT *uDelay); -typedef BOOL (WINAPI * PFNWGLQUERYGENLOCKMAXSOURCEDELAYI3DPROC) (HDC hDC, UINT *uMaxLineDelay, UINT *uMaxPixelDelay); -#ifdef WGL_WGLEXT_PROTOTYPES -BOOL WINAPI wglEnableGenlockI3D (HDC hDC); -BOOL WINAPI wglDisableGenlockI3D (HDC hDC); -BOOL WINAPI wglIsEnabledGenlockI3D (HDC hDC, BOOL *pFlag); -BOOL WINAPI wglGenlockSourceI3D (HDC hDC, UINT uSource); -BOOL WINAPI wglGetGenlockSourceI3D (HDC hDC, UINT *uSource); -BOOL WINAPI wglGenlockSourceEdgeI3D (HDC hDC, UINT uEdge); -BOOL WINAPI wglGetGenlockSourceEdgeI3D (HDC hDC, UINT *uEdge); -BOOL WINAPI wglGenlockSampleRateI3D (HDC hDC, UINT uRate); -BOOL WINAPI wglGetGenlockSampleRateI3D (HDC hDC, UINT *uRate); -BOOL WINAPI wglGenlockSourceDelayI3D (HDC hDC, UINT uDelay); -BOOL WINAPI wglGetGenlockSourceDelayI3D (HDC hDC, UINT *uDelay); -BOOL WINAPI wglQueryGenlockMaxSourceDelayI3D (HDC hDC, UINT *uMaxLineDelay, UINT *uMaxPixelDelay); -#endif -#endif /* WGL_I3D_genlock */ - -#ifndef WGL_I3D_image_buffer -#define WGL_I3D_image_buffer 1 -#define WGL_IMAGE_BUFFER_MIN_ACCESS_I3D 0x00000001 -#define WGL_IMAGE_BUFFER_LOCK_I3D 0x00000002 -typedef LPVOID (WINAPI * PFNWGLCREATEIMAGEBUFFERI3DPROC) (HDC hDC, DWORD dwSize, UINT uFlags); -typedef BOOL (WINAPI * PFNWGLDESTROYIMAGEBUFFERI3DPROC) (HDC hDC, LPVOID pAddress); -typedef BOOL (WINAPI * PFNWGLASSOCIATEIMAGEBUFFEREVENTSI3DPROC) (HDC hDC, const HANDLE *pEvent, const LPVOID *pAddress, const DWORD *pSize, UINT count); -typedef BOOL (WINAPI * PFNWGLRELEASEIMAGEBUFFEREVENTSI3DPROC) (HDC hDC, const LPVOID *pAddress, UINT count); -#ifdef WGL_WGLEXT_PROTOTYPES -LPVOID WINAPI wglCreateImageBufferI3D (HDC hDC, DWORD dwSize, UINT uFlags); -BOOL WINAPI wglDestroyImageBufferI3D (HDC hDC, LPVOID pAddress); -BOOL WINAPI wglAssociateImageBufferEventsI3D (HDC hDC, const HANDLE *pEvent, const LPVOID *pAddress, const DWORD *pSize, UINT count); -BOOL WINAPI wglReleaseImageBufferEventsI3D (HDC hDC, const LPVOID *pAddress, UINT count); -#endif -#endif /* WGL_I3D_image_buffer */ - -#ifndef WGL_I3D_swap_frame_lock -#define WGL_I3D_swap_frame_lock 1 -typedef BOOL (WINAPI * PFNWGLENABLEFRAMELOCKI3DPROC) (void); -typedef BOOL (WINAPI * PFNWGLDISABLEFRAMELOCKI3DPROC) (void); -typedef BOOL (WINAPI * PFNWGLISENABLEDFRAMELOCKI3DPROC) (BOOL *pFlag); -typedef BOOL (WINAPI * PFNWGLQUERYFRAMELOCKMASTERI3DPROC) (BOOL *pFlag); -#ifdef WGL_WGLEXT_PROTOTYPES -BOOL WINAPI wglEnableFrameLockI3D (void); -BOOL WINAPI wglDisableFrameLockI3D (void); -BOOL WINAPI wglIsEnabledFrameLockI3D (BOOL *pFlag); -BOOL WINAPI wglQueryFrameLockMasterI3D (BOOL *pFlag); -#endif -#endif /* WGL_I3D_swap_frame_lock */ - -#ifndef WGL_I3D_swap_frame_usage -#define WGL_I3D_swap_frame_usage 1 -typedef BOOL (WINAPI * PFNWGLGETFRAMEUSAGEI3DPROC) (float *pUsage); -typedef BOOL (WINAPI * PFNWGLBEGINFRAMETRACKINGI3DPROC) (void); -typedef BOOL (WINAPI * PFNWGLENDFRAMETRACKINGI3DPROC) (void); -typedef BOOL (WINAPI * PFNWGLQUERYFRAMETRACKINGI3DPROC) (DWORD *pFrameCount, DWORD *pMissedFrames, float *pLastMissedUsage); -#ifdef WGL_WGLEXT_PROTOTYPES -BOOL WINAPI wglGetFrameUsageI3D (float *pUsage); -BOOL WINAPI wglBeginFrameTrackingI3D (void); -BOOL WINAPI wglEndFrameTrackingI3D (void); -BOOL WINAPI wglQueryFrameTrackingI3D (DWORD *pFrameCount, DWORD *pMissedFrames, float *pLastMissedUsage); -#endif -#endif /* WGL_I3D_swap_frame_usage */ - -#ifndef WGL_NV_DX_interop -#define WGL_NV_DX_interop 1 -#define WGL_ACCESS_READ_ONLY_NV 0x00000000 -#define WGL_ACCESS_READ_WRITE_NV 0x00000001 -#define WGL_ACCESS_WRITE_DISCARD_NV 0x00000002 -typedef BOOL (WINAPI * PFNWGLDXSETRESOURCESHAREHANDLENVPROC) (void *dxObject, HANDLE shareHandle); -typedef HANDLE (WINAPI * PFNWGLDXOPENDEVICENVPROC) (void *dxDevice); -typedef BOOL (WINAPI * PFNWGLDXCLOSEDEVICENVPROC) (HANDLE hDevice); -typedef HANDLE (WINAPI * PFNWGLDXREGISTEROBJECTNVPROC) (HANDLE hDevice, void *dxObject, GLuint name, GLenum type, GLenum access); -typedef BOOL (WINAPI * PFNWGLDXUNREGISTEROBJECTNVPROC) (HANDLE hDevice, HANDLE hObject); -typedef BOOL (WINAPI * PFNWGLDXOBJECTACCESSNVPROC) (HANDLE hObject, GLenum access); -typedef BOOL (WINAPI * PFNWGLDXLOCKOBJECTSNVPROC) (HANDLE hDevice, GLint count, HANDLE *hObjects); -typedef BOOL (WINAPI * PFNWGLDXUNLOCKOBJECTSNVPROC) (HANDLE hDevice, GLint count, HANDLE *hObjects); -#ifdef WGL_WGLEXT_PROTOTYPES -BOOL WINAPI wglDXSetResourceShareHandleNV (void *dxObject, HANDLE shareHandle); -HANDLE WINAPI wglDXOpenDeviceNV (void *dxDevice); -BOOL WINAPI wglDXCloseDeviceNV (HANDLE hDevice); -HANDLE WINAPI wglDXRegisterObjectNV (HANDLE hDevice, void *dxObject, GLuint name, GLenum type, GLenum access); -BOOL WINAPI wglDXUnregisterObjectNV (HANDLE hDevice, HANDLE hObject); -BOOL WINAPI wglDXObjectAccessNV (HANDLE hObject, GLenum access); -BOOL WINAPI wglDXLockObjectsNV (HANDLE hDevice, GLint count, HANDLE *hObjects); -BOOL WINAPI wglDXUnlockObjectsNV (HANDLE hDevice, GLint count, HANDLE *hObjects); -#endif -#endif /* WGL_NV_DX_interop */ - -#ifndef WGL_NV_DX_interop2 -#define WGL_NV_DX_interop2 1 -#endif /* WGL_NV_DX_interop2 */ - -#ifndef WGL_NV_copy_image -#define WGL_NV_copy_image 1 -typedef BOOL (WINAPI * PFNWGLCOPYIMAGESUBDATANVPROC) (HGLRC hSrcRC, GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, HGLRC hDstRC, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei width, GLsizei height, GLsizei depth); -#ifdef WGL_WGLEXT_PROTOTYPES -BOOL WINAPI wglCopyImageSubDataNV (HGLRC hSrcRC, GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, HGLRC hDstRC, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei width, GLsizei height, GLsizei depth); -#endif -#endif /* WGL_NV_copy_image */ - -#ifndef WGL_NV_delay_before_swap -#define WGL_NV_delay_before_swap 1 -typedef BOOL (WINAPI * PFNWGLDELAYBEFORESWAPNVPROC) (HDC hDC, GLfloat seconds); -#ifdef WGL_WGLEXT_PROTOTYPES -BOOL WINAPI wglDelayBeforeSwapNV (HDC hDC, GLfloat seconds); -#endif -#endif /* WGL_NV_delay_before_swap */ - -#ifndef WGL_NV_float_buffer -#define WGL_NV_float_buffer 1 -#define WGL_FLOAT_COMPONENTS_NV 0x20B0 -#define WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_R_NV 0x20B1 -#define WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RG_NV 0x20B2 -#define WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RGB_NV 0x20B3 -#define WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RGBA_NV 0x20B4 -#define WGL_TEXTURE_FLOAT_R_NV 0x20B5 -#define WGL_TEXTURE_FLOAT_RG_NV 0x20B6 -#define WGL_TEXTURE_FLOAT_RGB_NV 0x20B7 -#define WGL_TEXTURE_FLOAT_RGBA_NV 0x20B8 -#endif /* WGL_NV_float_buffer */ - -#ifndef WGL_NV_gpu_affinity -#define WGL_NV_gpu_affinity 1 -DECLARE_HANDLE(HGPUNV); -struct _GPU_DEVICE { - DWORD cb; - CHAR DeviceName[32]; - CHAR DeviceString[128]; - DWORD Flags; - RECT rcVirtualScreen; -}; -typedef struct _GPU_DEVICE *PGPU_DEVICE; -#define ERROR_INCOMPATIBLE_AFFINITY_MASKS_NV 0x20D0 -#define ERROR_MISSING_AFFINITY_MASK_NV 0x20D1 -typedef BOOL (WINAPI * PFNWGLENUMGPUSNVPROC) (UINT iGpuIndex, HGPUNV *phGpu); -typedef BOOL (WINAPI * PFNWGLENUMGPUDEVICESNVPROC) (HGPUNV hGpu, UINT iDeviceIndex, PGPU_DEVICE lpGpuDevice); -typedef HDC (WINAPI * PFNWGLCREATEAFFINITYDCNVPROC) (const HGPUNV *phGpuList); -typedef BOOL (WINAPI * PFNWGLENUMGPUSFROMAFFINITYDCNVPROC) (HDC hAffinityDC, UINT iGpuIndex, HGPUNV *hGpu); -typedef BOOL (WINAPI * PFNWGLDELETEDCNVPROC) (HDC hdc); -#ifdef WGL_WGLEXT_PROTOTYPES -BOOL WINAPI wglEnumGpusNV (UINT iGpuIndex, HGPUNV *phGpu); -BOOL WINAPI wglEnumGpuDevicesNV (HGPUNV hGpu, UINT iDeviceIndex, PGPU_DEVICE lpGpuDevice); -HDC WINAPI wglCreateAffinityDCNV (const HGPUNV *phGpuList); -BOOL WINAPI wglEnumGpusFromAffinityDCNV (HDC hAffinityDC, UINT iGpuIndex, HGPUNV *hGpu); -BOOL WINAPI wglDeleteDCNV (HDC hdc); -#endif -#endif /* WGL_NV_gpu_affinity */ - -#ifndef WGL_NV_multisample_coverage -#define WGL_NV_multisample_coverage 1 -#define WGL_COVERAGE_SAMPLES_NV 0x2042 -#define WGL_COLOR_SAMPLES_NV 0x20B9 -#endif /* WGL_NV_multisample_coverage */ - -#ifndef WGL_NV_present_video -#define WGL_NV_present_video 1 -DECLARE_HANDLE(HVIDEOOUTPUTDEVICENV); -#define WGL_NUM_VIDEO_SLOTS_NV 0x20F0 -typedef int (WINAPI * PFNWGLENUMERATEVIDEODEVICESNVPROC) (HDC hDC, HVIDEOOUTPUTDEVICENV *phDeviceList); -typedef BOOL (WINAPI * PFNWGLBINDVIDEODEVICENVPROC) (HDC hDC, unsigned int uVideoSlot, HVIDEOOUTPUTDEVICENV hVideoDevice, const int *piAttribList); -typedef BOOL (WINAPI * PFNWGLQUERYCURRENTCONTEXTNVPROC) (int iAttribute, int *piValue); -#ifdef WGL_WGLEXT_PROTOTYPES -int WINAPI wglEnumerateVideoDevicesNV (HDC hDC, HVIDEOOUTPUTDEVICENV *phDeviceList); -BOOL WINAPI wglBindVideoDeviceNV (HDC hDC, unsigned int uVideoSlot, HVIDEOOUTPUTDEVICENV hVideoDevice, const int *piAttribList); -BOOL WINAPI wglQueryCurrentContextNV (int iAttribute, int *piValue); -#endif -#endif /* WGL_NV_present_video */ - -#ifndef WGL_NV_render_depth_texture -#define WGL_NV_render_depth_texture 1 -#define WGL_BIND_TO_TEXTURE_DEPTH_NV 0x20A3 -#define WGL_BIND_TO_TEXTURE_RECTANGLE_DEPTH_NV 0x20A4 -#define WGL_DEPTH_TEXTURE_FORMAT_NV 0x20A5 -#define WGL_TEXTURE_DEPTH_COMPONENT_NV 0x20A6 -#define WGL_DEPTH_COMPONENT_NV 0x20A7 -#endif /* WGL_NV_render_depth_texture */ - -#ifndef WGL_NV_render_texture_rectangle -#define WGL_NV_render_texture_rectangle 1 -#define WGL_BIND_TO_TEXTURE_RECTANGLE_RGB_NV 0x20A0 -#define WGL_BIND_TO_TEXTURE_RECTANGLE_RGBA_NV 0x20A1 -#define WGL_TEXTURE_RECTANGLE_NV 0x20A2 -#endif /* WGL_NV_render_texture_rectangle */ - -#ifndef WGL_NV_swap_group -#define WGL_NV_swap_group 1 -typedef BOOL (WINAPI * PFNWGLJOINSWAPGROUPNVPROC) (HDC hDC, GLuint group); -typedef BOOL (WINAPI * PFNWGLBINDSWAPBARRIERNVPROC) (GLuint group, GLuint barrier); -typedef BOOL (WINAPI * PFNWGLQUERYSWAPGROUPNVPROC) (HDC hDC, GLuint *group, GLuint *barrier); -typedef BOOL (WINAPI * PFNWGLQUERYMAXSWAPGROUPSNVPROC) (HDC hDC, GLuint *maxGroups, GLuint *maxBarriers); -typedef BOOL (WINAPI * PFNWGLQUERYFRAMECOUNTNVPROC) (HDC hDC, GLuint *count); -typedef BOOL (WINAPI * PFNWGLRESETFRAMECOUNTNVPROC) (HDC hDC); -#ifdef WGL_WGLEXT_PROTOTYPES -BOOL WINAPI wglJoinSwapGroupNV (HDC hDC, GLuint group); -BOOL WINAPI wglBindSwapBarrierNV (GLuint group, GLuint barrier); -BOOL WINAPI wglQuerySwapGroupNV (HDC hDC, GLuint *group, GLuint *barrier); -BOOL WINAPI wglQueryMaxSwapGroupsNV (HDC hDC, GLuint *maxGroups, GLuint *maxBarriers); -BOOL WINAPI wglQueryFrameCountNV (HDC hDC, GLuint *count); -BOOL WINAPI wglResetFrameCountNV (HDC hDC); -#endif -#endif /* WGL_NV_swap_group */ - -#ifndef WGL_NV_vertex_array_range -#define WGL_NV_vertex_array_range 1 -typedef void *(WINAPI * PFNWGLALLOCATEMEMORYNVPROC) (GLsizei size, GLfloat readfreq, GLfloat writefreq, GLfloat priority); -typedef void (WINAPI * PFNWGLFREEMEMORYNVPROC) (void *pointer); -#ifdef WGL_WGLEXT_PROTOTYPES -void *WINAPI wglAllocateMemoryNV (GLsizei size, GLfloat readfreq, GLfloat writefreq, GLfloat priority); -void WINAPI wglFreeMemoryNV (void *pointer); -#endif -#endif /* WGL_NV_vertex_array_range */ - -#ifndef WGL_NV_video_capture -#define WGL_NV_video_capture 1 -DECLARE_HANDLE(HVIDEOINPUTDEVICENV); -#define WGL_UNIQUE_ID_NV 0x20CE -#define WGL_NUM_VIDEO_CAPTURE_SLOTS_NV 0x20CF -typedef BOOL (WINAPI * PFNWGLBINDVIDEOCAPTUREDEVICENVPROC) (UINT uVideoSlot, HVIDEOINPUTDEVICENV hDevice); -typedef UINT (WINAPI * PFNWGLENUMERATEVIDEOCAPTUREDEVICESNVPROC) (HDC hDc, HVIDEOINPUTDEVICENV *phDeviceList); -typedef BOOL (WINAPI * PFNWGLLOCKVIDEOCAPTUREDEVICENVPROC) (HDC hDc, HVIDEOINPUTDEVICENV hDevice); -typedef BOOL (WINAPI * PFNWGLQUERYVIDEOCAPTUREDEVICENVPROC) (HDC hDc, HVIDEOINPUTDEVICENV hDevice, int iAttribute, int *piValue); -typedef BOOL (WINAPI * PFNWGLRELEASEVIDEOCAPTUREDEVICENVPROC) (HDC hDc, HVIDEOINPUTDEVICENV hDevice); -#ifdef WGL_WGLEXT_PROTOTYPES -BOOL WINAPI wglBindVideoCaptureDeviceNV (UINT uVideoSlot, HVIDEOINPUTDEVICENV hDevice); -UINT WINAPI wglEnumerateVideoCaptureDevicesNV (HDC hDc, HVIDEOINPUTDEVICENV *phDeviceList); -BOOL WINAPI wglLockVideoCaptureDeviceNV (HDC hDc, HVIDEOINPUTDEVICENV hDevice); -BOOL WINAPI wglQueryVideoCaptureDeviceNV (HDC hDc, HVIDEOINPUTDEVICENV hDevice, int iAttribute, int *piValue); -BOOL WINAPI wglReleaseVideoCaptureDeviceNV (HDC hDc, HVIDEOINPUTDEVICENV hDevice); -#endif -#endif /* WGL_NV_video_capture */ - -#ifndef WGL_NV_video_output -#define WGL_NV_video_output 1 -DECLARE_HANDLE(HPVIDEODEV); -#define WGL_BIND_TO_VIDEO_RGB_NV 0x20C0 -#define WGL_BIND_TO_VIDEO_RGBA_NV 0x20C1 -#define WGL_BIND_TO_VIDEO_RGB_AND_DEPTH_NV 0x20C2 -#define WGL_VIDEO_OUT_COLOR_NV 0x20C3 -#define WGL_VIDEO_OUT_ALPHA_NV 0x20C4 -#define WGL_VIDEO_OUT_DEPTH_NV 0x20C5 -#define WGL_VIDEO_OUT_COLOR_AND_ALPHA_NV 0x20C6 -#define WGL_VIDEO_OUT_COLOR_AND_DEPTH_NV 0x20C7 -#define WGL_VIDEO_OUT_FRAME 0x20C8 -#define WGL_VIDEO_OUT_FIELD_1 0x20C9 -#define WGL_VIDEO_OUT_FIELD_2 0x20CA -#define WGL_VIDEO_OUT_STACKED_FIELDS_1_2 0x20CB -#define WGL_VIDEO_OUT_STACKED_FIELDS_2_1 0x20CC -typedef BOOL (WINAPI * PFNWGLGETVIDEODEVICENVPROC) (HDC hDC, int numDevices, HPVIDEODEV *hVideoDevice); -typedef BOOL (WINAPI * PFNWGLRELEASEVIDEODEVICENVPROC) (HPVIDEODEV hVideoDevice); -typedef BOOL (WINAPI * PFNWGLBINDVIDEOIMAGENVPROC) (HPVIDEODEV hVideoDevice, HPBUFFERARB hPbuffer, int iVideoBuffer); -typedef BOOL (WINAPI * PFNWGLRELEASEVIDEOIMAGENVPROC) (HPBUFFERARB hPbuffer, int iVideoBuffer); -typedef BOOL (WINAPI * PFNWGLSENDPBUFFERTOVIDEONVPROC) (HPBUFFERARB hPbuffer, int iBufferType, unsigned long *pulCounterPbuffer, BOOL bBlock); -typedef BOOL (WINAPI * PFNWGLGETVIDEOINFONVPROC) (HPVIDEODEV hpVideoDevice, unsigned long *pulCounterOutputPbuffer, unsigned long *pulCounterOutputVideo); -#ifdef WGL_WGLEXT_PROTOTYPES -BOOL WINAPI wglGetVideoDeviceNV (HDC hDC, int numDevices, HPVIDEODEV *hVideoDevice); -BOOL WINAPI wglReleaseVideoDeviceNV (HPVIDEODEV hVideoDevice); -BOOL WINAPI wglBindVideoImageNV (HPVIDEODEV hVideoDevice, HPBUFFERARB hPbuffer, int iVideoBuffer); -BOOL WINAPI wglReleaseVideoImageNV (HPBUFFERARB hPbuffer, int iVideoBuffer); -BOOL WINAPI wglSendPbufferToVideoNV (HPBUFFERARB hPbuffer, int iBufferType, unsigned long *pulCounterPbuffer, BOOL bBlock); -BOOL WINAPI wglGetVideoInfoNV (HPVIDEODEV hpVideoDevice, unsigned long *pulCounterOutputPbuffer, unsigned long *pulCounterOutputVideo); -#endif -#endif /* WGL_NV_video_output */ - -#ifndef WGL_OML_sync_control -#define WGL_OML_sync_control 1 -typedef BOOL (WINAPI * PFNWGLGETSYNCVALUESOMLPROC) (HDC hdc, INT64 *ust, INT64 *msc, INT64 *sbc); -typedef BOOL (WINAPI * PFNWGLGETMSCRATEOMLPROC) (HDC hdc, INT32 *numerator, INT32 *denominator); -typedef INT64 (WINAPI * PFNWGLSWAPBUFFERSMSCOMLPROC) (HDC hdc, INT64 target_msc, INT64 divisor, INT64 remainder); -typedef INT64 (WINAPI * PFNWGLSWAPLAYERBUFFERSMSCOMLPROC) (HDC hdc, int fuPlanes, INT64 target_msc, INT64 divisor, INT64 remainder); -typedef BOOL (WINAPI * PFNWGLWAITFORMSCOMLPROC) (HDC hdc, INT64 target_msc, INT64 divisor, INT64 remainder, INT64 *ust, INT64 *msc, INT64 *sbc); -typedef BOOL (WINAPI * PFNWGLWAITFORSBCOMLPROC) (HDC hdc, INT64 target_sbc, INT64 *ust, INT64 *msc, INT64 *sbc); -#ifdef WGL_WGLEXT_PROTOTYPES -BOOL WINAPI wglGetSyncValuesOML (HDC hdc, INT64 *ust, INT64 *msc, INT64 *sbc); -BOOL WINAPI wglGetMscRateOML (HDC hdc, INT32 *numerator, INT32 *denominator); -INT64 WINAPI wglSwapBuffersMscOML (HDC hdc, INT64 target_msc, INT64 divisor, INT64 remainder); -INT64 WINAPI wglSwapLayerBuffersMscOML (HDC hdc, int fuPlanes, INT64 target_msc, INT64 divisor, INT64 remainder); -BOOL WINAPI wglWaitForMscOML (HDC hdc, INT64 target_msc, INT64 divisor, INT64 remainder, INT64 *ust, INT64 *msc, INT64 *sbc); -BOOL WINAPI wglWaitForSbcOML (HDC hdc, INT64 target_sbc, INT64 *ust, INT64 *msc, INT64 *sbc); -#endif -#endif /* WGL_OML_sync_control */ - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/engine/code/winquake.h b/engine/code/winquake.h deleted file mode 100644 index fc2634f..0000000 --- a/engine/code/winquake.h +++ /dev/null @@ -1,183 +0,0 @@ -/* -Copyright (C) 1996-1997 Id Software, Inc. - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ -// winquake.h: Win32-specific Quake header file - -#pragma warning( disable : 4229 ) // mgraph gets this - -#include -#define WM_MOUSEWHEEL 0x020A - -#ifndef SERVERONLY -#include -#include -#ifndef GLQUAKE -#include -#endif -#endif - -extern HINSTANCE global_hInstance; -extern int global_nCmdShow; - -#ifndef SERVERONLY - -extern LPDIRECTDRAW lpDD; -extern qboolean DDActive; -extern LPDIRECTDRAWSURFACE lpPrimary; -extern LPDIRECTDRAWSURFACE lpFrontBuffer; -extern LPDIRECTDRAWSURFACE lpBackBuffer; -extern LPDIRECTDRAWPALETTE lpDDPal; -extern LPDIRECTSOUND pDS; -extern LPDIRECTSOUNDBUFFER pDSBuf; - -extern DWORD gSndBufSize; -//#define SNDBUFSIZE 65536 - -void VID_LockBuffer (void); -void VID_UnlockBuffer (void); - -#endif - -typedef enum {MS_WINDOWED, MS_FULLSCREEN, MS_FULLDIB, MS_UNINIT} modestate_t; - -// jkrige - moved to winquake.h (here) -#define MAX_MODE_LIST 30 -#ifdef GLQUAKE -#define BASEWIDTH 640 -#define BASEHEIGHT 480 -#define BASEFOV 90 - -//#define SCALEHEIGHT 540.0f -//#define SCALEWIDTH SCALEHEIGHT / 0.5625f // / 0.75f - -#else -#define BASEWIDTH 320 -#define BASEHEIGHT 240 // jkrige - was 200 - -//#define SCALEWIDTH 320 -//#define SCALEHEIGHT 240 // jkrige - was 200 -#endif -// jkrige - moved to winquake.h (here) - -// jkrige - moved to winquake.h (here) -#ifdef GLQUAKE -typedef struct { - modestate_t type; - int width; - int height; - int modenum; - int dib; - int fullscreen; - int bpp; - int halfscreen; - // jkrige - increased maximum video mode descriptions - char modedesc[33]; - //char modedesc[17]; - // jkrige - increased maximum video mode descriptions -} vmode_t; -#else -typedef struct { - modestate_t type; - int width; - int height; - int modenum; - int mode13; - int stretched; - int dib; - int fullscreen; - int bpp; - int halfscreen; - char modedesc[13]; -} vmode_t; -#endif -// jkrige - moved to winquake.h (here) - -// jkrige - scale2d -#ifdef GLQUAKE -extern qpic_t *conback; -#endif -extern vmode_t modelist[MAX_MODE_LIST]; -// jkrige - scale2d - -extern modestate_t modestate; - -extern HWND mainwindow; -extern qboolean ActiveApp, Minimized; - -//extern qboolean WinNT; // jkrige - remove windows version check - -int VID_ForceUnlockedAndReturnState (void); -void VID_ForceLockState (int lk); - -void IN_ShowMouse (void); -void IN_DeactivateMouse (void); -void IN_HideMouse (void); -void IN_ActivateMouse (void); -void IN_RestoreOriginalMouseState (void); -void IN_SetQuakeMouseState (void); -void IN_MouseEvent (int mstate); - -extern qboolean winsock_lib_initialized; - -extern cvar_t _windowed_mouse; - -// jkrige - scale2d -extern cvar_t vid_mode; -// jkrige - scale2d - - -// jkrige - non power of two -extern cvar_t gl_texture_non_power_of_two; -// jkrige - non power of two - - -extern int window_center_x, window_center_y; -extern RECT window_rect; - -extern qboolean mouseinitialized; -extern HWND hwnd_dialog; - -extern HANDLE hinput, houtput; - -void IN_UpdateClipCursor (void); -void CenterWindow(HWND hWndCenter, int width, int height, BOOL lefttopjustify); - -void S_BlockSound (void); -void S_UnblockSound (void); - -void VID_SetDefaultMode (void); - -int (PASCAL FAR *pWSAStartup)(WORD wVersionRequired, LPWSADATA lpWSAData); -int (PASCAL FAR *pWSACleanup)(void); -int (PASCAL FAR *pWSAGetLastError)(void); -SOCKET (PASCAL FAR *psocket)(int af, int type, int protocol); -int (PASCAL FAR *pioctlsocket)(SOCKET s, long cmd, u_long FAR *argp); -int (PASCAL FAR *psetsockopt)(SOCKET s, int level, int optname, - const char FAR * optval, int optlen); -int (PASCAL FAR *precvfrom)(SOCKET s, char FAR * buf, int len, int flags, - struct sockaddr FAR *from, int FAR * fromlen); -int (PASCAL FAR *psendto)(SOCKET s, const char FAR * buf, int len, int flags, - const struct sockaddr FAR *to, int tolen); -int (PASCAL FAR *pclosesocket)(SOCKET s); -int (PASCAL FAR *pgethostname)(char FAR * name, int namelen); -struct hostent FAR * (PASCAL FAR *pgethostbyname)(const char FAR * name); -struct hostent FAR * (PASCAL FAR *pgethostbyaddr)(const char FAR * addr, - int len, int type); -int (PASCAL FAR *pgetsockname)(SOCKET s, struct sockaddr FAR *name, - int FAR * namelen); diff --git a/engine/code/winquake.rc b/engine/code/winquake.rc deleted file mode 100644 index c52e44e..0000000 --- a/engine/code/winquake.rc +++ /dev/null @@ -1,108 +0,0 @@ -// Microsoft Visual C++ generated resource script. -// -#include "resource.h" - -#define APSTUDIO_READONLY_SYMBOLS -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 2 resource. -// -#include "afxres.h" - -///////////////////////////////////////////////////////////////////////////// -#undef APSTUDIO_READONLY_SYMBOLS - -///////////////////////////////////////////////////////////////////////////// -// English (United States) resources - -#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) -LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US -#pragma code_page(1252) - -#ifdef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// TEXTINCLUDE -// - -1 TEXTINCLUDE -BEGIN - "resource.h\0" -END - -2 TEXTINCLUDE -BEGIN - "#include ""afxres.h""\r\n" - "\0" -END - -3 TEXTINCLUDE -BEGIN - "\r\n" - "\0" -END - -#endif // APSTUDIO_INVOKED - - -///////////////////////////////////////////////////////////////////////////// -// -// Icon -// - -// Icon with lowest ID value placed first to ensure application icon -// remains consistent on all systems. -IDI_ICON2 ICON "quake.ico" - - -///////////////////////////////////////////////////////////////////////////// -// -// Dialog -// - -IDD_DIALOG1 DIALOGEX 0, 0, 155, 72 -STYLE DS_SETFONT | DS_MODALFRAME | DS_SETFOREGROUND | DS_CENTER | WS_POPUP | WS_VISIBLE -EXSTYLE WS_EX_TOOLWINDOW -FONT 16, "Times New Roman", 0, 0, 0x1 -BEGIN - CONTROL IDB_BITMAP1,IDC_STATIC,"Static",SS_BITMAP,0,0,155,72 -END - - -///////////////////////////////////////////////////////////////////////////// -// -// DESIGNINFO -// - -#ifdef APSTUDIO_INVOKED -GUIDELINES DESIGNINFO -BEGIN - IDD_DIALOG1, DIALOG - BEGIN - END -END -#endif // APSTUDIO_INVOKED - - -///////////////////////////////////////////////////////////////////////////// -// -// Bitmap -// - -IDB_QUAKE1 BITMAP "quake.bmp" - -#endif // English (United States) resources -///////////////////////////////////////////////////////////////////////////// - - - -#ifndef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 3 resource. -// - - -///////////////////////////////////////////////////////////////////////////// -#endif // not APSTUDIO_INVOKED - diff --git a/engine/code/wqreadme.txt b/engine/code/wqreadme.txt deleted file mode 100644 index 9ba2f1b..0000000 --- a/engine/code/wqreadme.txt +++ /dev/null @@ -1,1119 +0,0 @@ --------------------------- -| wqreadme.txt | -| WinQuake documentation | -| 3/21/97 | --------------------------- - -WinQuake (WQ) is a native Win32 version of Quake, and will run on -either Win95 or Windows NT 4.0 or later. It is designed to take -advantage of whatever enhanced video, sound, and input capabilities -(such as DirectX or VESA VBE video modes) are present, but has -fallback functionality so it can run on any Win95 or NT 4.0 or later -system, even if neither DirectX nor VESA VBE is available. You may -experience problems running WQ on some systems, because driver and -operating-system support for game functionality are not yet mature -under Win32, and many bugs and incompatibilities remain in those -components. If you encounter what seems to be a bug, first please -check through the list of known problems, below. If your problem -doesn't appear on the list, please fill out and submit the WQ bug -report at http://www.idsoftware.com/contact/. - -The material accompanying Quake is the reference for all -non-Windows-related matters concerning WinQuake; in terms of gameplay, -WQ is the same as Quake. This file contains Windows-related -information only. - -The rest of this document is organized as follows: - -Installing and running WinQuake -Common problems and workarounds -A bit about how WQ video works -Video command-line switches -A bit about how WQ sound works -Sound command-line switches -Notes on networking -Notes on the mouse -Log of changes to documentation -Special thanks - - ------------------------------------ -| Installing and running WinQuake | ------------------------------------ - -In order to run WinQuake, you must first have Quake installed. -Assuming Quake is installed in the standard directory, c:\quake, -unzip the WinQuake zip file into c:\quake. The following files -from the zip file must be present in order for WQ to run: - -winquake.exe -pmpro16.dll -pmpro32.dll -wdir16.dll -wdir32.dll -wdirnop.com -wdirnop.pif - -Then you can run WinQuake by making c:\quake the current directory, -typing "winquake" and pressing the Enter key. Alternatively, you can -use wq.bat to run WinQuake. The wq batch file requires one parameter -describing how to configure WQ for performance; just type "wq" to get -a list of the six options. The first of the six options is - -wq fast - -This is the same as typing "winquake"; this runs WinQuake in an -aggressive configuration that is likely to yield the best performance -if it runs successfully on your system, but which has a risk of -causing WinQuake or even your system to crash if there are bugs or -incompatibilities in your video or sound drivers. Alternatively, you -can use - -wq safe - -to run WinQuake in a conservative configuration, likely to run -on almost all machines with no problems, but possibly with slower -graphics, fewer high-resolution modes, and delayed sound. Or you -can run - -wq verysafe - -to run WinQuake in a very conservative configuration that is pretty -much guaranteed to run, but will probably have slow performance, and -will have no sound. Two other options are - -wq fastvid - -which has maximum video performance, but greater sound latency (delay -until the sound is heard), and - -wq fastsnd - -which uses more conservative video modes, but low-latency sound. - -(One odd note is that DirectSound has much lower-latency sound than -wave sound, but is currently quite a bit slower overall. Thus you -may find that "wq fastvid" is actually faster, by as much as 5-10%, -than "wq fast"; however, it may not feel faster, because the sound -will lag.) - -Finally, you can use - -wq max - -which is the same as wq fast, but turns on DirectInput, which -provides more responsive mouse control, but does not work properly -on all systems. - -Note that DirectX is not required for WQ to run, but WQ will -automatically take advantage of DirectSound and DirectDraw if they -are present. If DirectSound is not present, there will generally be -considerable sound latency (sound will become audible several hundred -milliseconds after the event that caused it). Note also that there -are currently no true DirectSound drivers for Windows NT, so WQ will -always run using wave output on NT, and will consequently have lagged -sound. See below for information about obtaining DirectX if you do -not have it. - -Note that VESA VBE modes aren't required for WQ to run, but WQ will -automatically make VESA modes available if they're present. Your BIOS -may already have VESA VBE 2.0 support built in, but most BIOSes -don't. Worse, some BIOSes do have VESA VBE 2.0 built-in, but have -buggy implementations, which may prevent you from being able to run -the faster configurations of WQ. An easy way to get reliable VESA 2.0 -support is by obtaining SciTech Display Doctor; see below for -further information. WQ can also use VBE/AF 1.0 and greater modes; -again, SciTech Display Doctor is the commonest way to get VBE/AF -support. - -Note that winquake -dedicated completely replaces the old winded -dedicated Win32 server, which is now obsolete. - -WinQuake normally uses half the physical memory in your system for its -heap, but not less than 8.5 Mb and not more than 16 Mb. You can -override this with "-heapsize n", where n is the amount of memory to -allocate for the heap, in Kb. - -To use the joystick, you must bring down the console by pressing the -tilde ('~') key, and type "joystick 1"; you can disable the -joystick with "joystick 0" at any time. The joystick setting -remains in effect for subsequent WinQuake sessions until changed, so -you only need to do joystick 1 once to enable the joystick. If the -joystick somehow causes problems that keep you from being able to run -WinQuake at all, you can start WinQuake -nojoy to complete disable the -joystick for that session. - - ------------------------------------ -| Common problems and workarounds | ------------------------------------ - -WQ crashes or won't run ------------------------ - -If WQ refuses to run or crashes on your system, try running -it using "wq safe" or "wq verysafe". Or you can use command-line -switches: - -winquake -nodirectdraw -nowindirect -wavonly - -This will almost certainly solve your problem; however, it may result -in lagged sound (a long delay from action to hearing the sound), may -result in fewer or slower high-res video modes, and the mouse may be -somewhat less responsive. If this does work, you can try removing -each of the command-line switches until you identify the one that -fixes the problem, thereby sacrificing as little functionality as -possible. - -If the above command line does not fix your problems, try: - -winquake -dibonly -nosound - -which forces WQ into silent operation with bare-bones video support -and no use of DirectInput for mouse input (the normal Windows mouse -APIs are used instead). Again, if this works, try removing switches -until you identify the needed one. - -Both of the above command lines are quick fixes. Often, the problem -is caused by outdated or buggy DirectX drivers or code, and can -frequently be completely fixed simply by installing the latest -Microsoft-supplied version of DirectX, which you may be able to find -on http://www.microsoft.com/mediadev/download/directx.exe, although -the availability and location of the DirectX file changes -periodically; note that at last check, this is a 3.4 Mb file. (Be -aware, though, that sometimes Microsoft's DirectX drivers don't -support features that the manufacturers' drivers do support, such as -display refresh rate control.) - -One known problem of this sort involves the current SB16 drivers from -Creative Labs, which cause WQ to crash on some machines. The -DirectSound drivers from Microsoft, available via the above-mentioned -URL, fix this problem. - -It can also sometimes help to get the latest Windows drivers for your -video adapter or sound card (although as the SB16 example indicates, -this is not always a good idea), and for video boards that have flash -BIOSes, it can sometimes help to get the latest BIOS upgrade. - - -How do I select fullscreen or windowed WQ operation? ----------------------------------------------------- -Check out WQ's new, spiffy Video menu, accessible from the Options -menu. There are now two types of modes listed, windowed and -fullscreen. You can make any of these modes the current and/or -default mode, just as in DOS Quake. If you make a windowed mode the -default, WQ will still briefly start up in fullscreen mode, then -switch to windowed; if this is a problem, use the -startwindowed -command-line switch. More complete video control is available -through the console, as described in the "A bit about how WQ video -works" section, below. - - -Gee, I wish I could use a mouse to play WQ with in a window ------------------------------------------------------------ -You can! While in a windowed mode, go to the Options menu. At the -bottom, you'll find a new selection that lets you choose to have the -mouse active when you're in a window. Of course, if you do this, -you'll have to use the keyboard (Alt-Tab, the Windows key, Ctrl-Esc, -Alt-Esc, or Shift-Alt-Tab) to switch away from WQ. - - -Serial/modem menu is missing ----------------------------- -WQ currently does not support direct connect serial or modem play. - - -DOS Quake reports unknown variables on startup after running WQ ---------------------------------------------------------------- -WQ uses some console variables that do not exist in DOS Quake, and -some of these are automatically archived in config.cfg when you exit -WQ. If you then start DOS Quake, DOS Quake will complain that it -doesn't recognize those variables. You will also lose the settings -of these variables when you return to WQ. Apart from losing the -settings, this is harmless; ignore it. - - -Problems running WQ on NT 3.51 ------------------------------- -NT 3.51 isn't supported by WQ. - - -WQ crashes while switching modes or Alt-Tabbing ------------------------------------------------ -So far, all cases of this seem to be tied to Creative Lab's SB16 sound -drivers, and have been fixed by getting the latest DirectX drivers, as -described above. Alternatively, you should be able to fix this either -by not switching modes or Alt-Tabbing, or by running -wavonly to -disable DirectSound support. - - -WQ sometimes runs pretty slowly fullscreen ------------------------------------------- -There are several possible reasons for this, starting with "You have a -slow computer." Assuming that's not the case, if you don't have -either DirectDraw or SciTech Display Doctor installed (see the "A bit -about how WQ video works" section), it would probably be a good thing -to install one or the other, because slow operation can be a result -of slow copying or stretching of pixels to the screen by a Windows -driver, something that's eliminated by both DirectDraw and Display -Doctor. You can also sometimes get a faster 320x200 mode on Win95 by -doing vid_describemodes, then using vid_mode to select a non-VGA -320x200 mode, as described in the "A bit about how WQ video works" -section. - -You can also try using a primary sound buffer on Win95 (this doesn't -work on NT) by using the -primarysound command-line switch; this can -improve performance by several percent, but does not work on all -systems, and can result in odd sound effects on some systems when -minimizing WQ or switching the focus away from it. If you use this -switch, please don't report sound bugs; it's in there purely for you -to use if it helps you, and we know it has problems on many systems. -Finally, you can use -wavonly to select wave sound; this will increase -your sound latency (sounds will be heard later than they should), but -allows WQ to run 5-10% faster on some systems. That's about all you -can do to speed up fullscreen WQ on Win95, other than shrinking the -active area of the screen with the screen size control in the Options -menu. - -NT 4.0 comes with DirectX installed, but doesn't have any resolutions -lower than 640x480. In order to support a lower-resolution 320x240 -mode, WQ has NT double each pixel in both directions to get enough -pixels for 640x480. The extra stretching costs some performance, the -result being that NT can seem sluggish on all but high-end Pentiums -and Pentium Pros. (In fact, depending on the quality of your driver's -stretching code, it can sometimes be faster to run WQ at 640x480 than -320x240-stretched on NT.) One thing that can help on NT is switching -to 640x480, then using the Options menu to shrink the active area of -the screen. - -A common cause of slowness running in a window is having the desktop -run in 16- or 32-bpp mode. WQ is an 8-bpp application, and it slows -things down if pixels have to be translated from 8-bpp to 16- or -32-bpp. (Note that this is generally a problem only when running in a -window; fullscreen apps rarely suffer from this.) - - -Sound is sluggish on NT ------------------------ -NT doesn't have any real DirectSound drivers yet, so there's no way to -do quick-response sound on NT. When DirectSound drivers for NT -appear, WQ's sound should automatically be snappier. - - -Sound breaks up or gets choppy, especially in menus ---------------------------------------------------- -This is generally a sign that WQ's frame rate is too low on your -system. Try reducing resolution or shrinking the active area of the -screen. In some circumstances, it may help to set the console -variable _snd_mixahead to a larger value. - - -The color black doesn't change with palette flashes sometimes -------------------------------------------------------------- -Normally, DirectDraw lets WQ change all 256 colors, so when a palette -flash happens, we can change all the colors, including black. -However, on NT DirectDraw currently doesn't allow changing black; -likewise, on both NT and Win95, black can't be changed in a window, -either a normal window or fullscreen. Consequently, in some modes and -in a window, some parts of the WQ screen (such as the sigils on the -status bar and the spray where a shotgun blast hits) stay black when -the palette flashes. There is no workaround. - - -Problems can result if Office shortcut bar is running ------------------------------------------------------ -Various odd behaviors, especially with sound, have been reported if -the Office shortcut bar is running while WQ is running. If you -experience odd problems, you might try shutting down the Office -shortcut bar and see if that fixes anything. - - -Other apps fail to play sound while WinQuake is running -------------------------------------------------------- -The sound hardware is currently not a fully shareable resource on -Win32. Consequently, while WQ is running, it always has the sound -hardware allocated to itself, to make sure that sound is never lost to -another app. This means that normally (when WQ is using DirectSound), -apps that use wave sound (most non-game apps) will not be able to play -sound while WQ is running, even if WQ is minimized or not the active -app, although other DirectSound apps will be able to play sound when -WQ is not the active app. If WQ is using wave sound rather than -DirectSound (either because -wavonly is used on the command line, or -because there is no DirectSound driver, as is always the case on NT), -then no other app will be able to play any sound while WQ is running, -period. - - -WQ doesn't have quite the right colors when it’s not the active app -------------------------------------------------------------------- -We're working on fixing this. But WQ puts everything back again as -soon as it is reactivated, and anyway, when it’s not active, you can’t -actually do anything in WQ, so it doesn’t really matter anyway, right? - - -Desktop is weird colors when WQ runs windowed ---------------------------------------------- -WQ needs all 256 colors to look right and run fast, which causes it to -have to change some of the 20 colors used to draw the desktop. - - -Sometimes Permedia boards crash unless -nowindirect is used ------------------------------------------------------------ -It looks like this is probably a Permedia driver bug, so it might help -if you get the most recent drivers. - - -Right-click on WQ button in task bar to close doesn’t work as expected ----------------------------------------------------------------------- -In some modes, right-clicking on the WQ task bar button doesn't work -the way you'd expect. We're trying to fix this, but if it's a -problem, don't right-click. - - -Screen saver never kicks in when running WQ fullscreen ------------------------------------------------------- -It does work windowed, but when WinQuake is fullscreen, it completely -owns the screen and doesn't share it with anyone, even the -screensaver. If you use Alt-Tab to minimize WQ, the screensaver will -then be enabled, so Alt-Tab away from WQ if you're leaving your -computer alone for a while and want the screensaver to be able to kick -in. - - -WQ doesn’t work in a window in 16-color mode --------------------------------------------- -That’s 16 *colors*, not 16-bpp. If you’re still running a 16-color -desktop, run WQ fullscreen. - - -Can't minimize window while mouse active ----------------------------------------- -When running in a window with the mouse active as a WQ input device, -there is no easy way to minimize the window, because the system menu -can't be brought up from the keyboard (because some of you use Alt -and Spacebar for playing the game), and the mouse can't be used to -manipulate the window because it's controlling WQ. To minimize, you -can disable the mouse for WQ and use it to minimize the window. Or -on Win95 you can Alt-Tab away from WQ, then use the mouse to -minimize (this doesn't work on NT, where clicking on the window -controls just reactivates WQ). Or you can bind a key to the -vid_minimize command, as in - -bind m "vid_minimize" - -and press that key to minimize the window. - - -Window controls don't work on NT when mouse enabled ---------------------------------------------------- -When running in a window on NT with the mouse enabled (so you can use -the mouse to play WQ), if you Alt-Tab away from WQ, then use the mouse -to click on the WQ system menu control, or the minimize, maximize, or -close controls, the controls are ignored and WQ just reactivates. - - -Mouse sometimes vanishes in system menu on Win95 ------------------------------------------------- -On Win95, if WQ is running in a window with the mouse enabled (so you -can use the mouse to play WQ), if you Alt-Tab away, then click on the -system menu, the menu comes up, but the mouse vanishes. However, you -can still use the keyboard to select system menu items, or to exit -the system menu. - - -WQ behaves oddly if Scandisk starts defragmenting -------------------------------------------------- -If WQ is running fullscreen on Win95 when Scandisk starts an automatic -defragging, WQ is forced to minimize, and when it is brought back up, -may either be in a strange mode where it runs one frame for each -keystroke (in which case Alt-Tab generally fixes things), or may hang -the system. We don't know what the problem is right now, but you may -want to make sure you don't leave WQ sitting there fullscreen -overnight if you have automatic defragging. - - -Hang reported with zero sound volume ------------------------------------- -When sound is turned all the way down via the WQ menus, hangs have -been reported. - - -Joystick worked fine with earlier versions of WinQuake but not now ------------------------------------------------------------------- -The joystick was enabled by default in earlier versions of -WinQuake, but quite a few people reported serious problems that -forced them to disable the joystick--even some people who didn't -have a joystick attached. Since most people don't have joysticks, -we've decided to disable the joystick by default, and let people -who do want to use it set joystick 1 in the console (WinQuake -remembers this setting, so this only needs to be done once). - - -WQ runs very slowly when it has the focus under NT --------------------------------------------------- -In one case, WQ ran very slowly when it had the focus, but fast when -it didn't (obviously this is only visible in windowed modes). The -problem turned out to be that NT had a Sidewinder 3D Pro joystick -driver installed; when the driver was removed, things were fine. -If you see a similar problem, check whether WQ is detecting that -your system has a joystick when you don't think it should; if so, -try doing "joystick 0", or -nojoy on the command line, and see if -that fixes it. If so, there's something flaky in your system -joystick setup. - - -Joystick doesn't seem calibrated properly ------------------------------------------ -WQ relies on the information about your joystick stored in the -system registry. If the joystick seems miscalibrated, run the -joystick applet and recalibrate and see if that fixes things. - - -Playdemo fails across multiple levels -------------------------------------- -If "record" is used to record a client-side demo, bad things will -happen on playback via playdemo if a level change is recorded. -(Timedemo works fine.) This is unfortunate, but WinQuake -internals make this not fixable without a good chance of -breaking something more important, so it'll have to stay this way. - - -Alt-Tab fullscreen only works sometimes ---------------------------------------- -I know it seems that way, but actually the trick is that on Win95 -it only works if you let go of Tab before you let go of Alt. -This is due to a Windows quirk involving what key sequences are -passed along, so you'll have to work around it by remembering to -let go of Tab first. - - -MS-DOS windows get scrunched on Alt-Tab ---------------------------------------- -This is a quirk of Windows; when you run WinQuake in a low-res -mode, sometimes when you exit WinQuake or Alt-Tab back to the -desktop, any open MS-DOS windows will be scrunched down to the -size of the low-res mode. There is no known workaround. - - -Dprint in progs doesn't work ----------------------------- -Dprint means "developer print," so it only works if the developer -console variable is set to 1. It was a bug in earlier versions that -it worked even when developer was set to 0. - - -Some DirectDraw modes flicker badly and look wrong --------------------------------------------------- -Page flipping doesn't work properly in some modes on some -systems, particularly when using some DirectDraw modes. You -can work around this by setting the console variable -vid_nopageflip to 1, then setting the desired mode (note -that the vid_nopageflip setting does not take effect until -the next mode set after the setting is changed). Bear in -mind, though, that the vid_nopageflip setting is remembered -until it is explicitly changed again, meaning that once you -change it, it thereafter applies to all modes, even if you -exit and restart WinQuake. - - -The Windows key doesn't do anything fullscreen on Win95 -------------------------------------------------------- -True. This is a minor bug we haven't figured out how to fix yet. -You'll have to use Ctrl-Esc, Alt-Tab, or Alt-Esc to switch away. - - -My default mode is windowed, but WQ goes fullscreen first ---------------------------------------------------------- -For internal reasons, WQ has to pick a single mode to always -initialize when it starts up, before it sets whatever default you've -selected. We've chosen fullscreen mode, because that's the way most -people will play. If this is a problem for you, however, you can -run WQ with the -startwindowed command-line parameter. - - -Some high-resolution video modes flicker or fail to initialize --------------------------------------------------------------- -We think these problems are all fixed, but if not, they have to -do with triple-buffering in some modes on some DirectDraw drivers. -If you encounter this problem, either don't use the problem modes -or try using the -notriplebuf command-line parameter to turn off -triple buffering. Note, though, that turning off triple-buffering -can reduce performance in some modes, so do this only if needed. - - -Right-click doesn't work right on minimized WinQuake ----------------------------------------------------- -If you right-click on minimized WinQuake on the task bar, the -Close selection in the right-click menu doesn't work; you have -to restore WQ before you can exit it. Also, the cursor vanishes -over the right-click menu, although it still works. - - -The screen briefly blanks when you exit WQ ------------------------------------------- -We're trying to fix this, but it's not harmful, just a mite ugly. - - -QBENCH doesn't work with WinQuake ---------------------------------- -We've had a report that QBENCH doesn't work with WinQuake, but -haven't had a chance to look into it yet. - - -MWAVE sound loses focus ------------------------ -We've had a report that on a ThinkPad with MWAVE sound, WQ loses -sound focus (and thus sound) every few seconds. - - -Desktop doesn't reset to proper resolution on WQ exit ------------------------------------------------------ -We've had a report that on exiting WQ, the desktop didn't reset -to the proper dimensions. This may be a bug with the Matrox -drivers, but we're not sure. If it's a problem and newer -drivers don't fix it, you can run -dibonly, which solves the -problem but can cost some performance. - - -Palette goes bad periodically on #9 Imagine card ------------------------------------------------- -There's only one report of this, so maybe it's a flaky board, -or maybe it's a driver bug. Newer drivers might help. - - -System with Packard Bell sound card III crashes on CapsLock ------------------------------------------------------------ -This appears to be the result of buggy DirectSound drivers; --wavonly makes the problem go away. - - -Dvorak keyboard mapping ignored -------------------------------- -WQ is hardwired for QWERTY. - - -Cursor messed up after running WQ ---------------------------------- -This is a Windows driver bug; the driver isn't restoring the -cursor properly on return from fullscreen WQ to the desktop. -Try newer drivers. - - -Dedicated server runs very slowly while typing at console ---------------------------------------------------------- -When you type at a dedicated server's console, the game runs -very slowly for everyone who's connected. - - -Ctrl-Alt-Del on NT sometimes doesn't allow return to WQ -------------------------------------------------------- -This happens on some machines while running WQ fullscreen. -If you experience this problem, the only workaround is not -to press Ctrl-Alt-Del while fullscreen; Alt-Tab away first. - - -Many fast Alt-Tabs on Win95 sometimes disable WQ input ------------------------------------------------------- -If you Alt-Tab fast lots of times on Win95 with WQ running -fullscreen, sometimes you end up in fullscreen WQ, with the -game not accepting any keyboard input (so there's no way to -exit). The only workaround is to not do lots of fast -Alt-Tabs (why you'd want to, I'm not sure). - - - ----------------------------------- -| A bit about how WQ video works | ----------------------------------- - -WQ has the built-in ability to draw into windows (both normal, framed -desktop windows and fullscreen, borderless windows). It also has -built- in support for VGA 320x200 graphics, and supports DirectDraw, -VESA VBE 2.0 and VESA VBE/AF (Accelerator Functions) graphics modes, -if those are available. - -WQ does not require DirectDraw, but in order for DirectDraw modes to -be available, you must have DirectDraw installed; some systems come -with it preinstalled, but if it's not on your system, you can download -it from http://www.microsoft.com/mediadev/download/directx.exe (the -exact URL may vary), and install it. - -WQ does not require VESA VBE, but in order for VESA VBE modes to be -available, your graphics card must be VESA VBE 2.0 or VBE/AF -compliant; a VESA driver can either be built into the BIOS of your -graphics card, or loadable via software. If you don't have a VESA VBE -driver, Scitech Display Doctor, available from Scitech Software, will -update most graphics cards to VESA VBE 2.0 and VBE/AF. - - -SciTech Display Doctor ----------------------- -If you are having problems with your video drivers, or if you would -like to take a shot at improving your video performance in WQ, you may -want to try out SciTech Display Doctor (SDD). SDD works on just about -any graphics card and it can do several things that can make WQ run -better on your system: - -1. It will update your graphics card to be compatible with VESA VBE -2.0 and VESA VBE/AF (Accelerator Functions). These modes will usually -give you the best performance in WQ (which is often but not always -faster than your current performance). - -2. It creates low-resolution modes on your graphics card. -Low-resolution video modes (such as 320x240, 400x300 and 512x384) -allow you to adjust the level of detail in WQ so you can get the best -balance between performance and image quality. - -The latest version of SciTech Display Doctor can be obtained from the -following locations: - -www: http://www.scitechsoft.com -ftp: ftp.scitechsoft.com -CIS: GO SCITECH -AOL: Keyword SciTech - -SciTech can be contacted at: - -email: info@scitechsoft.com - -SciTech Software, Inc. -505 Wall Street -Chico, CA 95926-1989 -916-894-8400 -916-894-9069 FAX - - -Video modes supported in Win95 ------------------------------- -What all this means is that on Win95, WQ will always be able to run in -the following modes: - -1) in a window -2) fullscreen 320x200 VGA mode 0x13 -3) fullscreen high-resolution of some sort - -Category #3 can be any of several configurations. On Win95, if either -DirectDraw or VESA VBE modes are available, then all the DirectDraw -and VESA modes will be presented as high-res choices. (320x200 will -always default to VGA mode 0x13.) In the case that a given resolution -is supported by both DirectDraw and VESA, the VESA mode will be used. -(However, the command-line switch -nowindirect can turn off VESA modes -entirely.) If neither DirectDraw nor VESA modes are available, then -high-resolution modes will be provided by using fullscreen, borderless -windows in whatever resolutions the Windows driver supports, usually -starting at 640x480 and going up. - - -Video Modes Supported in Windows NT ------------------------------------ -NT is similar but not identical, because neither VESA VBE modes nor -VGA mode 0x13 are available. On NT, WQ will always be able to run in -the following modes: - -1) in a window -2) fullscreen high-resolution of some sort - -On NT, category #2 can be one of two configurations. If DirectDraw -modes are available, then those will be the high-res choices; -otherwise, fullscreen, borderless windows will be used in whatever -resolutions the driver supports, usually starting at 640x480 and going -up. Because there is normally no low-resolution mode such as 320x200 -or 320x240 on NT, a pseudo low-res mode is created by rendering at -320x240, then stretching the image by doubling it in each direction -while copying it to a 640x480 screen. However, stretching performance -depends on the driver, and can be slow, so sometimes 640x480 is -actually faster than 320x240 on NT. - -The bottom line here is that you can generally just use the Video menu -and pick one of the modes and be happy. In some cases, though, you -may need to use command-line switches (described next) to get the -types of modes you want. One useful tip is to go into the console and -do vid_describemodes, which lists all the modes WQ makes available on -your machine given the command-line switches you've used. Each mode -is followed by the name of the internal WQ driver that supports it, so -you can tell which modes are DirectDraw, VESA, and so on, as follows: - -WINDOWED: WQ runs in a normal window -FULLSCREEN DIB: fullscreen borderless window -FULLSCREEN VGA8.DRV: VGA 320x200 mode -FULLSCREEN DDRAW8.DRV: DirectDraw mode -FULLSCREEN LINEAR8.DRV: VESA VBE 2.0+ mode -FULLSCREEN ACCEL8.DRV: VESA VBE/AF (Accelerator Functions) mode - (note that WQ does not take advantage of - VBE/AF acceleration; so far as WQ is - concerned VBE/AF is the same as normal VBE) - -You can use vid_mode from the console to set any of these modes. So, -for example, if you see that there are two 320x200 modes (such as one -VGA mode 0x13, normally mode 3, and one VESA mode, normally mode 4), -you can choose the VESA mode, which will often be faster, with -vid_mode 4. (You can make it the default by setting -_vid_default_mode_win to the mode number.) - -There's more to the windowed modes than you might think. 320x240 is -just what you’d expect, but 640x480 is actually rendered at 320x240 -and stretched up to 640x480, because most machines can’t handle the -performance demands of real 640x480 rendering. Likewise, 800x600 is a -stretched 400x300. Actually, though, vid_mode 2 (the 800x600 mode) is -a user-configurable mode. By setting the following console variables, -you can change the characteristics of vid_mode 2: - -vid_config_x: width of mode 2 window - -vid_config_y: height of mode 2 window - -vid_stretch_by_2: whether to render at half-resolution in each -direction and stretch up to the specified size in mode 2, or render at -full resolution. - -After setting these variables in the console, do a vid_forcemode 2, -and you’ll have the window you specified. Note that after making -these changes, the new resolution will show up as the third windowed -mode in the Video menu. - -If you don't have WQ mouse play enabled in windowed mode, you can also -go from windowed to fullscreen mode simply by clicking on the maximize -button. The mode switched to is controlled by the vid_fullscreen_mode -console variable, and defaults to mode 3. - -Other video console commands include: - -vid_fullscreen: switch to the mode specified by the -vid_fullscreen_mode console variable. - -vid_windowed: switch to the mode specified by the vid_windowed_mode -console variable. - -Vid_fullscreen and vid_windowed can be bound to keys, so it's possible -to flip between windowed and fullscreen with a single key press. - -Also, vid_minimize minimizes the WinQuake window if and only if -WinQuake is running in a windowed mode. You can bind a key to -the commands "vid_windowed; wait; vid_minimize" to minimize WQ -regardless of whether you're running in windowed or fullscreen mode. - -You can turn off page flipping by setting the console variable -vid_nopageflip to 1, then setting a new mode. (Note that the -vid_nopageflip setting does not take effect until the next mode set.) -Some systems run faster with page flipping turned off; also, page -flipping does not work properly on some adapters, and vid_nopageflip -is a workaround for this. Note that vid_nopageflip is a persistent -variable; it retains its setting until it is explicitly changed again, -even across multiple WinQuake sessions. - -The vid_forcemode console command sets the specified mode, even if -it's the same as the current mode (normally the mode set only happens -if the new mode differs from the current mode). This is generally -useful only if you've modified the characteristics of video mode 2 -(the configurable window) while you're in mode 2, and want to force -the new characteristics to take effect. - -Whenever you switch to running WinQuake in a window, the window is -placed at the same location it was in the last time WinQuake ran -in a window. You can reset the window position to the upper left -by using the -resetwinpos command-line switch. The window position -is stored in the vid_window_x and vid_window_y console variables. - - - -------------------------------- -| Video command-line switches | -------------------------------- - -The full list of video-related command-line switches is: - --dibonly: WQ will use only windows (both normal, framed windows on the -desktop and fullscreen, borderless windows), not any direct hardware -access modes such as DirectDraw or VESA modes, or even VGA 320x200 -mode. This is the closest thing to a guaranteed-to-run fullscreen -mode WQ has. - --nowindirect: WQ will not try to use VESA VBE 2.0 modes, or VBE/AF -1.0 or later modes. Note that if there are both DirectDraw and VESA -modes for a given resolution, WQ will normally use the VESA mode; --nowindirect allows DirectDraw modes to be the preferred choice for -all resolutions except 320x200. This can be useful if WQ is crashing -because of a buggy VESA driver. - --nodirectdraw: WQ will not try to use DirectDraw modes. This can be -useful if WQ is crashing because of a buggy DirectDraw driver. - --novbeaf: WQ will not try to use VBE/AF 1.0 or later modes. - --startwindowed: WQ will come up in a windowed mode, without going -fullscreen even during initialization. - --noforcevga: normally, WQ uses VGA mode 0x13 for the default 320x200 -mode, even if a DirectDraw or VESA 320x200 mode exists. However, -DirectDraw and VESA modes can be considerably faster than mode 0x13, -because they can set up a linear framebuffer with higher memory -bandwidth. If you specify -noforcevga, the default 320x200 mode in -the menu will be a DirectDraw or VESA mode if one exists. This has no -effect on modes selected via the console variable vid_mode, and if -320x200 is already your video mode, -noforcevga doesn't do anything -until you use the menu to select another mode, then select 320x200 -again. (So if your default mode is 320x200 and you then specify --noforcevga, switch away to some other mode and then back to 320x200 -to get the potentially faster 320x200 mode.) The downside to this -switch is that DirectDraw and VESA modes can cause problems in some -systems, due to driver bugs or hardware incompatibilities; if you -experience problems with this switch, don't use it. - --noautostretch: don't stretch windowed modes selected with --startwindowed to double resolution. - --nofulldib: don't use fullscreen, borderless windows, even if there -are no DirectDraw or VESA modes available. - --allow360: allow listing of 360-wide modes in the video mode menu. -These are normally filtered out to make sure the menu doesn't get too -full, which could cause high-res modes not to be displayed. - --notriplebuf: prevent triple-buffered page flipping (rather than double- -buffered). This may result in slower performance, but is a workaround -if you encounter problems with flicker or initialization failure, which -could possibly happen in some modes with some DirectDraw drivers. - - - ----------------------------------- -| A bit about how WQ sound works | ----------------------------------- - -WQ can use either DirectSound or Windows wave output to generate -sound. If DirectSound is available, it is used; if not, if wave sound -is available it is used; and if neither is available, there is no -sound. DirectSound results in the best sound quality, and also the -lowest-latency sound; use it if you can, because you will be happier -with the results. (Note, though, that no NT sound drivers yet support -DirectSound.) Wave sound will often have high latency, lagging the -events that generate sound by hundreds of milliseconds on some -machines. - -You can tell what kind of sound WQ uses on your system by looking at -the startup portion of the console; you will see either "DirectSound -initialized" or "Wave sound initialized" (neither message is printed -if there's no sound). Any sound failure messages will also be printed -in the startup portion of the console. - -Note that WQ generates sound only when it is the active app, the one -with the input focus. - - - -------------------------------- -| Sound command-line switches | -------------------------------- - -The full list of sound-related command-line switches is: - --wavonly: don’t use DirectSound, but use wave sound if available. -Note that wave sound is generally faster than DirectSound, but has -considerably greater latency. This switch is redundant on NT, because -all sound output on current NT drivers is wave sound. - --nosound: don’t output any sound. - --primarysound: use DirectSound primary buffer output. This is -generally faster than normal secondary buffer output, but does not -work in some systems, and produces odd sound glitches on minimization -and focus switching in other systems. Use it at your own risk, and -please do not report sound bugs if you're using this switch. - --snoforceformat: WQ will not try to force the sound hardware to 11 -KHz, 16 bits per sample. This may be useful if DirectSound is failing -for no apparent reason, but generally WQ will produce better sound and -better performance if this switch is not used. - - - ------------------------ -| Notes on networking | ------------------------ - -The winsock TCP/IP driver will not cause a dial-up internet connection -to automatically start up when Quake is started. If you start Quake -with it inactive, the connection will be activated when you either try -to connect to a server or search for local servers. - -The local IP address will not always be known at startup. If it is -currently unknown the menu will display "INADDR_ANY". This will be -replaced with the real address when it is known. The IP address will -become known when you try to connect to a server, you search for local -servers, or you start a server. - -For multi-homed machines (machines with more than one network adapter -and IP adress), you can force WinQuake to bind to a specific IP -address. There is a command line option "-ip" that takes an IP -address as its parameter. - - - ----------------------- -| Notes on the mouse | ----------------------- - -If DirectInput is installed and functioning, WinQuake can use it for -mouse input, but does not do so automatically because DirectInput does -not work properly on all systems. DirectInput can be enabled via the -command-line switch -dinput. If DirectInput is not available or is -not enabled, WinQuake uses the normal Windows mouse APIs instead. -DirectInput provides slightly smoother motion; also, it tends to be -more responsive to fast spinning motions, and we recommend that you use -it if it works properly on your system. You can determine if WQ uses -DirectInput on your system when you use -dinput by checking for -"DirectInput initialized" in the startup console text. If not, you -might try installing DirectX 3 (note, though, that as I write this -there is no released DirectInput support for Windows NT, only Win95). - - - ------------------------------------ -| Log of changes to documentation | ------------------------------------ - -*** WinQuake 0.994 *** - -Fixed bug where in some cases involving IPX, whenever a new person -entered the game, a current player got dumped. - -Added DirectInput mouse support, and the -dinput command-line to -enable it. - -Added -notriplebuf to disable triple buffering to work around -possible problems with some modes on some DirectDraw drivers. - -Added remembering last window position, and restoring that, rather -than centering the window, whenever WinQuake runs in a window. -Can be reset with the -resetwinpos command-line switch. - -Added the vid_minimize command, which minimizes WinQuake if and only -if the current mode is windowed. - -Made it so WinQuake no longer gets suspended when Alt-Tab is used to -switch away from a fullscreen session. The means you can Alt-Tab -away from fullscreen WinQuake without losing a connection to a -Quake server. - -Added vid_nopageflip console variable to turn off page flipping, and -documented page flipping problems this can be used to work around. - -Documented that Del-Ctrl-Alt (in that order) causes WinQuake to -fault on Win95. - -Fixed the winsock TCP/IP driver so it will not cause a dial-up -internet connection to automatically start up when Quake is started. -If you start Quake with the internet connection already active, there -will be no difference. If you start Quake with it inactive, the -connection will be activated when you either try to connect to a -server or search for local servers. - -The local IP address will not always be known at startup now. If it -is currently unknown the menu will display "INADDR_ANY". This -will be replaced with the real address when it is known. The IP -address will become known when: you try to connect to a server, -you search for local servers, or you start a server. - -For multi-homed machines (machines with more than one network -adapter and IP adress), you can now force WinQuake to bind to a -specific IP adress. There is a new command line option "-ip" that -takes an IP address as its parameter. - -Added vid_fullscreen_mode and ability to select that mode by -clicking on the maximize button. Added two commands: -vid_fullscreen to switch to vid_fullscreen_mode, and -vid_windowed to switch to vid_windowed mode. - -Changed joystick default to disabled; now it only works if the -joystick cvar is set to 1; however, this setting now remains in -effect permanently. Added joystick documentation below. - -Documented dprint only works if developer set to 1. - -Documented scrunching of MS-DOS windows on Alt-Tab. - -Documented that NT versions earlier to 4.0 are not supported. - -Added DirectInput support for devices such as First Person -Gaming's Assassin controller. All buttons should now -be configurable in WinQuake. - -Fixed bug where when low-res fullscreen DIB modes selected from -the menu sometimes ran very slowly or produced garbled displays. - -Fixed bug where 1.06 and earlier save files couldn't be loaded -by WinQuake. - -Removed "Net play pauses every few seconds" bug; it was determined -not to be a bug, just an artifact of network play. - -Noted that even when BIOSes do have VESA 2.0 built-in, it's often -so buggy that WinQuake crashes in faster configurations, and that -SciTech Display Doctor is the easiest way to get reliable VESA -support. - -Added note on Alt-Tab only working if Tab released first. - - -*** WinQuake 0.992 *** - -Implemented force_centerview. - -Fixed backspace bug in dedicated console. - -Made "player entering game" messages and "say" messages visible -in dedicated console. - -Added description of -heapsize (how to change default memory -allocation). - -Added description of "net play pauses every few seconds" bug. - -Added description of "playdemo fails across multiple levels" bug. - -Added hooks for QHost; however, WinQuake won't work with QHost -until a new version of QHost 3.0, which uses the hooks, is -released. QHost 3.0 will not work with WinQuake. - -Fixed bug where savegame descriptions weren't always terminated -properly. - -Fixed bug where running -dedicated reset part of config.cfg to -defaults. - - -*** WinQuake 0.991 *** - -Fixed problem with pre-1.07 (DOS) clients connecting to WinQuake. - -Got rid of "Starting Quake..." dialog when running -dedicated. - -Added -novbeaf switch to turn off VBE/AF support in case of problems, -and updated documentation. - -Corrected SciTech's U.S. Mail address in documentation. - -Added joystick bug decriptions and workarounds. - - - ------------------- -| Special thanks | ------------------- - -Special thanks for help with WinQuake to: - -James Barnes -Kendall Bennett -Raymond Chen -John Colleran -Andrew Goossen -Mike Harrington -Chris Hecker -Todd Laney -Scott Ludwig -...and all the beta testers! - -====================================================================== -End of Document 3/21/97 -====================================================================== diff --git a/engine/docs/COMEXP.TXT b/engine/docs/COMEXP.TXT deleted file mode 100644 index 06bc4af..0000000 --- a/engine/docs/COMEXP.TXT +++ /dev/null @@ -1,487 +0,0 @@ - COMMERCIAL EXPLOITATION LICENSE AGREEMENT FOR QUAKE - - This Commercial Exploitation License Agreement for QUAKE -(the "Agreement") is between Id Software, Inc., a Texas -Corporation, (hereinafter "Id Software") and Licensee (as described -on the signature page hereof) and is made effective beginning on -the date of last signature hereto (the "Effective Date"). - - R E C I T A L S - - WHEREAS, Id Software is the owner and developer of the -computer software game entitled QUAKE; - - WHEREAS, Id Software desires to license certain -non-exclusive rights regarding QUAKE to Licensee; and - - WHEREAS, Licensee desires to receive a license for such -rights. - - T E R M S A N D C O N D I T I O N S - - NOW, THEREFORE, for and in consideration of the mutual -premises contained herein and for other good and valuable -consideration, the receipt and sufficiency of which is hereby -acknowledged, the undersigned parties do hereby agree as follows: - - 1. DEFINITIONS. As used in this Agreement, the parties -hereto agree the words set forth below shall have the specified -meanings: - - a. "Authorized Copy" shall mean one (1) copy of the - Subject Game actually purchased by Licensee from an - Id Software approved retailer; and - - b. "Subject Game" shall mean the full registered - version of QUAKE on a CD-ROM and shall not mean the - shareware or any other version. - - 2. GRANT OF RIGHTS. Id Software hereby grants to -Licensee and Licensee hereby accepts, subject to the provisions and -conditions hereof, a world-wide (except as otherwise provided -herein), non-exclusive, non-transferable, and non-assignable -license to: - - a. publicly display an Authorized Copy in exchange for - rental payment; - - b. run the Authorized Copy so that it will accept - network/modem connections in exchange for payments - from end-users who also must have actually purchased - an Authorized Copy; and - - c. otherwise commercially exploit an Authorized Copy, - except that Licensee shall not copy, reproduce, - manufacture or distribute the Authorized Copy. - - 3. RESERVATION OF RIGHTS AND PROHIBITIONS. Id Software -expressly reserves all rights not granted herein. Under no -circumstances shall Licensee copy, reproduce, manufacture or -distribute (free of charge or otherwise) the Authorized Copy or the -Subject Game. Licensee shall not reverse engineer, decompile, -disassemble, modify or alter the Authorized Copy. Licensee is not -receiving any rights hereunder regarding the Trademark or any -artwork, sound, music or other element of the Subject Game. - - 4. OWNERSHIP. Title to and all ownership rights in and -to the Subject Game, and the QUAKE Trademark (the "Trademark") and -the copyrights, trademarks, patents and other intellectual property -rights related thereto shall remain with Id Software which shall have -the exclusive right to protect the same by copyright or otherwise. -Licensee shall have no ownership rights in or to the Subject Game or -the Trademark and Licensee shall not own any intellectual property -rights regarding the Authorized Copy, including, without limitation, -the copyright regarding the Authorized Copy. Licensee acknowledges -that it only has a limited license to use the Authorized Copy, as -specified in that certain QUAKE Enduser License contained within the -Authorized Copy and as specified in this Agreement. - - 5. TERM AND TERMINATION. - - a. The term of this Agreement and the license granted -herein begins on the Effective Date and shall expire on a date one -(1) calendar year from the Effective Date. - - b. Either party may terminate this Agreement, for any -reason or no reason, on thirty (30) days written notice to the -other party. Termination will be effective on the thirtieth (30th) -day following delivery of the described notice. Notwithstanding -anything to the contrary herein, this Agreement shall immediately -terminate, without the requirement of any notice from Id Software -to Licensee, upon the occurrence of any of the following: (a) if -Licensee shall file a petition in bankruptcy or make an assignment -for the benefit of creditors, or if any bankruptcy proceeding or -assignment for benefit of creditors, shall be commenced against -Licensee and not be dismissed within sixty (60) days after the date -of its commencement; (b) the insolvency of Licensee; (c) the -cessation by Licensee of its business; or (d) the cessation by -Licensee, without the prior written consent of Id Software of the -distribution, manufacture, and sale responsibilities embodied -herein. Further, Id Software may elect to terminate this Agreement -upon the occurrence of any of the following: (1) if Licensee's -business operations are interrupted for forty (40) consecutive -calendar days; or (2) if each of two Id Software audit inspections -during any eighteen (18) month period demonstrates an -understatement by Licensee of Royalty payments due Id Software for -the six (6) month period immediately preceding each such inspection -of five percent (5%) or more. Upon the occurrence of such -terminating event, and the election of Id Software, if necessary, -to cause such termination, this Agreement and any and all rights -thereunder shall terminate without prejudice to any rights or -claims Id Software may have, and all rights hereunder shall -thereupon terminate, revert to and be vested in Id Software. - - 6. EFFECT OF TERMINATION OR EXPIRATION. Termination or -expiration of this Agreement, either by Id Software or -automatically, shall not create any liability against Id Software. -Upon expiration or earlier termination of this Agreement, Licensee -shall have no further right to exercise the rights licensed -hereunder or otherwise acquired in relation to this Agreement. - - 7. INDEMNIFICATION. Licensee hereby agrees to -indemnify, hold harmless and defend Id Software and Id Software's -predecessors, successors, assigns, officers, directors, -shareholders, employees, agents, representatives, licensees, -sublicensees, distributors, attorneys and accountants -(collectively, the "Id Related Parties") from and against any and -all damages, claims, losses, causes of action, liabilities, -lawsuits, judgments and expenses (including, without limitation, -reasonable attorneys' fees and expenses) arising from, relating to -or in connection with a breach of this Agreement by Licensee and -arising from, relating to or in connection with the Licensee's use -or non-use of the Authorized Copy (collectively, the "Claims"). Id -Software agrees to notify Licensee of any such Claims within a -reasonable time after Id Software learns of same. Licensee, at its -own expense, shall defend Id Software and the Id Related Parties -from any and all Claims. Id Software and the Id Related Parties -reserve the right to participate in any defense of the Claims with -counsel of their choice, and at their own expense. In the event -Licensee fails to provide a defense, then Licensee shall be -responsible for paying the attorneys' fees and expenses incurred by -Id Software and the Id Related Parties regarding the defense of the -Claims. Id Software and the Id Related Parties, as applicable, -agree to reasonably assist in the defense of the Claims. No -settlement by Licensee of any Claims shall be valid unless Licensee -receives the prior written consent of Id Software and the Id -Related Parties, as applicable, to any such settlement. - - 8. CONFIDENTIALITY. It is understood and agreed that -any proprietary information of Id Software that may from time to -time be made available or become known to Licensee is to be treated -as confidential, is to be used solely in connection with Licensee's -performance under this Agreement, and is to be disclosed only to -employees of Licensee who have a need for access. Such proprietary -information shall include, but not be limited to, trade secrets, -release information, financial information, personnel information, -and the like. Reasonable measures shall be taken by Licensee to -protect the confidentiality of Id Software's proprietary -information and any memoranda or papers containing proprietary -information of Id Software's that Licensee may receive are to be -returned to Id Software upon request. Licensee's obligations and -duties under this paragraph shall survive expiration or earlier -termination of this Agreement. Licensee shall obtain from its -employees an undertaking in a form which may be supplied by Id -Software, and which is subject to Id Software's prior written -approval, not to use or disclose to any third party any information -or knowledge concerning the business of Id Software which may be -communicated to such employees. - - 9. LIMITATION OF LIABILITY. ID SOFTWARE EXPRESSLY -DISCLAIMS ALL WARRANTIES NOT PROVIDED BY ID SOFTWARE HEREUNDER. -UNDER NO CIRCUMSTANCES SHALL ID SOFTWARE BE LIABLE TO LICENSEE FOR -ACTUAL, SPECIAL, INCIDENTAL, CONSEQUENTIAL OR PUNITIVE DAMAGES OR -ANY OTHER DAMAGES, WHETHER OR NOT ID SOFTWARE RECEIVES NOTICE OF -ANY SUCH DAMAGES. - - 10. COMPLIANCE WITH APPLICABLE LAWS. In performing -under this Agreement, Licensee agrees to comply with all applicable -laws, [including, without limitation, 22 U.S.C., 2778 and 22 -U.S.C. C.F.R. Parts 120-130 (1995)] regulations, ordinances and -statutes, including, but not limited to, the import/export laws and -regulations of the United States and its governmental and -regulatory agencies (including, without limitation, the Bureau of -Export Administration and the U.S. Department of Commerce) and all -applicable international treaties and laws. Further, Licensee -shall defend, indemnify and hold harmless Id Software from any and -all sales tax, tariffs and/or duties in connection with Licensee's -performance hereunder. - - 11. SPECIFIC UNDERTAKINGS BY LICENSEE. In addition to -the obligations of Licensee otherwise set forth in this Agreement, -during the term of this Agreement, and thereafter where specified, -Licensee agrees that: - - a. It will not attack the title of Id Software to the -Subject Game or the Trademark and any copyright, patent or -trademark or other intellectual property right related thereto and -it will not attack the validity of the license granted hereunder -during the term hereof or thereafter; and - - b. It will promptly inform Id Software of any -unauthorized use of the Authorized Copy, the Subject Game and the -Trademark and any portions thereof and reasonably assist Id -Software in the enforcement of any rights Id Software may have -against such unauthorized users. - - 12. FINANCIAL OBLIGATIONS AND ACCOUNTING. - - a. Payment of Royalties. Licensee agrees to pay Id -Software a royalty ("Royalty") at the rate of twelve and one-half -percent (12.5%) of Net Income. The term "Net Income" shall mean -all revenue received by Licensee from the commercial use of the -Authorized Copy, less only Licensee's actual, documented costs -relating directly to such use. A Royalty shall only be due for -those months in which Licensee's gross revenue from QUAKE -distribution exceeds U.S. Five Thousand Dollars ($5,000.00) and in -such months Licensee shall pay a full Royalty on all revenue -received. - - b. Rendition of Statements. Licensee shall account to -Id Software with regard to transactions hereunder within forty-five -(45) days following the conclusion of each calendar quarter. -Licensee hereby represents and warrants that such statements of -account to be prepared shall be true and correct. The accounts -shall show in summary form the appropriate calculations relating to -the computation of Royalties, if any. The statements shall also -show the gross revenue received by Licensee per month. The -Royalties payable to Id Software hereunder shall be remitted with -the particular statement indicating such amount to be due. All -statements hereunder shall be deemed rendered when deposited, -postage prepaid, in the United States mail, addressed to Id -Software at Id Software's address set forth on the signature page -hereof. - - c. Books of Account and Audits. Licensee shall keep -books of account relating to the commercial use of the Authorized -Copy on the basis of generally accepted accounting principles and -shall maintain such books of account for a period of at least two -(2) years after the expiration or earlier termination of this -Agreement; provided, however, that Licensee shall not be required -to keep such records longer than seven (7) years from their date of -origination. Id Software may, upon reasonable notice and at its -own expense, audit the applicable records at Licensee's office, in -order to verify statements rendered hereunder. Any such audit -shall take place during reasonable business hours and in such -manner so as not to interfere with Licensee's normal business -activities. Id Software agrees that such information inspected -and/or copied on behalf of Id Software hereunder shall be used only -for the purpose of determining the accuracy of the statements, and -shall be revealed only to such officers, directors, employees, -agents and/or representatives of Id Software as necessary to verify -the accuracy of the statements. If in an audit of Licensee's books -and records it is determined that there is a short fall of ten -percent (10%) or more in Royalties reported for any calendar -quarter, in addition to payment of such short fall and interest as -may be due, as provided herein, Licensee shall reimburse Id -Software for the full out-of-pocket costs of the audit including -reasonable travel costs and expenses; provided, however, that the -amount of reimbursement paid by Licensee shall not exceed U.S. -Fifteen Thousand Dollars ($15,000.00) for any audit. - - d. Payment of the Royalty. Licensee assumes all risks -associated with fluctuations in foreign currency exchange rates. -Licensee shall pay and agrees to pay all sums due Id Software in -United States Dollars. With respect to Royalties due for -commercial use outside the United States, other currencies shall be -exchanged at the expense of Licensee into United States Dollars -using the bid price quoted at the Citibank, N.A. of New York, New -York, for the purchase of United States Dollars at the close of -business on the last day of the calendar quarter during which any -amounts accrue. Payment of the Royalties shall be made in Dallas -County, Texas. - - e. Interest. If Id Software does not receive the -applicable Royalty payment on or before the due date of such -payment, Licensee agrees to pay and shall pay interest on Royalties -owed to Id Software from such date as specified in the following -sentence at a rate per annum equal to the Index Rate. For purposes -of clarification, the interest will begin to accrue on the first -(1st) day following the due date of the Royalty payment, unless the -Royalty payment is paid timely. The "Index Rate" shall be the -prime rate as published in The Wall Street Journal's "Money Rates" -table. If multiple prime rates are quoted in the table, then the -highest prime rate will be the Index Rate. In the event that the -prime rate is no longer published in the "Money Rates" table, then -Id Software will choose a substitute Index Rate which is based upon -comparable information. The applicable interest rate will be -determined and take effect on the first day of each month. - - NOTHING HEREIN SHALL BE CONSTRUED AS A REQUEST OR DEMAND BY -ID SOFTWARE OF INTEREST AT A RATE HIGHER THAN ALLOWED BY APPLICABLE -LAW. IT IS THE INTENT OF THE PARTIES HERETO THAT NO INTEREST BE -CHARGED HEREUNDER WHICH EXCEEDS THE MAXIMUM RATE ALLOWED BY -APPLICABLE LAW. IF THE RATE REFERENCED ABOVE EXCEEDS THE MAXIMUM -RATE ALLOWED BY APPLICABLE LAW, THEN THE INTEREST RATE MADE -APPLICABLE HEREIN SHALL BE THE MAXIMUM RATE ALLOWED BY APPLICABLE -LAW. - - 13. SUBLICENSE. Licensee shall not be entitled to -sublicense any of its rights under this Agreement. - - 14. GOODWILL. Licensee recognizes the great value of -the goodwill associated with the Subject Game and the Trademark, -and acknowledges that such goodwill, now existing and hereafter -created, exclusively belongs to Id Software and that the Trademark -has acquired a secondary meaning in the mind of the public. - - 15. REMEDIES. In the event of a breach of this -Agreement by Id Software, Licensee's sole remedy shall be to -terminate this Agreement. In the event of a breach by Licensee of -this Agreement, Id Software may pursue the remedies to which it is -entitled under applicable law, including, but not limited to, -termination of this Agreement. Licensee agrees that its failure to -comply with the terms of this Agreement upon expiration or earlier -termination hereof or Licensee's unauthorized use of the Authorized -Copy may result in immediate and irreparable damage to Id Software -for which there is no adequate remedy at law, and in the event of -such failure by Licensee, Id Software shall be entitled to -injunctive relief. Pursuit of any remedy by Id Software shall not -constitute a waiver of any other right or remedy of Id Software -under this Agreement or under applicable law. Termination of this -Agreement shall not be a pre-condition to Id Software pursuing its -other remedies for breach. - - 16. LICENSEE'S WARRANTIES. Licensee warrants and -represents that it has full legal rights to enter into this -Agreement and to perform its obligations hereunder and that it will -comply, at all times during the terms of this Agreement, with all -applicable laws, as set forth hereinabove. - - 17. BANKRUPTCY. If Licensee's liabilities exceed its -assets, or if Licensee becomes unable to pay its debts as they -become due or if Licensee files for voluntary bankruptcy, or is -placed in bankruptcy which is not dissolved or dismissed after -thirty (30) days from the petition filing date, or if Licensee -becomes insolvent, or makes an assignment for the benefit of its -creditors or an arrangement pursuant to any bankruptcy laws or if -Licensee discontinues its business or if a receiver is appointed -for its business, this Agreement shall automatically terminate, -without notice, and become null and void; provided, however, all -duties of Licensee upon termination or expiration of this Agreement -shall continue in full force and effect. - - 18. ENTIRE AGREEMENT AND ASSIGNMENT. This Agreement -constitutes the entire understanding between Licensee and Id -Software regarding the Subject Game. Each and every clause of this -Agreement is severable from the whole and shall survive unless the -entire Agreement is declared unenforceable. No prior or present -agreements or representations shall be binding upon any of the -parties hereto unless incorporated in this Agreement. No -modification or change in this Agreement shall be valid or binding -upon the parties unless in writing, executed by the parties to be -bound thereby. This Agreement shall bind and inure to the benefit -of Id Software, its successors and assigns, and Id Software may -assign its rights hereunder, in Id Software's sole discretion. -This Agreement is personal to Licensee, and Licensee shall not -sublicense, assign, transfer, convey nor franchise its rights -granted hereunder. - - 19. CHOICE OF LAW, VENUE AND SERVICE OF PROCESS. This -Agreement shall be construed in accordance with the laws of the -State of Texas and applicable U.S. federal law and all claims -and/or lawsuits in connection with this Agreement must be brought -in Dallas County, Texas. Licensee hereby agrees that service of -process by certified mail to the address set forth below, with -return receipt requested, shall constitute valid service of process -upon Licensee. If for any reason Licensee has moved or cannot be -validly served, then Licensee appoints the Secretary of State of -the state of Texas to accept service of process on Licensee's -behalf. - - 20. EXCUSED PERFORMANCE. Neither party shall be deemed -to be in default of any provision of this Agreement nor be liable -for any delay, failure in performance or interruption of service, -resulting directly or indirectly from acts of God, civil or -military authority, civil disturbance, military action, war, -strikes, other catastrophes or any other similar cause beyond its -reasonable control. Written notice to the non-affected party of any -such condition shall be given by the affected party within ten (10) -days of the event. - - 21. DELIVERY OF NOTICES, AND DELIVERY OF PAYMENTS. -Unless otherwise directed in writing by the parties, all notices -given hereunder and all payments made hereunder shall be sent to -the addresses set forth on the signature page hereof. All -notices, requests, consents and other communications under this -Agreement shall be in writing and shall be deemed to have been -delivered on the date personally delivered or on the date deposited -in the United States Postal Service, postage prepaid, by certified -mail, return receipt requested, or telegraphed and confirmed, or -delivered by electronic facsimile and confirmed. Any notice to Id -Software shall also be sent to its counsel: D. Wade Cloud, Jr., -Hiersche, Martens, Hayward, Drakeley & Urbach, P.C., 15303 Dallas -Parkway, Suite 700, LB 17, Dallas, Texas 75248. - - 22. NO PARTNERSHIP, ETC. This Agreement does not -constitute and shall not be construed as constituting a partnership -or joint venture between Id Software and Licensee. Neither party -shall have any right to obligate or bind the other party in any -manner whatsoever, and nothing herein contained shall give, or is -intended to give, any rights of any kind to any third persons. - - 23. COUNTERPARTS. This Agreement may be executed in -several counterparts, each of which will be deemed to be an -original, and each of which alone and all of which together, shall -constitute one and the same instrument, but in making proof of this -Agreement it shall not be necessary to produce or account for each -copy of any counterpart other than the counterpart signed by the -party against whom this Agreement is to be enforced. This -Agreement may be transmitted by facsimile, and it is the intent of -the parties for the facsimile of any autograph printed by a -receiving facsimile machine to be an original signature and for the -facsimile and any complete photocopy of the Agreement to be deemed -an original counterpart. - - 24. MEDIATION. If a dispute arises out of or relates to -this Agreement, or a breach of this Agreement, and if the dispute -cannot be settled through direct discussion, then the parties agree -to endeavor to settle the dispute in an amicable manner by -mediation, under the applicable provisions of Section 154.00 et -seq., Texas Civil Practices and Remedies Code, as supplemented by -the rules of the Association of Attorney Mediators. - - 25. SURVIVAL. The following provisions shall survive -the expiration or earlier termination of this Agreement: -paragraphs 4., 7., 8., and the audit rights of Id Software in -paragraph 12.c. - - 26. MISCELLANEOUS. - - a. All captions in this Agreement are intended solely -for the convenience of the parties, and none shall effect the -meaning or construction of any provision. - - b. The terms and conditions of this Agreement have been -negotiated fully and freely among the parties. Accordingly, the -preparation of this Agreement by counsel for a given party will not -be material to the construction hereof, and the terms of this -Agreement shall not be strictly construed against such party. - - By signing in the spaces provided below, the parties have -agreed to all of the terms and conditions set forth in this -Agreement. - - -AGREED: - -LICENSEE: - - -Signed:_______________________________ -Printed Name:_________________________ -Title:________________________________ -Address:______________________________ -______________________________________ -______________________________________ -Telephone #: _________________________ -Fax #:________________________________ -E-Mail Address:_______________________ -Date: ________________________________ - - -AGREED: - -ID SOFTWARE, INC. - - -Signed:_______________________________ -Printed Name:_________________________ -Title:________________________________ -Address:______________________________ -______________________________________ -______________________________________ -Telephone #: _________________________ -Fax #:________________________________ -E-Mail Address:_______________________ -Date: ________________________________ - - - -June 10, 1996 - - - -COMMERCIAL EXPLOITATION LICENSE AGREEMENT FOR QUAKE -(DWC:dw:3406.0299:dwc\doc:5017) - - diff --git a/engine/docs/HELP.TXT b/engine/docs/HELP.TXT deleted file mode 100644 index ef79fbd..0000000 --- a/engine/docs/HELP.TXT +++ /dev/null @@ -1,119 +0,0 @@ -TECH SUPPORT -Any of the information listed below could change. Check the id software -Web Site, at www.idsoftware.com, for updates. - -A. Tech Support Options -id Software does charge for technical support, but we strive to offer -this service at the lowest cost possible. Because volume on the support -lines dictate costs, we periodically adjust our rates for Voice Tech -Support. Check our web site for current pricing. - -Paying for Voice or Automated Support -1 -- You can get Voice Support using a major credit card for a one-time -shot. The system asks for your credit card number and expiration date, -then pre-authorizes your credit card for the tech support call. You will -only be billed for the number of minutes actually used. - -2 -- You can assign yourself a rechargeable PIN account. The system prompts -you for your credit card information, and assigns you a PIN account number. -You can use the PIN to access Voice Support, Automated Support and the -Game Hints Line. Once your account runs out, you can charge it up again. - -3 -- You may also charge up a PIN account using the number 1 (900) call-2-id. -Then call back at 1(800)ID-GAMES (1(800)434-3627), and use your new PIN to -receive all the support and hints you wish. - -4 -- id Software's Game Hints Line is accessible either using a PIN account -via 1 (800) ID-GAMES (see above), or by calling 1 (900) CALL2-ID, which -places the call on your phone bill. - - 1. Voice Support - Telephone -- 1 (800) id-games - - Lines Open from 12 noon to 10pm Central Time, 7 Days a - week ($1.75 per minute). Closed some holidays - - Please have the following information handy. - 1. Game title and version number. (The version - number can be found on the end text screen.) - 2. Your operating system, processor, processor - speed and amount of RAM. - 3. If you are having a sound, video or modem - problem, we need to know the device brand name - and model. - - 2. Automated Support - Telephone -- 1 (800) id-games - - Lines Open 24 hours a day, 365 days a year, or 366 days - in Leap years ($0.25 per minute) - - Please have pencil and paper handy. - - 3. E-mail Support - Just send your e-mail to support@idsoftware.com - - We will do our best to respond within 48 hours after - receiving your e-mail. - - When sending e-mail, cut and paste the following into your - e-mail message and fill in the blanks: - -Date: -Name: -Phone number: -E-mail address: (please include this, we redirect tons of mail) -Game Title: -Version #: -Operating system (eg., DOS 6.0 or Windows 95): -Computer type: -Processor type: -Processor speed: -Video card brand and model: (only if video problem) -Audio card brand and model: (only if audio problem) -Modem brand and model: (only if modem problem) -Network card brand and model: (only if netgame problem) -Network configuration (eg., NET.CFG file): (only if netgame problem) -Drivers, protocol stacks, and versions: (eg., lsl v2.14, exp16odi -v2.33, and ipxodi v3.01) (only if netgame problem) -If there were any error messages or fault information, report them -here: -Please state the problem you encountered: -Please state how to reproduce the problem: - - 4. Web Support - Found at www.idsoftware.com - - Our web support pages provide the same information that's - available via Automated Support, except it's free! - - 5. News Sites - For information, FAQ, or announcements: - rec.games.computer.quake.announce - For editing and hecking Quake-related files: - rec.games.computer.quake.editing - For general Quake discussion: - rec.games.computer.quake.misc - - 6. Game Hints Line - Telephone -- 1 (800) id-games or 1 (900) call-2-id - - Lines Open 24 hours a day, 365 days a year, or 366 days - in Leap years ($0.85 per minute) - You must be 18 years of age or have parental permission - to call 1 (900) call-2-id. - -B. In Europe - The help lines in Europe are open 7:30am - 5:00pm GMT, - Monday - Friday. - -English: +44 01923 209145 -German: +44 (0)1923 209151 -French: +44 (0)1923 209148 - -C. Problems - If you have an unfavorable experience using our services, please - send e-mail to 911@idsoftware.com. We would also like to hear - from you if you have something positive to share with us. Kindly - include your full name, address, phone number, and the problem - encountered or information you'd like to tell us about. diff --git a/engine/docs/LICINFO.TXT b/engine/docs/LICINFO.TXT deleted file mode 100644 index f909e38..0000000 --- a/engine/docs/LICINFO.TXT +++ /dev/null @@ -1,97 +0,0 @@ -Here is a brief explanation of all the legal mumbo jumbo contained in the -various license agreements that may or may not be part of this package. - -(This document was designed to be a quick overview of our license terms. -You must refer to the full text of the license for a complete listing of -terms and conditions.) - -QUAKE SHAREWARE END USER LICENSE (slicnse.txt) or -What You Can and Cannot Do With the Shareware Version of Quake. - -CAN DO: --- Play & Enjoy the single player game --- Setup a shareware version based server on a not-for-profit basis - -CANNOT DO: --- Run the game with user developed levels. --- You may not commercially exploit the shareware version in any way - This specifically excludes retail distribution of the shareware - version. Do not call or e-mail to ask if you can be a retail - distributor of the shareware version -- the answer is no! --- Commercially exploit any id copyrighted and/or trademarked property. - Example: Game names, logos, graphics, etc. - - -QUAKE REGISTERED VERSION END USER LICENSE (rlicnse.txt) or -What You Can and Cannot Do With the Registered Version of Quake. - -CAN DO: --- Play & Enjoy the single player game --- Setup a registered version based server on a not-for-profit basis --- Develop new levels and/or level creation utilities. --- Play the game and/or setup a Registered Version based server using - a user-developed level. - -CANNOT DO: --- Commercially exploit the Registered Version of Quake in any way; - see commercially exploitation license info below. --- Commercially exploit any id copyrighted and/or trademarked - property. - Example: Game names, logos, game graphics, etc. --- Sell user-developed levels and/or tools - -COMMERCIAL EXPLOITATION LICENSE (comexp.txt -- accompanies Quake - registered version only) - -If you are interested in trying to make money using the registered version -of Quake (this sort of thing is not allowed using the shareware version) you -must sign our easy-to-digest Commercial Exploitation License. - -This is a royalty free license that allows you to run Quake for a profit -through a certain monthly gross profit range. If your Quake-related business -becomes successful the agreement brings id into the revenue stream. - -Basic terms of the commercial exploitation license: - --- License grants a royalty free commercial exploitation right for the - registered version of Quake as a whole so long as Quake's monthly gross - revenue is below $5,000.00 - --- License provides for a 12.5% royalty to be paid to id Software in months - where the licensee's Quake related monthly gross revenue is above $5,000.00 - --- Royalty is based off net income. Net income is defined as Quake-related - gross income less Quake-related expenses. - --- License expressly prohibits commercial exploitation via the sale (retail - or otherwise) of the shareware or registered versions of Quake. - --- License expressly prohibits advertising/marketing use of our copyrighted - and/or trademarked properties. - -To get into bed with us on this deal you must print two (2) copies of the -document named comexp.txt. (You should find comexp.txt somewhere on the -registered version CD.) Sign/fill in the blanks of both copies where -indicated and mail both to: - - id Software - 18601 LBJ #666 - Mesquite, TX 75150 - Attn: ComExp License - -We will then countersign the documents and mail one back to you. - -Two items worth noting here: - -1. It is VERY IMPORTANT that the information you enter in the signature -block be legible. We prefer it if you enter the info into the blanks before -printing your two copies. If we cannot read your information we will not be -able to return the documents to you. - -2. The terms of this document are not subject to negotiation. If you cannot -live with the terms spelled out in the agreement do not engage in any -commercial exploitation of Quake and do not sign the document. - - - - diff --git a/engine/docs/MANUAL.TXT b/engine/docs/MANUAL.TXT deleted file mode 100644 index bc674d6..0000000 --- a/engine/docs/MANUAL.TXT +++ /dev/null @@ -1,1030 +0,0 @@ -Table of Contents - I. THE STORY - A. Background - B. Prelude to Destruction - - II. INSTALLING QUAKE - A. Installation - B. README.TXT - C. MANUAL.TXT - D. TECHINFO.TXT - - III. THE BASICS OF PLAY - A. Goal of the Game - B. Skill - C. Episode - D. Getting About - E. Finding Things - - IV. CONTROLS - A. Keyboard Commands - B. The Main Menu - C. Console - D. Command Line - E. Cheat Codes - - V. THE GAME - A. The Screen - B. Messages - C Ending a Level - D. Ending a Dimension - - VI. YOUR NEW ENVIRONMENT - A. Firepower - B. Ammo - C. Power-ups - D. Bad Guys - E. Environmental Hazards and Effects - - VII. MULTIPLAYER ACTION - A. Cooperative - B. Deathmatch - C. Team Games - - VIII. COMMONLY ASKED QUESTIONS - - IX. TECH SUPPORT - A. Tech Support Options - B. In Europe - C. Problems - - X. LEVELS AND DESIGNERS - - XI. LEGAL BOILERPLATE -**************** -I. THE STORY -A. Background - You get the phone call at 4 a.m. By 5:30 you're in the secret - installation. The commander explains tersely, "It's about the Slipgate - device. Once we perfect these, we'll be able to use them to transport - people and cargo from one place to another instantly. - - "An enemy codenamed Quake, is using his own slipgates to insert death - squads inside our bases to kill, steal, and kidnap.. - - "The hell of it is we have no idea where he's from. Our top scientists - think Quake's not from Earth, but another dimension. They say Quake's - preparing to unleash his real army, whatever that is. - - "You're our best man. This is Operation Counterstrike and you're in - charge. Find Quake, and stop him ... or it ... You have full authority - to requisition anything you need. If the eggheads are right, all our - lives are expendable.." - -B. Prelude to Destruction - While scouting the neighborhood, you hear shots back at the base Damn, - that Quake bastard works fast! He heard about Operation Counterstrike, - and hit first. Racing back, you see the place is overrun. You are almost - certainly the only survivor. Operation Counterstrike is over. Except for - you. - - You know that the heart of the installation holds a slipgate. - Since Quake's killers came through, it is still set to his dimension. - You can use it to get loose in his hometown. Maybe you can get to the - asshole personally. You pump a round into your shotgun, and get moving. - -II. INSTALLING QUAKE -A. Installation - You must install Quake before you can play it. It will not run off the - CD-ROM. Place the CD-ROM into your drive, log on to that drive, and type - 'INSTALL'. If you have downloaded Quake via modem, simply go to the - directory you've placed Quake in, unzip it, and type 'INSTALL'. - -B. README.TXT - After you install Quake, you go right into the README.TXT file, which is - henceforth available in your Quake directory. This is a full listing of - Quake's technical parameters, and is constantly updated with new versions - of Quake. We strongly recommend that after you install Quake, you glance - through README.TXT. - - You may wish to print this file out, so you can have a copy of it on hand - while playing Quake. - -C. MANUAL.TXT - Also available in your Quake directory is a file labeled MANUAL.TXT. - This is the file you are now reading. - -D. TECHINFO.TXT - For those who are more technically inclined, or to fill out a bug report, - check out TECHINFO.TXT. Information on filling out a bug report is located - at the end of TECHINFO.TXT. - - -III. THE BASICS OF PLAY -A. Goal of the Game - Quake has two basic goals. First, stay alive. Second, get out of the - place you're in. The first level of each episode ends in a slipgate -- - these signify that you're entering another dimension. When you complete - an entire dimension (this takes six to eight levels), you'll find a - Rune and another slipgate, which returns you to the start. - -B. Skill - The start area has three short hallways. The one you go down selects - the Skill you wish to play at. - Easy -- This is meant for little kids and grandmas. - Medium -- Most people should start Quake at Medium skill. - Hard -- Here at id, we play Hard skill, and we think you should too, - once you're ready. - (Nightmare) -- This is so bad that the entry is hidden, so people - won't wander in by accident. If you find it, don't say we didn't warn - you. - -C. Episode - After the Skill halls, you're in a room with four exits. Each exit - leads to a different military complex, at the end of which is a - slipgate leading to a new dimension. If you have not registered, the - first episode, Dimension of the Doomed, is the only place you can go. - After registration, all four episodes are available. The other three - episodes, in order from second to fourth, are Realm of Black Magic, - Netherworld, and The Elder World. - -============================================================================= -== TIP -- From episode 1 to episode 4, the dimensions become progressively == -== more difficult. We suggest you play the episodes in the proper order to == -== get the maximum fun out of Quake. == -============================================================================= - -D. Getting About - The specific keys named below can be changed by using the Configure Keys - Menu. If you have renamed Run as the R key, for instance, then the Shift - key will not double your speed. - Walk - Use the arrow keys or the mouse. To walk steadily forward, hold down - the Forward key (up arrow or center mouse button). Turn left or right - with the left or right arrow keys or sliding your mouse to the left or - right. - Run - Hold down Run (the Shift key) to double your speed. - Jumping - Tap the Jump key (the space bar or Enter key). You jump further if - you're moving forward, and you jump higher if you're moving up a slope at - the time. You'll be surprised at the spots you can reach in a jump. You - can even avoid some attacks by jumping at the right time. - Swimming - When underwater, aim yourself in the direction you wish to go, and - move forward. You have full three-dimensional freedom. Unfortunately, - as in real life, you may lose your bearings while underwater. Use - jump (the space bar or Enter key) to kick straight up towards the - surface. Once on the surface, tread water by holding down jump. - To get out of the drink, swim towards the shore. Once there, use jump - to clamber up. If you're down a well or you can't get a grip, you may - not be able to climb out. There is always another way out, but you may - have to submerge to find it. - Shooting - Tap the Shoot key (the Ctrl key or left mousebutton) to fire. Hold it - down to keep firing. - Use - Quake has no "Use" function. To push a button or open a door, walk up - to it. To ride a platform up or down, step atop it. If a door won't open - or a platform won't lower, you may need to do something special to - activate it. - Picking up stuff - To pick up items, weapons, and power-ups, walk over them. If you can't - pick up something, it means you already have the maximum possible of - that thing. If it is armor, it means the stuff you're trying to get is - worse than what you now have. - -E. Finding Things - Buttons and Floorplates - Buttons activate with a touch, and floorplates must be stepped on. - If you see a distinctive-looking button in a spot you cannot reach, - it's probably a shootable button-- fire at it. - Doors - Most doors open at your approach. If one doesn't, seek a button, - floorplate, or key. - Secret Doors - Some doors are camouflaged. Almost all secret doors open when they are - shot or hit with an axe. The rest are opened by hidden pressure plates - or buttons. - Platforms - Most platforms only go up and down, while some follow tracks around - rooms or levels. When you step atop of a platform, it rises to its - full height, and usually only lowers when you step off. Some platforms - must be activated via button or pressure plate. - Pressure Plates & Motion Detectors - Invisible or visible sensors which open doors, unleash traps, warn - monsters, etc. - Uncovering Secrets - Secrets are hidden lots of ways. You might need to shoot a button, kill - a monster, walk through a secret motion detector, etc. - The Secret of Secrets - All secrets in Quake are indicated by clues. Don't waste your time - hacking at every wall. It's much more productive (and fun) to use your - brain and your eyes. Look up. An angled texture, a light shining under - a wall, a strange sound -- anything -- might be the clue. Something - prominent in a room might be decoration ... or it might be the clue. - -============================================================================= -== TIP -- Bouncing a grenade off a shootable button or secret door won't == -== open it, but if the grenade's explosion goes off nearby, this may == -== activate such secrets. == -============================================================================= - -IV. CONTROLS -A. Keyboard Commands - By using the key configuration option from the Main Menu, you can - customize the keyboard to suit your fancy, except for the Function keys, - the Escape key, and the ~ (tilde) key. - -FUNCTION KEYS -Help F1 -Save Game F2 -Load Game F3 -Options Menu F4 -Multiplayer Menu F5 -Quicksave F6 -Quickload F9 -Quit to operating system F10 -Screenshot F12 - -WEAPONS -Axe 1 -Shotgun 2 -Double Barrelled Shotgun 3 -Nailgun 4 -Supernailgun 5 -Grenade Launcher 6 -Rocket Launcher 7 -Thunderbolt 8 -Change to next weapon / - -MOVEMENT -Move / Turn arrow keys -Jump / Swim Space bar or Enter -Run Shift -Sidestep Left . or > -Sidestep Right , or < -Strafe * Alt -Swim Up D -Swim Down C - -OTHER CONTROLS -Main Menu Escape -Console ~ (tilde) -Look Up A or PgDn -Look Down Z or Del -Center View X or End -Mouse Look ** \ or center mouse button -Keyboard Look *** Ins - - * Turning right or left sidesteps instead while the Strafe key is pressed. - ** Sliding your mouse forward and back looks up and down while the Mouse - Look key is pressed. -*** The walk forward/backpedal arrows will look up and down while the - Keyboard Look key is pressed. - -B. The Main Menu - Tap the Escape key to pop up the Main Menu. While you are in the menu, - the game is paused. - Use the arrow keys to move the Quake icon up and down the menu. Place - the icon before the desired option, and tap the Enter key. To return to the - Main Menu, tap the Escape key again. To exit the menu and return to the - game, tap the Escape key when you are on the Main Menu. - - NEW GAME - Discards the game you're playing, and starts anew. - - MULTIPLAYER - Controls multiplayer game starting and details... - Name - Type your name or alias here, and all messages about you will use - this. So the computer says stuff like, "Josephine rides Bad Bill's - rocket." - Shirt Color - Lets you select your character's uniform color from 14 different - options (numbered 0-13). - Pants Color - As above, but your pants color also determines what team you're on, - if in team play. (After all, pants are more important than shirts.) - Communications Configuration - Takes you to a separate menu on which you can change communications - settings. - Com Port - Selects the COM Port to use for Communications. A null modem or - modem must be connected to this port. - Baud Rate - Selects the COM port baud rate (9600-57600bps). This is NOT the - same as setting the modem speed. The COM port speed must be AT - LEAST the same speed as the modem speed. - Device - Selects the type of connection, either direct (null-modem) or - modem. - Modem Init String - The Initialization string for the modem. - - Start a Multiplayer Game - If you want your machine to be the host for a multiplayer game - (Note: if you are starting a listen server, id Software strongly - recommends that the fastest machine act as the host! If you are - playing a game with more than 4 players, we suggest using a - dedicated server as the host!), select this option, and you'll get - the following menu ... - Begin Game - Starts up the game. Now all your friends have to do is log on, - using either "search for local network games" or "join a - running game at..." Multiplayer options (see below). - Maximum Players - You can have up to 16 players. You need at least 2, or it's not - "multiplayer", right? - Game Type - Toggles between cooperative and deathmatch. - Team Color Rules - Toggles between "none" and "no friendly fire". In the latter mode, - your shots won't injure someone wearing the exact same color - pants as you. - Skill - Chooses skill level. Only applicable in a cooperative game. - Frag Limit - From none to 100, in ten-frag increments. When someone reaches - the frag limit, by killing the 40th (or whatever) person, then - the game ends immediately, and final scores are printed. If your - frag limit is none, the game won't end till someone exits the - level or the time limit expires. - Time Limit - From none to 60 minutes, in 10 minute increments. When the time - limit is up, the game ends immediately, and final scores are - printed. If your time limit is none, the game won't end till - someone exits the level or the frag limit is reached. - Start Map - Lets you choose what map you'd like to play on. The top line - gives you the episode name, and the lower line is the level's - name. Note that all levels in Quake are fun to play, but the - episode Deathmatch Arena is composed of special levels that are - solely-designed for deathmatch play. Try them, you'll like them. - Search For Local Network Games - Has your computer look through your network. It will list all the - games it finds on the console, and you can choose to join one of - them by typing connect . - Join A Running Game At ... - Lets you join a game either by typing its net address (for a net - game) or your friend's modem phone number (for a modem game). - If necessary, ensure your modem and network connections are operative - by checking your Communications Configuration menu. - - SAVE - Brings up a list of saved games. Highlight the desired slot, and tap the Enter key. Each saved game is identified by the level's name, plus the - proportion of kills you have achieved so far. - LOAD - Brings up a list of saved games. Highlight the desired slot, and tap the - Enter key. - OPTIONS - Miscellaneous game options ... - Configure Keys - Permits you to customize Quake so every action is linked to the - button or key that you prefer. - First, move the cursor (via the arrow keys) to the action you - wish to change. Then tap the Enter key. Now press the key or - button you want to bind to that action. For instance, if you wish - to use the Alt key for Jump, move the cursor to Jump / Swim, tap - the Enter key, then press the Alt key. - Each action can have two different keys assigned to it. If you - already have two keys in an entry, you cannot add more from this - menu. - To clear the keys bound to an action, move the cursor to that - action and tap the Backspace or Delete key instead of the Enter - key. This will clear the keys formerly bound to that action, - leaving it blank. - You can bind any key to an action except Function keys, the - Escape key, and the ~ (tilde) key. "Weird" keys such as Scroll - Lock, Print Screen, etc. may or may not work, depending on your - machine, but why bother? - - Attack - Fires your weapon - Change Weapon - Switches to the weapon "above" the one you're now using. Wraps - around to the axe. - Jump / Swim Up - If you're on land, jumps. If you're underwater, kicks you - towards the surface. If you're right at the water's edge, pops - you up out of the water, if you combine it with forward - movement. - Walk Forward - Backpedal - Turn Left - Turn Right - Run - Press this while moving, and you move at double speed. - Step Left - Sidesteps (strafes) left - Step Right - Sidesteps (strafes) right - Sidestep - Press this when using turn left or turn right and you sidestep - (strafe) instead. - Look Up - Lets you angle your view upwards. Your view returns to - horizontal when you start walking forward. - Look Down - Lets you angle your view upwards. Your view returns to - horizontal when you start walking forward. - Center View - If you're looking up or down, returns your view to dead - center. - Mouse Look - Press this to allow your mouse to look up or down (by - sliding it forward and back), and to remain looking up or - down even if you move forward. - Keyboard Look - Press this to use your movement keys to look up or down. - Go To Console - Brings down the Console. Also possible by tapping the - ~ (tilde) key. - Reset To Defaults - Everything you've changed in the options menu is reset by - this option. Consider it an "Oops" key. - Screen Size - A slider which enlarges or shrinks your view area. All - Quake's sliders use the right and left arrow keys. - Brightness - Pretty much self-explanatory. Choose a brightness which - doesn't strain your eyes. - Mouse Speed - Adjusts mouse sensitivity. The further you set the slider - to the right, the quicker your mouse reacts. - Music Volume - Self-explanatory - Sound Effects Volume - Self-explanatory - Always Run - When this is selected, you do not need the Run key -- you - are always at double speed. - Invert Mouse Up / Down - This gives your mouse "airplane-style" controls. This means - that pushing the mouse forward "noses down", and pulling it - back "noses up". Some people prefer this control technique. - Lookspring - Returns your view immediately to straight ahead when you - release the look up / down key. Otherwise, you must move - forward for a step or two before your view snaps back. - Lookspring does not work while you are underwater. - Lookstrafe - If you are using the look up / down key, then this option - causes you to sidestep instead of turn when you try to move - left or right. - - HELP / ORDERING - Lists the default keyboard and mouse commands. Also contains the - information you need to register Quake. - QUIT - Exits Quake at once. - -============================================================================= -== TIP -- Quake saves your current key configuration when you quit, so == -== next time you play, you have the same configuration. == -============================================================================= - -C. Console - Tap the ~ (tilde) key to bring down the console. As with the Main Menu, - when the console is down, a singleplayer game is paused. A wide variety of - esoteric commands can be entered at the console. If your keyboard has no - ~ (tilde), the Options Menu (inside the Main Menu) has a "Console" option. - -D. Command Line - For special command line parameters, see README.TXT. - -E. Cheat Codes - id Software, as in our previous games, has removed all cheat codes from - Quake. - -V. THE GAME -A. The Screen - The large top part of the screen is the view area, in which you see - monsters and architecture. Immediately below is the Inventory, beneath - which is the Status Bar. You can enlarge the viewing area (tap the + key), - so much that it engulfs first the Inventory Bar and then the Status Bar. - The - key shrinks the view area. - - Inventory Bar - Lists ammo, weapons, deathmatch scores, and power-ups. - The active weapon is lit up. Each weapon has a number by it -- type - the appropriate number key to switch to that weapon. - In addition, this gives the amount of ammo you have of each type, - any keys you possess, and any power=ups currently active. Plus it shows - how many and which of the four Runes you possess. - In Deathmatch, it shows the top four scores in the game. - - Status Bar - A vital part of the screen. When your armor, hit points, or ammo get - low, the number turns red. - From left to right, the big numbers represent: Armor Points, Health, - and Ammo (of the current weapon). Icons show the Armor Type (green, - yellow, or red), your adorable face, and your Ammo Type). - - Score Bar - Hold down theTab key to replace the Status Bar with the Score Bar. - This lists the proportion of monsters you've killed, secrets you've - found, and time you've spent, along with the level name. - In Deathmatch, the Score bar lists the top six scorers, along with - their names. - -B. Messages - Quake talks to you from time to time. Some messages appear at the top of - the screen. These are non-critical, and tell you that you've picked up an - object, or you've died in an interesting fashion. Ignore these messages if - you please. - Certain messages appear inconveniently in the middle of your view. These - are always important, and you do not want to ignore them! - -D Ending a Level - Once you finish a level, you'll find a slipgate or a distinctive archway - leading to the next level. Pass through to emerge onto a new level. - You start the new level with the same armor, weapons, and ammo you had at - the end of the previous one. If a power-up was active at the end of the - previous level, it is now, sadly, gone. Make the best of it. If your hit - points were over 100 or under 50, they are altered to 100 or 50, - respectively. Otherwise, your hit points are unchanged. - -D. Ending a Dimension - Once you've finished all the levels in a particular dimension, you return - to the starting hall. New dimensions are started from scratch -- you, your - shotgun, and axe. - -VI. Your New Environment -A. Firepower - You are blessed with eight different Means o' Mass Destruction. Each has - its place in a balanced diet. - - Axe - The last resort. Face it -- going toe-to-toe with the uglies in Quake - demonstrates all the good sense of a man parachuting into an alligator - farm. - - Shotgun - The basic gun, to which all other guns compare favorably. - - Double-barrelled Shotgun - A worthy weapon with three minor drawbacks: first, it uses up 2 shells - per blast; second, it's slow; third, its shot pattern is very loose at - long range. But in general, once you find this puppy, the other shotgun - starts rusting from disuse. - - Nailgun - A two-barrel dingus that prickles bad guys with armor-piercing darts, - technically termed "nails". - - Supernailgun - The great equalizer. Four cyclic barrels that hose out spikes like - crazy. Pro: foes drop like flies. Con: eats ammo like popcorn. - - Grenade Launcher - Thumps neat exploding bombs into the air. You can even bounce a grenade - off the wall or floor.. When a grenade hits someone, it explodes. - If it misses, the bomb sits on the floor for a moment, then explodes. - Even though I sometimes bounce grenades into myself, this gun's still - my favorite. - - Rocket Launcher - For when a grenade positively, absolutely, has to be there on time. - - Thunderbolt - Try it. You'll like it. Use the same technique as watering your - rosebush. - - Switching Between Weapons - If you are firing a weapon and run out of ammo, Quake automatically - switches you to another weapon. It will never switch to the grenade - launcher or rocket launcher, however, for reasons that ought to be - obvious. So if you're firing away happily and suddenly switch to the - axe, it doesn't mean you're out of all ammo -- you may still have - grenades. But Quake requires you to select such dangerous - explosives on your own. - -============================================================================= -== TIP -- If you shoot the Thunderbolt underwater, it discharges all its == -== cells in every direction in a single gigantic KA-ZAP, with you at the == -== center. Don't try this at home. == -============================================================================= - -B. Ammo - The eight weapons use four types of ammo. Each ammo type comes in two - flavors -- small and large. The large boxes carry twice as much as the - small. - - Shells - For shotguns and double-barrelled shotguns. A small box holds 20. - - Flechettes - For nailguns and supernailgunss. A small box holds 25. - - Grenades - For grenade launchers and rocket launchers. A small crate holds 5. - - Cells - For Mr. Thunderbolt. A small battery has 6 charges, lasting a little - over a second. - -C. Power-ups - All power-ups except armor burn out after a while, so smoke 'em while you - got 'em. - - Armor - Comes in three flavors; green, yellow, and red, from weakest to most - powerful. - - Megahealth - Gives you 100 additional hit points. After a few seconds, all hit points - over 100 start slowing draining away, because it's too much for the human - frame to hold. Still, it's nice while it lasts. - - Biosuit - lets you breathe underwater and swim through slime without harm. Does - not protect against lava. - - Ring of Shadows - Renders you almost totally invisible. Only your eyes can be seen. - Monsters don't detect you unless you do something stupid. Like shoot. - - Pentagram of Protection - Renders you invulnerable. - - Quad Damage - Magnum upgrade! You now deliver four times the pain! - -============================================================================= -== TIP -- When quad damage is activated, use the grenade or rocket == -== launcher with care -- their bursts are four times as deadly to you, as == -== well as your enemies. == -============================================================================= - -D. Bad Guys - Quake critters are extremely tough, but you have the firepower to vent - your grievances on them anyway. Good hunting. - - Rottweiler - Bad, bad doggie! Play dead! -- blam! -- yipe! Good dog! - - Grunt - Goons with probes inserted into their pleasure centers; wired up so - when they kill someone, they get paroxysms of ecstasy. In essence, - customized serial killers. Easy to kill, and they tote shotgun shells. - It's like a little Christmas each time you blow a Grunt away! - - Enforcer (registered only) - Grunt, Mark Two. Recruits who are surlier and beefier than the rest get - outfitted in combat armor and built-in blasters. - - Knight - Canned meat. Open 'er up and see if it's still fresh. - - Death Knight (registered only) - This particular canned meat tends to open you up instead. - - Rotfish (registered only) - Disgusting little critters who dish it out, but can't take it. - - Zombie - Thou canst not kill that which doth not live. But you can blast it - into chunky kibbles. - - Scrag - Floats like a butterfly, stings like a bee. Ugly as hell. They're not - real tough, but like to bushwhack you. - - Ogre - What's worse than a cannibal monster eight feet tall? One with a - chainsaw. And a sack of grenades. - - Spawn (registered) - A merrily bouncing blob as dangerous to kill as to ignore. Blech. - - Fiend - In essence, organic buzzsaws, rife with pummeling power! - - Vore (registered) - A spideresque hybrid horror. Keep your eye on the energy pod he hurls. - - Shambler - Even other monsters fear him, so expect a clobbering. He shrugs off - explosions. Good luck. - -============================================================================= -== TIP -- Some weapons are better vs. particular monsters than others. If == -== a new monster seems real tough, switch weapons. == -============================================================================= - -E. Environmental Hazards and Effects - - Explosions - Radioactive containers are in some military bases. Shooting these - things unleashes a big boom, so be careful -- you may not want to - stand too close in a firefight. - Your own grenades and rockets cause explosions too, of course -- the - blast can hurt you if you're too close. - - Water - Safe enough unless you stay under so long you start to drown. Come up - for air periodically to prevent this. - - Slime - Hurts you instantly and keeps on hurting. Stay out of slime unless you - have a very good reason to take a dip. - - Lava - If you're quick and the lava's shallow, you might escape before you're - burnt to a crisp, but don't bet on it. - - Traps - Quake has many different traps. Don't be paranoid, because traps aren't - really very common, but be aware of their existence. Traps can't be - classified because they come in many varieties -- monsters in ambush, - spike shooters, crushing walls, trapdoors, etc. - - Teleporters - These are distinctive in appearance and emit a unique sound. When you - step into a teleporter, you're instantly transported to another - teleporter, or atop a teleport pad. If you teleport directly right atop - of somebody else, he or she is killed instantly. - -============================================================================= -== TIP -- Monsters are smart enough not to activate their own traps, but == -== if you activate the traps, the monsters can get caught by them. == -============================================================================= - -VII. Multiplayer Action - Quake can be even more fun when you're playing with friends than when - you're playing by yourself. - When you are using the console or Main Menu in multiplayer, the game does - not pause. Irresponsible players and monsters can freely shoot you, and - your only recourse is bloodthirsty vengeance. - The Talk function is useful here. When you talk, the message appears at - the top of all players' screens, preceded by the speaker's name. - To talk, press 'T' and start typing your message. Press ENTER to set - the message to everyone. - To set up, run, or join a multiplayer game, use the Main Menu Multiplayer - option. README.TXT contains details that may be useful if your network or - modem need special configurations. - -A. Cooperative - In a co-op game, you and your friends work together to finish the level. - When one person exits, everyone else exits too, wherever they might be. If - you are killed in co-op, you reappear at the start area, and have to catch - up to your buddies. Use Talk to find out where they are. See the - Multiplayer options on the Main Menu for more info. - -B. Deathmatch - In a deathmatch, play is totally cutthroat. No monsters exist, and when - you are killed, you reappear in a random spot. After you pick up an item, - it respawns (i.e. pops back into existence) after a while. (Some items - take longer to respawn than others.) Every time you kill someone, you get - a Frag. The person with the most Frags wins, so wreak slaughter amongst - your pals! - If you kill yourself, whether intentionally or by accident, you lose a - Frag. This includes drowning, getting crushed, and so forth. See the - Multiplayer options on the Main Menu for more info. - -C. Team Games - Team play is a cool combination of co-op and deathmatch. Each team picks - a "uniform" and everyone on that team changes their color to the team - color. The team with the most Frags wins. See README.TXT or the Main Menu - for details. - -============================================================================= -== TIP -- if you have the Team Color Rules set to No Friendly Fire, your == -== weapons won't hurt other players wearing the same color pants as you. == -== (You can still have differently-colored shirts.) Your shots still wear == -== down their armor, and your own grenade and rocket explosions still hurt == -== YOU, just not them. == -============================================================================= - -VIII. Commonly Asked Questions - -Q. I'm stuck. How do I get through the level? -A. Take a stroll around and look for a place you haven't been yet. Sometimes -you have to kill a particular monster in order to progress, so exterminate -them all! - -Q. How can I find all the secrets? -A. Don't worry about it. You never have to find a secret to finish a level.. -Also, some secrets are intentionally hard to find. - -Q. I've cleared out the whole level, but my monster kill score isn't 100%. -Where are they hiding? -A. Some monsters hide inside secrets, or are released by them. You won't be -able to kill those monsters until you find their secrets. Also, some monsters -might lurk underwater. Good fishing. - -Q. Don't you worry that Quake teaches people that all problems can be solved -by the misuse of deadly force? -A. No. - -Q. Did I really see two monsters fighting each other? -A. Probably. Some monsters hate one another almost as much as they hate you. -You can use this to your advantage (exercise left up to the reader). - -Q. How do I prevent motion sickness when watching Quake? -A. If you're one of the unlucky sufferers from motion sickness in Quake, -we're sorry to say the answer seems to differs from person to person. Try -sitting closer to the screen, or further away. Dim the lights in your room, -or turn them up high. Adjust screen brightness up or down. Take a break from -Quake and rest your eyes every hour or so. One or more of these tricks, or a -combination, ought to work. - -Q. Are you guys Satan-worshipers? -A. No. - -IX. Tech Support - Any of the information listed below could change. Check the id software Web -Site, at www.idsoftware.com, for updates. - -A. Tech Support Options -id Software does charge for technical support, but we strive to offer this -service at the lowest cost possible. Because volume on the support lines -dictates costs, we periodically adjust our rates for Voice Tech Support. -Check our web site for current pricing. - -Paying for Voice or Automated Support - 1 -- You can get Voice Support using a major credit card for a one-time - shot. The system asks for your credit card number and expiration date, then - pre-authorizes your credit card for the tech support call. You will only be - billed for the number of minutes actually used. - - 2 -- You can assign yourself a rechargeable PIN account. The system - prompts you for your credit card information, and assigns you a PIN account - number. You can use the PIN to access Voice Support, Automated Support and - the Game Hints Line. Once your account runs out, you can charge it up - again. - - 3 -- You may also charge up a PIN account using the number - 1 (900) call-2-id. Then call back at 1 (800) id-games, and use your - new PIN to receive all the support and hints you wish. - -Voice Support -Telephone -- 1 (800) id-games - Lines Open from 12 noon to 10pm Central Time - 7 Days a week ($1.75 per minute maximum as of this printing) - Closed some holidays -Please have the following information handy. - 1. Game title and version number. (The version number can be found in the - lower right-hand corner of the console.) - 2. Your operating system, processor, processor speed and amount of RAM. - 3. If you are having a sound, video or modem problem, we need to know the - device brand name and model. - -Automated Support -Telephone -- 1 (800) id-games - Lines Open 24 hours a day, 365 days a year (366 in Leap year) - ($0.25 per minute) -Please have pencil and paper handy - -E-mail Support - Just send your e-mail to support@idsoftware.com - We will respond within 48 hours after receiving your e-mail. When sending - e-mail, cut and paste the following into your e-mail message and fill - in the blanks -- - -Date: -Name: -Phone number: -E-mail address: (please include this, we redirect tons of mail) -Game Title: -Version #: -Operating system (eg., DOS 6.0 or Windows 95): -Computer type: -Processor type: -Processor speed: -Video card brand and model: (only if video problem) -Audio card brand and model: (only if audio problem) -Modem brand and model: (only if modem problem) -Network card brand and model: (only if netgame problem) -Network configuration (eg., NET.CFG file): (only if netgame problem) -Drivers, protocol stacks, and versions: (eg., lsl v2.14, exp16odi -v2.33, and ipxodi v3.01) (only if netgame problem) -If there were any error messages or fault information, report them -here: -Please state the problem you encountered: -Please state how to reproduce the problem: - -Web Support - Found at www.idsoftware.com - Our web support pages provide the same information that's available via - Automated Support, except it's free! - -News Sites - For information, FAQ, or announcements, check out - rec.games.computer.quake.announce - - For editing and hecking Quake-related files, check out - rec.games.computer.quake.editing - - For general Quake discussion, check out - rec.games.computer.quake.misc - -Game Hints Line -Telephone -- 1 (800) id-games or 1 (900) call-2-id - Lines Open 24 hours a day, 365 days a year (366 in Leap year) - ($0.85 per minute) - -B. In Europe - Our help lines in Europe are open 7:30am - 5:00pm GMT, Monday - Friday. - - English: +44 01923 209145 - German: +44 (0)1923 209151 - French: +44 (0)1923 209148 - -C. Problems - If you have an unfavorable experience using our services, please send - e-mail to support@idsoftware.com. Kindly include your full name, - address, phone number, and the problem encountered. - -X. LEVELS & DESIGNERS - -*************************************** -The Beginning -start -- Welcome to Quake -- by John Romero -*************************************** -Dimension of the Doomed (shareware episode) -e1m1: Slipgate Complex -- by John Romero -e1m2: Castle of the Damned -- by Tim Willits -e1m3: The Necropolis -- by Tim Willits -e1m4: The Grisly Grotto -- by Tim Willits -e1m5: Gloom Keep -- by Tim Willits -e1m6: The Door To Chthon -- by American McGee -e1m7: The House of Chthon -- by American McGee -*************************************** -Realm of Black Magic -e2m1: The Installation -- by John Romero -e2m2: Ogre Citadel -- by John Romero -e2m3: Crypt of Decay -- by John Romero -e2m4: The Ebon Fortress -- by John Romero -e2m5: The Wizard's Manse -- by John Romero -e2m6: The Dismal Oubliette -- by John Romero -*************************************** -Netherworld -e3m1: Termination Central -- by John Romero -e3m2: The Vaults of Zin -- by American McGee -e3m3: The Tomb of Terror -- by American McGee -e3m4: Satan's Dark Delight -- by American McGee -e3m5: Wind Tunnels --by Tim Willits -e3m6: Chambers of Torment -- by American McGee & Tim Willits -*************************************** -The Elder World -e4m1: The Sewage System -- by Tim Willits -e4m2: The Tower of Despair --by Sandy Petersen -e4m3: The Elder God Shrine --by Sandy Petersen -e4m4: The Palace of Hate --by Sandy Petersen -e4m5: Hell's Atrium --by Sandy Petersen -e4m6: The Pain Maze --by Sandy Petersen -e4m7: Azure Agony --by Sandy Petersen -*************************************** -The End -end: Shub-Niggurath's Pit --by John Romero -*************************************** -The Deathmatch Arenas -dm1: Place of Two Deaths --by Tim Willits -dm2: Claustrophobopolis --by American McGee -dm3: The Abandoned Base --by John Romero -dm4: The Bad Place --by American McGee -dm5: The Cistern --by Tim Willits -dm6: The Dark Zone --by Tim Willits -*************************************** -??? -Ziggurat Vertigo --by American McGee -Underearth --by Tim Willits -The Haunted Halls -- by American McGee -The Nameless City -- by Sandy Petersen -*************************************** - -XI. Legal Boilerplate - Quake (tm) (c) id Software, Inc. All rights reserved. All trademarks are - the property of their respective companies. For full information on the - legal issues of owning and using Quake, please refer to the files - LICINFO.TXT and ORDER.TXT. - -The program you've purchased was produced through the effort of many people. -Don't make copies for others who have not paid for the right to the -registered version of Quake. To report copyright violations to the Software -Publishers Association, call 1 (800) 388-PIR8 or write: - - Software Publishers Association - Suite 901 - 1101 Connecticut Avenue NW - Washington, DC 20036 - -XII. MUSIC CREDITS - -Titles of Songs or Themes (C) 1996 TVT/Interscope Records. -All Rights Reserved. -Written by Trent Reznor (C) 1996 Leaving Hope/TVT Music. -ASCAP All Rights Reserved. - -Note: music is ONLY available on CD. See your local software retailer -or order Quake today at 1-800-idgames! - -XIII. Thanks - -id Software would like to give special thanks to: - -Sean Barrett -Raymond Chen -DJ Delorie -Andy Glew -Lance Hacking -Chris Hecker -Todd Laney -Terje Mathisen -Charles Sandmann -Jon Vondrak -Billy Zelsnack -The GameTech crew -Syntrillium Software for CoolEdit diff --git a/engine/docs/ORDER.TXT b/engine/docs/ORDER.TXT deleted file mode 100644 index fb4598d..0000000 --- a/engine/docs/ORDER.TXT +++ /dev/null @@ -1,103 +0,0 @@ -ORDERING INFO - To order the full version of Quake (or any other id Software -product) in North America, call our fulfillment center at 1-800-idgames -(1-800-434-3627). Except as noted by our operators, you can expect -Airborne Express afternoon delivery. The price for the full version -of Quake (available on PC CDROM only) is $45, plus $5 shipping, for a -total of $50. Our fulfillment center accepts Visa, Mastercard, and -American Express. You can also fax, mail, or email your order using -the attached forms. The fax number is (317) 361-3710 and the email -address is idsoftware@stream.com. To prepay and order with a check -by mail, send your check and the order form to: - - id Software - P.O. Box 4500 - Crawfordsville, IN 47933 - - To see an electronic catalog of our software, tshirts, hint books, and - other merchandise available, check out the Shopping Maul section of our - website at www.idsoftware.com. - -INTERNATIONAL ORDERS -Quake is available worldwide as a full retail product. To find out -which local stores carry Quake and other id products, contact the -following international affiliates: - -Europe Australia -GT Interactive Software Roadshow New Media -1712 583791 (U.K.) 1 902 962000 - -Taiwan Singapore -U.S. Summit Corporation Summit Co. (Singapore) Pte. Ltd. -706-0660 273-9988 - -Malaysia Honk Kong -Summit Co. (Malaysia) Sdn Bhd Tsun Tsun Trading Company -757-2244 571-4231 - -Thailand Israel/Jordan/Lebanon/Egypt -U.S. Summit Corp. (Overseas) Mirage Mulimedia -374-3956 972 3 510 5764 - -If you are in a territory that cannot access 1(800)idgames, and you -wish to order our products directly, you must place your order in -writing to the fax, mail, or email addresses listed above under -ORDERING INFO. - -International phone orders will NOT be accepted. Unfortunately, due -to international shipping costs, all international orders are sent -out via US Mail. This means we cannot guarantee timeliness of delivery -due to customs and other delays inherent to international shipping -______________________________________________________________________ - ORDER FORM -- USE THIS FORM TO FAX , MAIL OR EMAIL YOUR ORDER. - -id Software Order Center Date ______________ -PO BOX 4500 Phone: 1800 id games -Crawfordsville, IN 47933 Fax: (317) 361-3710 - idsoftware@stream.com - - -Product List and Prices in U.S. Currency: (check items) - -Quake (CD ROM only) $45 ____ -The Ultimate DOOM (Mac version available – must specify) $25 ____ -DOOM II (Mac version available – must specify) $40 ____ -Master Levels for DOOM II (CD ROM only) $25 ____ -Final DOOM (CD ROM only) $40 ____ -DOOM Hint Book $15 ____ -Original DOOM Tshirt (S,M.L.XL) $13 ____ -The Ultimate DOOM Tshirt (XXL only) $13 ____ -Final DOOM Tshirt $13 ____ -Heretic:Shadow of the Serpent Riders (CD ROM only) $40 ____ -Heretic Hint Book $15 ____ -Hexen:Beyond Heretic (Mac version available – must specify) $40 ____ -Hexen:Deathkings of the Dark Citadel (CD ROM only) $25 ____ -Hexen Hint Book $15 ____ -Hexen Tshirt (XXL only) $13 ____ -Wolfenstein 3D (PC CD only) $20 ____ -Commander Keen (3.5 disk only) $15 ____ - - Order total: $______ - -Name: Age (optional): - -Form of payment (check, money order, or credit card): - -Credit card number: Expiration Date: - -Exact mailing address:______________________________________ - _______________________________________ - _______________________________________ - _______________________________________ - -Phone: Fax: Email: - -Shipping: US orders-$5.00 first product/$2.00 each additional -(allow 3-5 business days) - -International shipping for prepaid orders are via US Mail, and -we cannot guarantee the time it will take to arrive. - -*Prices subject to change - - diff --git a/engine/docs/README.TXT b/engine/docs/README.TXT deleted file mode 100644 index fc62729..0000000 --- a/engine/docs/README.TXT +++ /dev/null @@ -1,456 +0,0 @@ -Welcome to Quake! - -This file details how to get Quake running on your system and what to do -if you have problems. We would like to thank Gandalf Technologies, Inc and -MPath Interactive for the use of their technology. We would also like to -thank Trent Reznor and Nine Inch Nails for their tremendous contributions -to Quake's entire audio portion. - -The NIN logo is a Registered Trademark licensed to Nothing Interactive, Inc. -All Rights Reserved. - -Quake System Requirements -------------------------- -IBM PC and Compatibles -Pentium processor or better -VGA Compatible Display or better -8MB RAM minimum, 16MB recommended (16 MB required for running under Win95) -CD-ROM drive Required -MS-DOS 5.0 or better or Windows 95 (does NOT run under Windows NT) -Hard Drive (30MB for Shareware, 80 MB for Registered) - -*** IMPORTANT!: Quake requires a floating point processor. -Systems that do not have an FPU installed will not run Quake -- at all. - -*** IMPORTANT Video Adapter Note! *** -On some ATI Mach32 cards, Quake can come up with a garbled video display. -This is due to a problem with the card in which 320x200 mode isn't -initialized correctly. Workarounds include: - -1) If running from Windows, start Quake from an icon, or from a windowed -(not fullscreen) MS-DOS prompt. If Quake is already running and has -the garbled screen, press Alt-Enter twice to switch to the desktop and -back to fullscreen, and the screen will display properly. - -2) If running from DOS, either put the line - -vid_mode 1 - -in id1\autoexec.cfg, or, typing blind, press tilde ('~') to bring down -the console, type - -vid_mode 1 - -and the screen will display properly. - -======================================================================== -Here are the text files included with the shareware release of Quake and -what they are: - -README.TXT This file -TECHINFO.TXT Technical information on Quake's subsystems and - their advanced use. -MANUAL.TXT Text version of the printed game manual -LICINFO.TXT Info on the various license files included with Quake -SLICNSE.TXT Shareware Quake end-user license -ORDER.TXT How to order Quake -HELP.TXT How to get help with Quake - -Here are the text files included with the registered version of Quake and -what they are: - -README.TXT This file -TECHINFO.TXT Technical information on Quake's subsystems and - their advanced use. -MANUAL.TXT Text version of the printed game manual -LICINFO.TXT Info on the various license files included with Quake -RLICNSE.TXT Registered Quake end-user license -COMEXP.TXT Commercial exploitation agreement -ORDER.TXT How to order Quake -HELP.TXT How to get help with Quake - - -Running Quake -------------- - -DOS: To launch Quake from the DOS Prompt, go to the Quake directory and -simply type "QUAKE" . (no quotes) - -Windows 95: To launch Quake in single player mode, double click on the file -QUAKE.EXE From Windows Explorer. To run Quake in Multi-Player mode using -the TCP/IP protocol, first check your network settings to ensure the -protocol is installed, then double click on the Q95.BAT file to launch the -game. In this version (v0.91) there is a minor bug that will cause the -Q95.BAT file to exit the first time you run it, without running Quake. -Merely double-click on that file again and it will work. - -Audio Setup ------------ - -When using a Sound Card with Quake, there are a few setup steps which must -be taken. First, the "BLASTER" environment variable setting must be in your -autoexec.bat (or you can type it in manually from the MS-DOS command prompt). -Running the Sound Blaster utility diagnose.exe will automatically configure -your sound card and put this statement in your autoexec.bat file for you. -A typical blaster setting looks like this (although yours may vary): - -SET BLASTER=A220 I5 D1 H5 P330 T6 - -If you want to play the audio track from the CD-ROM while playing Quake, -you must ensure that the audio cable from the CD-ROM is connected to the -sound card. - -If you think your sound card is setup properly and it STILL doesn't work, -check to make sure that your BLASTER environment variable contains the -high DMA setting (H5 in the above example). - -If you don't get sound while trying to play the audio track, check to see -if a small cable goes from the back of your CD-ROM player directly to your -sound card. If the CD-ROM audio cable is connected to your sound board (or -the motherboard in some cases) and you STILL don't hear CD Audio coming from -your speakers, make sure the MIXER program has the CD volume turned up. -You will also need to run the CD-ROM driver MSCDEX.EXE. Here is an example -of the files you should see (yours probably will vary) listed in your -CONFIG.SYS and AUTOEXEC.BAT (explanation is in parentheses): - -CONFIG.SYS: - -DEVICE=C:\PROSCSI\CDROM.SYS /D:PROCD01 (CD-ROM driver) - -AUTOEXEC.BAT: - -SET BLASTER=A220 I5 D1 H5 P330 T6 (sound environment variable setting) -C:\WINDOWS\COMMAND\MSCDEX.EXE /D:PROCD01 /L:D (CD-ROM driver) - -=================================================== -UltraSound MAX and UltraSound PnP Support for Quake -=================================================== - -Before running Quake, make sure that your sound card works and your -environment variables are set correctly. - -Other UltraSound Cards (ACE & Classic) --------------------------------------- -These drivers are not for the UltraSound ACE or UltraSound Classic -sound cards. We have heard mixed reports that MegaEm or SBOS -have a chance of working with the UltraSound Classic but there is a -short sound F/X delay. - -UltraSound PnP and PnP Pro --------------------------- -You must make sure that you do NOT have IWSBOS or MegaEm loaded. - -Setup ------ -Quake will automatically detect that the UltraSound Max or PnP -are installed. It does this by looking at the SET INTERWAVE (PnP) -and SET ULTRA16 (Max) environment variables. - -Quake will use the settings found on the SET ULTRASND/ULTRA16 (Max) -and in the IW.INI (PnP) file to determine what port settings to use. - -Troubleshooting Windows 95 (DOS Box) ------------------------------------- -We recommend that you restart your computer in MS-DOS Mode. DOS Box -may or may not work, so use at your own risk. - -CD Audio Input --------------- -If you have not already enabled CD audio output by default you will -need to enable it. For the UltraSound MAX you can run "ULTRINIT -EC". -For the UltraSound PnP you will need to enable the CD audio output -in Win'95 and then restart your computer into MS-DOS. - -=================================================== -Mouse Setup ------------ - -If you are going to use a mouse when playing Quake, you will need to load -your mouse driver. This should go in the AUTOEXEC.BAT file as well. Here -is an example: - -C:\LOGITECH\MOUSE\MOUSE.EXE (mouse driver) - - -Booting Clean -------------- - -If you are going to be running Quake with only 8 megabytes of RAM, it is best -to boot clean . You eliminate unwanted utilities or applications from taking -up valuable memory, without having to alter your regular AUTOEXEC.BAT and -CONFIG.SYS. Booting clean can be done in one of two ways. If you have -MS-DOS version 6.xx, booting clean is as simple a pressing the shift key -when you see the words "Starting MS-DOS". If you have MS-DOS ver 5.xx you -will need to make a system disk. - -To make a boot disk, type the following from the MS-DOS command prompt: - -FORMAT A: /S - -1. Make sure that this is a disk you wish to erase. -2. This disk absolutely HAS to be formatted in the A: drive. - -To use the system disk, place the disk in the A: drive and reset the -computer. - -NOTE: If your sound card requires a driver to be loaded, or you will be -using a mouse, or you will be using Quake's CD audio feature, the system -disk will need to have a CONFIG.SYS and AUTOEXEC.BAT that load the -appropriate drivers. - -Creating a Quake Shortcut - -As an alternative to making a Boot Disk, Windows 95 users can create a -Quake Shortcut. By double clicking onthis shortcut, Windows 95 will reboot -in MS-DOS mode and install only the desired drivers, giving you the same -results as using a Boot Disk. To create a Quake Shortcut, do the following: - -1. Using Explorer, right click and drag the file QUAKE.EXE, from the Quake - directory, to your desktop. Windows 95 will make an MS-DOS Icon titled - "Shortcut to quake". -2. Right click on the new icon, and from the menu that pops up, choose - "Properties". Then choose the "Program" tab at the top. -3. Now click on the "Advanced..." button near the bottom. The "Advanced - Program Settings" window should appear. -4. Select the "MS-DOS mode" check box and the "Specify a new MS-DOS - configuration" option button. -5. Now simply fill in the "CONFIG.SYS for MS-DOS mode:" and "AUTOEXEC.BAT - for MS-DOS mode:" boxes with the same sound, CD-ROM and mouse settings as - mentioned above in the Boot Disks section. -6. Click on "OK" when you are finished. If you wish, you can change your - Quake Shortcut Icon to something a little more exciting by clicking on - "Change Icon...". -7. To finish, click on "OK" again. - 8. You can rename your Quake Shortcut by right clicking on the shortcut - icon, choosing "Rename" and typing in the new name. - - -====================================================== -== Known Problems == -====================================================== - -Problem: Zombies sometime get stuck on the ground and connot get back up. -(You can still hear them, but you cannot kill them. This bug makes it -impossible to get 100% kills on whatever level it occurs on.) -Solution: There is no workaround for this bug. - -Problem: It is sometimes possible for the player to get stuck in a room or -in a wall. -Solution: If you get stuck, use the 'kill' console command. It is a good -idea to save your game often. - -Problem: View centering problems. Sometimes during a game, the view will not -center properly. The end result is the player view looking up torwards the -ceiling while walking. -Solution: Exit to the next level or use the 'kill' console command.. - - -====================================================== -== Troubleshooting == -====================================================== - -If Quake fails to start up, or has problems not addressed elsewhere in the -documentation, try the -safe command line switch, which disables a number -of parts of Quake that can be problems if there are hardware or configuration -problems. The -safe command line switch is equivalent to -stdvid, -nosound, --nonet, and -nocdaudio together. Those four switches do the following: - --stdvid: disables VESA video modes. - --nosound: disables sound card support. - --nonet: disables network card support. - --nocdaudio: disables CD audio support. - -If -safe makes the problem go away, try using each of the switches -individually to isolate the area in which you're experiencing the problem, -then either correct the configuration or hardware problem or play Quake with -that functionality disabled. - -If you still have problems, try booting clean in conjunction with -the -safe command line parameter. For information on booting clean, refer -to the "Booting Clean" section above. - -If you experience page faults while running Quarterdeck's QDPMI DPMI server, -this is caused by a bug in QDPMI. Workarounds: Remove QDPMI from CONFIG.SYS, -issue the command QDPMI OFF before running QUAKE, or get the update patch -for QDPMI from Quarterdeck. You may be running QDPMI without knowing it if -you have QEMM installed, because it can be installed as part of the QEMM -installation. - - -Technical Support ------------------ - -If you are having trouble installing or running Quake you can receive -technical support by sending e-mailing to support@idsoftware.com. You can -also refer to our web page, www.idsoftware.com, or call 1-800-idgames. - -When sending support e-mail, cut and paste the following into your e-mail -message and fill in the blanks: - -Date: -Name: -Phone number: -E-mail address: (please include this, we redirect tons of mail) -Game Title: -Version #: -Operating system (i.e., DOS 6.0 or Windows 95): -Computer type: -BIOS date: -BIOS version: -Processor type: -Processor speed: -Do you program at school/work? -Do you provide tech. support at school/work? -Please state the problem you encountered: -Please state how to reproduce the problem: - -If program crashed with nasty undecipherable techno-garbage, please -look for the eight-digit hex number which comes after "eip=" -and write it down here: - -** NOTE: If you are sending a bug report, PLEASE refer to the TECHINFO.TXT -file for the correct form and procedures. - - -====================================================== -== Version History == -====================================================== -v1.01 -- Bugs fixed ------------------------------------------------------- -* Fixed modem code -* Fixed fraglimit & timelimit -* Added NOEXIT cvar (so no one can exit a level) ------------------------------------------------------- -v1.00 -- Bugs fixed ------------------------------------------------------- -* Gravis Ultrasound audio support (still has bugs) -* More deathmatch start spots on E1M6 and END -* Print server version and PROG CRC on connect -* -dedicated starts start.map if nothing else specified -* fixed lookspring function during net game -* fixed rare crash during long running dedicated server ------------------------------------------------------- -v0.94 -- Bugs fixed / Features added -- LIMITED BETA VERSION ------------------------------------------------------- -* Totally rewritten menus -* New lighting model with overbrighting -* Parsed lowercase BLASTER parms -* Better Sound Blaster shutdown code -* Rewrote BLASTER initialization -* Fixed DMA channel 0 bugs -* Added SBPro 8 stereo setup -* Fix delayed sound on 8 bit Sound Blasters -* Fixed speed key affecting angle-turning from keyboard -* Fixed "no such Alias frame" bugs -* Fixed Zombie not getting up bug -* Checked for very high joystick values, signalling a failed read -* Unstuck jumping Fiends and Spawn -* Fixed large BModels blinking out in complex areas -* Fixed s_localsound with no sound started -* Saved spawn parms in savegame -* Fixed screenshot save location -* Bind with no arguments no longer clears value -* Allow console in intermission / finale -* Fixed false gib messages -* Full-screen TAB scoreboard in DeathMatch -* Fixed "+playdemo " from command line -* Trapped overflow in sizebuf messages -* Moveup / movedown in water! -* Fixed-up Talk command -* Added unsupported crosshair option ("crosshair 1" from console) -* Colored chat messages with notify sound -* Fixed "connect during intermission" bug -* Changelevel while demos running no longer crashes -* Fixed changelevel with no map left up loading screen -* Fixed long names entered from the console causing crash -* Stopped demos changing while in the menus - -* Fixed modem initialization from menu -* Fixed serial reliable stream getting stalled -* Serial/modem code fixes - 16550a lost transmit buffer empty interrupts - fixed sometimes processing interrupts from com1 when using com2 - added com3/com4 support from menus - fixed first character of modem init not getting sent - saved serial/modem settings in config.cfg -* Fixed name and colors not always sent to server at startup -* Fixed "stopdemo" crashing the system when there wasn't a demo playing -* Added server's TCP/IP and IPX addresses (if available) to status command - -* In 0.92, an additional check for a usable VESA video mode was added; -the numpages field was verified to be greater than 0, and no mode was -supported that had numpages set to 0 (which indicates that there's not -enough video memory for that mode). ATI's VESA driver, m64vbe, -reports 0 for numpages, so VESA video modes that were available in 0.91 -were no longer available in 0.92. This extra numpages check has -been removed. - ------------------------------------------------------------------------ -v0.93 -- Never officially released; internal testing only. ------------------------------------------------------------------------ -v0.92 -- Bugs fixed ------------------------------------------------------------------------ -Typing long strings in the hostname or modem init field in the menus caused -crashes. - -Under Win95 IPX was detected but not functional, resulting in the game -exiting to DOS. - -If -nosound, got "S_LocalSound: can't cache" on every keypress in the menu. - -When vid_nopageflip was set to 1 in VESA modes, going underwater resulted in -only the upper left corner of the drawing area being updated. - -The single player scoreboard (tab) printed text incorrectly in all modes -greater than 320 pixels wide. - -On network connections that dropped packets, the reliable message stream -could get stopped up, resulting in frag counts and talk messages no longer -being delivered, although game movement continued. - -The com port settings from the menu were getting saved & restored but -not used. - -Direct serial connections did not work with slist. - -Quake now checks the vesa information for hardware incabable of page-flipping. - -Menu sound sometimes didn't play. - -Q95 (qlaunch.exe) frequently failed to execute on the first attempt. - -Q95 (quakeudp.dll) was running out of buffers when running a server. - -Teams were not being set according to pants colors. - - -Joystick notes --------------- -Your joystick must be plugged in when Quake is launched. - -If you have a joystick plugged in, but don't want to use it in Quake -(it slows the game down a few percent), or you have weird hardware that -doesn't like being tested as a joystick add "-nojoy" to your Quake -command line. - -You can turn off joystick reading during the game by typing "joystick 0" at -the Quake command console. - -You MUST configure your buttons from the configure keys menu before they will -work. There is no default configuration. - -If your joystick or interface card improperly sets the third or fourth -joystick buttons, type "joybuttons 2" at the quake console or in your -.CFG file. - -The "mlook" button command now lets the joystick as well as the mouse control -pitch angles. - -The "sidestep" buttom command works on joysticks as with mice and keyboard -movement. - -The "invert mouse up/down" menu option also inverts the joystick pitch -direction. diff --git a/engine/docs/RLICNSE.TXT b/engine/docs/RLICNSE.TXT deleted file mode 100644 index a3fdc35..0000000 --- a/engine/docs/RLICNSE.TXT +++ /dev/null @@ -1,204 +0,0 @@ -REGISTERED VERSION: QUAKE -LIMITED USE SOFTWARE LICENSE AGREEMENT - - This Limited Use Software License Agreement (the -"Agreement") is a legal agreement between you, the end-user, and Id -Software, Inc. ("ID"). By continuing the installation of this game -program, by loading or running the game, or by placing or copying -the game program onto your computer hard drive, you are agreeing to -be bound by the terms of this Agreement. If you do not agree to -the terms of this Agreement, promptly return the game program and -the accompanying items (including all written materials), along -with your receipt to the place from where you obtained them for a -full refund. - -ID SOFTWARE LICENSE - - 1. Grant of License. ID grants to you the limited -right to use one (1) copy of the enclosed or foregoing game program -(the "Software") on a single computer. You have no ownership or -proprietary rights in or to the Software or the written materials -accompanying the Software. For purposes of this section, "use" -means loading the Software into RAM, as well as installation on a -hard disk or other storage device. You may create a map editor, -modify maps and make your own maps (collectively referenced as the -"Permitted Derivative Works") for the Software. Permitted -Derivative Works may not be sold, whether by you or by any other -person or entity, but you may exchange the Permitted Derivative -Works at no charge amongst other end-users. The Software, together -with any archive copy thereof, shall be either returned to ID or -destroyed when no longer used in accordance with this Agreement, or -when the right to use the Software is terminated. You agree that -the Software will not be shipped, transferred or exported into any -country in violation of the U.S. Export Administration Act (or any -other law governing such matters) and that you will not utilize, in -any other manner, the Software in violation of any applicable law. - - 2. Commercial Use is Prohibited. Except as provided in -paragraph 5. hereinbelow in regard to the Software, under no -circumstances shall you, the end-user, be permitted, allowed or -authorized to commercially exploit the Software, any data -comprising the Software. Neither you nor anyone at your direction -shall do any of the following acts (any such acts shall be deemed -void and a breach of this Agreement) with regard to the Software, -or any portion thereof, such as a screen display or a screenshot: - - a. Rent the Software; - - b. Sell the Software; - - c. Lease or lend the Software; - - d. Offer the Software on a pay-per-play basis; - - e. Distribute, by electronic means or otherwise, the - Software for money or any other consideration; or - - f. In any other manner and through any medium - whatsoever commercially exploit the Software or use - the Software for any commercial purpose. - - 3. Additional Prohibited Uses. Neither you nor anyone -at your direction shall take the following action in regard to the -Software, or any portion thereof, such as a screen display or a -screenshot: - - a. Modify, disassemble, reverse engineer or decompile - the Software; - - b. Translate the Software; - - c. Reproduce the Software; - - d. Publicly display the Software; - - e. Prepare derivative works based upon the Software - (except Permitted Derivative Works); or - - f. Distribute, by electronic means or otherwise, the - Software. - - 4. Use of Other Material is Prohibited. Use, in any manner, of - the trademarks, such as Quake(tm) and the NIN(r) logo, logos, symbols, - art work, images, screen displays or screenshots, sound effects, music, - and other such material contained within, generated by or relating to - the Software is prohibited. - - 5. To Receive Permission to Commercially Exploit. If -you desire to commercially exploit the Software, you may execute -the Commercial Exploitation License Agreement for QUAKE (the -"License") contained within the QUAKE install package and forward -the original License to Id Software at the address noted therein. -Please note that ID may refuse your request and not sign the -License in ID's sole discretion. - - 6. Restrictions Apply to Third Parties. The -prohibitions and restrictions described herein apply to anyone in -possession of the Software and/or Permitted Derivative Works. - - 7. Copyright. The Software and all copyrights related -thereto (including all characters and other images generated by the -Software or depicted in the Software) is owned by ID and is protected -by United States copyright laws and international treaty provisions. -You must treat the Software like any other copyrighted material, -except that you may either (a) make one copy of the Software solely -for back-up or archival purposes, or (b) transfer the Software to a -single hard disk provided you keep the original solely for back-up or -archival purposes. You may not otherwise reproduce, copy or disclose -to others, in whole or in any part, the Software. You may not copy -the written materials accompanying the Software. The same -restrictions and prohibitions regarding your use of the Software as -provided in this Agreement apply to your use of the written materials -accompanying the Software. The written materials are owned by ID and -are protected by United States copyright laws and international -treaties. You agree to use your best efforts to see that any user of -the Software licensed hereunder complies with this Agreement. - - 8. Limited Warranty. ID warrants that if properly -installed and operated on a computer for which it is designed, the -Software will perform substantially in accordance with the -accompanying written materials for a period of ninety (90) days -from the date of purchase of the Software. ID's entire liability -and your exclusive remedy shall be, at ID's option, either (a) -return of the price paid or (b) repair or replacement of the -Software that does not meet ID's Limited Warranty. To make a -warranty claim, return the Software to the point of purchase, -accompanied by proof of purchase, your name, your address, and a -statement of defect, or return the Software with the above -information to ID. This Limited Warranty is void if failure of the -Software has resulted in whole or in part from accident, abuse, -misapplication or violation of this Agreement. Any replacement -Software will be warranted for the remainder of the original -warranty period or thirty (30) days from your receipt of the -replacement software, whichever is longer. This warranty allocates -risks of product failure between Licensee and ID. ID's product -pricing reflects this allocation of risk and the limitations of -liability contained in this warranty. - - 9. NO OTHER WARRANTIES. ID DISCLAIMS ALL OTHER -WARRANTIES, BOTH EXPRESS IMPLIED, INCLUDING BUT NOT LIMITED TO, -IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR -PURPOSE WITH RESPECT TO THE SOFTWARE AND THE ACCOMPANYING WRITTEN -MATERIALS. THIS LIMITED WARRANTY GIVES YOU SPECIFIC LEGAL RIGHTS. -YOU MAY HAVE OTHER RIGHTS WHICH VARY FROM JURISDICTION TO -JURISDICTION. ID DOES NOT WARRANT THAT THE OPERATION OF THE -SOFTWARE WILL BE UNINTERRUPTED, ERROR FREE OR MEET LICENSEE'S -SPECIFIC REQUIREMENTS. THE WARRANTY SET FORTH ABOVE IS IN LIEU OF -ALL OTHER EXPRESS WARRANTIES WHETHER ORAL OR WRITTEN. THE AGENTS, -EMPLOYEES, DISTRIBUTORS, AND DEALERS OF ID ARE NOT AUTHORIZED TO -MAKE MODIFICATIONS TO THIS WARRANTY, OR ADDITIONAL WARRANTIES ON -BEHALF OF ID. ADDITIONAL STATEMENTS SUCH AS DEALER ADVERTISING OR -PRESENTATIONS, WHETHER ORAL OR WRITTEN, DO NOT CONSTITUTE -WARRANTIES BY ID AND SHOULD NOT BE RELIED UPON. - - 10. Exclusive Remedies. You agree that your exclusive -remedy against ID, its affiliates, contractors, suppliers, and -agents for loss or damage caused by any defect or failure in the -Software regardless of the form of action, whether in contract, -tort, including negligence, strict liability or otherwise, shall be -the return of the purchase price paid or replacement of the -Software. This Agreement shall be construed in accordance with and -governed by the laws of the State of Texas. Copyright and other -proprietary matters will be governed by United States laws and -international treaties. IN ANY CASE, ID SHALL NOT BE LIABLE FOR -LOSS OF DATA, LOSS OF PROFITS, LOST SAVINGS, SPECIAL, INCIDENTAL, -CONSEQUENTIAL, INDIRECT OR OTHER SIMILAR DAMAGES ARISING FROM -BREACH OF WARRANTY, BREACH OF CONTRACT, NEGLIGENCE, OR OTHER LEGAL -THEORY EVEN IF ID OR ITS AGENT HAS BEEN ADVISED OF THE POSSIBILITY -OF SUCH DAMAGES, OR FOR ANY CLAIM BY ANY OTHER PARTY. Some -jurisdictions do not allow the exclusion or limitation of -incidental or consequential damages, so the above limitation or -exclusion may not apply to you. - - 11. General Provisions. Neither this Agreement nor any -part or portion hereof shall be assigned, sublicensed or otherwise -transferred by you. Should any provision of this Agreement be held -to be void, invalid, unenforceable or illegal by a court, the -validity and enforceability of the other provisions shall not be -affected thereby. If any provision is determined to be -unenforceable, you agree to a modification of such provision to -provide for enforcement of the provision's intent, to the extent -permitted by applicable law. Failure of a party to enforce any -provision of this Agreement shall not constitute or be construed as -a waiver of such provision or of the right to enforce such -provision. If you fail to comply with any terms of this Agreement, -YOUR LICENSE IS AUTOMATICALLY TERMINATED. - - YOU ACKNOWLEDGE THAT YOU HAVE READ THIS AGREEMENT, THAT YOU -UNDERSTAND THIS AGREEMENT, AND UNDERSTAND THAT BY CONTINUING THE -INSTALLATION OF THE SOFTWARE, BY LOADING OR RUNNING THE SOFTWARE, OR -BY PLACING OR COPYING THE SOFTWARE ONTO YOUR COMPUTER HARD DRIVE, YOU -AGREE TO BE BOUND BY THIS AGREEMENT'S TERMS AND CONDITIONS. YOU -FURTHER AGREE THAT, EXCEPT FOR WRITTEN SEPARATE AGREEMENTS BETWEEN ID -AND YOU, THIS AGREEMENT IS A COMPLETE AND EXCLUSIVE STATEMENT OF THE -RIGHTS AND LIABILITIES OF THE PARTIES. THIS AGREEMENT SUPERSEDES ALL -PRIOR ORAL AGREEMENTS, PROPOSALS OR UNDERSTANDINGS, AND ANY OTHER -COMMUNICATIONS BETWEEN ID AND YOU RELATING TO THE SUBJECT MATTER OF -THIS AGREEMENT. - -June 21, 1996 - -REGISTERED VERSION: QUAKE LIMITED USE SOFTWARE LICENSE AGREEMENT Page 4 -(DWC:dw:3406.0024:DWC\doc:1164) - - diff --git a/engine/docs/SLICNSE.TXT b/engine/docs/SLICNSE.TXT deleted file mode 100644 index 057302b..0000000 --- a/engine/docs/SLICNSE.TXT +++ /dev/null @@ -1,175 +0,0 @@ -SHAREWARE VERSION: QUAKE -LIMITED USE SOFTWARE LICENSE AGREEMENT - - This Limited Use Software License Agreement (the "Agreement") is a - legal agreement between you, the end-user, and id Software, Inc. - ("ID"). By continuing the installation of this game program, by - loading or running the game, or by placing or copying the game - program onto your computer hard drive, you are agreeing to be bound - by the terms of this Agreement. - -ID SOFTWARE LICENSE - - 1. Grant of License. ID grants to you the limited right to use - one (1) copy of the enclosed or foregoing Id Software game program - (the "Software"), which is the shareware version or episode one of - the game program. For purposes of this section, "use" means loading - the Software into RAM, as well as installation on a hard disk or - other storage device. You agree that the Software will not be - shipped, transferred or exported into any country in violation of - the U.S. Export Administration Act (or any other law governing such - matters) and that you will not utilize, in any other manner, the - Software in violation of any applicable law. - - 2. Commercial Use is Prohibited. Under no circumstances shall - you, the end-user, be permitted, allowed or authorized to - commercially exploit the Software, or any portion thereof, such - as a screen display or a screenshot. Neither you nor anyone at your - direction shall do any of the following acts: - - a. Rent the Software; - - b. Sell the Software; - - c. Lease or lend the Software; - - d. Offer the Software on a pay-per-play basis; - - e. Distribute the Software for money or any other - consideration; or - - f. In any other manner and through any medium - whatsoever commercially exploit the Software or use - the Software for any commercial purpose. - - 3. Additional Prohibited Uses. Neither you, nor anyone at your - direction, shall take the following action in regard to the - Software, or any portion thereof, such as a screen display or - a screenshot: - - a. Modify, disassemble, reverse engineer or decompile - the Software; - - b. Translate the Software; - - c. Reproduce the Software; - - d. Publicly display the Software; or - - e. Prepare derivative works based upon the Software. - - 4. Use of Other Material is Prohibited. Use, in any manner, of - the trademarks, such as Quake(tm) and the NIN(r) logo, logos, symbols, - art work, images, screen displays or screenshots, sound effects, music, - and other such material contained within, generated by or relating to - the Software is prohibited. - - 5. Restrictions Apply to Third Parties. The prohibitions and - restrictions described herein apply to anyone in possession of - the Software. - - 6. Permitted Distribution. So long as this Agreement - accompanies the Software at all times, ID grants to Providers the - limited right to distribute, free of charge, except normal access - fees, and by electronic means only, the Software; provided, however, - the Software must be so electronically distributed only in a - compressed format. The term "Providers," as used in the foregoing - sentence, shall mean persons whose business it is to provide - services on the Internet, on commercial online networks, or on the - BBS. Anyone who receives the Software from a Provider shall be - limited to all the terms and conditions of this Agreement. Further, - ID grants to you, the end-user, the limited right to distribute, - free of charge only, the Software as a whole. - - 7. Copyright. The Software is owned by ID and is protected by - United States copyright laws and international treaty provisions. - You must treat the Software like any other copyrighted material, - except that you may make copies of the Software to give to other - persons. You may not charge or receive any consideration from any - other person for the receipt or use of the Software. You agree to - use your best efforts to see that any user of the Software licensed - hereunder complies with this Agreement. - - 8. Limited Warranty. ID warrants that if properly installed and - operated on a computer for which it is designed, the Software will - perform substantially in accordance with its designed purpose for a - period of ninety (90) days from the date the Software is first - obtained by an end-user. ID's entire liability and your exclusive - remedy shall be, at ID's option, either (a) return of the retail - price paid, if any, or (b) repair or replacement of the Software - that does not meet ID's Limited Warranty. To make a warranty claim, - return the Software to the point of purchase, accompanied by proof - of purchase, your name, your address, and a statement of defect, or - return the Software with the above information to ID. This Limited - Warranty is void if failure of the Software has resulted in whole - or in part from accident, abuse, misapplication or violation of this - Agreement. Any replacement Software will be warranted for the - remainder of the original warranty period or thirty (30) days, - whichever is longer. This warranty allocates risks of product - failure between Licensee and ID. ID's product pricing reflects this - allocation of risk and the limitations of liability contained in - this warranty. - - 9. NO OTHER WARRANTIES. ID DISCLAIMS ALL OTHER WARRANTIES, - EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO, IMPLIED - WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A pARTICULAR PURPOSE - WITH RESPECT TO THE SOFTWARE AND THE ACCOMPANYING WRITTEN MATERIALS, - IF ANY. THIS LIMITED WARRANTY GIVES YOU SPECIFIC LEGAL RIGHTS. YOU - MAY HAVE OTHERS WHICH VARY FROM JURISDICTION TO JURISDICTION. ID - DOES NOT WARRANT THAT THE OPERATION OF THE SOFTWARE WILL BE - UNINTERRUPTED, ERROR FREE OR MEET LICENSEE'S SPECIFIC REQUIREMENTS. - THE WARRANTY SET FORTH ABOVE IS IN LIEU OF ALL OTHER EXPRESS - WARRANTIES WHETHER ORAL OR WRITTEN. THE AGENTS, EMPLOYEES, - DISTRIBUTORS, AND DEALERS OF ID ARE NOT AUTHORIZED TO MAKE - MODIFICATIONS TO THIS WARRANTY, OR ADDITIONAL WARRANTIES ON BEHALF - OF ID. ADDITIONAL STATEMENTS SUCH AS DEALER ADVERTISING OR - PRESENTATIONS, WHETHER ORAL OR WRITTEN, DO NOT CONSTITUTE WARRANTIES - BY ID AND SHOULD NOT BE RELIED UPON. - - 10. Exclusive Remedies. You agree that your exclusive remedy - against ID, its affiliates, contractors, suppliers, and agents for - loss or damage caused by any defect or failure in the Software - regardless of the form of action, whether in contract,tort, - including negligence, strict liability or otherwise, shall be the - return of the retail purchase price paid, if any, or replacement of - the Software. This Agreement shall be construed in accordance with - and governed by the laws of the State of Texas. Copyright and other - proprietary matters will be governed by United States laws and - international treaties. IN ANY CASE, ID SHALL NOT BE LIABLE FOR LOSS - OF DATA, LOSS OF PROFITS, LOST SAVINGS, SPECIAL, INCIDENTAL, - CONSEQUENTIAL, INDIRECT OR OTHER SIMILAR DAMAGES ARISING FROM BREACH - OF WARRANTY, BREACH OF CONTRACT, NEGLIGENCE, OR OTHER LEGAL THEORY - EVEN IF ID OR ITS AGENT HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH - DAMAGES, OR FOR ANY CLAIM BY ANY OTHER PARTY. Some jurisdictions do - not allow the exclusion or limitation of incidental or consequential - damages, so the above limitation or exclusion may not apply to you. - - 11. General Provisions. Neither this Agreement nor any part or - portion hereof shall be assigned or sublicensed, except as described - herein. Should any provision of this Agreement be held to be void, - invalid, unenforceable or illegal by a court, the validity and - enforceability of the other provisions shall not be affected thereby. - If any provision is determined to be unenforceable, you agree to a - modification of such provision to provide for enforcement of the - provision's intent, to the extent permitted by applicable law. Failure - of a party to enforce any provision of this Agreement shall not - constitute or be construed as a waiver of such provision or of the - right to enforce such provision. If you fail to comply with any terms - of this Agreement, YOUR LICENSE IS AUTOMATICALLY TERMINATED. - - YOU ACKNOWLEDGE THAT YOU HAVE READ THIS AGREEMENT, YOU UNDERSTAND - THIS AGREEMENT, AND UNDERSTAND THAT BY CONTINUING THE INSTALLATION - OF THE SOFTWARE, BY LOADING OR RUNNING THE SOFTWARE, OR BY PLACING - OR COPYING THE SOFTWARE ONTO YOUR COMPUTER HARD DRIVE, YOU AGREE TO - BE BOUND BY THIS AGREEMENT'S TERMS AND CONDITIONS. YOU FURTHER - AGREE THAT, EXCEPT FOR WRITTEN SEPARATE AGREEMENTS BETWEEN ID AND - YOU, THIS AGREEMENT IS A COMPLETE AND EXCLUSIVE STATEMENT OF THE - RIGHTS AND LIABILITIES OF THE PARTIES. THIS AGREEMENT SUPERSEDES - ALL PRIOR ORAL AGREEMENTS, PROPOSALS OR UNDERSTANDINGS, AND ANY - OTHER COMMUNICATIONS BETWEEN ID AND YOU RELATING TO THE SUBJECT - MATTER OF THIS AGREEMENT. - -June 21, 1996 - -SHAREWARE VERSION: QUAKE LIMITED USE SOFTWARE LICENSE AGREEMENT -(DWC:dw:3406.0024:DWC\doc:1163) diff --git a/engine/docs/TECHINFO.TXT b/engine/docs/TECHINFO.TXT deleted file mode 100644 index 31c0501..0000000 --- a/engine/docs/TECHINFO.TXT +++ /dev/null @@ -1,1901 +0,0 @@ -Welcome to the Quake Technical Information file! - -TABLE OF CONTENTS ------------------ -Introduction to the Console.............. -Video Subsystem Documentation............ -Sound Subsystem Documentation............ -CD Audio Subsystem Documentation......... -Network Subsystem Documentation.......... -Modem Strings............................ -Win95 Documentation...................... -Key Binding and Aliases.................. -Quake Keys and Common Commands........... -Making a Config File..................... -Demos.................................... -Reporting Quake Bugs..................... - - -========================================== -== Introduction to the Console == -========================================== - -Throughout this document, examples of commands are given, all of which -are typed in at the console. To bring up the console, press the tilde ('~') -key or press ESC to bring up the menu, select Options, and select Console... -from the options menu. To exit the console, press ESC. - -The console provides a way to change console variables and also accepts -commands that change game settings such as movement keys, video mode, as -well as providing an interface for key binding and command aliasing (more -on that later). - -The console also has a command history with which you can browse through -previous commands. Use the up and down arrows to navigate through the -command history and press to re-issue a command. - -Partially typing a command and then pressing the TAB key will complete the -currently typed text with the first matching console variable or command. -(Yes, this is a good way to look for console commands.) - -To review previous actions by page, use the PGUP and PGDN keys. - - -========================================== -== Video Subsystem Documentation == -========================================== - -The Video Modes menu --------------------- - -Video modes can most easily be selected from the the Video Modes menu, which -is brought up by selecting the Video Options choice in the Options menu. -All the resolutions that Quake can support on the current computer are -displayed. - -Please note that higher-resolution modes require correspondingly more -system memory in order for Quake to run, and that some high-resolution -modes may not be available when running Quake on 8 Mb machines. Such -modes are not listed in the Video Modes menu. Please do not report -video modes that do not appear in the Video Modes menu as bugs; either -those modes are not supported by your video adapter, or there is not -enough system memory for Quake to support those modes. - -The video modes listed in the Video Modes menu can be tested, set, and made -the default mode for Quake from the Video menu, as follows: - -* The arrow keys can be used to move the blinking indicator to any of the -modes listed in the Video menu. - -* Pressing the 'T' key tests the mode the blinking indicator points to, by -setting the mode, leaving it set for 5 seconds, and returning to the previous -mode. This lets you verify that your computer does in fact support that -mode. We highly recommend that you always test modes with 'T' before setting -them permanently by pressing the Enter key, in case some sort of hardware or -software glitch causes a mode to function incorrectly and produce a garbled -screen. It is unlikely but possible that testing or setting a mode will -cause your computer to hang or crash; if this happens, there is a serious -hardware or software bug, and you should not attempt to select that mode -again. - -* Pressing the Enter key sets the mode the blinking indicator points to, -leaving it set so Quake will then run in that mode. We suggest that you -test a mode by pressing the 'T' key before setting it by pressing the Enter -key. Note that a selection made with the Enter key remains in effect only -until Quake is exited (or a new mode is set). You must explictly make a mode -the default mode by pressing the 'D' key in order to automatically set that -mode when you start Quake up in the future. - -* Pressing the 'D' key makes the current mode the default mode that Quake -starts up with. Note that the current mode is the mode that's displayed in -white in the mode list, not necessarily the mode that the blinking indicator -points to. The current default mode is listed in the description of the 'D' -key at the bottom of the Video Modes menu. - -* Pressing Esc exits the Video Modes menu. - -Please see "Bug Reporting," below, for information on how to report any -problems you encounter. - - -Video modes from the console: Quick start ------------------------------------------- - -More comprehensive but more complex video control is available through the -Quake console. This section describes the commands necessary to perform -basic mode setting through the console (this is similar to what can be -accomplished through the Video Modes menu), and following sections describe -console video control in detail. - -To see all the video modes that are available, bring up the console (either -press tilde ('~'), or press Esc to bring up the menu, select Options, and -select Console... from the Options menu). - -From the console, type vid_describemodes to see all available modes. -Type vid_mode to set a mode, where is the mode number -listed for the desired mode by vid_describemodes. Higher-resolution modes -generally require more extra system memory in order to run, and many are -not available in 8 Mb systems; modes that are supported by the video -adapter but are currently unavailable due to system memory limitations -will still show up in the mode list from vid_describemodes, but will -have "**" in place of a mode number. (Such modes will not show up at -all in the Video Modes menu.) If you try to set a mode for which -there is insufficient system memory, you will receive a message to that -effect, and the video mode will remain unchanged. - - -More detail ------------ - -This version of Quake supports software drawing in a variety of -video modes. It does not support any 3-D hardware accelerators. -Video modes that are built into Quake are: - -320x200, 360x200, 320x240, 360x240, 320x350, 360x350, 320x400, -360x400, 320x480, 360x480 - -However, the higher-resolution modes on this list require additional -memory, and may not be available in 8 Mb systems. - -In addition, all VESA 2.0 256-color linear framebuffer modes -supported by the video adapter are supported. Further information -about VESA 2.0 is provided below. - - -Video mode reporting and selection ----------------------------------- - -Quake assigns each available video mode a mode number, which can -then be used to query information about the mode or to select the -mode. The first 11 mode numbers are always as follows: - -0: 320x200 -1: 320x200 -2: 360x200 -3: 320x240 -4: 360x240 -5: 320x350 -6: 360x350 -7: 320x400 -8: 360x400 -9: 320x480 -10: 360x480 - -You will notice that modes 0 and 1 are both 320x200; mode 1 is a -Mode X-style version, which may someday allow support of page -flipping for cleaner graphics, but right now it's just slower with -no advantages, so use mode 0 for 320x200 resolution. Modes 2-10 -are all higher resolution than mode 0, and look very nice, but are -also all slower than mode 0. Mode 0 is the fastest of the 11 -built-in modes. - -In addition to the built-in modes, Quake checks for the presence -of a VESA version 2.0 driver. If such a driver is detected, the -driver is queried for all 8-bit-per-pixel linear framebuffer (LFB) -modes that are supported; also, if no LFB 320x200 mode is available, -a banked 320x200 VESA mode is queried for. All such modes are added -to the mode list starting at mode 11. The available modes will vary -depending on adapter, graphics chipset, amount of video memory, and VESA -2.0 driver. The higher the resolution, the lower the performance, and -the higher-resolution modes will often be too slow for good gameplay -on most machines. (Also, higher-resolution modes often need more memory -than is available in an 8 Mb system.) The screen can be sized down to -improve performance in higher-resolution modes, but then of course the -effective resolution of Quake is reduced. - -At the same resolution, VESA LFB modes are often faster than the non-VESA -modes 0-10, because adapters often have faster memory access in LFB modes. - -If a given VESA mode can support page flipping, then it defaults to page- -flipped operation. A VESA mode can be forced to non-page-flipped operation -by setting the vid_nopageflip console variable to 1, then setting the mode - (note that vid_nopageflip takes operation on the next, not the current, mode -set, and note that it then stays in effect permanently, even when Quake is -exited and restarted, unless it is manually set back to 0). If there is not -enough memory for two pages in a VESA mode, or if the -adapter doesn't support page flipping, then the mode will automatically -be non-page-flipped. Page flipping can have higher visual quality, but may -be either faster or slower, depending on the graphics adapter and other -hardware. (See the discussion of the Pentium Pro, below, for a -discussion of why page flipping can be faster but is sometimes much slower -on that processor.) Page-flipped modes use less system memory than non- -page-flipped modes. - -Quake's VESA support, including VESA driver detection, can be disabled by -using the -stdvid command-line switch, and can also be disabled, along with -sound, network, and other hardware support, by the -safe command-line switch. - -The maximum resolution supported by Quake is 1280x1024. Modes with higher -resolutions will not be reported by vid_describemodes, and cannot be set. - -There is no support for any 3-D accelerator boards in this version of Quake. -Coming soon. - -Quake always starts up in mode 0, and modes 0-10 are always available, given -enough system memory. - - -A note on modes reported in the Video Modes menu ------------------------------------------------- - -The vid_describemodes console command lists all modes with -resolution less than or equal to 1280x1024 that are -supported by the video adapter, although modes for which there -is not enough system memory have "**" for the mode number. VGA, -Mode X-style, and VESA 2.0 modes are listed separately, so a -single resolution can be listed as many as three times, once for -each hardware mode that supports it. For example, mode 0 is -VGA mode 0x13, which supports 320x200 resolution, and mode 1 is -320x200 Mode X-style mode. Quake looks identical in both -modes, although it usually runs faster in mode 0. - -The Video Modes menu is much simpler. Only modes with resolution -less than or equal to 1280x1024 that are both supported by the -hardware and for which there is sufficient system memory are -listed. Further, a given resolution is listed only once. If a -given resolution is available in multiple hardware modes, then -selecting that resolution will select the appropriate hardware mode -as follows: - -If the mode is 320x200, then VGA mode 0x13 is selected, and -equivalent Mode X and VESA modes are ignored; - -Otherwise, the VESA version of the mode is used. - -You can always see what video mode is selected from the console by typing -the command: - -vid_mode - -command. - -None of this has any effect on selecting modes through the -console, where all the different versions of each mode are -listed, and the desired version can be selected by using the -appropriate mode number. - - -How to get VESA 2.0 support ---------------------------- - -Some video adapters have VESA 2.0 support in ROM. Other video -adapters come with loadable VESA 2.0 TSRs. In the absence of either -of these, UniVBE, a shareware product from SciTech, provides VESA 2.0 -support for most video adapters. The latest version of UniVBE can be -obtained from the following locations: - -www: http://www.scitechsoft.com -ftp: ftp.scitechsoft.com -CIS: GO SCITECH -AOL: Keyword SciTech - -SciTech can be contacted at: - -email: sales@scitechsoft.com - -SciTech Software -5 Governors Lane, Suite D -Chico, CA -95926-1989 - -The current version at this writing is UniVBE 5.2. This version -supports many more adapters than previous versions, and adds -a number of useful low- and medium-resolution modes, such as 400x300 -and 512x384. - - -Video-related commands ----------------------- - -vid_describecurrentmode - lists the description for the current video mode. - -vid_describemode - lists the description for the specified video mode, where is as - reported by vid_describemodes. - -vid_describemodes - lists descriptions for all available video modes. - -vid_mode - sets the display to the specified mode, where is as reported by - vid_describemodes. - -vid_nopageflip <1|0> - when set to 1, VESA mode sets will always select non-page-flipped - operation. When set to 0, VESA mode sets will select page-flipped - operation whenever possible. All non-VESA modes are always - non-page-flipped. The setting of vid_nopageflip is remembered - when Quake is exited (by being saved in config.cfg), and is reloaded - when Quake is restarted, so once vid_nopageflip is set to 1, all - VESA modes set in all Quake sessions after that point be will non-page- - flipped until vid_nopageflip is set to 0. Note that setting this - variable doesn't affect whether the current video mode is page-flipped, - but rather whether page-flipping can be used by future mode sets. - -vid_nummodes - reports the total number of modes available. - -vid_testmode - tries to switch Quake to the specified mode, then returns to the current - mode after 5 seconds. This allows you to try an untested mode without - ending up with a black screen if, for example, the monitor can't display - the mode properly. There may still be instances in which, due to VESA - driver or hardware bugs, the machine will hang in certain modes; - vid_testmode can't recover from these situations, but it can recover - from a blank or scrambled screen. - -vid_wait - sets the type of waiting that the video adapter should do, as follows: - 0: no waiting - 1: wait for vertical sync active - 2: wait for display enable active - -The default state of vid_wait depends on the video mode selected. -(_vid_wait_override can force vid_wait to 1, wait for vertical -sync; see the description of _vid_wait_override below.) -In built-in modes 0-10, the default is always 0, no waiting. You -can set vid_wait to 1 (wait for vertical sync) to eliminate shear -and tearing in these modes (so partially-completed frames are never -drawn, resulting in a rock-solid image). However, waiting for -vertical sync can result in substantial performance loss. - -In VESA modes, if the adapter is VGA compatible and there's enough -memory for three video pages, then triple-buffering is enabled and -vid_wait is set to 2, wait for display enable. There is little -performance loss to this sort of waiting. If the adapter is not -VGA compatible, or if there's only enough memory for double-buffering, -then vid_wait is set to 1 (wait for vertical sync). This can cause -significant loss of performance, but some sort of wait is generally -necessary to avoid occasional glitching of the screen when -page-flipping; we always choose the lowest-cost wait option that -seems to be safe to use. If there's only enough memory for one -page, or if vid_nopageflip 1 is in effect, then vid_wait is set to 0 -(no wait). As with modes 0-10, vid_wait 1 can be used to eliminate -shear, but at a performance cost. - -We have encountered problems with a few adapters in VESA modes when -vid_wait is set to 2 (wait for display enable). Apparently some adapters -just toggle display enable all the time, rather than only when pixels -are being sent to the screen; this can cause occasional glitches in -which the screen image jumps for one frame. You can fix this by -setting vid_wait to 1 (wait for vertical sync). We would have made -vid_wait 1 the default, but it's slower, and vid_wait 2 works on most -machines. - -The default setting for vid_wait can be changed from the console -at any time. If you are in a VESA mode that waits for vertical -sync and want to turn it off to get a speed-up, you can do so. -However, changing a vid_wait 1 default in a VESA mode may result -in problems. If vid_wait defaults to 1 (wait for vertical sync) -in a mode, and you force it to 2 (wait for display enable), the -machine may hang, because some VGA-incompatible adapters, such as -some ATI Mach64s, don't support the display enable status. If you -force vid_wait to 0 (no wait), then the screen may glitch periodically -if the page flips at a time that results in a bad flip address, -although some adapters work fine with no wait at all. - -If you force a new setting for vid_wait and encounter problems, DO -NOT send us a bug report! - -_vid_wait_override <1|0> - can be used to force wait for vertical sync in all modes. When - _vid_wait_override is set to 0, the type of waiting, if any, for - each video mode that's set thereafter is automatically set to - what appears to be the fastest safe state. However, it is - possible in some cases that automatic setting may result in some - screen glitching, and it is also true that shear can be - eliminated by waiting for vertical sync (although at a cost in - performance), so it may be desirable in some cases to override - the automatic wait selection and always wait for vertical sync. - This can be done by setting _vid_wait_override to 1. Once set, - this remains in effect through all succeeding mode sets, even - when Quake is exited and re-entered; the only way to keep Quake - from waiting for vertical sync once _vid_wait_override is set to - 1 is to set _vid_wait_override to 0. Note that changing - _vid_wait_override doesn't affect the current mode, but rather - takes effect on the next mode set. _vid_wait_override is initially - set to 0. - -_vid_default_mode - can be used to force Quake to start up in a particular mode. - The easiest way to select a default mode is by pressing the - 'D' key in the Video Modes menu, but you can alternatively - use _vid_default_mode to specify the mode in which you want - Quake to start up in future Quake sessions. _vid_default_mode - is initially set to 0. - - -Higher-quality perspective texture mapping ------------------------------------------- - -For maximum speed, perspective correction is performed only every 16 -pixels. This is normally fine, but it is possible to see texture ripples -in surfaces that are viewed at sharp angles. For more precise texture -mapping, set the console variable d_subdiv16 to 0. Doing this will result -in somewhat slower performance, however, and the difference in visual -quality will not normally be noticeable. - - -Known video problems and workarounds ------------------------------------- - -If you think you've encountered a bug, see "Bug Reporting," below. -As a general rule, go back to mode 0 if you have problems; mode 0 -should work properly in all cases. - -On some ATI Mach64 adapters, the palette is sometimes too dark in -some VESA modes, and is tinted oddly (too red, for example) in other -modes. The workaround is to use different modes, or modes 0-10. - -In modes 0-10, shear and tearing can occur as partially finished -frames are displayed. Workaround: set vid_wait to 1 (wait for -vertical sync); this can result in a substantial performance loss, -however. An alternative is to use a page-flipped VESA mode. - -In page-flipped VESA modes, occasional glitched frames may occur with some -VESA driver-hardware combinations. Workaround: set vid_wait to 1 (wait -for vertical sync) (you can set _vid_wait_override to 1 to make waiting -for vertical sync permanent for future Quake sessions), or use a different -mode. - -The VESA video drivers that come with some video adapters don't -support low-resolution modes such as 320x200; often, -nothing lower than 640x400 is supported. For example, -this is the case with some ATI adapters. There's nothing -Quake can do to provide low-resolution VESA modes in these -cases, because Quake simply supports whatever modes the VESA -driver chooses to report as supported. Unfortunately, 640x400 -is too high a resolution for really good performance unless you -have a very fast Pentium or a Pentium Pro, so on machines with -this sort of adapter, the VESA modes aren't very usable. -Workaround: Use UniVBE 5.2, which supports low-resolution modes -on a wide variety of adapters. Note that a few adapters simply can't -support low-resolution modes, in which case you'll have to stick with -the low-resolution VGA and Mode X modes that are built into Quake, -which run fine but may be somewhat slower than VESA modes. - -A few video adapters are almost but not fully VGA compatible, because -they don't support some unusual VGA video modes. In particular, a few -adapters don't support the 360-wide Mode X-style video modes that are -build into Quake (modes 2, 4, 6, 8, and 10), and display garbage in those -modes. Workaround: use different modes, such as 0, 3, 5, 7, 9, or any -VESA modes that are available. - -Under Win 95, the palette occasionally gets messed up when switching from -Quake to the desktop and back again. You can restore the palette by -bringing down the console (either press tilde ('~'), or press Esc to bring -up the menu, select Options, and select Console... from the Options menu), -and typing bf and pressing the enter key, to generate a background flash, -which sets the palette. Press Esc to exit the console. Alternatively, -setting the screen brightness, either from the Options menu or via the -gamma console variable, sets the palette. - -Under Win 95, if the system key (the key with the Win 95 flag on it) is -pressed while Quake is running fullscreen in a VESA mode, Win 95 may be -unable to switch back from the desktop to Quake, in which case it will -notify you of this, then terminate the Quake session. This is a quirk -of Win 95, and normally there is no workaround other than not to press -that key or not to use VESA modes. (Some people go so far as to remove -the system key from their keyboard.) However, you can -disable the system key for Quake with the following utility: - -http://www.microsoft.com/windows/download/doswinky.exe - -Switching away from Quake with Alt-Enter, Ctrl-Esc, Alt-Tab, or -Alt-Spacebar all work fine (except that if you disable the system key -with doswinky.exe, Ctrl-Esc will also be disabled). - - -Performance ------------ - -Quake's graphics should be adequately fast in mode 0 (320x200) on all -Pentium-class machines. If you feel Quake is running slowly, set the -showturtle console variable to 1; you will then see a turtle icon -appear in the upper left corner of the screen if the frame rate drops -below 10 frame/second. If you are getting the turtle, you are probably -not getting great gameplay. Performance can be improved in several ways: - -* size down the screen with the minus key - -* select a lower-resolution mode, if possible - -* use a VESA mode - -* if you're using a VESA mode and vid_wait is set to 1 (wait for -vertical sync) by default (you can check by typing vid_wait -in the console), you can try setting vid_wait to 0 or 2, as detailed -in the discussion of the vid_wait command above. Be aware that -risks of screen glitching or hung machines are associated with -overriding a default vid_wait 1 setting in VESA modes. - -To see how exactly fast Quake is running, bring up the console and type - -host_speeds 1 - -You will see a display at the top indicating total frame time in -milliseconds, and also server, graphics, and sound frame time in -milliseconds. (Note, though, that unless you also do - -snd_noextraupdate 1 - -sound time will actually show up as graphics time. However, -snd_noextraupdate 1 can cause sound to get choppy, so it's not -generally recommended.) - -Lower numbers are better. - -Type - -host_speeds 0 - -to turn off the frame time display. - - -Pentium Pro Performance ------------------------ - -The Pentium Pro is a very fast Quake platform, but has one weak spot; it is -by default very slow on writes to video memory. This means that in default -hardware configurations, you are usually much better off setting -vid_nopageflip to 1 if you use VESA modes, so drawing is done to system -memory instead of to video memory. Remember that you must set the mode -after setting vid_nopageflip to 1 in order to get vid_nopageflip to take -effect. (vid_nopageflip can sometimes be faster on a Pentium, too, but -not by nearly as much in general, and it's often slower.) - -The Pentium Pro has some special features that are not turned on by default, -but which can help Quake performance a LOT. These features can be enabled -by John Hinkley's program FASTVID, which can be obtained from -ftp://members.aol.com/JHinkley/fastvid.zip. Performance in 640x480 -mode on a Pentium Pro/150 nearly doubled after FASTVID was run; Quake -was very playable (and looked great!) at this resolution. - -There's the usual caution with FASTVID: It could conceivably make your -system run goofily, or who knows what. FASTVID is not a product of -id Software, and id makes no guarantees regarding FASTVID. In other words, -use FASTVID at your own risk. - -************************************************************************ -IMPORTANT NOTE: FASTVID works only on Pentium Pros!!! Please do NOT -contact either John Hinkley or id with problems concerning FASTVID on -Pentium or 486 machines. -************************************************************************ - - -Video Bug Reporting -------------------- - -If you encounter a video-related bug, please fill out the form found at the -end of this file and e-mail it to support@idsoftware.com. There are several -problems that are not bugs, and shouldn't be reported, including: - -* unavailability of some VESA modes; VESA modes are only supported by -Quake if they are 8-bpp, are LFB modes (except for 320x200), and are -no greater than 1280x1024 in resolution. If you have a VESA mode -that doesn't seem to be working properly, please contact the -manufacturer; we just use the information that the VESA driver -provides us with. - -* problems that occur when you change vid_wait from a default value -of 1 (wait for vertical sync) in VESA modes - -* sluggish performance on 486s - -* the known palette problem on some Mach64s. - -* the known palette problems switching from fullscreen to the desktop and -back under Win95. - -* the known problems switching back from the desktop in VESA modes after the -system (Windows flag) key has switched from fullscreen to the desktop. - -* video modes that are not listed in the Video Modes menu, or that are not -listed or are listed with "**" in the output from vid_describemodes; such -modes are either not supported by your video adapter, or cannot be supported -by Quake in the amount of memory your system has. High-resolution modes will -often not be available in 8 Mb systems. - -* 360-wide video modes that don't work although other resolutions do work - -* lack of low-resolution VESA modes; the availability of low-resolution modes -is the responsibility of the VESA driver. UniVBE 5.2 provides low-resolution -modes on most adapters. - -Apart from these, we would very much like to hear about any video -problems you encounter. - - -========================================== -== Sound Subsystem Documentation == -========================================== - -Quake's sound subsystem works only with Sound Blaster compatible sound -cards. For Quake to get the correct settings for DMA channel and PORT -address, you must set your BLASTER environment variable (or have it set for -you with the DIAGNOSE utility in your SB16 directory). If you do not have -the BLASTER environment variable set, your sound will not work. If your -sound card supports Sound Blaster compatibility, Windows 95 should set this -variable for you. - -Note: some sound cards do not have 100% Sound Blaster compatible -hardware, but emulate the Sound Blaster interface. Such cards may -display some inconsistencies relative to an actual sound blaster. -In particular, sound may be delayed on some cards. - -Note: it is possible for sound to get choppy if the frame rate -drops to a very low level, below 5 frames a second. A frame rate -that low will not provide a good gameplay experience, so if you -do experience choppy sound, your machine is almost certainly not -fast enough to run Quake satisfactorily in general. - -If (when) you see bugs, please use the form attached to the end -of these docs to submit a bug report. - -Sound Card Command Line Options, Commands, and Variables -================================================================== - -The commands and variables below work under any operating system. -Command-Line options are typed on the command line in most any place -but only in operating systems which support command line interfaces, -like DOS's COMMAND.COM, or NEXTSTEP's or Linux's csh, sh, or bash. -For example, under DOS, the NOSOUND option would be used like this: -"C:> quake -nosound". - -Command-Line Options --------------------- - -NOSOUND - Syntax: -nosound - Description: This will prevent *any* sound code from being executed. If - you are having technical difficulty with the game and then try - running the game with this option and the problem goes away, then - the problem is probably somewhere in the sound code. - -SSPEED - Syntax: -sspeed - Description: This will ask the sound code to set the playback speed - within the constraints of the capabilities of the card. This is - 11025 Hz by default and usually from 8000 to 44100. Making this - faster requires more CPU horsepower, and has no actual benefits, - because the sounds only contain 11 KHz data. Making this slower - degrades sound quality, but improves performance and saves memory. - -Commands --------- - -SOUNDINFO - Syntax: soundinfo - Description: This prints the "portable" information on your current - audio hardware setting in the game. It specifies whether there is - stereo output (0 or 1), the number of samples in the DMA buffer, the - current sample position (changes each time you run SOUNDINFO and - ranges from 0 to the number of samples), the number of sample bits, - the submission chunk (1 in DOS or Linux w/ mmaped sound, larger in - Linux w/o mmaped sound), playback speed in Hz, the DMA buffer address - in hexadecimal (usually 8 digits after the 0x, starting with 0xf00.. - in DOS, starting with 0x400.. in Linux, and less than 8 digits if the - hardware was not initialized successfully), and the number of - channels mixed in software (8 by default, changeable w/NUMCHANNELS - command). - -STOPSOUNDS - Syntax: stopsounds - Description: Stops any current looping sounds. - - -Sound Blaster Sound Card Command-Line Options and Commands -========================================================== - -The following applies to Sound Blaster cards or compatibles under DOS -or a DOS box. - -Commands --------- - -SBINFO - Syntax: sbinfo - Description: This will print information on the Sound Blaster card - in the system. If the version is 4 or greater, then it is some - kind of Sound Blaster 16 or compatible. Version 2 is an 8 bit mono - sound blaster, Version 3 is an 8 bit stereo sound blaster pro. - The port is the I/O port sensed from the A variable in the BLASTER - environment variable. The DMA is the DMA channel and is confirmed in - hardware if the card is version 4 or higher. The mixer port can be - ignored. - - -========================================== -== CD Audio Subsystem Documentation == -========================================== - -Overview -======== -Quake is designed to play background music off of a CD-ROM. The Quake CD has -music tracks on it and each level has been assigned a track that will be -played. - -Win95 Users: Putting a CD other than the Quake CD into the drive when Quake -is already running will sometimes cause another Windows application to start -and switch you back to Windows with Quake running in the background. You -will probably want to stop whatever was started and switch back to Quake as -quickly as possible... especially if you are playing deathmatch. - - -Command Line Parameters -======================= --nocdaudio - This will prevent the CD audio system from even attempting to initialize. - No CD commands or functions will be available. The game will just run - with no music. - --cdmediacheck - This causes the game to periodically check to see if the CD has been - removed and a new one placed in the player. It is off by default since - this operation is very slow on some CD players and is not needed under - Win95. There is normally no reason to enable this option; it would - only be useful if you were going to be changing the CD from within the - game on a regular basis. - -Commands -======== -There is normally no reason you would need to use any of these commands. If -you are playing Quake with the Quake CD in your CD-ROM drive, the appropriate -music track will be played automatically. - -cd on - Re-enables the CD audio system after a "cd off" command. - -cd off - Shuts down the CD audio system. No more music will be played unless it - is re-enabled. - -cd reset - Causes the CD audio to re-initialize. This is useful if you change - CDs or insert the CD after you've already run Quake. - -cd play - Plays the specified track one time. - -cd loop - Plays the specified track. It will be repeated until either it is - manually stopped or another track is started. - -cd stop - Stops the currently playing track. - -cd resume - Will resume playback of a stopped track. - -cd eject - This is for CD players that do not have a manual eject button. - -cd remap ... - Allows you to switch what tracks are played. This is especially useful - if you want to play music other than that on the Quake CD. If the CD - audio system is told to play track 1, it will instead play the 1st - track you specified. For example: assuming a CD with 1 data track and - 8 music tracks, the command "cd remap 1 9 8 7 6 5 4 3 2" would leave - the data alone and play the audio tracks as if they had been placed on - the CD in the opposite order. - -cd info - Reports information such as the number and types of tracks on the current - CD, what track (if any) is currently playing, and the playback volume. - - -Variables -========= -bgmvolume - The background music volume. Valid values are 0.0 though 1.0. Changes - will normally be made using the options menu. - - Not all CD-ROM players support variable volume. The 0.0 to 1.0 value - translated to a value from 0 to 255 before it is passed to MSCDEX. How - this value is interpreted varies from drive to drive. The only thing - required by the MSCDEX specification is that 0 is off and anything else - is on. Some CD-ROM drives only have on and off so change to bgmvolume - will have have no effect on volume once it is on. - - -Messages -======== -CDAudio_Init: MSCDEX version 2.00 or later required. - MSCDEX was either not loaded, or is a version earlier than 2.00. - -CDAudio_Init: First CD-ROM drive will be used - MSCDEX reported that the system has more than one CD-ROM drive. - Quake will always use the first drive in this case. - -CDAudio_Init: Unable to allocate low memory. - We were unable to allocate the memory needed to communicate with MSCDEX. - Although the game can still run, this indicates a severe low memory - condition. - -CD Audio Initialized - Indicates that the CD audio system has successfully initialized. - -CDAudio_Play: Bad track number N. - We attempted to play a track number that that is outside the range of - tracks recorded on the CD currently in the CD-ROM drive. Probable causes - are that a CD other than Quake is in the player, or a custom level has - specified an invalid track number. - -CDAudio_Play: Can not play data. - A valid track was requested to be played, but it was a not an audio track. - The probable causes are the same as for a bad track number. - -CDAudio_Play: track N failed - A valid audio track was going to be played, but the play command to MSCDEX - returned an error. - -CDAudio: media changed - This is simply a notification. It can only occur if the "-cdmediacheck" - option was specified on the command line. - -CDAudio: Error - playback stopped N - An error occurred while the CD was playing audio. Playback has been - stopped and no further automatic play will be attempted; the game will - proceed without music. - -CDAudio_Init: No CD in player. - MSCDEX reported an error while Quake was attempting to get information - about the current CD. There is either no CD in the player, or it was - unable to get the track information. No automatic CD play will be - attempted; the game will proceed without music. - - -========================================== -== Network Subsystem Documentation == -========================================== - -Overview -======== - -Quake is a client/server game. You are always running over some type of -network. In a standalone game, you are using a loopback network; it just -passes messages back and forth in memory buffers. This readme is talking -about real networks and multiplayer deathmatches. There are three main -sections: commands, LANs, and Serial. - -Most normal configuration can be done via the game menus. - -There are two types of Quake servers: dedicated and listen. A listen server -is a machine that is used to play the game and also hosts the game for other -players. A dedicated server only hosts the game; it runs in text mode and -does not let anyone play on that machine. A single player game is really -just a 1 player listen server that doesn't listen for network connections. - -Dedicated vs Listen. I'll try to make this simple: it is always better to -use a dedicated server. Why? Fairness and playability. With a listen -server, the person on the server always has advantages. They will always be -the first person into a level, they will always have zero latency, and they -will get a server update on each and every frame. On a dedicated server -everyone gets equal treatment. Getting into the server is a first come, -first served proposition; latency is determined by each player's connection; -and everyone is sent the same number of updates. It's about as fair as life -gets. By the way, a good 486 machine works nicely as dedicated server. - -Another suggestion. Until there is a native Win95 version of Quake, IPX will -usually provide better gameplay on a local area network. This is due to the -delicate balancing act that is required to let a DOS program use the Win95 -TCP/IP stack. - -To start a Dedicated Server, you invoke Quake with the "-dedicated" -command-line parameter. When the server starts, you can type any command -that you would normally type in the Quake Console, such as "map e1m1" to -start the server on a specific map. This can be done from the command- -line as well by typing "quake -dedicated +map e1m1". If a value is entered -after "-dedicated", that is the amount of players allowed to connect, up -to a maximum of 16 players. A dedicated server will quit to the OS whenever -a fraglimit or timelimit is reached. Example: "quake -dedicated 16" will -start a 16-player dedicated server. - -To start a Listen Server, you invoke Quake with the "-listen" command- -line parameter, or use the Multiplayer menu in the game. Starting a listen -server from the command-line will allow you to handle more than 4 players, -as 4 is the limit when starting a game from the Multiplayer menu. If a -value is used after the "-listen", that is the maximum amount of players -allowed, up to 16 players. - -Command Line Parameters, Commands, and Variables -================================================ - -Command line parameters ------------------------ --nolan - Disables IPX, TCP/IP, and serial support. - --noudp - Disables support for TCP/IP. - --udpport - Specifies a UDP port to be used other than the default of 26000. - --noipx - Disables support for IPX. - --ipxport - Specifies a IPX port to be used other than the default of 26000. - --noserial - Disable serial support. - --mpath - Enables support for code to use Win95's TCP/IP stack. Do NOT use this - under DOS! - --listen [n] - Starts Quake ready to be a non-dedicated server for up to - players. If you do not specify a number after -listen it will - default to 8. The maximum allowed value is 16. - --dedicated [n] - Starts Quake ready to be a dedicated server for up to players. - If you do not specify a number after -listen it will default to 8. - The maximum allowed value is 16. A dedicated Quake server stays in - text mode. This is the Quake console with most commands still - available; those that make no sense (like vid_mode) are ommitted. - -Console Variables ------------------ - -net_messagetimeout - Specifies how long Quake should wait for a message to arrive before - deciding the connection has died. The default is 3 minutes. For - reference, messages usually arrive at the rate of about 20 per second. - -hostname - This is the name for your server that will show up on an slist - (see below). The default value is "unnamed". - -sys_ticrate - Only used by dedicated servers. This determines the rate at which the - server will send out updates to the clients. The default value is 0.05 - (20 updatesper second). For servers where bandwidth is limited, using - modems or the internet for example, it is advisable to lower this value - to 0.1 (10 updates per second). This will have a very minor effect on - responsiveness, but will half to outbound bandwitdh required making the - modem players a lot happier. - - -Console commands ----------------- - -net_stats - This is for debugging. It displays various network statistics. - -slist - Looks for Quake servers on a local LAN (or over a null modem - cable). This will NOT go outside the local LAN (will not cross - routers). - - -LANs -==== - -Here are the LANs that are supported by the Quake test -release. For each one, you'll be told how to connect to a server -*if it is not on your local network*. If it is, you can use the -"slist" command and connect by hostname. See the main readme for -a discussion of the connect command. - -IPX ---- - -Quake has been run with Novell's ODI IPX stack under DOS, PDIPX with packet -drivers under DOS, and the Microsoft IPX stack in a Win95 DOS box. When -connecting to a server using IPX, you specify its network:nodeaddress (like -12345678:1234567890AB). If you are on the same network, you can just specify -the node address. If you are doing a connect command from the console, a -full IPX address must be enclosed in quotes. - -For example, the server's IPX address is "00FADE23:00aa00b9b5b2", you would -enter: connect "00FADE23:00aa00b9b5b2" - -Win95 TCP/IP ------------- - -Please see the Win95 section of this file for details about playing using -TCP/IP under Win95. - -Kali ----- - -To Quake, Kali appears to be IPX. Once you've got Kali up and running, run -Quake as if it was on an IPX network. - -Beame & Whiteside TCP/IP ------------------------- - -This is the only DOS TCP/IP stack supported in the test release. -It is not shareware...it's what we use on our network (in case you -were wondering why this particular stack). This has been "tested" -extensively over ethernet and you should encounter no problems -with it. Their SLIP and PPP have not been tested. When connecting -to a server using TCP/IP (UDP actually), you specifiy it's "dot notation" -address (like 123.45.67.89). You only need to specify the unique portion -of the adress. For example, if your IP address is 123.45.12.34 -and the server's is 123.45.56.78, you could use "connect 56.78". - -Playing over the Internet -------------------------- -Yes, you can play Quake over the Internet. How many people can be in -the game? That depends. How smooth will the game be? That depends. -There are just too many variables (bandwidth, latency, current load, -etc...) for us to make any kind of promises about Internet play. - - -Serial/Modem -============ - -The Quake serial driver supports two COM ports. Although they are referred -to as COM1 and COM2, you can configure them to use any normal hardware -COM port (1 thru 4 on most PCs). The com ports are used with interrupts, -so their IRQ may not be used for another purpose (such as a LAN adapter -or sound card). The IRQ may not be shared with another device either; -not even another COM port. A client can only be connected to one server -at a time, so multiple ports are really only useful on a server. -When using modems, the client must originate the call and the server -must answer. This holds true even for a two player, non-dedicated -server configuration. - -In the Multiplayer menu, the default modem string is "ATZ". If your modem -games are too slow, you can change this string to the appropriate one for -your modem as listed below in the "Modem Strings" section. - - -The COMx commands ------------------ - -Use the menus for serial play whenever possible. The console -interface is only for unusual configurations. It is much more -difficult to understand and use correctly. - -Those of you who do use the console commands for serial play need to -know that the menus always use the first Quake COM line (COM1); yes, -even for COM2. The names COM1 and COM2 here mean the first and second -serial ports, not necessarily the PC COM1 and COM2 ports (although those -are the default configurations). - -There are two commands to support serial/modem play for Quake. They -are: COM1 and COM2. Entering one of these commands with no arguments -will display the status of that serial port, similar to this: - -Settings for COM1 -enabled: true -connected: false -uart: 16550 -port: 3f8 -irq: 4 -baud: 57600 -CTS: ignored -DSR: ignored -CD: ignored -clear: ATZ -startup: -shutdown: ATH - -When used with arguments, these commands change the settings and -status of the COM ports. The possible arguments are listed below; -examples follow. - -enable | disable - "enable" means that your configuration is complete and you want to use - the COM port. "disable" is used to turn off a COM port, usually to - change its settings. The default (initial) state is disabled. - - -modem | direct - Use one of these two to let Quake know if you are using a modem or a - direct connection (also called a null modem). Quake uses this to know - if it needs to handles modem initialization strings, dialing sequences, - and hangup procedures. - -reset - This will reset the COM port to its default settings and state. - - -port -irq - These are used to set the I/O Port and IRQ that your serial port uses. - The default values are: port=3f8 irq=4 for COM1 and port=2f8 irq=3 for - COM2. Note that the port number is displayed in hexadecimal; to enter - it you would use something like "COM2 port 0x2f8"; the "0x" preceding - the "2f8" indicates that you are giving the value in hexadecimal - otherwise decimal is assumed. - - -baud - Sets the baud rate. Valid values for are: 9600, 14400, - 28800, 57600, and 115200. 57600 is the default. Please note that - this is the baud rate used for the uart, not your modem. It is - perfectly valid to use 57600 on a COM port that is connected to a - 28.8 modem. - -8250 | 16550 - Specifies the type of uart chip in your system. Normally this is - automatically detected, one of these need only be used if your chip - is incorrectly detected. - -clear -startup -shutdown - This allows you to specify the clear, startup, and shutdown strings - needed for a modem for playing Quake. If you've found values that - previously worked with Doom, use them here. If you are playing over - a null modem cable, leave these blank. - --cts | +cts --dsr | +dsr --cd | +cd - These determine if certain serial control lines should be honored or - ignored. The "-" means you want that line ignored, the "+" means to honor - it. "cts" is an abbreviation for "clear to send", "dsr" for - "data set ready", and "cd" for "carrier detect". Do not change these - values unless you are absolutely positive you need to. The default is to - ignore all 3 lines. - -Quake always uses no parity, 8 data bits, and 1 stop bit; these -values can not be changed. The baud, port, irq, and uart type can -not be changed on an enabled port, you must disable it first. - - -Configuration examples ----------------------- -Example1: You have a machine with two serial ports you are going -to use as a Quake server. COM1 will be using a null modem cable and -COM2 will be connected to a 14.4 modem. You would use commands similar -(the startup string would almost certainly be different) to these: - -COM1 baud 57600 enable -COM2 baud 14400 modem startup AT\N0%C0B8 enable - - -Example2: You are going to use your machine to connect to a dial-up -Quake server with your 28.8 modem connected to COM2. You would -use a command something like this: - -COM2 baud 57600 modem startup AT\N0%C0B8 enable - -Note the baud rate is not the same as the modem speed. This allows -the modem-to-uart communications to occur at a higher rate than -the modem-to-modem communications. - -Connecting to a serial Quake server ------------------------------------ - -Connecting to a Quake server over a serial/modem connection is done -using the "connect" command. The command "connect 5551212" would try to -connect to a Quake server at the phone number 555-1212. Note: your local -phone company would probably appreciate it if you didn't try this number! - -If you are using a null modem cable, you can type "connect #". -Quake will then attempt to connect to the server. - - -Known problems / workarounds -============================ -Packet drivers with PDIPX - there is a bug that stops a server running on -this combination from responding to the slist command. Use the patched -version of PDIPX included with Quake to correct this problem. - -SLIST sees no servers - Some PCMCIA ethernet cards and PPP drivers will -not do the UDP broadcasts needed for the SLIST command (search for local -games from the menu) to function correctly. In these cases you must -connect to a Quake game using either its IP address or hostname -(DNS resolvable hostname, not the hostname variable in Quake). - -"BW_OpenSocket failed: 5" - This error is specific to the Beame and -Whitesdie TCP/IP stack. This stack uses DOS file handles as it's -socket handles. This error occurs when DOS runs out of file handles. -You need to increase the number specified by "FILES=" in the DOS -config.sys file. - -Severe lag using TCP/IP under Win95: - - Occasionaly when you first connect in to a Quake game using Win95 -TCP/IP you will experience severe lag and not be able to control your -player's actions. This usually clears up in 10 to 15 seconds. - - There is apparently a strange limbo state for Microsoft's File and -Print sharing. This has been seen when it was installed and then later -removed, but it still appears on the menus. For some unknown reason -this causes severe lag for a Quake game. You need to go back and make -sure that it is either completely installed or removed. - - -========================================== -== Modem Strings == -========================================== - -Boca M1440i (internal): -ATS48=0S37=9S46=136%C0%E0%M0&K0&Q0&R1&C1&D2\G0\N1N0 - -Boca 14.4k (internal): -AT&C0N0S37=9&K0W0&Q0S36=3S48=128%C0 - -Boca 14.4 Fax/Modem -AT S46=0 S37=9 N0 &Q0 &D2 &K4 - -Boca 14.4k (external): -AT &F S0=1 S36=0 &K0 &Q6N0S37=9 &D2 - -Boca 14.4k: -AT S46=0 S37=9 N0 &Q0 &D2 &K0 %C0 - -Cardinal 14.4k v.32bis, v.42bis Fax/Modem: -AT &F N0 S37=9 &Q0 &D2 \N1 - -Digicom Systems (DSI) (softmodem): -AT Z \N0 &D2 &K0 S48=48 - -Digicom Systems Scout Plus: -ATZ*E0*N3*M0*S0*F0&D2 - -Gateway Telepath: -AT &F S37=9 %C0 &K0 &Q6 \G0 - -Gateway Telepath 14.4k: -AT S46=0 S37=9 N0 &Q0 &D2 &K0 %C0 - -Gateway Telepath I: -AT S0=1 &N6 &K0 &M0 - -Gateway Telepath II: -AT S0=1 S37=9 %C0 &Q0 &K0 - -Generic v.32bis 14.4k Fax/Modem: -AT \N0 %C0 B8 - -Generic 14.4k Fax/Modem: -AT S46=0 S37=9 N0 &Q0 &D2 %C0 \G0 &K0 - -GVC 14.4k (internal): -AT &F B8 \Q0 - -Hayes 28.8k V.FAST Modem: -AT &Q6 &K S37=9 N %C0 \N0 - -Infotel 144I: -AT&Q0 S37=9 N0 &D2 - -Infotel 14.4: -&F0 \N1 &D2 S37=F8 - -Intel 14.4k: -AT \N0 %C0 \Q0 B8 - -Intel 14.4k (internal): -AT Z B8 Q1 \C0 \N1 %C0 \V "H - -Linelink 144e: -AT &F &D1 &K0 &Q6 S36=3 S46=136 %C0 -19200 - -Microcom AX: -&F \N1 \Q0 &D2 - -Microcom QX/4232bis: -AT %C0 \N0 - -Netcomm M7F: -AT &E &K0 B0 \V0 X4 &D2 \N1 \Q0 #J0 #Q9 %C0 - -Nokia ECM 4896M Trellis V.32: -AT Z %C0 /N0 - -Nuvotel IFX 14.4 (internal): -&F \N1 &D2 - -Practical Peripherals 14400FX v.32bis: -AT Z S46=0 &Q0 &D2 - -Practical Peripherals 14400FX v.32bis: -AT S46=0 &Q0 &K0 &D2 - -Supra: -AT &F0 S46=136 %C0 - -Supra (external): -AT &K &Q &D \N1 - -Supra 14.4k v.32bis: -AT &F S46=136 &Q0 &D2 - -Supra 14.4k v.32bis: -AT &K &Q &D \N1 - -Supra Fax Modem 14.4K v.32 bis -AT &F %C0 S48=7 Q0 V1 W1 - -Telepath 14.4k: -AT &F&M0&K0&N6&H0 S0=1 - -Twincomm DFi 14.4: -AT&F &Q0 %C0 S37=9 &D2 - -UDS V.3223: -&F \N1 \Q &D2 - -UDS Fastalk 32BX: -&F0 \N1 &D2 - -USR Courier v.32bis: -ATS0=1 S7=60 E1 Q0 V1 &C1 &D2 &H0 &K0 &M0 &N6 &A3 - -USR Courier HST/DS 16.8k: -First reset the modem in a communication program with AT&F&W -AT X4 B0 &A0 &B0 &H2 &I0 &K0 &M0 &N6a - -USR DS v.32bis v.42bis (external): -AT&m0&n6&a0&r1&h0&k0&i0&s0&b1x1 - -USR Sporster 9600: -AT&M0&K0&N6 - -USR Sportster V.34 28.8 (note: works best at 19200 baud): -AT &F &M0 &I0 &K0 &B0 &N0 - -USR Sportster 14.4k Fax/Modem USING ERROR CORRECTION: -AT S0=1 S7=60 E1 QO V1 &C1 &D2 &K0 &N6 &A3 - -USR Sportster 14.4k Fax/Modem (internal): -AT &F&M0&K0&N6&H0 - -USR Sportster 14.4k (internal): -AT &F &B1 &H0 &I0 &K0 &M0 &N6 &R1 - -USR Sportster 14.4k: -ATS0=1S7=60E1Q0V1&C1&D2&K0&N6&A3 - -USR Sportster 14.4k: -AT &F0 &K0 &M0 &N6 &H0 &I0 &B1 &R1 - -USR Sportster 14,000 Fax Modem: -AT S0=2 &N6 &K0 &M0 &I0 &H0 &R1 &A0 V1 X4 - -USR 14.4k: -AT &F&A0&K0&M0 - -USR 14.4k -AT &K0 &H0 &D0 &I0 &R1 - -USR 14.4k Dual Standard -ATB0&R1&B1&N6Q0X4&A0&D2&H0&I0&K0&M0M1 - -USR (model?): -&F E1 V1 X4 &C1 &D2 &N0 - -ViVa 14.4k: -AT&F&Q6\N0%C0&D2N0S37=9 - -ViVa modem (internal): -&F&Q6\N0%C0&D2N0S37=9 - -Zoltrix model 14/14 VE: -AT S0=Q0 V1 &C1 &D2 W2 &Q0 - -Zoom 14.4k VFX: -AT&Q6S37=9N0%C\N0 - -Zoom 14.4k VFX: -AT&Q6S37=11N0%C&K0 - -Zoom OEM Modem: -AT&Q6S37=9N0&K0 - -Zyxel U-1496E: -AT Z &N4 &K0 - - -========================================== -== Win95 Documentation == -========================================== - -Quake is a DOS application. However, it runs fine from the MS-DOS prompt -under Win95, so long as the Properties for the MS-DOS prompt are set up so -that Quake can run. (See "Set the MS-DOS Prompt Properties", below, for -information about setting MS-DOS Prompt Properties.) Quake will NOT run -under Windows NT. Following are some steps that can help Quake run better -under Win95. - - -Have enough memory ------------------- - -Quake requires at least 16 Mb of installed memory in order to run under -Win95. - - -Set the MS-DOS Prompt Properties --------------------------------- - -If Quake won't run, the MS-DOS Prompt Properties may not be set correctly. -To set the Properties for the MS-DOS prompt, bring up a DOS session, and -either click on the MS-DOS icon in the upper left corner or press -Alt-Spacebar, then select Properties from the menu that comes up, and make -sure the following settings are correct. - -In the Program sheet of MS-DOS Prompt Properties, make sure the "Suggest -MS-DOS mode as necessary" is checked. - -In the Memory sheet of MS-DOS Prompt Properties, make sure all five fields -are "Auto". - -In the Screen sheet of MS-DOS Prompt Properties, set "Usage" to Full-screen. - -In the Misc sheet of MS-DOS Prompt Properties, uncheck the "Allow screen -saver" box, and check the "Always suspend" box. - - -Make sure there's enough free disk space ----------------------------------------- - -If you get error messages like "can't lock memory" under Win 95, or if you -get other weird, inexplicable errors, make sure you haven't run out of disk -space; delete some files if necessary. You can see how much disk space is -free by bringing up "My Computer" and clicking on the disk icon; the free -disk space will be shown at the bottom of the window. - - -Run fullscreen --------------- - -Quake can run in a window under Win95--but it will run very slowly. You are -unlikely to get satisfactory performance unless you run Quake fullscreen. -Quake normally comes up fullscreen under Win95; if you have switched it back -to windowed mode, you can get that window back to fullscreen by clicking on -it and then pressing Alt-Enter. - - -Shut down other applications ----------------------------- - -Many Win95 apps and DOS apps run even when they're not the foreground -application. Such applications contend for system resources such as memory, -processor cycles, and sound hardware. If Quake seems to be running choppily, -if sound is garbled, or if the disk is going all the time, try shutting down -whatever other applications you have running. For example, some players -have reported that Quake does not run as well when the Office shortcut bar -is running. - - -Restore the palette if it gets garbled --------------------------------------- - -Under Win 95, the palette occasionally gets messed up when switching from -Quake to the desktop and back again. You can restore the palette by -bringing down the console (either press tilde ('~'), or press Esc to bring -up the menu, select Options, and select Console... from the Options menu), -and typing bf and pressing the enter key, to generate a background flash, -which sets the palette. Press Esc to exit the console. Alternatively, -setting the screen brightness, either from the Options menu or via the -gamma console command, sets the palette. - - -Avoid the system key --------------------- - -Under Win 95, if the system key (the key with the Win 95 flag on it) is -pressed while Quake is running fullscreen in a VESA mode, Win 95 may be -unable to switch back from the desktop to Quake, in which case it will -notify you of this, then terminate the Quake session. This is a quirk -of Win 95, and there is no workaround other than not to press that key -or not to use VESA modes. (Some people go so far as to remove the system -key from their keyboard.) Switching away from Quake with Alt-Enter, -Ctrl-Esc, Alt-Tab, or Alt-Spacebar all work fine. - - -Give Quake more and/or locked memory ------------------------------------- - -By default, Quake tries to allocate 8 Mb of unlocked memory for heap space -under Win 95. More memory helps Quake run faster; you can allocate more -memory for Quake under Win95 by setting the command-line switch - --winmem x - -where x is the number of megabytes to allocate for Quake. If there's enough -memory in the system, the larger the number, up to about 16, the better the -performance. If, however, there isn't enough memory in the system, or many -other applications are running, the larger number can just cause Quake to -page to disk a lot, and can actually slow performance considerably. Also, -higher numbers can also cause Win 95 to take longer to start Quake and take -longer to return to the desktop afterward. If you have 32 Mb or more in your -machine, -winmem 16 should provide the best performance for Quake. If you -have less than 32 Mb, or a lot of applications running, then you will have -to experiment to find the best amount of memory to allocate for Quake. - -You may optionally instruct Quake to lock itself in memory by using the -command-line switch - --winlock - -so it won't get paged out by other applications. This can avoid hitches when -parts of Quake get paged into and out of memory, and thus provide a smoother -playing experience. On the other hand, it can cause Quake to take longer to -start, and can make the return to the desktop take longer when Quake ends, -because Quake has been hogging a lot of memory. It is even possible, if most -of the memory in the system is locked by Quake, that it will take many -minutes to switch back to the desktop while Quake is running, so the system -will effectively be nearly frozen. Therefore, use -winlock with caution; -Quake is not as well-behaved a Win95 citizen when -winlock is specified, and -does not share resources particularly well. - --winmem can be used in conjunction with -winlock; if -winmem specifies more -memory than is available to be locked, then Quake will lock as much memory -as possible. Being too aggressive about how much memory is locked can -actually slow Quake performance, because unlocked parts of the system like -system CD and sound code and data can then be forced to page, so if you do -lock memory, you will have to experiment to find the sweet spot, unless you -have 32 Mb or more of memory. - --winlockunlock can be specified as an alternative to -winlock, to tell Quake -to lock its memory when it starts, then immediately unlock it. The -advantages of doing this are: 1) it forces all of Quake's pages into memory, -so no pages should need to be brought in as Quake runs, making for smoother -running at the start, and 2) it enables Quake to determine whether the -specified amount of memory (if -winmem is also specified) is available in the -machine, so you can be sure Quake won't try to allocate more heap space than -the the amount of physical memory that's actually available. Like -winlock, --winlockunlock causes Quake to take quite a bit longer to start up, but it -has the advantage of making Quake a good Win95 citizen if you need to switch -back to the desktop, or have other apps running. - -In general, Quake will run fine without any of the -winxxx switches, but you -may find that one or more of them--particularly -winmem if you have more than -16 Mb--helps Quake performance on your machine. - -None of this is an issue under DOS itself (as oppsed to a DOS box under -Win95), because Quake just uses all the memory in the machine under DOS. - -By default, Quake tries to allocate 8 Mb of unlocked memory for heap space - - -Watch out for limbo subsystems ------------------------------- -Microsoft's File and Print sharing and IPX protocol stack have both been -known to cause strange problems when they are in a limbo state. The limbo -state is seems to be an uninstall that did not complete succesfully. Both -of these cause poor network play performance. If you are experiencing -severe lag, check the File and Print services. If you the warning "IPX -driver send failue: 04", check the IPX protocol stack. They need to be -either completely installed or removed; the problems only occur when they -get into this strange semi-installed state. - - -========================================== -== Key Binding and Aliases == -========================================== - -Pressing the tilde key ("~") will bring down the console (pressing the -tilde key or ESC while in the console will close the console). From the -console you can adjust your player controls, this is done by "binding" -keys to commands. The format for binding keys is as follows: - -bind - -Where is a valid key control and is a valid quake command. - -Example: -To bind the j key to the 'jump' command, you would type: -bind j +jump -and press enter. - -Non-printable keys such as 'page up' and buttons from the mouse/joystick are -bound in the same manner as printable characters. A list of bindable keys can -be found at the end of this file. - -Example: -To bind the page up key to the 'jump' command, you would type: -bind pageup +jump -and press enter. - -To bind the right mouse button to the attack command, you would type: -bind mouse2 +attack -and press enter. - -The alias command is used to create a reference to a command or list of -commands. When aliasing multiple commands, or commands that contain -multiple words (such as "fraglimit 50"), you must enclose all the commands -in quotation marks and separate each command with a semi-colon. - -Example of an alias that changes some Deathmatch server parameters: - -alias net_game "hostname my_server ; fraglimit 15 ; timelimit 15" -bind INS net_game - -Once the server is spawned (you must be the one running the -listen server), -you just push the Insert key to set the hostname, frag limit and time limit -of the server. So now the first person to 15 frags, or with the one with the -most frags in 15 minutes, wins. - -Another example would be to change to the Rocket Launcher, fire one rocket, -and change back to the Double Barrel Shotgun, when you press the "," key: - -alias rl_dbsg "impulse 7 ; +attack ; wait ; -attack ; impulse 3" -bind , rl_dbsg - -Aliasing is very powerful, allowing you great flexibility, so you should -experiment by aliasing different commands in various ways. - -A list of common commands can be found in the next section. - - -========================================== -== Quake Keys and Common Commands == -========================================== - -The following keys can be bound: - -A-Z 0-9 -*F1-F12 *TAB -ENTER SPACE -BACKSPACE UPARROW -DOWNARROW LEFTARROW -RIGHTARROW ALT -CTRL SHIFT -INS DEL -PGDN PGUP -HOME END -PAUSE SEMICOLON - -MOUSE1 (mouse button 1) -MOUSE2 (mouse button 2) -MOUSE3 (mouse button 3) - -*~ (tilde) - -* Can only be bound on the command line or in a .cfg file. - -The ESC key cannot be bound. - - -========================================== -== Making a Config File == -========================================== - -The commands (bindings and aliases) discussed above can be included into a -file containing all of your personal configurations, known as a "config" -file. This file can then be loaded during game play to enable all your -personal bindings and settings. - -To do this, use your favorite editor to create a new file, such as -"fragmstr.cfg". Your .cfg file MUST be located in the quake\id1 directory -or quake won't find it. Then after launching Quake, you would type "exec -fragmstr.cfg" and press enter, from the console. You can also exec you .cfg -file from the DOS command prompt by typing "quake +exec fragmstr.cfg". -When you exec a config file, it is the same as typing all the lines in your -config file into the console, only Quake does it for you. Here is an -example config file (c:\quake\id1\bear.cfg) and the meaning of all the -bindings, aliases and settings: - --------------------------------cut here------------------------------------- -name player1 // Sets player name to player1 (lets your opponent - // know who fragged them) - -sensitivity 4 // Sets the mouse sensitivity to 4 - -scr_conspeed 5000 // Sets the console raise/lower speed - -lookspring 0 // Sets Mouse Look Spring to 0 (0=keep looking, - // 1=spring back, when mouse button is released) - -vid_mode 10 // Sets Video Mode to mode 10 (360X480 resolution) - -gamma .8 // Sets Gamma Correction to .8 (<1=Lighter, 1=normal - // and >1=darker) - -viewsize 70 // Sets the Screen View size to 70 degrees - -bind mouse1 +forward // Binds the left mouse button to Move Forward - -bind mouse3 +attack // Binds the middle mouse button to Fire - -bind mouse2 +mlook // Binds the right mouse button to Mouse Look - -bind HOME "save bear1" // Binds the Home Key to quick save, saves to - // bear1.sav - -bind ENTER +showscores // Binds the Enter key to show Deathmatch Scores - -bind SHIFT +speed // Binds the Shift key to Run - -bind CTRL +jump // Binds the Control key to Jump - -bind ; +mlook // Binds the ; key to Mouse Look also - -bind . +moveleft // Binds the . key to Strafe Left - -bind / +moveright // Binds the / key to Strafe Right - -color 3 4 // Makes Uniform Top green and Pants Red for Net play - -alias rl_dbsg "impulse 7 ; +attack ; wait ; -attack ; impulse 3" - -bind , rl_dbsg // Aliases single rocket attack command and binds - // it to the ',' key. --------------------------------cut here------------------------------------- - - -========================================== -== Demos == -========================================== - -The standard Demos ------------------- - -Quake has 3 standard demos that start playing when you first run the game. -It will cycle through these demos until you start or join a game. - -Recording a Demo ----------------- -"record [track]" This starts up level and begins -recording a demo into a file name .dem. You can specify the -optional to choose a background music from the CD, otherwise the -default selection for that map will be played. - -Playing a Demo --------------- -"playdemo " This command will open the file .dem and -play the demo. - -How to not play the standard demos at startup ---------------------------------------------- - -So you've seen the Necropolis demo 10 billion times now and really don't -ever want to see it again? Here's how. - -The easy way is to start Quake with a "+map" command. You could do -"quake +map start" and you'll start on the single player start level. -Or you could do "quake +map nonsense" and you'll wind up at the Quake -console since there is no map named nonsense. You can accomplish the -same thing with a "+connect" too. "+connect" by itself will look for -Quake servers on the local network, "+connect 192.12.34.56" or -"+connect host.timbuktu.edu" will try to connect the the specified -Quake server. - -There is another way to not show the demos; one that also keeps your -customizations in a seperate directory from the data files in the -Quake distribution. - -Do this in the quake directory (the directory where you installed Quake; -where you find "quake.exe" and "the id1" directory). Create a file named -"quake.rc". Its contents should be: - -exec default.cfg -exec config.cfg -exec autoexec.cfg -stuffcmds -menu_main - -Create a batch file to run Quake in the quake directory. "Q.BAT" is a good -name. It's contents should be: - -quake -game . %1 %2 %3 %4 %5 %6 %7 %8 %9 - -If you normally use the Q95 batch file, just add the "-game ." part to -that file. - -Now you can run "q" and quake will start off with the main menu displayed -instead of running the demos. - -You can also make a seperate subdirectory for this if you'd like. For -example, make a directory named "mine" in the quake directory. Create -the "quake.rc" file as specified above in this directory. Use -"-game mine" instead of "-game ." in your batch file. - -Important note: The directory specified by "-game" is where Quake will -look for config.cfg, load and save games, and record and play -demos. - - -========================================== -== Reporting Quake Bugs == -========================================== - -How to use the bug report: - -Where to send bug reports: -E-mail : support@idsoftware.com -FAX : 214-686-9288 - -There are two sections of information - primary and secondary. - -Primary information contains information such as date, your name, e-mail -address, etc. Secondary information is actual bug information. There are -a few different sections depending on what type of bug you revieced -(sound, video, etc). Only fill out and include information from the section -related to the type of bug you received. - -If possible, start Quake with the "-condebug" command line parameter -and try to reproduce the bug. Attach the "qconsole.log" file found in the -"id1" directory to the end of the bug report. If the bug is sound related, -while in Quake, execute the SOUNDINFO and SBINFO (DOS only) commands from -the console. - -Please attach a copy of your CONFIG.SYS and AUTOEXEC.BAT file to the end of -the report. - -Bugs submitted properly with this form will get attention. -Unformatted ones sent to personal accounts will be ignored. -If you see problems, please take the time to do this. - -If you do not have all of the information requested in the form, -don't worry. Send what you do have. - -Please include the version #. THe version # for Quake can be found in the -lower right hand corner of the console. To bring up the console, press the -tilde ('~') key. Press tilde ('~') again or ESC to exit. - --------------------------------cut here------------------------------------- - - -============================================================================ -== Quake Bug Report - Primary information == -============================================================================ - -Date: -Name: -Phone number: -E-mail address: (please include this, we redirect tons of mail) -Game Title: -Version #: -Operating system (i.e., DOS 6.0 or Windows 95): -Computer type: -BIOS date: -BIOS version: -Processor type: -Processor speed: -Do you program at school/work? -Do you provide tech. support at school/work? -Please state the problem you encountered: -Please state how to reproduce the problem: - -If program crashed with nasty undecipherable techno-garbage, please -look for the eight-digit hex number which comes after "eip=" -and write it down here: - - -============================================================================ -== Quake Bug Report - Secondary information == -============================================================================ - ------------------------------- Video Related ------------------------------ - -Video Card Manufacturer: -Video Card Model: -Chipset Used: -BIOS Date: -(If using UniVBE, The above information can be found by running uvconfig) - -Did the problem occur while in a VESA mode? - -If so, what is the VESA driver and version? (eg., UniVBE 5.1a, -built into board BIOS, or manufacturer provided TSR) - ------------------------------- Sound Related ------------------------------ - -Audio card brand and model: - -If DOS or a DOS box, please run the command "set > set.txt" then -attach "set.txt" to the end of the report. - ------------------------------ Network Related ----------------------------- - -What type of network connection was established when the error occurred? -(modem, nullmodem, or network) -If modem, Modem brand and model: - -If network, Network card brand and model: - Network protocol/configuration: - ---------------------------------------------------------------------------- - - - - - - - - diff --git a/engine/docs/UQE Quake.pdf b/engine/docs/UQE Quake.pdf deleted file mode 100644 index d3939c7..0000000 Binary files a/engine/docs/UQE Quake.pdf and /dev/null differ diff --git a/engine/fmodcore/inc/fmod.cs b/engine/fmodcore/inc/fmod.cs deleted file mode 100644 index 4e75c91..0000000 --- a/engine/fmodcore/inc/fmod.cs +++ /dev/null @@ -1,3794 +0,0 @@ -/* ======================================================================================== */ -/* FMOD Core API - C# wrapper. */ -/* Copyright (c), Firelight Technologies Pty, Ltd. 2004-2021. */ -/* */ -/* For more detail visit: */ -/* https://fmod.com/resources/documentation-api?version=2.0&page=core-api.html */ -/* ======================================================================================== */ - -using System; -using System.Text; -using System.Runtime.InteropServices; -using System.Collections.Generic; - -namespace FMOD -{ - /* - FMOD version number. Check this against FMOD::System::getVersion / System_GetVersion - 0xaaaabbcc -> aaaa = major version number. bb = minor version number. cc = development version number. - */ - public class VERSION - { - public const int number = 0x00020016; -#if (UNITY_IPHONE || UNITY_TVOS || UNITY_SWITCH || UNITY_WEBGL) && !UNITY_EDITOR - public const string dll = "__Internal"; -#elif (UNITY_PS4) && DEVELOPMENT_BUILD - public const string dll = "libfmodL"; -#elif (UNITY_PS4) && !UNITY_EDITOR - public const string dll = "libfmod"; -#elif (UNITY_PSP2) && !UNITY_EDITOR - public const string dll = "libfmodstudio"; -#elif ((UNITY_WSA || UNITY_ANDROID || UNITY_XBOXONE || UNITY_STADIA) && DEVELOPMENT_BUILD) - public const string dll = "fmodL"; -#elif (UNITY_EDITOR) || (UNITY_STANDALONE && DEVELOPMENT_BUILD) - public const string dll = "fmodstudioL"; -#elif (UNITY_STANDALONE) - public const string dll = "fmodstudio"; -#else - public const string dll = "fmod"; -#endif - } - - public class CONSTANTS - { - public const int MAX_CHANNEL_WIDTH = 32; - public const int MAX_LISTENERS = 8; - public const int REVERB_MAXINSTANCES = 4; - public const int MAX_SYSTEMS = 8; - } - - /* - FMOD core types - */ - public enum RESULT : int - { - OK, - ERR_BADCOMMAND, - ERR_CHANNEL_ALLOC, - ERR_CHANNEL_STOLEN, - ERR_DMA, - ERR_DSP_CONNECTION, - ERR_DSP_DONTPROCESS, - ERR_DSP_FORMAT, - ERR_DSP_INUSE, - ERR_DSP_NOTFOUND, - ERR_DSP_RESERVED, - ERR_DSP_SILENCE, - ERR_DSP_TYPE, - ERR_FILE_BAD, - ERR_FILE_COULDNOTSEEK, - ERR_FILE_DISKEJECTED, - ERR_FILE_EOF, - ERR_FILE_ENDOFDATA, - ERR_FILE_NOTFOUND, - ERR_FORMAT, - ERR_HEADER_MISMATCH, - ERR_HTTP, - ERR_HTTP_ACCESS, - ERR_HTTP_PROXY_AUTH, - ERR_HTTP_SERVER_ERROR, - ERR_HTTP_TIMEOUT, - ERR_INITIALIZATION, - ERR_INITIALIZED, - ERR_INTERNAL, - ERR_INVALID_FLOAT, - ERR_INVALID_HANDLE, - ERR_INVALID_PARAM, - ERR_INVALID_POSITION, - ERR_INVALID_SPEAKER, - ERR_INVALID_SYNCPOINT, - ERR_INVALID_THREAD, - ERR_INVALID_VECTOR, - ERR_MAXAUDIBLE, - ERR_MEMORY, - ERR_MEMORY_CANTPOINT, - ERR_NEEDS3D, - ERR_NEEDSHARDWARE, - ERR_NET_CONNECT, - ERR_NET_SOCKET_ERROR, - ERR_NET_URL, - ERR_NET_WOULD_BLOCK, - ERR_NOTREADY, - ERR_OUTPUT_ALLOCATED, - ERR_OUTPUT_CREATEBUFFER, - ERR_OUTPUT_DRIVERCALL, - ERR_OUTPUT_FORMAT, - ERR_OUTPUT_INIT, - ERR_OUTPUT_NODRIVERS, - ERR_PLUGIN, - ERR_PLUGIN_MISSING, - ERR_PLUGIN_RESOURCE, - ERR_PLUGIN_VERSION, - ERR_RECORD, - ERR_REVERB_CHANNELGROUP, - ERR_REVERB_INSTANCE, - ERR_SUBSOUNDS, - ERR_SUBSOUND_ALLOCATED, - ERR_SUBSOUND_CANTMOVE, - ERR_TAGNOTFOUND, - ERR_TOOMANYCHANNELS, - ERR_TRUNCATED, - ERR_UNIMPLEMENTED, - ERR_UNINITIALIZED, - ERR_UNSUPPORTED, - ERR_VERSION, - ERR_EVENT_ALREADY_LOADED, - ERR_EVENT_LIVEUPDATE_BUSY, - ERR_EVENT_LIVEUPDATE_MISMATCH, - ERR_EVENT_LIVEUPDATE_TIMEOUT, - ERR_EVENT_NOTFOUND, - ERR_STUDIO_UNINITIALIZED, - ERR_STUDIO_NOT_LOADED, - ERR_INVALID_STRING, - ERR_ALREADY_LOCKED, - ERR_NOT_LOCKED, - ERR_RECORD_DISCONNECTED, - ERR_TOOMANYSAMPLES, - } - - public enum CHANNELCONTROL_TYPE : int - { - CHANNEL, - CHANNELGROUP, - MAX - } - - [StructLayout(LayoutKind.Sequential)] - public struct VECTOR - { - public float x; - public float y; - public float z; - } - - [StructLayout(LayoutKind.Sequential)] - public struct ATTRIBUTES_3D - { - public VECTOR position; - public VECTOR velocity; - public VECTOR forward; - public VECTOR up; - } - - [StructLayout(LayoutKind.Sequential)] - public struct ASYNCREADINFO - { - public IntPtr handle; - public uint offset; - public uint sizebytes; - public int priority; - - public IntPtr userdata; - public IntPtr buffer; - public uint bytesread; - public FILE_ASYNCDONE_FUNC done; - } - - public enum OUTPUTTYPE : int - { - AUTODETECT, - - UNKNOWN, - NOSOUND, - WAVWRITER, - NOSOUND_NRT, - WAVWRITER_NRT, - - WASAPI, - ASIO, - PULSEAUDIO, - ALSA, - COREAUDIO, - AUDIOTRACK, - OPENSL, - AUDIOOUT, - AUDIO3D, - WEBAUDIO, - NNAUDIO, - WINSONIC, - AAUDIO, - - MAX, - } - - public enum DEBUG_MODE : int - { - TTY, - FILE, - CALLBACK, - } - - [Flags] - public enum DEBUG_FLAGS : uint - { - NONE = 0x00000000, - ERROR = 0x00000001, - WARNING = 0x00000002, - LOG = 0x00000004, - - TYPE_MEMORY = 0x00000100, - TYPE_FILE = 0x00000200, - TYPE_CODEC = 0x00000400, - TYPE_TRACE = 0x00000800, - - DISPLAY_TIMESTAMPS = 0x00010000, - DISPLAY_LINENUMBERS = 0x00020000, - DISPLAY_THREAD = 0x00040000, - } - - [Flags] - public enum MEMORY_TYPE : uint - { - NORMAL = 0x00000000, - STREAM_FILE = 0x00000001, - STREAM_DECODE = 0x00000002, - SAMPLEDATA = 0x00000004, - DSP_BUFFER = 0x00000008, - PLUGIN = 0x00000010, - PERSISTENT = 0x00200000, - ALL = 0xFFFFFFFF - } - - public enum SPEAKERMODE : int - { - DEFAULT, - RAW, - MONO, - STEREO, - QUAD, - SURROUND, - _5POINT1, - _7POINT1, - _7POINT1POINT4, - - MAX, - } - - public enum SPEAKER : int - { - NONE = -1, - FRONT_LEFT, - FRONT_RIGHT, - FRONT_CENTER, - LOW_FREQUENCY, - SURROUND_LEFT, - SURROUND_RIGHT, - BACK_LEFT, - BACK_RIGHT, - TOP_FRONT_LEFT, - TOP_FRONT_RIGHT, - TOP_BACK_LEFT, - TOP_BACK_RIGHT, - - MAX, - } - - [Flags] - public enum CHANNELMASK : uint - { - FRONT_LEFT = 0x00000001, - FRONT_RIGHT = 0x00000002, - FRONT_CENTER = 0x00000004, - LOW_FREQUENCY = 0x00000008, - SURROUND_LEFT = 0x00000010, - SURROUND_RIGHT = 0x00000020, - BACK_LEFT = 0x00000040, - BACK_RIGHT = 0x00000080, - BACK_CENTER = 0x00000100, - - MONO = (FRONT_LEFT), - STEREO = (FRONT_LEFT | FRONT_RIGHT), - LRC = (FRONT_LEFT | FRONT_RIGHT | FRONT_CENTER), - QUAD = (FRONT_LEFT | FRONT_RIGHT | SURROUND_LEFT | SURROUND_RIGHT), - SURROUND = (FRONT_LEFT | FRONT_RIGHT | FRONT_CENTER | SURROUND_LEFT | SURROUND_RIGHT), - _5POINT1 = (FRONT_LEFT | FRONT_RIGHT | FRONT_CENTER | LOW_FREQUENCY | SURROUND_LEFT | SURROUND_RIGHT), - _5POINT1_REARS = (FRONT_LEFT | FRONT_RIGHT | FRONT_CENTER | LOW_FREQUENCY | BACK_LEFT | BACK_RIGHT), - _7POINT0 = (FRONT_LEFT | FRONT_RIGHT | FRONT_CENTER | SURROUND_LEFT | SURROUND_RIGHT | BACK_LEFT | BACK_RIGHT), - _7POINT1 = (FRONT_LEFT | FRONT_RIGHT | FRONT_CENTER | LOW_FREQUENCY | SURROUND_LEFT | SURROUND_RIGHT | BACK_LEFT | BACK_RIGHT) - } - - public enum CHANNELORDER : int - { - DEFAULT, - WAVEFORMAT, - PROTOOLS, - ALLMONO, - ALLSTEREO, - ALSA, - - MAX, - } - - public enum PLUGINTYPE : int - { - OUTPUT, - CODEC, - DSP, - - MAX, - } - - [StructLayout(LayoutKind.Sequential)] - public struct PLUGINLIST - { - PLUGINTYPE type; - IntPtr description; - } - - [Flags] - public enum INITFLAGS : uint - { - NORMAL = 0x00000000, - STREAM_FROM_UPDATE = 0x00000001, - MIX_FROM_UPDATE = 0x00000002, - _3D_RIGHTHANDED = 0x00000004, - CHANNEL_LOWPASS = 0x00000100, - CHANNEL_DISTANCEFILTER = 0x00000200, - PROFILE_ENABLE = 0x00010000, - VOL0_BECOMES_VIRTUAL = 0x00020000, - GEOMETRY_USECLOSEST = 0x00040000, - PREFER_DOLBY_DOWNMIX = 0x00080000, - THREAD_UNSAFE = 0x00100000, - PROFILE_METER_ALL = 0x00200000, - MEMORY_TRACKING = 0x00400000, - } - - public enum SOUND_TYPE : int - { - UNKNOWN, - AIFF, - ASF, - DLS, - FLAC, - FSB, - IT, - MIDI, - MOD, - MPEG, - OGGVORBIS, - PLAYLIST, - RAW, - S3M, - USER, - WAV, - XM, - XMA, - AUDIOQUEUE, - AT9, - VORBIS, - MEDIA_FOUNDATION, - MEDIACODEC, - FADPCM, - OPUS, - - MAX, - } - - public enum SOUND_FORMAT : int - { - NONE, - PCM8, - PCM16, - PCM24, - PCM32, - PCMFLOAT, - BITSTREAM, - - MAX - } - - [Flags] - public enum MODE : uint - { - DEFAULT = 0x00000000, - LOOP_OFF = 0x00000001, - LOOP_NORMAL = 0x00000002, - LOOP_BIDI = 0x00000004, - _2D = 0x00000008, - _3D = 0x00000010, - CREATESTREAM = 0x00000080, - CREATESAMPLE = 0x00000100, - CREATECOMPRESSEDSAMPLE = 0x00000200, - OPENUSER = 0x00000400, - OPENMEMORY = 0x00000800, - OPENMEMORY_POINT = 0x10000000, - OPENRAW = 0x00001000, - OPENONLY = 0x00002000, - ACCURATETIME = 0x00004000, - MPEGSEARCH = 0x00008000, - NONBLOCKING = 0x00010000, - UNIQUE = 0x00020000, - _3D_HEADRELATIVE = 0x00040000, - _3D_WORLDRELATIVE = 0x00080000, - _3D_INVERSEROLLOFF = 0x00100000, - _3D_LINEARROLLOFF = 0x00200000, - _3D_LINEARSQUAREROLLOFF = 0x00400000, - _3D_INVERSETAPEREDROLLOFF = 0x00800000, - _3D_CUSTOMROLLOFF = 0x04000000, - _3D_IGNOREGEOMETRY = 0x40000000, - IGNORETAGS = 0x02000000, - LOWMEM = 0x08000000, - VIRTUAL_PLAYFROMSTART = 0x80000000 - } - - public enum OPENSTATE : int - { - READY = 0, - LOADING, - ERROR, - CONNECTING, - BUFFERING, - SEEKING, - PLAYING, - SETPOSITION, - - MAX, - } - - public enum SOUNDGROUP_BEHAVIOR : int - { - BEHAVIOR_FAIL, - BEHAVIOR_MUTE, - BEHAVIOR_STEALLOWEST, - - MAX, - } - - public enum CHANNELCONTROL_CALLBACK_TYPE : int - { - END, - VIRTUALVOICE, - SYNCPOINT, - OCCLUSION, - - MAX, - } - - public struct CHANNELCONTROL_DSP_INDEX - { - public const int HEAD = -1; - public const int FADER = -2; - public const int TAIL = -3; - } - - public enum ERRORCALLBACK_INSTANCETYPE : int - { - NONE, - SYSTEM, - CHANNEL, - CHANNELGROUP, - CHANNELCONTROL, - SOUND, - SOUNDGROUP, - DSP, - DSPCONNECTION, - GEOMETRY, - REVERB3D, - STUDIO_SYSTEM, - STUDIO_EVENTDESCRIPTION, - STUDIO_EVENTINSTANCE, - STUDIO_PARAMETERINSTANCE, - STUDIO_BUS, - STUDIO_VCA, - STUDIO_BANK, - STUDIO_COMMANDREPLAY - } - - [StructLayout(LayoutKind.Sequential)] - public struct ERRORCALLBACK_INFO - { - public RESULT result; - public ERRORCALLBACK_INSTANCETYPE instancetype; - public IntPtr instance; - public StringWrapper functionname; - public StringWrapper functionparams; - } - - [Flags] - public enum SYSTEM_CALLBACK_TYPE : uint - { - DEVICELISTCHANGED = 0x00000001, - DEVICELOST = 0x00000002, - MEMORYALLOCATIONFAILED = 0x00000004, - THREADCREATED = 0x00000008, - BADDSPCONNECTION = 0x00000010, - PREMIX = 0x00000020, - POSTMIX = 0x00000040, - ERROR = 0x00000080, - MIDMIX = 0x00000100, - THREADDESTROYED = 0x00000200, - PREUPDATE = 0x00000400, - POSTUPDATE = 0x00000800, - RECORDLISTCHANGED = 0x00001000, - ALL = 0xFFFFFFFF, - } - - /* - FMOD Callbacks - */ - public delegate RESULT DEBUG_CALLBACK (DEBUG_FLAGS flags, StringWrapper file, int line, StringWrapper func, StringWrapper message); - public delegate RESULT SYSTEM_CALLBACK (IntPtr system, SYSTEM_CALLBACK_TYPE type, IntPtr commanddata1, IntPtr commanddata2, IntPtr userdata); - public delegate RESULT CHANNELCONTROL_CALLBACK(IntPtr channelcontrol, CHANNELCONTROL_TYPE controltype, CHANNELCONTROL_CALLBACK_TYPE callbacktype, IntPtr commanddata1, IntPtr commanddata2); - public delegate RESULT SOUND_NONBLOCK_CALLBACK (IntPtr sound, RESULT result); - public delegate RESULT SOUND_PCMREAD_CALLBACK (IntPtr sound, IntPtr data, uint datalen); - public delegate RESULT SOUND_PCMSETPOS_CALLBACK (IntPtr sound, int subsound, uint position, TIMEUNIT postype); - public delegate RESULT FILE_OPEN_CALLBACK (StringWrapper name, ref uint filesize, ref IntPtr handle, IntPtr userdata); - public delegate RESULT FILE_CLOSE_CALLBACK (IntPtr handle, IntPtr userdata); - public delegate RESULT FILE_READ_CALLBACK (IntPtr handle, IntPtr buffer, uint sizebytes, ref uint bytesread, IntPtr userdata); - public delegate RESULT FILE_SEEK_CALLBACK (IntPtr handle, uint pos, IntPtr userdata); - public delegate RESULT FILE_ASYNCREAD_CALLBACK (IntPtr info, IntPtr userdata); - public delegate RESULT FILE_ASYNCCANCEL_CALLBACK(IntPtr info, IntPtr userdata); - public delegate RESULT FILE_ASYNCDONE_FUNC (IntPtr info, RESULT result); - public delegate IntPtr MEMORY_ALLOC_CALLBACK (uint size, MEMORY_TYPE type, StringWrapper sourcestr); - public delegate IntPtr MEMORY_REALLOC_CALLBACK (IntPtr ptr, uint size, MEMORY_TYPE type, StringWrapper sourcestr); - public delegate void MEMORY_FREE_CALLBACK (IntPtr ptr, MEMORY_TYPE type, StringWrapper sourcestr); - public delegate float CB_3D_ROLLOFF_CALLBACK (IntPtr channelcontrol, float distance); - - public enum DSP_RESAMPLER : int - { - DEFAULT, - NOINTERP, - LINEAR, - CUBIC, - SPLINE, - - MAX, - } - - public enum DSPCONNECTION_TYPE : int - { - STANDARD, - SIDECHAIN, - SEND, - SEND_SIDECHAIN, - - MAX, - } - - public enum TAGTYPE : int - { - UNKNOWN = 0, - ID3V1, - ID3V2, - VORBISCOMMENT, - SHOUTCAST, - ICECAST, - ASF, - MIDI, - PLAYLIST, - FMOD, - USER, - - MAX - } - - public enum TAGDATATYPE : int - { - BINARY = 0, - INT, - FLOAT, - STRING, - STRING_UTF16, - STRING_UTF16BE, - STRING_UTF8, - - MAX - } - - [StructLayout(LayoutKind.Sequential)] - public struct TAG - { - public TAGTYPE type; - public TAGDATATYPE datatype; - public StringWrapper name; - public IntPtr data; - public uint datalen; - public bool updated; - } - - [Flags] - public enum TIMEUNIT : uint - { - MS = 0x00000001, - PCM = 0x00000002, - PCMBYTES = 0x00000004, - RAWBYTES = 0x00000008, - PCMFRACTION = 0x00000010, - MODORDER = 0x00000100, - MODROW = 0x00000200, - MODPATTERN = 0x00000400, - } - - public struct PORT_INDEX - { - public const ulong NONE = 0xFFFFFFFFFFFFFFFF; - } - - [StructLayout(LayoutKind.Sequential)] - public struct CREATESOUNDEXINFO - { - public int cbsize; - public uint length; - public uint fileoffset; - public int numchannels; - public int defaultfrequency; - public SOUND_FORMAT format; - public uint decodebuffersize; - public int initialsubsound; - public int numsubsounds; - public IntPtr inclusionlist; - public int inclusionlistnum; - public SOUND_PCMREAD_CALLBACK pcmreadcallback; - public SOUND_PCMSETPOS_CALLBACK pcmsetposcallback; - public SOUND_NONBLOCK_CALLBACK nonblockcallback; - public IntPtr dlsname; - public IntPtr encryptionkey; - public int maxpolyphony; - public IntPtr userdata; - public SOUND_TYPE suggestedsoundtype; - public FILE_OPEN_CALLBACK fileuseropen; - public FILE_CLOSE_CALLBACK fileuserclose; - public FILE_READ_CALLBACK fileuserread; - public FILE_SEEK_CALLBACK fileuserseek; - public FILE_ASYNCREAD_CALLBACK fileuserasyncread; - public FILE_ASYNCCANCEL_CALLBACK fileuserasynccancel; - public IntPtr fileuserdata; - public int filebuffersize; - public CHANNELORDER channelorder; - public IntPtr initialsoundgroup; - public uint initialseekposition; - public TIMEUNIT initialseekpostype; - public int ignoresetfilesystem; - public uint audioqueuepolicy; - public uint minmidigranularity; - public int nonblockthreadid; - public IntPtr fsbguid; - } - -#pragma warning disable 414 - [StructLayout(LayoutKind.Sequential)] - public struct REVERB_PROPERTIES - { - public float DecayTime; - public float EarlyDelay; - public float LateDelay; - public float HFReference; - public float HFDecayRatio; - public float Diffusion; - public float Density; - public float LowShelfFrequency; - public float LowShelfGain; - public float HighCut; - public float EarlyLateMix; - public float WetLevel; - - #region wrapperinternal - public REVERB_PROPERTIES(float decayTime, float earlyDelay, float lateDelay, float hfReference, - float hfDecayRatio, float diffusion, float density, float lowShelfFrequency, float lowShelfGain, - float highCut, float earlyLateMix, float wetLevel) - { - DecayTime = decayTime; - EarlyDelay = earlyDelay; - LateDelay = lateDelay; - HFReference = hfReference; - HFDecayRatio = hfDecayRatio; - Diffusion = diffusion; - Density = density; - LowShelfFrequency = lowShelfFrequency; - LowShelfGain = lowShelfGain; - HighCut = highCut; - EarlyLateMix = earlyLateMix; - WetLevel = wetLevel; - } - #endregion - } -#pragma warning restore 414 - - public class PRESET - { - /* Instance Env Diffus Room RoomHF RmLF DecTm DecHF DecLF Refl RefDel Revb RevDel ModTm ModDp HFRef LFRef Diffus Densty FLAGS */ - public static REVERB_PROPERTIES OFF() { return new REVERB_PROPERTIES( 1000, 7, 11, 5000, 100, 100, 100, 250, 0, 20, 96, -80.0f );} - public static REVERB_PROPERTIES GENERIC() { return new REVERB_PROPERTIES( 1500, 7, 11, 5000, 83, 100, 100, 250, 0, 14500, 96, -8.0f );} - public static REVERB_PROPERTIES PADDEDCELL() { return new REVERB_PROPERTIES( 170, 1, 2, 5000, 10, 100, 100, 250, 0, 160, 84, -7.8f );} - public static REVERB_PROPERTIES ROOM() { return new REVERB_PROPERTIES( 400, 2, 3, 5000, 83, 100, 100, 250, 0, 6050, 88, -9.4f );} - public static REVERB_PROPERTIES BATHROOM() { return new REVERB_PROPERTIES( 1500, 7, 11, 5000, 54, 100, 60, 250, 0, 2900, 83, 0.5f );} - public static REVERB_PROPERTIES LIVINGROOM() { return new REVERB_PROPERTIES( 500, 3, 4, 5000, 10, 100, 100, 250, 0, 160, 58, -19.0f );} - public static REVERB_PROPERTIES STONEROOM() { return new REVERB_PROPERTIES( 2300, 12, 17, 5000, 64, 100, 100, 250, 0, 7800, 71, -8.5f );} - public static REVERB_PROPERTIES AUDITORIUM() { return new REVERB_PROPERTIES( 4300, 20, 30, 5000, 59, 100, 100, 250, 0, 5850, 64, -11.7f );} - public static REVERB_PROPERTIES CONCERTHALL() { return new REVERB_PROPERTIES( 3900, 20, 29, 5000, 70, 100, 100, 250, 0, 5650, 80, -9.8f );} - public static REVERB_PROPERTIES CAVE() { return new REVERB_PROPERTIES( 2900, 15, 22, 5000, 100, 100, 100, 250, 0, 20000, 59, -11.3f );} - public static REVERB_PROPERTIES ARENA() { return new REVERB_PROPERTIES( 7200, 20, 30, 5000, 33, 100, 100, 250, 0, 4500, 80, -9.6f );} - public static REVERB_PROPERTIES HANGAR() { return new REVERB_PROPERTIES( 10000, 20, 30, 5000, 23, 100, 100, 250, 0, 3400, 72, -7.4f );} - public static REVERB_PROPERTIES CARPETTEDHALLWAY() { return new REVERB_PROPERTIES( 300, 2, 30, 5000, 10, 100, 100, 250, 0, 500, 56, -24.0f );} - public static REVERB_PROPERTIES HALLWAY() { return new REVERB_PROPERTIES( 1500, 7, 11, 5000, 59, 100, 100, 250, 0, 7800, 87, -5.5f );} - public static REVERB_PROPERTIES STONECORRIDOR() { return new REVERB_PROPERTIES( 270, 13, 20, 5000, 79, 100, 100, 250, 0, 9000, 86, -6.0f );} - public static REVERB_PROPERTIES ALLEY() { return new REVERB_PROPERTIES( 1500, 7, 11, 5000, 86, 100, 100, 250, 0, 8300, 80, -9.8f );} - public static REVERB_PROPERTIES FOREST() { return new REVERB_PROPERTIES( 1500, 162, 88, 5000, 54, 79, 100, 250, 0, 760, 94, -12.3f );} - public static REVERB_PROPERTIES CITY() { return new REVERB_PROPERTIES( 1500, 7, 11, 5000, 67, 50, 100, 250, 0, 4050, 66, -26.0f );} - public static REVERB_PROPERTIES MOUNTAINS() { return new REVERB_PROPERTIES( 1500, 300, 100, 5000, 21, 27, 100, 250, 0, 1220, 82, -24.0f );} - public static REVERB_PROPERTIES QUARRY() { return new REVERB_PROPERTIES( 1500, 61, 25, 5000, 83, 100, 100, 250, 0, 3400, 100, -5.0f );} - public static REVERB_PROPERTIES PLAIN() { return new REVERB_PROPERTIES( 1500, 179, 100, 5000, 50, 21, 100, 250, 0, 1670, 65, -28.0f );} - public static REVERB_PROPERTIES PARKINGLOT() { return new REVERB_PROPERTIES( 1700, 8, 12, 5000, 100, 100, 100, 250, 0, 20000, 56, -19.5f );} - public static REVERB_PROPERTIES SEWERPIPE() { return new REVERB_PROPERTIES( 2800, 14, 21, 5000, 14, 80, 60, 250, 0, 3400, 66, 1.2f );} - public static REVERB_PROPERTIES UNDERWATER() { return new REVERB_PROPERTIES( 1500, 7, 11, 5000, 10, 100, 100, 250, 0, 500, 92, 7.0f );} - } - - [StructLayout(LayoutKind.Sequential)] - public struct ADVANCEDSETTINGS - { - public int cbSize; - public int maxMPEGCodecs; - public int maxADPCMCodecs; - public int maxXMACodecs; - public int maxVorbisCodecs; - public int maxAT9Codecs; - public int maxFADPCMCodecs; - public int maxPCMCodecs; - public int ASIONumChannels; - public IntPtr ASIOChannelList; - public IntPtr ASIOSpeakerList; - public float vol0virtualvol; - public uint defaultDecodeBufferSize; - public ushort profilePort; - public uint geometryMaxFadeTime; - public float distanceFilterCenterFreq; - public int reverb3Dinstance; - public int DSPBufferPoolSize; - public uint stackSizeStream; - public uint stackSizeNonBlocking; - public uint stackSizeMixer; - public DSP_RESAMPLER resamplerMethod; - public uint commandQueueSize; - public uint randomSeed; - } - - [Flags] - public enum DRIVER_STATE : uint - { - CONNECTED = 0x00000001, - DEFAULT = 0x00000002, - } - - /* - FMOD System factory functions. Use this to create an FMOD System Instance. below you will see System init/close to get started. - */ - public struct Factory - { - public static RESULT System_Create(out System system) - { - return FMOD5_System_Create(out system.handle); - } - - #region importfunctions - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_System_Create(out IntPtr system); - - #endregion - } - - /* - FMOD global system functions (optional). - */ - public struct Memory - { - public static RESULT Initialize(IntPtr poolmem, int poollen, MEMORY_ALLOC_CALLBACK useralloc, MEMORY_REALLOC_CALLBACK userrealloc, MEMORY_FREE_CALLBACK userfree, MEMORY_TYPE memtypeflags = MEMORY_TYPE.ALL) - { - return FMOD5_Memory_Initialize(poolmem, poollen, useralloc, userrealloc, userfree, memtypeflags); - } - - public static RESULT GetStats(out int currentalloced, out int maxalloced, bool blocking = true) - { - return FMOD5_Memory_GetStats(out currentalloced, out maxalloced, blocking); - } - - #region importfunctions - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_Memory_Initialize(IntPtr poolmem, int poollen, MEMORY_ALLOC_CALLBACK useralloc, MEMORY_REALLOC_CALLBACK userrealloc, MEMORY_FREE_CALLBACK userfree, MEMORY_TYPE memtypeflags); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_Memory_GetStats (out int currentalloced, out int maxalloced, bool blocking); - - #endregion - } - - public struct Debug - { - public static RESULT Initialize(DEBUG_FLAGS flags, DEBUG_MODE mode = DEBUG_MODE.TTY, DEBUG_CALLBACK callback = null, string filename = null) - { - using (StringHelper.ThreadSafeEncoding encoder = StringHelper.GetFreeHelper()) - { - return FMOD5_Debug_Initialize(flags, mode, callback, encoder.byteFromStringUTF8(filename)); - } - } - - #region importfunctions - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_Debug_Initialize(DEBUG_FLAGS flags, DEBUG_MODE mode, DEBUG_CALLBACK callback, byte[] filename); - - #endregion - } - - /* - 'System' API. - */ - public struct System - { - public RESULT release() - { - return FMOD5_System_Release(this.handle); - } - - // Setup functions. - public RESULT setOutput(OUTPUTTYPE output) - { - return FMOD5_System_SetOutput(this.handle, output); - } - public RESULT getOutput(out OUTPUTTYPE output) - { - return FMOD5_System_GetOutput(this.handle, out output); - } - public RESULT getNumDrivers(out int numdrivers) - { - return FMOD5_System_GetNumDrivers(this.handle, out numdrivers); - } - public RESULT getDriverInfo(int id, out string name, int namelen, out Guid guid, out int systemrate, out SPEAKERMODE speakermode, out int speakermodechannels) - { - IntPtr stringMem = Marshal.AllocHGlobal(namelen); - - RESULT result = FMOD5_System_GetDriverInfo(this.handle, id, stringMem, namelen, out guid, out systemrate, out speakermode, out speakermodechannels); - using (StringHelper.ThreadSafeEncoding encoding = StringHelper.GetFreeHelper()) - { - name = encoding.stringFromNative(stringMem); - } - Marshal.FreeHGlobal(stringMem); - - return result; - } - public RESULT getDriverInfo(int id, out Guid guid, out int systemrate, out SPEAKERMODE speakermode, out int speakermodechannels) - { - return FMOD5_System_GetDriverInfo(this.handle, id, IntPtr.Zero, 0, out guid, out systemrate, out speakermode, out speakermodechannels); - } - public RESULT setDriver(int driver) - { - return FMOD5_System_SetDriver(this.handle, driver); - } - public RESULT getDriver(out int driver) - { - return FMOD5_System_GetDriver(this.handle, out driver); - } - public RESULT setSoftwareChannels(int numsoftwarechannels) - { - return FMOD5_System_SetSoftwareChannels(this.handle, numsoftwarechannels); - } - public RESULT getSoftwareChannels(out int numsoftwarechannels) - { - return FMOD5_System_GetSoftwareChannels(this.handle, out numsoftwarechannels); - } - public RESULT setSoftwareFormat(int samplerate, SPEAKERMODE speakermode, int numrawspeakers) - { - return FMOD5_System_SetSoftwareFormat(this.handle, samplerate, speakermode, numrawspeakers); - } - public RESULT getSoftwareFormat(out int samplerate, out SPEAKERMODE speakermode, out int numrawspeakers) - { - return FMOD5_System_GetSoftwareFormat(this.handle, out samplerate, out speakermode, out numrawspeakers); - } - public RESULT setDSPBufferSize(uint bufferlength, int numbuffers) - { - return FMOD5_System_SetDSPBufferSize(this.handle, bufferlength, numbuffers); - } - public RESULT getDSPBufferSize(out uint bufferlength, out int numbuffers) - { - return FMOD5_System_GetDSPBufferSize(this.handle, out bufferlength, out numbuffers); - } - public RESULT setFileSystem(FILE_OPEN_CALLBACK useropen, FILE_CLOSE_CALLBACK userclose, FILE_READ_CALLBACK userread, FILE_SEEK_CALLBACK userseek, FILE_ASYNCREAD_CALLBACK userasyncread, FILE_ASYNCCANCEL_CALLBACK userasynccancel, int blockalign) - { - return FMOD5_System_SetFileSystem(this.handle, useropen, userclose, userread, userseek, userasyncread, userasynccancel, blockalign); - } - public RESULT attachFileSystem(FILE_OPEN_CALLBACK useropen, FILE_CLOSE_CALLBACK userclose, FILE_READ_CALLBACK userread, FILE_SEEK_CALLBACK userseek) - { - return FMOD5_System_AttachFileSystem(this.handle, useropen, userclose, userread, userseek); - } - public RESULT setAdvancedSettings(ref ADVANCEDSETTINGS settings) - { - settings.cbSize = Marshal.SizeOf(settings); - return FMOD5_System_SetAdvancedSettings(this.handle, ref settings); - } - public RESULT getAdvancedSettings(ref ADVANCEDSETTINGS settings) - { - settings.cbSize = Marshal.SizeOf(settings); - return FMOD5_System_GetAdvancedSettings(this.handle, ref settings); - } - public RESULT setCallback(SYSTEM_CALLBACK callback, SYSTEM_CALLBACK_TYPE callbackmask = SYSTEM_CALLBACK_TYPE.ALL) - { - return FMOD5_System_SetCallback(this.handle, callback, callbackmask); - } - - // Plug-in support. - public RESULT setPluginPath(string path) - { - using (StringHelper.ThreadSafeEncoding encoder = StringHelper.GetFreeHelper()) - { - return FMOD5_System_SetPluginPath(this.handle, encoder.byteFromStringUTF8(path)); - } - } - public RESULT loadPlugin(string filename, out uint handle, uint priority = 0) - { - using (StringHelper.ThreadSafeEncoding encoder = StringHelper.GetFreeHelper()) - { - return FMOD5_System_LoadPlugin(this.handle, encoder.byteFromStringUTF8(filename), out handle, priority); - } - } - public RESULT unloadPlugin(uint handle) - { - return FMOD5_System_UnloadPlugin(this.handle, handle); - } - public RESULT getNumNestedPlugins(uint handle, out int count) - { - return FMOD5_System_GetNumNestedPlugins(this.handle, handle, out count); - } - public RESULT getNestedPlugin(uint handle, int index, out uint nestedhandle) - { - return FMOD5_System_GetNestedPlugin(this.handle, handle, index, out nestedhandle); - } - public RESULT getNumPlugins(PLUGINTYPE plugintype, out int numplugins) - { - return FMOD5_System_GetNumPlugins(this.handle, plugintype, out numplugins); - } - public RESULT getPluginHandle(PLUGINTYPE plugintype, int index, out uint handle) - { - return FMOD5_System_GetPluginHandle(this.handle, plugintype, index, out handle); - } - public RESULT getPluginInfo(uint handle, out PLUGINTYPE plugintype, out string name, int namelen, out uint version) - { - IntPtr stringMem = Marshal.AllocHGlobal(namelen); - - RESULT result = FMOD5_System_GetPluginInfo(this.handle, handle, out plugintype, stringMem, namelen, out version); - using (StringHelper.ThreadSafeEncoding encoder = StringHelper.GetFreeHelper()) - { - name = encoder.stringFromNative(stringMem); - } - Marshal.FreeHGlobal(stringMem); - - return result; - } - public RESULT getPluginInfo(uint handle, out PLUGINTYPE plugintype, out uint version) - { - return FMOD5_System_GetPluginInfo(this.handle, handle, out plugintype, IntPtr.Zero, 0, out version); - } - public RESULT setOutputByPlugin(uint handle) - { - return FMOD5_System_SetOutputByPlugin(this.handle, handle); - } - public RESULT getOutputByPlugin(out uint handle) - { - return FMOD5_System_GetOutputByPlugin(this.handle, out handle); - } - public RESULT createDSPByPlugin(uint handle, out DSP dsp) - { - return FMOD5_System_CreateDSPByPlugin(this.handle, handle, out dsp.handle); - } - public RESULT getDSPInfoByPlugin(uint handle, out IntPtr description) - { - return FMOD5_System_GetDSPInfoByPlugin(this.handle, handle, out description); - } - /* - public RESULT registerCodec (ref CODEC_DESCRIPTION description, out uint handle, uint priority) - public RESULT registerCodec (ref CODEC_DESCRIPTION description, out uint handle, uint priority = 0) - public RESULT registerCodec(ref CODEC_DESCRIPTION description, out uint handle, uint priority) - { - return FMOD5_System_RegisterCodec(this.handle, ref description, out handle, priority); - } - */ - public RESULT registerDSP(ref DSP_DESCRIPTION description, out uint handle) - { - return FMOD5_System_RegisterDSP(this.handle, ref description, out handle); - } - /* - public RESULT registerOutput(ref OUTPUT_DESCRIPTION description, out uint handle) - { - return FMOD5_System_RegisterOutput(this.handle, ref description, out handle); - } - */ - - // Init/Close. - public RESULT init(int maxchannels, INITFLAGS flags, IntPtr extradriverdata) - { - return FMOD5_System_Init(this.handle, maxchannels, flags, extradriverdata); - } - public RESULT close() - { - return FMOD5_System_Close(this.handle); - } - - // General post-init system functions. - public RESULT update() - { - return FMOD5_System_Update(this.handle); - } - public RESULT setSpeakerPosition(SPEAKER speaker, float x, float y, bool active) - { - return FMOD5_System_SetSpeakerPosition(this.handle, speaker, x, y, active); - } - public RESULT getSpeakerPosition(SPEAKER speaker, out float x, out float y, out bool active) - { - return FMOD5_System_GetSpeakerPosition(this.handle, speaker, out x, out y, out active); - } - public RESULT setStreamBufferSize(uint filebuffersize, TIMEUNIT filebuffersizetype) - { - return FMOD5_System_SetStreamBufferSize(this.handle, filebuffersize, filebuffersizetype); - } - public RESULT getStreamBufferSize(out uint filebuffersize, out TIMEUNIT filebuffersizetype) - { - return FMOD5_System_GetStreamBufferSize(this.handle, out filebuffersize, out filebuffersizetype); - } - public RESULT set3DSettings(float dopplerscale, float distancefactor, float rolloffscale) - { - return FMOD5_System_Set3DSettings(this.handle, dopplerscale, distancefactor, rolloffscale); - } - public RESULT get3DSettings(out float dopplerscale, out float distancefactor, out float rolloffscale) - { - return FMOD5_System_Get3DSettings(this.handle, out dopplerscale, out distancefactor, out rolloffscale); - } - public RESULT set3DNumListeners(int numlisteners) - { - return FMOD5_System_Set3DNumListeners(this.handle, numlisteners); - } - public RESULT get3DNumListeners(out int numlisteners) - { - return FMOD5_System_Get3DNumListeners(this.handle, out numlisteners); - } - public RESULT set3DListenerAttributes(int listener, ref VECTOR pos, ref VECTOR vel, ref VECTOR forward, ref VECTOR up) - { - return FMOD5_System_Set3DListenerAttributes(this.handle, listener, ref pos, ref vel, ref forward, ref up); - } - public RESULT get3DListenerAttributes(int listener, out VECTOR pos, out VECTOR vel, out VECTOR forward, out VECTOR up) - { - return FMOD5_System_Get3DListenerAttributes(this.handle, listener, out pos, out vel, out forward, out up); - } - public RESULT set3DRolloffCallback(CB_3D_ROLLOFF_CALLBACK callback) - { - return FMOD5_System_Set3DRolloffCallback(this.handle, callback); - } - public RESULT mixerSuspend() - { - return FMOD5_System_MixerSuspend(this.handle); - } - public RESULT mixerResume() - { - return FMOD5_System_MixerResume(this.handle); - } - public RESULT getDefaultMixMatrix(SPEAKERMODE sourcespeakermode, SPEAKERMODE targetspeakermode, float[] matrix, int matrixhop) - { - return FMOD5_System_GetDefaultMixMatrix(this.handle, sourcespeakermode, targetspeakermode, matrix, matrixhop); - } - public RESULT getSpeakerModeChannels(SPEAKERMODE mode, out int channels) - { - return FMOD5_System_GetSpeakerModeChannels(this.handle, mode, out channels); - } - - // System information functions. - public RESULT getVersion(out uint version) - { - return FMOD5_System_GetVersion(this.handle, out version); - } - public RESULT getOutputHandle(out IntPtr handle) - { - return FMOD5_System_GetOutputHandle(this.handle, out handle); - } - public RESULT getChannelsPlaying(out int channels) - { - return FMOD5_System_GetChannelsPlaying(this.handle, out channels, IntPtr.Zero); - } - public RESULT getChannelsPlaying(out int channels, out int realchannels) - { - return FMOD5_System_GetChannelsPlaying(this.handle, out channels, out realchannels); - } - public RESULT getCPUUsage(out float dsp, out float stream, out float geometry, out float update, out float total) - { - return FMOD5_System_GetCPUUsage(this.handle, out dsp, out stream, out geometry, out update, out total); - } - public RESULT getFileUsage(out Int64 sampleBytesRead, out Int64 streamBytesRead, out Int64 otherBytesRead) - { - return FMOD5_System_GetFileUsage(this.handle, out sampleBytesRead, out streamBytesRead, out otherBytesRead); - } - - // Sound/DSP/Channel/FX creation and retrieval. - public RESULT createSound(string name, MODE mode, ref CREATESOUNDEXINFO exinfo, out Sound sound) - { - using (StringHelper.ThreadSafeEncoding encoder = StringHelper.GetFreeHelper()) - { - return FMOD5_System_CreateSound(this.handle, encoder.byteFromStringUTF8(name), mode, ref exinfo, out sound.handle); - } - } - public RESULT createSound(byte[] data, MODE mode, ref CREATESOUNDEXINFO exinfo, out Sound sound) - { - return FMOD5_System_CreateSound(this.handle, data, mode, ref exinfo, out sound.handle); - } - public RESULT createSound(IntPtr name_or_data, MODE mode, ref CREATESOUNDEXINFO exinfo, out Sound sound) - { - return FMOD5_System_CreateSound(this.handle, name_or_data, mode, ref exinfo, out sound.handle); - } - public RESULT createSound(string name, MODE mode, out Sound sound) - { - CREATESOUNDEXINFO exinfo = new CREATESOUNDEXINFO(); - exinfo.cbsize = Marshal.SizeOf(exinfo); - - return createSound(name, mode, ref exinfo, out sound); - } - public RESULT createStream(string name, MODE mode, ref CREATESOUNDEXINFO exinfo, out Sound sound) - { - using (StringHelper.ThreadSafeEncoding encoder = StringHelper.GetFreeHelper()) - { - return FMOD5_System_CreateStream(this.handle, encoder.byteFromStringUTF8(name), mode, ref exinfo, out sound.handle); - } - } - public RESULT createStream(byte[] data, MODE mode, ref CREATESOUNDEXINFO exinfo, out Sound sound) - { - return FMOD5_System_CreateStream(this.handle, data, mode, ref exinfo, out sound.handle); - } - public RESULT createStream(IntPtr name_or_data, MODE mode, ref CREATESOUNDEXINFO exinfo, out Sound sound) - { - return FMOD5_System_CreateStream(this.handle, name_or_data, mode, ref exinfo, out sound.handle); - } - public RESULT createStream(string name, MODE mode, out Sound sound) - { - CREATESOUNDEXINFO exinfo = new CREATESOUNDEXINFO(); - exinfo.cbsize = Marshal.SizeOf(exinfo); - - return createStream(name, mode, ref exinfo, out sound); - } - public RESULT createDSP(ref DSP_DESCRIPTION description, out DSP dsp) - { - return FMOD5_System_CreateDSP(this.handle, ref description, out dsp.handle); - } - public RESULT createDSPByType(DSP_TYPE type, out DSP dsp) - { - return FMOD5_System_CreateDSPByType(this.handle, type, out dsp.handle); - } - public RESULT createChannelGroup(string name, out ChannelGroup channelgroup) - { - using (StringHelper.ThreadSafeEncoding encoder = StringHelper.GetFreeHelper()) - { - return FMOD5_System_CreateChannelGroup(this.handle, encoder.byteFromStringUTF8(name), out channelgroup.handle); - } - } - public RESULT createSoundGroup(string name, out SoundGroup soundgroup) - { - using (StringHelper.ThreadSafeEncoding encoder = StringHelper.GetFreeHelper()) - { - return FMOD5_System_CreateSoundGroup(this.handle, encoder.byteFromStringUTF8(name), out soundgroup.handle); - } - } - public RESULT createReverb3D(out Reverb3D reverb) - { - return FMOD5_System_CreateReverb3D(this.handle, out reverb.handle); - } - public RESULT playSound(Sound sound, ChannelGroup channelgroup, bool paused, out Channel channel) - { - return FMOD5_System_PlaySound(this.handle, sound.handle, channelgroup.handle, paused, out channel.handle); - } - public RESULT playDSP(DSP dsp, ChannelGroup channelgroup, bool paused, out Channel channel) - { - return FMOD5_System_PlayDSP(this.handle, dsp.handle, channelgroup.handle, paused, out channel.handle); - } - public RESULT getChannel(int channelid, out Channel channel) - { - return FMOD5_System_GetChannel(this.handle, channelid, out channel.handle); - } - public RESULT getMasterChannelGroup(out ChannelGroup channelgroup) - { - return FMOD5_System_GetMasterChannelGroup(this.handle, out channelgroup.handle); - } - public RESULT getMasterSoundGroup(out SoundGroup soundgroup) - { - return FMOD5_System_GetMasterSoundGroup(this.handle, out soundgroup.handle); - } - - // Routing to ports. - public RESULT attachChannelGroupToPort(uint portType, ulong portIndex, ChannelGroup channelgroup, bool passThru = false) - { - return FMOD5_System_AttachChannelGroupToPort(this.handle, portType, portIndex, channelgroup.handle, passThru); - } - public RESULT detachChannelGroupFromPort(ChannelGroup channelgroup) - { - return FMOD5_System_DetachChannelGroupFromPort(this.handle, channelgroup.handle); - } - - // Reverb api. - public RESULT setReverbProperties(int instance, ref REVERB_PROPERTIES prop) - { - return FMOD5_System_SetReverbProperties(this.handle, instance, ref prop); - } - public RESULT getReverbProperties(int instance, out REVERB_PROPERTIES prop) - { - return FMOD5_System_GetReverbProperties(this.handle, instance, out prop); - } - - // System level DSP functionality. - public RESULT lockDSP() - { - return FMOD5_System_LockDSP(this.handle); - } - public RESULT unlockDSP() - { - return FMOD5_System_UnlockDSP(this.handle); - } - - // Recording api - public RESULT getRecordNumDrivers(out int numdrivers, out int numconnected) - { - return FMOD5_System_GetRecordNumDrivers(this.handle, out numdrivers, out numconnected); - } - public RESULT getRecordDriverInfo(int id, out string name, int namelen, out Guid guid, out int systemrate, out SPEAKERMODE speakermode, out int speakermodechannels, out DRIVER_STATE state) - { - IntPtr stringMem = Marshal.AllocHGlobal(namelen); - - RESULT result = FMOD5_System_GetRecordDriverInfo(this.handle, id, stringMem, namelen, out guid, out systemrate, out speakermode, out speakermodechannels, out state); - - using (StringHelper.ThreadSafeEncoding encoder = StringHelper.GetFreeHelper()) - { - name = encoder.stringFromNative(stringMem); - } - Marshal.FreeHGlobal(stringMem); - - return result; - } - public RESULT getRecordDriverInfo(int id, out Guid guid, out int systemrate, out SPEAKERMODE speakermode, out int speakermodechannels, out DRIVER_STATE state) - { - return FMOD5_System_GetRecordDriverInfo(this.handle, id, IntPtr.Zero, 0, out guid, out systemrate, out speakermode, out speakermodechannels, out state); - } - public RESULT getRecordPosition(int id, out uint position) - { - return FMOD5_System_GetRecordPosition(this.handle, id, out position); - } - public RESULT recordStart(int id, Sound sound, bool loop) - { - return FMOD5_System_RecordStart(this.handle, id, sound.handle, loop); - } - public RESULT recordStop(int id) - { - return FMOD5_System_RecordStop(this.handle, id); - } - public RESULT isRecording(int id, out bool recording) - { - return FMOD5_System_IsRecording(this.handle, id, out recording); - } - - // Geometry api - public RESULT createGeometry(int maxpolygons, int maxvertices, out Geometry geometry) - { - return FMOD5_System_CreateGeometry(this.handle, maxpolygons, maxvertices, out geometry.handle); - } - public RESULT setGeometrySettings(float maxworldsize) - { - return FMOD5_System_SetGeometrySettings(this.handle, maxworldsize); - } - public RESULT getGeometrySettings(out float maxworldsize) - { - return FMOD5_System_GetGeometrySettings(this.handle, out maxworldsize); - } - public RESULT loadGeometry(IntPtr data, int datasize, out Geometry geometry) - { - return FMOD5_System_LoadGeometry(this.handle, data, datasize, out geometry.handle); - } - public RESULT getGeometryOcclusion(ref VECTOR listener, ref VECTOR source, out float direct, out float reverb) - { - return FMOD5_System_GetGeometryOcclusion(this.handle, ref listener, ref source, out direct, out reverb); - } - - // Network functions - public RESULT setNetworkProxy(string proxy) - { - using (StringHelper.ThreadSafeEncoding encoder = StringHelper.GetFreeHelper()) - { - return FMOD5_System_SetNetworkProxy(this.handle, encoder.byteFromStringUTF8(proxy)); - } - } - public RESULT getNetworkProxy(out string proxy, int proxylen) - { - IntPtr stringMem = Marshal.AllocHGlobal(proxylen); - - RESULT result = FMOD5_System_GetNetworkProxy(this.handle, stringMem, proxylen); - using (StringHelper.ThreadSafeEncoding encoder = StringHelper.GetFreeHelper()) - { - proxy = encoder.stringFromNative(stringMem); - } - Marshal.FreeHGlobal(stringMem); - - return result; - } - public RESULT setNetworkTimeout(int timeout) - { - return FMOD5_System_SetNetworkTimeout(this.handle, timeout); - } - public RESULT getNetworkTimeout(out int timeout) - { - return FMOD5_System_GetNetworkTimeout(this.handle, out timeout); - } - - // Userdata set/get - public RESULT setUserData(IntPtr userdata) - { - return FMOD5_System_SetUserData(this.handle, userdata); - } - public RESULT getUserData(out IntPtr userdata) - { - return FMOD5_System_GetUserData(this.handle, out userdata); - } - - #region importfunctions - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_System_Release (IntPtr system); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_System_SetOutput (IntPtr system, OUTPUTTYPE output); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_System_GetOutput (IntPtr system, out OUTPUTTYPE output); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_System_GetNumDrivers (IntPtr system, out int numdrivers); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_System_GetDriverInfo (IntPtr system, int id, IntPtr name, int namelen, out Guid guid, out int systemrate, out SPEAKERMODE speakermode, out int speakermodechannels); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_System_SetDriver (IntPtr system, int driver); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_System_GetDriver (IntPtr system, out int driver); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_System_SetSoftwareChannels (IntPtr system, int numsoftwarechannels); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_System_GetSoftwareChannels (IntPtr system, out int numsoftwarechannels); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_System_SetSoftwareFormat (IntPtr system, int samplerate, SPEAKERMODE speakermode, int numrawspeakers); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_System_GetSoftwareFormat (IntPtr system, out int samplerate, out SPEAKERMODE speakermode, out int numrawspeakers); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_System_SetDSPBufferSize (IntPtr system, uint bufferlength, int numbuffers); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_System_GetDSPBufferSize (IntPtr system, out uint bufferlength, out int numbuffers); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_System_SetFileSystem (IntPtr system, FILE_OPEN_CALLBACK useropen, FILE_CLOSE_CALLBACK userclose, FILE_READ_CALLBACK userread, FILE_SEEK_CALLBACK userseek, FILE_ASYNCREAD_CALLBACK userasyncread, FILE_ASYNCCANCEL_CALLBACK userasynccancel, int blockalign); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_System_AttachFileSystem (IntPtr system, FILE_OPEN_CALLBACK useropen, FILE_CLOSE_CALLBACK userclose, FILE_READ_CALLBACK userread, FILE_SEEK_CALLBACK userseek); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_System_SetAdvancedSettings (IntPtr system, ref ADVANCEDSETTINGS settings); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_System_GetAdvancedSettings (IntPtr system, ref ADVANCEDSETTINGS settings); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_System_SetCallback (IntPtr system, SYSTEM_CALLBACK callback, SYSTEM_CALLBACK_TYPE callbackmask); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_System_SetPluginPath (IntPtr system, byte[] path); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_System_LoadPlugin (IntPtr system, byte[] filename, out uint handle, uint priority); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_System_UnloadPlugin (IntPtr system, uint handle); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_System_GetNumNestedPlugins (IntPtr system, uint handle, out int count); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_System_GetNestedPlugin (IntPtr system, uint handle, int index, out uint nestedhandle); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_System_GetNumPlugins (IntPtr system, PLUGINTYPE plugintype, out int numplugins); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_System_GetPluginHandle (IntPtr system, PLUGINTYPE plugintype, int index, out uint handle); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_System_GetPluginInfo (IntPtr system, uint handle, out PLUGINTYPE plugintype, IntPtr name, int namelen, out uint version); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_System_SetOutputByPlugin (IntPtr system, uint handle); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_System_GetOutputByPlugin (IntPtr system, out uint handle); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_System_CreateDSPByPlugin (IntPtr system, uint handle, out IntPtr dsp); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_System_GetDSPInfoByPlugin (IntPtr system, uint handle, out IntPtr description); - //[DllImport(VERSION.dll)] - //private static extern RESULT FMOD5_System_RegisterCodec (IntPtr system, out CODEC_DESCRIPTION description, out uint handle, uint priority); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_System_RegisterDSP (IntPtr system, ref DSP_DESCRIPTION description, out uint handle); - //[DllImport(VERSION.dll)] - //private static extern RESULT FMOD5_System_RegisterOutput (IntPtr system, ref OUTPUT_DESCRIPTION description, out uint handle); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_System_Init (IntPtr system, int maxchannels, INITFLAGS flags, IntPtr extradriverdata); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_System_Close (IntPtr system); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_System_Update (IntPtr system); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_System_SetSpeakerPosition (IntPtr system, SPEAKER speaker, float x, float y, bool active); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_System_GetSpeakerPosition (IntPtr system, SPEAKER speaker, out float x, out float y, out bool active); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_System_SetStreamBufferSize (IntPtr system, uint filebuffersize, TIMEUNIT filebuffersizetype); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_System_GetStreamBufferSize (IntPtr system, out uint filebuffersize, out TIMEUNIT filebuffersizetype); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_System_Set3DSettings (IntPtr system, float dopplerscale, float distancefactor, float rolloffscale); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_System_Get3DSettings (IntPtr system, out float dopplerscale, out float distancefactor, out float rolloffscale); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_System_Set3DNumListeners (IntPtr system, int numlisteners); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_System_Get3DNumListeners (IntPtr system, out int numlisteners); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_System_Set3DListenerAttributes (IntPtr system, int listener, ref VECTOR pos, ref VECTOR vel, ref VECTOR forward, ref VECTOR up); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_System_Get3DListenerAttributes (IntPtr system, int listener, out VECTOR pos, out VECTOR vel, out VECTOR forward, out VECTOR up); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_System_Set3DRolloffCallback (IntPtr system, CB_3D_ROLLOFF_CALLBACK callback); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_System_MixerSuspend (IntPtr system); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_System_MixerResume (IntPtr system); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_System_GetDefaultMixMatrix (IntPtr system, SPEAKERMODE sourcespeakermode, SPEAKERMODE targetspeakermode, float[] matrix, int matrixhop); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_System_GetSpeakerModeChannels (IntPtr system, SPEAKERMODE mode, out int channels); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_System_GetVersion (IntPtr system, out uint version); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_System_GetOutputHandle (IntPtr system, out IntPtr handle); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_System_GetChannelsPlaying (IntPtr system, out int channels, IntPtr zero); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_System_GetChannelsPlaying (IntPtr system, out int channels, out int realchannels); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_System_GetCPUUsage (IntPtr system, out float dsp, out float stream, out float geometry, out float update, out float total); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_System_GetFileUsage (IntPtr system, out Int64 sampleBytesRead, out Int64 streamBytesRead, out Int64 otherBytesRead); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_System_CreateSound (IntPtr system, byte[] name_or_data, MODE mode, ref CREATESOUNDEXINFO exinfo, out IntPtr sound); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_System_CreateSound (IntPtr system, IntPtr name_or_data, MODE mode, ref CREATESOUNDEXINFO exinfo, out IntPtr sound); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_System_CreateStream (IntPtr system, byte[] name_or_data, MODE mode, ref CREATESOUNDEXINFO exinfo, out IntPtr sound); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_System_CreateStream (IntPtr system, IntPtr name_or_data, MODE mode, ref CREATESOUNDEXINFO exinfo, out IntPtr sound); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_System_CreateDSP (IntPtr system, ref DSP_DESCRIPTION description, out IntPtr dsp); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_System_CreateDSPByType (IntPtr system, DSP_TYPE type, out IntPtr dsp); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_System_CreateChannelGroup (IntPtr system, byte[] name, out IntPtr channelgroup); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_System_CreateSoundGroup (IntPtr system, byte[] name, out IntPtr soundgroup); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_System_CreateReverb3D (IntPtr system, out IntPtr reverb); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_System_PlaySound (IntPtr system, IntPtr sound, IntPtr channelgroup, bool paused, out IntPtr channel); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_System_PlayDSP (IntPtr system, IntPtr dsp, IntPtr channelgroup, bool paused, out IntPtr channel); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_System_GetChannel (IntPtr system, int channelid, out IntPtr channel); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_System_GetMasterChannelGroup (IntPtr system, out IntPtr channelgroup); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_System_GetMasterSoundGroup (IntPtr system, out IntPtr soundgroup); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_System_AttachChannelGroupToPort (IntPtr system, uint portType, ulong portIndex, IntPtr channelgroup, bool passThru); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_System_DetachChannelGroupFromPort(IntPtr system, IntPtr channelgroup); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_System_SetReverbProperties (IntPtr system, int instance, ref REVERB_PROPERTIES prop); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_System_GetReverbProperties (IntPtr system, int instance, out REVERB_PROPERTIES prop); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_System_LockDSP (IntPtr system); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_System_UnlockDSP (IntPtr system); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_System_GetRecordNumDrivers (IntPtr system, out int numdrivers, out int numconnected); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_System_GetRecordDriverInfo (IntPtr system, int id, IntPtr name, int namelen, out Guid guid, out int systemrate, out SPEAKERMODE speakermode, out int speakermodechannels, out DRIVER_STATE state); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_System_GetRecordPosition (IntPtr system, int id, out uint position); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_System_RecordStart (IntPtr system, int id, IntPtr sound, bool loop); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_System_RecordStop (IntPtr system, int id); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_System_IsRecording (IntPtr system, int id, out bool recording); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_System_CreateGeometry (IntPtr system, int maxpolygons, int maxvertices, out IntPtr geometry); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_System_SetGeometrySettings (IntPtr system, float maxworldsize); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_System_GetGeometrySettings (IntPtr system, out float maxworldsize); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_System_LoadGeometry (IntPtr system, IntPtr data, int datasize, out IntPtr geometry); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_System_GetGeometryOcclusion (IntPtr system, ref VECTOR listener, ref VECTOR source, out float direct, out float reverb); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_System_SetNetworkProxy (IntPtr system, byte[] proxy); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_System_GetNetworkProxy (IntPtr system, IntPtr proxy, int proxylen); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_System_SetNetworkTimeout (IntPtr system, int timeout); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_System_GetNetworkTimeout (IntPtr system, out int timeout); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_System_SetUserData (IntPtr system, IntPtr userdata); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_System_GetUserData (IntPtr system, out IntPtr userdata); - #endregion - - #region wrapperinternal - - public IntPtr handle; - - public bool hasHandle() { return this.handle != IntPtr.Zero; } - public void clearHandle() { this.handle = IntPtr.Zero; } - - #endregion - } - - - /* - 'Sound' API. - */ - public struct Sound - { - public RESULT release() - { - return FMOD5_Sound_Release(this.handle); - } - public RESULT getSystemObject(out System system) - { - return FMOD5_Sound_GetSystemObject(this.handle, out system.handle); - } - - // Standard sound manipulation functions. - public RESULT @lock(uint offset, uint length, out IntPtr ptr1, out IntPtr ptr2, out uint len1, out uint len2) - { - return FMOD5_Sound_Lock(this.handle, offset, length, out ptr1, out ptr2, out len1, out len2); - } - public RESULT unlock(IntPtr ptr1, IntPtr ptr2, uint len1, uint len2) - { - return FMOD5_Sound_Unlock(this.handle, ptr1, ptr2, len1, len2); - } - public RESULT setDefaults(float frequency, int priority) - { - return FMOD5_Sound_SetDefaults(this.handle, frequency, priority); - } - public RESULT getDefaults(out float frequency, out int priority) - { - return FMOD5_Sound_GetDefaults(this.handle, out frequency, out priority); - } - public RESULT set3DMinMaxDistance(float min, float max) - { - return FMOD5_Sound_Set3DMinMaxDistance(this.handle, min, max); - } - public RESULT get3DMinMaxDistance(out float min, out float max) - { - return FMOD5_Sound_Get3DMinMaxDistance(this.handle, out min, out max); - } - public RESULT set3DConeSettings(float insideconeangle, float outsideconeangle, float outsidevolume) - { - return FMOD5_Sound_Set3DConeSettings(this.handle, insideconeangle, outsideconeangle, outsidevolume); - } - public RESULT get3DConeSettings(out float insideconeangle, out float outsideconeangle, out float outsidevolume) - { - return FMOD5_Sound_Get3DConeSettings(this.handle, out insideconeangle, out outsideconeangle, out outsidevolume); - } - public RESULT set3DCustomRolloff(ref VECTOR points, int numpoints) - { - return FMOD5_Sound_Set3DCustomRolloff(this.handle, ref points, numpoints); - } - public RESULT get3DCustomRolloff(out IntPtr points, out int numpoints) - { - return FMOD5_Sound_Get3DCustomRolloff(this.handle, out points, out numpoints); - } - - public RESULT getSubSound(int index, out Sound subsound) - { - return FMOD5_Sound_GetSubSound(this.handle, index, out subsound.handle); - } - public RESULT getSubSoundParent(out Sound parentsound) - { - return FMOD5_Sound_GetSubSoundParent(this.handle, out parentsound.handle); - } - public RESULT getName(out string name, int namelen) - { - IntPtr stringMem = Marshal.AllocHGlobal(namelen); - - RESULT result = FMOD5_Sound_GetName(this.handle, stringMem, namelen); - using (StringHelper.ThreadSafeEncoding encoder = StringHelper.GetFreeHelper()) - { - name = encoder.stringFromNative(stringMem); - } - Marshal.FreeHGlobal(stringMem); - - return result; - } - public RESULT getLength(out uint length, TIMEUNIT lengthtype) - { - return FMOD5_Sound_GetLength(this.handle, out length, lengthtype); - } - public RESULT getFormat(out SOUND_TYPE type, out SOUND_FORMAT format, out int channels, out int bits) - { - return FMOD5_Sound_GetFormat(this.handle, out type, out format, out channels, out bits); - } - public RESULT getNumSubSounds(out int numsubsounds) - { - return FMOD5_Sound_GetNumSubSounds(this.handle, out numsubsounds); - } - public RESULT getNumTags(out int numtags, out int numtagsupdated) - { - return FMOD5_Sound_GetNumTags(this.handle, out numtags, out numtagsupdated); - } - public RESULT getTag(string name, int index, out TAG tag) - { - using (StringHelper.ThreadSafeEncoding encoder = StringHelper.GetFreeHelper()) - { - return FMOD5_Sound_GetTag(this.handle, encoder.byteFromStringUTF8(name), index, out tag); - } - } - public RESULT getOpenState(out OPENSTATE openstate, out uint percentbuffered, out bool starving, out bool diskbusy) - { - return FMOD5_Sound_GetOpenState(this.handle, out openstate, out percentbuffered, out starving, out diskbusy); - } - public RESULT readData(IntPtr buffer, uint length, out uint read) - { - return FMOD5_Sound_ReadData(this.handle, buffer, length, out read); - } - public RESULT seekData(uint pcm) - { - return FMOD5_Sound_SeekData(this.handle, pcm); - } - public RESULT setSoundGroup(SoundGroup soundgroup) - { - return FMOD5_Sound_SetSoundGroup(this.handle, soundgroup.handle); - } - public RESULT getSoundGroup(out SoundGroup soundgroup) - { - return FMOD5_Sound_GetSoundGroup(this.handle, out soundgroup.handle); - } - - // Synchronization point API. These points can come from markers embedded in wav files, and can also generate channel callbacks. - public RESULT getNumSyncPoints(out int numsyncpoints) - { - return FMOD5_Sound_GetNumSyncPoints(this.handle, out numsyncpoints); - } - public RESULT getSyncPoint(int index, out IntPtr point) - { - return FMOD5_Sound_GetSyncPoint(this.handle, index, out point); - } - public RESULT getSyncPointInfo(IntPtr point, out string name, int namelen, out uint offset, TIMEUNIT offsettype) - { - IntPtr stringMem = Marshal.AllocHGlobal(namelen); - - RESULT result = FMOD5_Sound_GetSyncPointInfo(this.handle, point, stringMem, namelen, out offset, offsettype); - using (StringHelper.ThreadSafeEncoding encoder = StringHelper.GetFreeHelper()) - { - name = encoder.stringFromNative(stringMem); - } - Marshal.FreeHGlobal(stringMem); - - return result; - } - public RESULT getSyncPointInfo(IntPtr point, out uint offset, TIMEUNIT offsettype) - { - return FMOD5_Sound_GetSyncPointInfo(this.handle, point, IntPtr.Zero, 0, out offset, offsettype); - } - public RESULT addSyncPoint(uint offset, TIMEUNIT offsettype, string name, out IntPtr point) - { - using (StringHelper.ThreadSafeEncoding encoder = StringHelper.GetFreeHelper()) - { - return FMOD5_Sound_AddSyncPoint(this.handle, offset, offsettype, encoder.byteFromStringUTF8(name), out point); - } - } - public RESULT deleteSyncPoint(IntPtr point) - { - return FMOD5_Sound_DeleteSyncPoint(this.handle, point); - } - - // Functions also in Channel class but here they are the 'default' to save having to change it in Channel all the time. - public RESULT setMode(MODE mode) - { - return FMOD5_Sound_SetMode(this.handle, mode); - } - public RESULT getMode(out MODE mode) - { - return FMOD5_Sound_GetMode(this.handle, out mode); - } - public RESULT setLoopCount(int loopcount) - { - return FMOD5_Sound_SetLoopCount(this.handle, loopcount); - } - public RESULT getLoopCount(out int loopcount) - { - return FMOD5_Sound_GetLoopCount(this.handle, out loopcount); - } - public RESULT setLoopPoints(uint loopstart, TIMEUNIT loopstarttype, uint loopend, TIMEUNIT loopendtype) - { - return FMOD5_Sound_SetLoopPoints(this.handle, loopstart, loopstarttype, loopend, loopendtype); - } - public RESULT getLoopPoints(out uint loopstart, TIMEUNIT loopstarttype, out uint loopend, TIMEUNIT loopendtype) - { - return FMOD5_Sound_GetLoopPoints(this.handle, out loopstart, loopstarttype, out loopend, loopendtype); - } - - // For MOD/S3M/XM/IT/MID sequenced formats only. - public RESULT getMusicNumChannels(out int numchannels) - { - return FMOD5_Sound_GetMusicNumChannels(this.handle, out numchannels); - } - public RESULT setMusicChannelVolume(int channel, float volume) - { - return FMOD5_Sound_SetMusicChannelVolume(this.handle, channel, volume); - } - public RESULT getMusicChannelVolume(int channel, out float volume) - { - return FMOD5_Sound_GetMusicChannelVolume(this.handle, channel, out volume); - } - public RESULT setMusicSpeed(float speed) - { - return FMOD5_Sound_SetMusicSpeed(this.handle, speed); - } - public RESULT getMusicSpeed(out float speed) - { - return FMOD5_Sound_GetMusicSpeed(this.handle, out speed); - } - - // Userdata set/get. - public RESULT setUserData(IntPtr userdata) - { - return FMOD5_Sound_SetUserData(this.handle, userdata); - } - public RESULT getUserData(out IntPtr userdata) - { - return FMOD5_Sound_GetUserData(this.handle, out userdata); - } - - #region importfunctions - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_Sound_Release (IntPtr sound); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_Sound_GetSystemObject (IntPtr sound, out IntPtr system); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_Sound_Lock (IntPtr sound, uint offset, uint length, out IntPtr ptr1, out IntPtr ptr2, out uint len1, out uint len2); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_Sound_Unlock (IntPtr sound, IntPtr ptr1, IntPtr ptr2, uint len1, uint len2); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_Sound_SetDefaults (IntPtr sound, float frequency, int priority); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_Sound_GetDefaults (IntPtr sound, out float frequency, out int priority); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_Sound_Set3DMinMaxDistance (IntPtr sound, float min, float max); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_Sound_Get3DMinMaxDistance (IntPtr sound, out float min, out float max); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_Sound_Set3DConeSettings (IntPtr sound, float insideconeangle, float outsideconeangle, float outsidevolume); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_Sound_Get3DConeSettings (IntPtr sound, out float insideconeangle, out float outsideconeangle, out float outsidevolume); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_Sound_Set3DCustomRolloff (IntPtr sound, ref VECTOR points, int numpoints); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_Sound_Get3DCustomRolloff (IntPtr sound, out IntPtr points, out int numpoints); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_Sound_GetSubSound (IntPtr sound, int index, out IntPtr subsound); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_Sound_GetSubSoundParent (IntPtr sound, out IntPtr parentsound); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_Sound_GetName (IntPtr sound, IntPtr name, int namelen); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_Sound_GetLength (IntPtr sound, out uint length, TIMEUNIT lengthtype); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_Sound_GetFormat (IntPtr sound, out SOUND_TYPE type, out SOUND_FORMAT format, out int channels, out int bits); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_Sound_GetNumSubSounds (IntPtr sound, out int numsubsounds); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_Sound_GetNumTags (IntPtr sound, out int numtags, out int numtagsupdated); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_Sound_GetTag (IntPtr sound, byte[] name, int index, out TAG tag); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_Sound_GetOpenState (IntPtr sound, out OPENSTATE openstate, out uint percentbuffered, out bool starving, out bool diskbusy); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_Sound_ReadData (IntPtr sound, IntPtr buffer, uint length, out uint read); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_Sound_SeekData (IntPtr sound, uint pcm); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_Sound_SetSoundGroup (IntPtr sound, IntPtr soundgroup); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_Sound_GetSoundGroup (IntPtr sound, out IntPtr soundgroup); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_Sound_GetNumSyncPoints (IntPtr sound, out int numsyncpoints); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_Sound_GetSyncPoint (IntPtr sound, int index, out IntPtr point); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_Sound_GetSyncPointInfo (IntPtr sound, IntPtr point, IntPtr name, int namelen, out uint offset, TIMEUNIT offsettype); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_Sound_AddSyncPoint (IntPtr sound, uint offset, TIMEUNIT offsettype, byte[] name, out IntPtr point); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_Sound_DeleteSyncPoint (IntPtr sound, IntPtr point); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_Sound_SetMode (IntPtr sound, MODE mode); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_Sound_GetMode (IntPtr sound, out MODE mode); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_Sound_SetLoopCount (IntPtr sound, int loopcount); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_Sound_GetLoopCount (IntPtr sound, out int loopcount); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_Sound_SetLoopPoints (IntPtr sound, uint loopstart, TIMEUNIT loopstarttype, uint loopend, TIMEUNIT loopendtype); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_Sound_GetLoopPoints (IntPtr sound, out uint loopstart, TIMEUNIT loopstarttype, out uint loopend, TIMEUNIT loopendtype); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_Sound_GetMusicNumChannels (IntPtr sound, out int numchannels); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_Sound_SetMusicChannelVolume (IntPtr sound, int channel, float volume); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_Sound_GetMusicChannelVolume (IntPtr sound, int channel, out float volume); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_Sound_SetMusicSpeed (IntPtr sound, float speed); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_Sound_GetMusicSpeed (IntPtr sound, out float speed); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_Sound_SetUserData (IntPtr sound, IntPtr userdata); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_Sound_GetUserData (IntPtr sound, out IntPtr userdata); - #endregion - - #region wrapperinternal - - public IntPtr handle; - - public bool hasHandle() { return this.handle != IntPtr.Zero; } - public void clearHandle() { this.handle = IntPtr.Zero; } - - #endregion - } - - /* - 'ChannelControl' API - */ - interface IChannelControl - { - RESULT getSystemObject (out System system); - - // General control functionality for Channels and ChannelGroups. - RESULT stop (); - RESULT setPaused (bool paused); - RESULT getPaused (out bool paused); - RESULT setVolume (float volume); - RESULT getVolume (out float volume); - RESULT setVolumeRamp (bool ramp); - RESULT getVolumeRamp (out bool ramp); - RESULT getAudibility (out float audibility); - RESULT setPitch (float pitch); - RESULT getPitch (out float pitch); - RESULT setMute (bool mute); - RESULT getMute (out bool mute); - RESULT setReverbProperties (int instance, float wet); - RESULT getReverbProperties (int instance, out float wet); - RESULT setLowPassGain (float gain); - RESULT getLowPassGain (out float gain); - RESULT setMode (MODE mode); - RESULT getMode (out MODE mode); - RESULT setCallback (CHANNELCONTROL_CALLBACK callback); - RESULT isPlaying (out bool isplaying); - - // Note all 'set' functions alter a final matrix, this is why the only get function is getMixMatrix, to avoid other get functions returning incorrect/obsolete values. - RESULT setPan (float pan); - RESULT setMixLevelsOutput (float frontleft, float frontright, float center, float lfe, float surroundleft, float surroundright, float backleft, float backright); - RESULT setMixLevelsInput (float[] levels, int numlevels); - RESULT setMixMatrix (float[] matrix, int outchannels, int inchannels, int inchannel_hop); - RESULT getMixMatrix (float[] matrix, out int outchannels, out int inchannels, int inchannel_hop); - - // Clock based functionality. - RESULT getDSPClock (out ulong dspclock, out ulong parentclock); - RESULT setDelay (ulong dspclock_start, ulong dspclock_end, bool stopchannels); - RESULT getDelay (out ulong dspclock_start, out ulong dspclock_end); - RESULT getDelay (out ulong dspclock_start, out ulong dspclock_end, out bool stopchannels); - RESULT addFadePoint (ulong dspclock, float volume); - RESULT setFadePointRamp (ulong dspclock, float volume); - RESULT removeFadePoints (ulong dspclock_start, ulong dspclock_end); - RESULT getFadePoints (ref uint numpoints, ulong[] point_dspclock, float[] point_volume); - - // DSP effects. - RESULT getDSP (int index, out DSP dsp); - RESULT addDSP (int index, DSP dsp); - RESULT removeDSP (DSP dsp); - RESULT getNumDSPs (out int numdsps); - RESULT setDSPIndex (DSP dsp, int index); - RESULT getDSPIndex (DSP dsp, out int index); - - // 3D functionality. - RESULT set3DAttributes (ref VECTOR pos, ref VECTOR vel); - RESULT get3DAttributes (out VECTOR pos, out VECTOR vel); - RESULT set3DMinMaxDistance (float mindistance, float maxdistance); - RESULT get3DMinMaxDistance (out float mindistance, out float maxdistance); - RESULT set3DConeSettings (float insideconeangle, float outsideconeangle, float outsidevolume); - RESULT get3DConeSettings (out float insideconeangle, out float outsideconeangle, out float outsidevolume); - RESULT set3DConeOrientation (ref VECTOR orientation); - RESULT get3DConeOrientation (out VECTOR orientation); - RESULT set3DCustomRolloff (ref VECTOR points, int numpoints); - RESULT get3DCustomRolloff (out IntPtr points, out int numpoints); - RESULT set3DOcclusion (float directocclusion, float reverbocclusion); - RESULT get3DOcclusion (out float directocclusion, out float reverbocclusion); - RESULT set3DSpread (float angle); - RESULT get3DSpread (out float angle); - RESULT set3DLevel (float level); - RESULT get3DLevel (out float level); - RESULT set3DDopplerLevel (float level); - RESULT get3DDopplerLevel (out float level); - RESULT set3DDistanceFilter (bool custom, float customLevel, float centerFreq); - RESULT get3DDistanceFilter (out bool custom, out float customLevel, out float centerFreq); - - // Userdata set/get. - RESULT setUserData (IntPtr userdata); - RESULT getUserData (out IntPtr userdata); - } - - /* - 'Channel' API - */ - public struct Channel : IChannelControl - { - // Channel specific control functionality. - public RESULT setFrequency(float frequency) - { - return FMOD5_Channel_SetFrequency(this.handle, frequency); - } - public RESULT getFrequency(out float frequency) - { - return FMOD5_Channel_GetFrequency(this.handle, out frequency); - } - public RESULT setPriority(int priority) - { - return FMOD5_Channel_SetPriority(this.handle, priority); - } - public RESULT getPriority(out int priority) - { - return FMOD5_Channel_GetPriority(this.handle, out priority); - } - public RESULT setPosition(uint position, TIMEUNIT postype) - { - return FMOD5_Channel_SetPosition(this.handle, position, postype); - } - public RESULT getPosition(out uint position, TIMEUNIT postype) - { - return FMOD5_Channel_GetPosition(this.handle, out position, postype); - } - public RESULT setChannelGroup(ChannelGroup channelgroup) - { - return FMOD5_Channel_SetChannelGroup(this.handle, channelgroup.handle); - } - public RESULT getChannelGroup(out ChannelGroup channelgroup) - { - return FMOD5_Channel_GetChannelGroup(this.handle, out channelgroup.handle); - } - public RESULT setLoopCount(int loopcount) - { - return FMOD5_Channel_SetLoopCount(this.handle, loopcount); - } - public RESULT getLoopCount(out int loopcount) - { - return FMOD5_Channel_GetLoopCount(this.handle, out loopcount); - } - public RESULT setLoopPoints(uint loopstart, TIMEUNIT loopstarttype, uint loopend, TIMEUNIT loopendtype) - { - return FMOD5_Channel_SetLoopPoints(this.handle, loopstart, loopstarttype, loopend, loopendtype); - } - public RESULT getLoopPoints(out uint loopstart, TIMEUNIT loopstarttype, out uint loopend, TIMEUNIT loopendtype) - { - return FMOD5_Channel_GetLoopPoints(this.handle, out loopstart, loopstarttype, out loopend, loopendtype); - } - - // Information only functions. - public RESULT isVirtual(out bool isvirtual) - { - return FMOD5_Channel_IsVirtual(this.handle, out isvirtual); - } - public RESULT getCurrentSound(out Sound sound) - { - return FMOD5_Channel_GetCurrentSound(this.handle, out sound.handle); - } - public RESULT getIndex(out int index) - { - return FMOD5_Channel_GetIndex(this.handle, out index); - } - - public RESULT getSystemObject(out System system) - { - return FMOD5_Channel_GetSystemObject(this.handle, out system.handle); - } - - // General control functionality for Channels and ChannelGroups. - public RESULT stop() - { - return FMOD5_Channel_Stop(this.handle); - } - public RESULT setPaused(bool paused) - { - return FMOD5_Channel_SetPaused(this.handle, paused); - } - public RESULT getPaused(out bool paused) - { - return FMOD5_Channel_GetPaused(this.handle, out paused); - } - public RESULT setVolume(float volume) - { - return FMOD5_Channel_SetVolume(this.handle, volume); - } - public RESULT getVolume(out float volume) - { - return FMOD5_Channel_GetVolume(this.handle, out volume); - } - public RESULT setVolumeRamp(bool ramp) - { - return FMOD5_Channel_SetVolumeRamp(this.handle, ramp); - } - public RESULT getVolumeRamp(out bool ramp) - { - return FMOD5_Channel_GetVolumeRamp(this.handle, out ramp); - } - public RESULT getAudibility(out float audibility) - { - return FMOD5_Channel_GetAudibility(this.handle, out audibility); - } - public RESULT setPitch(float pitch) - { - return FMOD5_Channel_SetPitch(this.handle, pitch); - } - public RESULT getPitch(out float pitch) - { - return FMOD5_Channel_GetPitch(this.handle, out pitch); - } - public RESULT setMute(bool mute) - { - return FMOD5_Channel_SetMute(this.handle, mute); - } - public RESULT getMute(out bool mute) - { - return FMOD5_Channel_GetMute(this.handle, out mute); - } - public RESULT setReverbProperties(int instance, float wet) - { - return FMOD5_Channel_SetReverbProperties(this.handle, instance, wet); - } - public RESULT getReverbProperties(int instance, out float wet) - { - return FMOD5_Channel_GetReverbProperties(this.handle, instance, out wet); - } - public RESULT setLowPassGain(float gain) - { - return FMOD5_Channel_SetLowPassGain(this.handle, gain); - } - public RESULT getLowPassGain(out float gain) - { - return FMOD5_Channel_GetLowPassGain(this.handle, out gain); - } - public RESULT setMode(MODE mode) - { - return FMOD5_Channel_SetMode(this.handle, mode); - } - public RESULT getMode(out MODE mode) - { - return FMOD5_Channel_GetMode(this.handle, out mode); - } - public RESULT setCallback(CHANNELCONTROL_CALLBACK callback) - { - return FMOD5_Channel_SetCallback(this.handle, callback); - } - public RESULT isPlaying(out bool isplaying) - { - return FMOD5_Channel_IsPlaying(this.handle, out isplaying); - } - - // Note all 'set' functions alter a final matrix, this is why the only get function is getMixMatrix, to avoid other get functions returning incorrect/obsolete values. - public RESULT setPan(float pan) - { - return FMOD5_Channel_SetPan(this.handle, pan); - } - public RESULT setMixLevelsOutput(float frontleft, float frontright, float center, float lfe, float surroundleft, float surroundright, float backleft, float backright) - { - return FMOD5_Channel_SetMixLevelsOutput(this.handle, frontleft, frontright, center, lfe, surroundleft, surroundright, backleft, backright); - } - public RESULT setMixLevelsInput(float[] levels, int numlevels) - { - return FMOD5_Channel_SetMixLevelsInput(this.handle, levels, numlevels); - } - public RESULT setMixMatrix(float[] matrix, int outchannels, int inchannels, int inchannel_hop = 0) - { - return FMOD5_Channel_SetMixMatrix(this.handle, matrix, outchannels, inchannels, inchannel_hop); - } - public RESULT getMixMatrix(float[] matrix, out int outchannels, out int inchannels, int inchannel_hop = 0) - { - return FMOD5_Channel_GetMixMatrix(this.handle, matrix, out outchannels, out inchannels, inchannel_hop); - } - - // Clock based functionality. - public RESULT getDSPClock(out ulong dspclock, out ulong parentclock) - { - return FMOD5_Channel_GetDSPClock(this.handle, out dspclock, out parentclock); - } - public RESULT setDelay(ulong dspclock_start, ulong dspclock_end, bool stopchannels = true) - { - return FMOD5_Channel_SetDelay(this.handle, dspclock_start, dspclock_end, stopchannels); - } - public RESULT getDelay(out ulong dspclock_start, out ulong dspclock_end) - { - return FMOD5_Channel_GetDelay(this.handle, out dspclock_start, out dspclock_end, IntPtr.Zero); - } - public RESULT getDelay(out ulong dspclock_start, out ulong dspclock_end, out bool stopchannels) - { - return FMOD5_Channel_GetDelay(this.handle, out dspclock_start, out dspclock_end, out stopchannels); - } - public RESULT addFadePoint(ulong dspclock, float volume) - { - return FMOD5_Channel_AddFadePoint(this.handle, dspclock, volume); - } - public RESULT setFadePointRamp(ulong dspclock, float volume) - { - return FMOD5_Channel_SetFadePointRamp(this.handle, dspclock, volume); - } - public RESULT removeFadePoints(ulong dspclock_start, ulong dspclock_end) - { - return FMOD5_Channel_RemoveFadePoints(this.handle, dspclock_start, dspclock_end); - } - public RESULT getFadePoints(ref uint numpoints, ulong[] point_dspclock, float[] point_volume) - { - return FMOD5_Channel_GetFadePoints(this.handle, ref numpoints, point_dspclock, point_volume); - } - - // DSP effects. - public RESULT getDSP(int index, out DSP dsp) - { - return FMOD5_Channel_GetDSP(this.handle, index, out dsp.handle); - } - public RESULT addDSP(int index, DSP dsp) - { - return FMOD5_Channel_AddDSP(this.handle, index, dsp.handle); - } - public RESULT removeDSP(DSP dsp) - { - return FMOD5_Channel_RemoveDSP(this.handle, dsp.handle); - } - public RESULT getNumDSPs(out int numdsps) - { - return FMOD5_Channel_GetNumDSPs(this.handle, out numdsps); - } - public RESULT setDSPIndex(DSP dsp, int index) - { - return FMOD5_Channel_SetDSPIndex(this.handle, dsp.handle, index); - } - public RESULT getDSPIndex(DSP dsp, out int index) - { - return FMOD5_Channel_GetDSPIndex(this.handle, dsp.handle, out index); - } - - // 3D functionality. - public RESULT set3DAttributes(ref VECTOR pos, ref VECTOR vel) - { - return FMOD5_Channel_Set3DAttributes(this.handle, ref pos, ref vel); - } - public RESULT get3DAttributes(out VECTOR pos, out VECTOR vel) - { - return FMOD5_Channel_Get3DAttributes(this.handle, out pos, out vel); - } - public RESULT set3DMinMaxDistance(float mindistance, float maxdistance) - { - return FMOD5_Channel_Set3DMinMaxDistance(this.handle, mindistance, maxdistance); - } - public RESULT get3DMinMaxDistance(out float mindistance, out float maxdistance) - { - return FMOD5_Channel_Get3DMinMaxDistance(this.handle, out mindistance, out maxdistance); - } - public RESULT set3DConeSettings(float insideconeangle, float outsideconeangle, float outsidevolume) - { - return FMOD5_Channel_Set3DConeSettings(this.handle, insideconeangle, outsideconeangle, outsidevolume); - } - public RESULT get3DConeSettings(out float insideconeangle, out float outsideconeangle, out float outsidevolume) - { - return FMOD5_Channel_Get3DConeSettings(this.handle, out insideconeangle, out outsideconeangle, out outsidevolume); - } - public RESULT set3DConeOrientation(ref VECTOR orientation) - { - return FMOD5_Channel_Set3DConeOrientation(this.handle, ref orientation); - } - public RESULT get3DConeOrientation(out VECTOR orientation) - { - return FMOD5_Channel_Get3DConeOrientation(this.handle, out orientation); - } - public RESULT set3DCustomRolloff(ref VECTOR points, int numpoints) - { - return FMOD5_Channel_Set3DCustomRolloff(this.handle, ref points, numpoints); - } - public RESULT get3DCustomRolloff(out IntPtr points, out int numpoints) - { - return FMOD5_Channel_Get3DCustomRolloff(this.handle, out points, out numpoints); - } - public RESULT set3DOcclusion(float directocclusion, float reverbocclusion) - { - return FMOD5_Channel_Set3DOcclusion(this.handle, directocclusion, reverbocclusion); - } - public RESULT get3DOcclusion(out float directocclusion, out float reverbocclusion) - { - return FMOD5_Channel_Get3DOcclusion(this.handle, out directocclusion, out reverbocclusion); - } - public RESULT set3DSpread(float angle) - { - return FMOD5_Channel_Set3DSpread(this.handle, angle); - } - public RESULT get3DSpread(out float angle) - { - return FMOD5_Channel_Get3DSpread(this.handle, out angle); - } - public RESULT set3DLevel(float level) - { - return FMOD5_Channel_Set3DLevel(this.handle, level); - } - public RESULT get3DLevel(out float level) - { - return FMOD5_Channel_Get3DLevel(this.handle, out level); - } - public RESULT set3DDopplerLevel(float level) - { - return FMOD5_Channel_Set3DDopplerLevel(this.handle, level); - } - public RESULT get3DDopplerLevel(out float level) - { - return FMOD5_Channel_Get3DDopplerLevel(this.handle, out level); - } - public RESULT set3DDistanceFilter(bool custom, float customLevel, float centerFreq) - { - return FMOD5_Channel_Set3DDistanceFilter(this.handle, custom, customLevel, centerFreq); - } - public RESULT get3DDistanceFilter(out bool custom, out float customLevel, out float centerFreq) - { - return FMOD5_Channel_Get3DDistanceFilter(this.handle, out custom, out customLevel, out centerFreq); - } - - // Userdata set/get. - public RESULT setUserData(IntPtr userdata) - { - return FMOD5_Channel_SetUserData(this.handle, userdata); - } - public RESULT getUserData(out IntPtr userdata) - { - return FMOD5_Channel_GetUserData(this.handle, out userdata); - } - - #region importfunctions - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_Channel_SetFrequency (IntPtr channel, float frequency); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_Channel_GetFrequency (IntPtr channel, out float frequency); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_Channel_SetPriority (IntPtr channel, int priority); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_Channel_GetPriority (IntPtr channel, out int priority); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_Channel_SetPosition (IntPtr channel, uint position, TIMEUNIT postype); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_Channel_GetPosition (IntPtr channel, out uint position, TIMEUNIT postype); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_Channel_SetChannelGroup (IntPtr channel, IntPtr channelgroup); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_Channel_GetChannelGroup (IntPtr channel, out IntPtr channelgroup); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_Channel_SetLoopCount (IntPtr channel, int loopcount); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_Channel_GetLoopCount (IntPtr channel, out int loopcount); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_Channel_SetLoopPoints (IntPtr channel, uint loopstart, TIMEUNIT loopstarttype, uint loopend, TIMEUNIT loopendtype); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_Channel_GetLoopPoints (IntPtr channel, out uint loopstart, TIMEUNIT loopstarttype, out uint loopend, TIMEUNIT loopendtype); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_Channel_IsVirtual (IntPtr channel, out bool isvirtual); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_Channel_GetCurrentSound (IntPtr channel, out IntPtr sound); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_Channel_GetIndex (IntPtr channel, out int index); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_Channel_GetSystemObject (IntPtr channel, out IntPtr system); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_Channel_Stop (IntPtr channel); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_Channel_SetPaused (IntPtr channel, bool paused); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_Channel_GetPaused (IntPtr channel, out bool paused); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_Channel_SetVolume (IntPtr channel, float volume); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_Channel_GetVolume (IntPtr channel, out float volume); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_Channel_SetVolumeRamp (IntPtr channel, bool ramp); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_Channel_GetVolumeRamp (IntPtr channel, out bool ramp); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_Channel_GetAudibility (IntPtr channel, out float audibility); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_Channel_SetPitch (IntPtr channel, float pitch); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_Channel_GetPitch (IntPtr channel, out float pitch); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_Channel_SetMute (IntPtr channel, bool mute); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_Channel_GetMute (IntPtr channel, out bool mute); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_Channel_SetReverbProperties (IntPtr channel, int instance, float wet); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_Channel_GetReverbProperties (IntPtr channel, int instance, out float wet); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_Channel_SetLowPassGain (IntPtr channel, float gain); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_Channel_GetLowPassGain (IntPtr channel, out float gain); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_Channel_SetMode (IntPtr channel, MODE mode); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_Channel_GetMode (IntPtr channel, out MODE mode); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_Channel_SetCallback (IntPtr channel, CHANNELCONTROL_CALLBACK callback); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_Channel_IsPlaying (IntPtr channel, out bool isplaying); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_Channel_SetPan (IntPtr channel, float pan); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_Channel_SetMixLevelsOutput (IntPtr channel, float frontleft, float frontright, float center, float lfe, float surroundleft, float surroundright, float backleft, float backright); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_Channel_SetMixLevelsInput (IntPtr channel, float[] levels, int numlevels); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_Channel_SetMixMatrix (IntPtr channel, float[] matrix, int outchannels, int inchannels, int inchannel_hop); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_Channel_GetMixMatrix (IntPtr channel, float[] matrix, out int outchannels, out int inchannels, int inchannel_hop); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_Channel_GetDSPClock (IntPtr channel, out ulong dspclock, out ulong parentclock); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_Channel_SetDelay (IntPtr channel, ulong dspclock_start, ulong dspclock_end, bool stopchannels); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_Channel_GetDelay (IntPtr channel, out ulong dspclock_start, out ulong dspclock_end, IntPtr zero); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_Channel_GetDelay (IntPtr channel, out ulong dspclock_start, out ulong dspclock_end, out bool stopchannels); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_Channel_AddFadePoint (IntPtr channel, ulong dspclock, float volume); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_Channel_SetFadePointRamp (IntPtr channel, ulong dspclock, float volume); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_Channel_RemoveFadePoints (IntPtr channel, ulong dspclock_start, ulong dspclock_end); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_Channel_GetFadePoints (IntPtr channel, ref uint numpoints, ulong[] point_dspclock, float[] point_volume); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_Channel_GetDSP (IntPtr channel, int index, out IntPtr dsp); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_Channel_AddDSP (IntPtr channel, int index, IntPtr dsp); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_Channel_RemoveDSP (IntPtr channel, IntPtr dsp); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_Channel_GetNumDSPs (IntPtr channel, out int numdsps); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_Channel_SetDSPIndex (IntPtr channel, IntPtr dsp, int index); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_Channel_GetDSPIndex (IntPtr channel, IntPtr dsp, out int index); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_Channel_Set3DAttributes (IntPtr channel, ref VECTOR pos, ref VECTOR vel); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_Channel_Get3DAttributes (IntPtr channel, out VECTOR pos, out VECTOR vel); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_Channel_Set3DMinMaxDistance (IntPtr channel, float mindistance, float maxdistance); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_Channel_Get3DMinMaxDistance (IntPtr channel, out float mindistance, out float maxdistance); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_Channel_Set3DConeSettings (IntPtr channel, float insideconeangle, float outsideconeangle, float outsidevolume); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_Channel_Get3DConeSettings (IntPtr channel, out float insideconeangle, out float outsideconeangle, out float outsidevolume); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_Channel_Set3DConeOrientation (IntPtr channel, ref VECTOR orientation); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_Channel_Get3DConeOrientation (IntPtr channel, out VECTOR orientation); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_Channel_Set3DCustomRolloff (IntPtr channel, ref VECTOR points, int numpoints); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_Channel_Get3DCustomRolloff (IntPtr channel, out IntPtr points, out int numpoints); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_Channel_Set3DOcclusion (IntPtr channel, float directocclusion, float reverbocclusion); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_Channel_Get3DOcclusion (IntPtr channel, out float directocclusion, out float reverbocclusion); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_Channel_Set3DSpread (IntPtr channel, float angle); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_Channel_Get3DSpread (IntPtr channel, out float angle); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_Channel_Set3DLevel (IntPtr channel, float level); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_Channel_Get3DLevel (IntPtr channel, out float level); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_Channel_Set3DDopplerLevel (IntPtr channel, float level); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_Channel_Get3DDopplerLevel (IntPtr channel, out float level); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_Channel_Set3DDistanceFilter (IntPtr channel, bool custom, float customLevel, float centerFreq); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_Channel_Get3DDistanceFilter (IntPtr channel, out bool custom, out float customLevel, out float centerFreq); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_Channel_SetUserData (IntPtr channel, IntPtr userdata); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_Channel_GetUserData (IntPtr channel, out IntPtr userdata); - #endregion - - #region wrapperinternal - - public IntPtr handle; - - public bool hasHandle() { return this.handle != IntPtr.Zero; } - public void clearHandle() { this.handle = IntPtr.Zero; } - - #endregion - } - - /* - 'ChannelGroup' API - */ - public struct ChannelGroup : IChannelControl - { - public RESULT release() - { - return FMOD5_ChannelGroup_Release(this.handle); - } - - // Nested channel groups. - public RESULT addGroup(ChannelGroup group, bool propagatedspclock = true) - { - return FMOD5_ChannelGroup_AddGroup(this.handle, group.handle, propagatedspclock, IntPtr.Zero); - } - public RESULT addGroup(ChannelGroup group, bool propagatedspclock, out DSPConnection connection) - { - return FMOD5_ChannelGroup_AddGroup(this.handle, group.handle, propagatedspclock, out connection.handle); - } - public RESULT getNumGroups(out int numgroups) - { - return FMOD5_ChannelGroup_GetNumGroups(this.handle, out numgroups); - } - public RESULT getGroup(int index, out ChannelGroup group) - { - return FMOD5_ChannelGroup_GetGroup(this.handle, index, out group.handle); - } - public RESULT getParentGroup(out ChannelGroup group) - { - return FMOD5_ChannelGroup_GetParentGroup(this.handle, out group.handle); - } - - // Information only functions. - public RESULT getName(out string name, int namelen) - { - IntPtr stringMem = Marshal.AllocHGlobal(namelen); - - RESULT result = FMOD5_ChannelGroup_GetName(this.handle, stringMem, namelen); - using (StringHelper.ThreadSafeEncoding encoder = StringHelper.GetFreeHelper()) - { - name = encoder.stringFromNative(stringMem); - } - Marshal.FreeHGlobal(stringMem); - - return result; - } - public RESULT getNumChannels(out int numchannels) - { - return FMOD5_ChannelGroup_GetNumChannels(this.handle, out numchannels); - } - public RESULT getChannel(int index, out Channel channel) - { - return FMOD5_ChannelGroup_GetChannel(this.handle, index, out channel.handle); - } - - public RESULT getSystemObject(out System system) - { - return FMOD5_ChannelGroup_GetSystemObject(this.handle, out system.handle); - } - - // General control functionality for Channels and ChannelGroups. - public RESULT stop() - { - return FMOD5_ChannelGroup_Stop(this.handle); - } - public RESULT setPaused(bool paused) - { - return FMOD5_ChannelGroup_SetPaused(this.handle, paused); - } - public RESULT getPaused(out bool paused) - { - return FMOD5_ChannelGroup_GetPaused(this.handle, out paused); - } - public RESULT setVolume(float volume) - { - return FMOD5_ChannelGroup_SetVolume(this.handle, volume); - } - public RESULT getVolume(out float volume) - { - return FMOD5_ChannelGroup_GetVolume(this.handle, out volume); - } - public RESULT setVolumeRamp(bool ramp) - { - return FMOD5_ChannelGroup_SetVolumeRamp(this.handle, ramp); - } - public RESULT getVolumeRamp(out bool ramp) - { - return FMOD5_ChannelGroup_GetVolumeRamp(this.handle, out ramp); - } - public RESULT getAudibility(out float audibility) - { - return FMOD5_ChannelGroup_GetAudibility(this.handle, out audibility); - } - public RESULT setPitch(float pitch) - { - return FMOD5_ChannelGroup_SetPitch(this.handle, pitch); - } - public RESULT getPitch(out float pitch) - { - return FMOD5_ChannelGroup_GetPitch(this.handle, out pitch); - } - public RESULT setMute(bool mute) - { - return FMOD5_ChannelGroup_SetMute(this.handle, mute); - } - public RESULT getMute(out bool mute) - { - return FMOD5_ChannelGroup_GetMute(this.handle, out mute); - } - public RESULT setReverbProperties(int instance, float wet) - { - return FMOD5_ChannelGroup_SetReverbProperties(this.handle, instance, wet); - } - public RESULT getReverbProperties(int instance, out float wet) - { - return FMOD5_ChannelGroup_GetReverbProperties(this.handle, instance, out wet); - } - public RESULT setLowPassGain(float gain) - { - return FMOD5_ChannelGroup_SetLowPassGain(this.handle, gain); - } - public RESULT getLowPassGain(out float gain) - { - return FMOD5_ChannelGroup_GetLowPassGain(this.handle, out gain); - } - public RESULT setMode(MODE mode) - { - return FMOD5_ChannelGroup_SetMode(this.handle, mode); - } - public RESULT getMode(out MODE mode) - { - return FMOD5_ChannelGroup_GetMode(this.handle, out mode); - } - public RESULT setCallback(CHANNELCONTROL_CALLBACK callback) - { - return FMOD5_ChannelGroup_SetCallback(this.handle, callback); - } - public RESULT isPlaying(out bool isplaying) - { - return FMOD5_ChannelGroup_IsPlaying(this.handle, out isplaying); - } - - // Note all 'set' functions alter a final matrix, this is why the only get function is getMixMatrix, to avoid other get functions returning incorrect/obsolete values. - public RESULT setPan(float pan) - { - return FMOD5_ChannelGroup_SetPan(this.handle, pan); - } - public RESULT setMixLevelsOutput(float frontleft, float frontright, float center, float lfe, float surroundleft, float surroundright, float backleft, float backright) - { - return FMOD5_ChannelGroup_SetMixLevelsOutput(this.handle, frontleft, frontright, center, lfe, surroundleft, surroundright, backleft, backright); - } - public RESULT setMixLevelsInput(float[] levels, int numlevels) - { - return FMOD5_ChannelGroup_SetMixLevelsInput(this.handle, levels, numlevels); - } - public RESULT setMixMatrix(float[] matrix, int outchannels, int inchannels, int inchannel_hop) - { - return FMOD5_ChannelGroup_SetMixMatrix(this.handle, matrix, outchannels, inchannels, inchannel_hop); - } - public RESULT getMixMatrix(float[] matrix, out int outchannels, out int inchannels, int inchannel_hop) - { - return FMOD5_ChannelGroup_GetMixMatrix(this.handle, matrix, out outchannels, out inchannels, inchannel_hop); - } - - // Clock based functionality. - public RESULT getDSPClock(out ulong dspclock, out ulong parentclock) - { - return FMOD5_ChannelGroup_GetDSPClock(this.handle, out dspclock, out parentclock); - } - public RESULT setDelay(ulong dspclock_start, ulong dspclock_end, bool stopchannels) - { - return FMOD5_ChannelGroup_SetDelay(this.handle, dspclock_start, dspclock_end, stopchannels); - } - public RESULT getDelay(out ulong dspclock_start, out ulong dspclock_end) - { - return FMOD5_ChannelGroup_GetDelay(this.handle, out dspclock_start, out dspclock_end, IntPtr.Zero); - } - public RESULT getDelay(out ulong dspclock_start, out ulong dspclock_end, out bool stopchannels) - { - return FMOD5_ChannelGroup_GetDelay(this.handle, out dspclock_start, out dspclock_end, out stopchannels); - } - public RESULT addFadePoint(ulong dspclock, float volume) - { - return FMOD5_ChannelGroup_AddFadePoint(this.handle, dspclock, volume); - } - public RESULT setFadePointRamp(ulong dspclock, float volume) - { - return FMOD5_ChannelGroup_SetFadePointRamp(this.handle, dspclock, volume); - } - public RESULT removeFadePoints(ulong dspclock_start, ulong dspclock_end) - { - return FMOD5_ChannelGroup_RemoveFadePoints(this.handle, dspclock_start, dspclock_end); - } - public RESULT getFadePoints(ref uint numpoints, ulong[] point_dspclock, float[] point_volume) - { - return FMOD5_ChannelGroup_GetFadePoints(this.handle, ref numpoints, point_dspclock, point_volume); - } - - // DSP effects. - public RESULT getDSP(int index, out DSP dsp) - { - return FMOD5_ChannelGroup_GetDSP(this.handle, index, out dsp.handle); - } - public RESULT addDSP(int index, DSP dsp) - { - return FMOD5_ChannelGroup_AddDSP(this.handle, index, dsp.handle); - } - public RESULT removeDSP(DSP dsp) - { - return FMOD5_ChannelGroup_RemoveDSP(this.handle, dsp.handle); - } - public RESULT getNumDSPs(out int numdsps) - { - return FMOD5_ChannelGroup_GetNumDSPs(this.handle, out numdsps); - } - public RESULT setDSPIndex(DSP dsp, int index) - { - return FMOD5_ChannelGroup_SetDSPIndex(this.handle, dsp.handle, index); - } - public RESULT getDSPIndex(DSP dsp, out int index) - { - return FMOD5_ChannelGroup_GetDSPIndex(this.handle, dsp.handle, out index); - } - - // 3D functionality. - public RESULT set3DAttributes(ref VECTOR pos, ref VECTOR vel) - { - return FMOD5_ChannelGroup_Set3DAttributes(this.handle, ref pos, ref vel); - } - public RESULT get3DAttributes(out VECTOR pos, out VECTOR vel) - { - return FMOD5_ChannelGroup_Get3DAttributes(this.handle, out pos, out vel); - } - public RESULT set3DMinMaxDistance(float mindistance, float maxdistance) - { - return FMOD5_ChannelGroup_Set3DMinMaxDistance(this.handle, mindistance, maxdistance); - } - public RESULT get3DMinMaxDistance(out float mindistance, out float maxdistance) - { - return FMOD5_ChannelGroup_Get3DMinMaxDistance(this.handle, out mindistance, out maxdistance); - } - public RESULT set3DConeSettings(float insideconeangle, float outsideconeangle, float outsidevolume) - { - return FMOD5_ChannelGroup_Set3DConeSettings(this.handle, insideconeangle, outsideconeangle, outsidevolume); - } - public RESULT get3DConeSettings(out float insideconeangle, out float outsideconeangle, out float outsidevolume) - { - return FMOD5_ChannelGroup_Get3DConeSettings(this.handle, out insideconeangle, out outsideconeangle, out outsidevolume); - } - public RESULT set3DConeOrientation(ref VECTOR orientation) - { - return FMOD5_ChannelGroup_Set3DConeOrientation(this.handle, ref orientation); - } - public RESULT get3DConeOrientation(out VECTOR orientation) - { - return FMOD5_ChannelGroup_Get3DConeOrientation(this.handle, out orientation); - } - public RESULT set3DCustomRolloff(ref VECTOR points, int numpoints) - { - return FMOD5_ChannelGroup_Set3DCustomRolloff(this.handle, ref points, numpoints); - } - public RESULT get3DCustomRolloff(out IntPtr points, out int numpoints) - { - return FMOD5_ChannelGroup_Get3DCustomRolloff(this.handle, out points, out numpoints); - } - public RESULT set3DOcclusion(float directocclusion, float reverbocclusion) - { - return FMOD5_ChannelGroup_Set3DOcclusion(this.handle, directocclusion, reverbocclusion); - } - public RESULT get3DOcclusion(out float directocclusion, out float reverbocclusion) - { - return FMOD5_ChannelGroup_Get3DOcclusion(this.handle, out directocclusion, out reverbocclusion); - } - public RESULT set3DSpread(float angle) - { - return FMOD5_ChannelGroup_Set3DSpread(this.handle, angle); - } - public RESULT get3DSpread(out float angle) - { - return FMOD5_ChannelGroup_Get3DSpread(this.handle, out angle); - } - public RESULT set3DLevel(float level) - { - return FMOD5_ChannelGroup_Set3DLevel(this.handle, level); - } - public RESULT get3DLevel(out float level) - { - return FMOD5_ChannelGroup_Get3DLevel(this.handle, out level); - } - public RESULT set3DDopplerLevel(float level) - { - return FMOD5_ChannelGroup_Set3DDopplerLevel(this.handle, level); - } - public RESULT get3DDopplerLevel(out float level) - { - return FMOD5_ChannelGroup_Get3DDopplerLevel(this.handle, out level); - } - public RESULT set3DDistanceFilter(bool custom, float customLevel, float centerFreq) - { - return FMOD5_ChannelGroup_Set3DDistanceFilter(this.handle, custom, customLevel, centerFreq); - } - public RESULT get3DDistanceFilter(out bool custom, out float customLevel, out float centerFreq) - { - return FMOD5_ChannelGroup_Get3DDistanceFilter(this.handle, out custom, out customLevel, out centerFreq); - } - - // Userdata set/get. - public RESULT setUserData(IntPtr userdata) - { - return FMOD5_ChannelGroup_SetUserData(this.handle, userdata); - } - public RESULT getUserData(out IntPtr userdata) - { - return FMOD5_ChannelGroup_GetUserData(this.handle, out userdata); - } - - #region importfunctions - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_ChannelGroup_Release (IntPtr channelgroup); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_ChannelGroup_AddGroup (IntPtr channelgroup, IntPtr group, bool propagatedspclock, IntPtr zero); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_ChannelGroup_AddGroup (IntPtr channelgroup, IntPtr group, bool propagatedspclock, out IntPtr connection); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_ChannelGroup_GetNumGroups (IntPtr channelgroup, out int numgroups); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_ChannelGroup_GetGroup (IntPtr channelgroup, int index, out IntPtr group); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_ChannelGroup_GetParentGroup (IntPtr channelgroup, out IntPtr group); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_ChannelGroup_GetName (IntPtr channelgroup, IntPtr name, int namelen); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_ChannelGroup_GetNumChannels (IntPtr channelgroup, out int numchannels); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_ChannelGroup_GetChannel (IntPtr channelgroup, int index, out IntPtr channel); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_ChannelGroup_GetSystemObject (IntPtr channelgroup, out IntPtr system); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_ChannelGroup_Stop (IntPtr channelgroup); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_ChannelGroup_SetPaused (IntPtr channelgroup, bool paused); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_ChannelGroup_GetPaused (IntPtr channelgroup, out bool paused); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_ChannelGroup_SetVolume (IntPtr channelgroup, float volume); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_ChannelGroup_GetVolume (IntPtr channelgroup, out float volume); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_ChannelGroup_SetVolumeRamp (IntPtr channelgroup, bool ramp); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_ChannelGroup_GetVolumeRamp (IntPtr channelgroup, out bool ramp); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_ChannelGroup_GetAudibility (IntPtr channelgroup, out float audibility); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_ChannelGroup_SetPitch (IntPtr channelgroup, float pitch); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_ChannelGroup_GetPitch (IntPtr channelgroup, out float pitch); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_ChannelGroup_SetMute (IntPtr channelgroup, bool mute); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_ChannelGroup_GetMute (IntPtr channelgroup, out bool mute); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_ChannelGroup_SetReverbProperties (IntPtr channelgroup, int instance, float wet); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_ChannelGroup_GetReverbProperties (IntPtr channelgroup, int instance, out float wet); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_ChannelGroup_SetLowPassGain (IntPtr channelgroup, float gain); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_ChannelGroup_GetLowPassGain (IntPtr channelgroup, out float gain); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_ChannelGroup_SetMode (IntPtr channelgroup, MODE mode); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_ChannelGroup_GetMode (IntPtr channelgroup, out MODE mode); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_ChannelGroup_SetCallback (IntPtr channelgroup, CHANNELCONTROL_CALLBACK callback); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_ChannelGroup_IsPlaying (IntPtr channelgroup, out bool isplaying); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_ChannelGroup_SetPan (IntPtr channelgroup, float pan); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_ChannelGroup_SetMixLevelsOutput (IntPtr channelgroup, float frontleft, float frontright, float center, float lfe, float surroundleft, float surroundright, float backleft, float backright); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_ChannelGroup_SetMixLevelsInput (IntPtr channelgroup, float[] levels, int numlevels); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_ChannelGroup_SetMixMatrix (IntPtr channelgroup, float[] matrix, int outchannels, int inchannels, int inchannel_hop); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_ChannelGroup_GetMixMatrix (IntPtr channelgroup, float[] matrix, out int outchannels, out int inchannels, int inchannel_hop); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_ChannelGroup_GetDSPClock (IntPtr channelgroup, out ulong dspclock, out ulong parentclock); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_ChannelGroup_SetDelay (IntPtr channelgroup, ulong dspclock_start, ulong dspclock_end, bool stopchannels); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_ChannelGroup_GetDelay (IntPtr channelgroup, out ulong dspclock_start, out ulong dspclock_end, IntPtr zero); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_ChannelGroup_GetDelay (IntPtr channelgroup, out ulong dspclock_start, out ulong dspclock_end, out bool stopchannels); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_ChannelGroup_AddFadePoint (IntPtr channelgroup, ulong dspclock, float volume); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_ChannelGroup_SetFadePointRamp (IntPtr channelgroup, ulong dspclock, float volume); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_ChannelGroup_RemoveFadePoints (IntPtr channelgroup, ulong dspclock_start, ulong dspclock_end); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_ChannelGroup_GetFadePoints (IntPtr channelgroup, ref uint numpoints, ulong[] point_dspclock, float[] point_volume); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_ChannelGroup_GetDSP (IntPtr channelgroup, int index, out IntPtr dsp); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_ChannelGroup_AddDSP (IntPtr channelgroup, int index, IntPtr dsp); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_ChannelGroup_RemoveDSP (IntPtr channelgroup, IntPtr dsp); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_ChannelGroup_GetNumDSPs (IntPtr channelgroup, out int numdsps); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_ChannelGroup_SetDSPIndex (IntPtr channelgroup, IntPtr dsp, int index); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_ChannelGroup_GetDSPIndex (IntPtr channelgroup, IntPtr dsp, out int index); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_ChannelGroup_Set3DAttributes (IntPtr channelgroup, ref VECTOR pos, ref VECTOR vel); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_ChannelGroup_Get3DAttributes (IntPtr channelgroup, out VECTOR pos, out VECTOR vel); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_ChannelGroup_Set3DMinMaxDistance (IntPtr channelgroup, float mindistance, float maxdistance); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_ChannelGroup_Get3DMinMaxDistance (IntPtr channelgroup, out float mindistance, out float maxdistance); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_ChannelGroup_Set3DConeSettings (IntPtr channelgroup, float insideconeangle, float outsideconeangle, float outsidevolume); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_ChannelGroup_Get3DConeSettings (IntPtr channelgroup, out float insideconeangle, out float outsideconeangle, out float outsidevolume); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_ChannelGroup_Set3DConeOrientation(IntPtr channelgroup, ref VECTOR orientation); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_ChannelGroup_Get3DConeOrientation(IntPtr channelgroup, out VECTOR orientation); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_ChannelGroup_Set3DCustomRolloff (IntPtr channelgroup, ref VECTOR points, int numpoints); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_ChannelGroup_Get3DCustomRolloff (IntPtr channelgroup, out IntPtr points, out int numpoints); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_ChannelGroup_Set3DOcclusion (IntPtr channelgroup, float directocclusion, float reverbocclusion); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_ChannelGroup_Get3DOcclusion (IntPtr channelgroup, out float directocclusion, out float reverbocclusion); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_ChannelGroup_Set3DSpread (IntPtr channelgroup, float angle); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_ChannelGroup_Get3DSpread (IntPtr channelgroup, out float angle); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_ChannelGroup_Set3DLevel (IntPtr channelgroup, float level); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_ChannelGroup_Get3DLevel (IntPtr channelgroup, out float level); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_ChannelGroup_Set3DDopplerLevel (IntPtr channelgroup, float level); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_ChannelGroup_Get3DDopplerLevel (IntPtr channelgroup, out float level); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_ChannelGroup_Set3DDistanceFilter (IntPtr channelgroup, bool custom, float customLevel, float centerFreq); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_ChannelGroup_Get3DDistanceFilter (IntPtr channelgroup, out bool custom, out float customLevel, out float centerFreq); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_ChannelGroup_SetUserData (IntPtr channelgroup, IntPtr userdata); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_ChannelGroup_GetUserData (IntPtr channelgroup, out IntPtr userdata); - #endregion - - #region wrapperinternal - - public IntPtr handle; - - public bool hasHandle() { return this.handle != IntPtr.Zero; } - public void clearHandle() { this.handle = IntPtr.Zero; } - - #endregion - } - - /* - 'SoundGroup' API - */ - public struct SoundGroup - { - public RESULT release() - { - return FMOD5_SoundGroup_Release(this.handle); - } - - public RESULT getSystemObject(out System system) - { - return FMOD5_SoundGroup_GetSystemObject(this.handle, out system.handle); - } - - // SoundGroup control functions. - public RESULT setMaxAudible(int maxaudible) - { - return FMOD5_SoundGroup_SetMaxAudible(this.handle, maxaudible); - } - public RESULT getMaxAudible(out int maxaudible) - { - return FMOD5_SoundGroup_GetMaxAudible(this.handle, out maxaudible); - } - public RESULT setMaxAudibleBehavior(SOUNDGROUP_BEHAVIOR behavior) - { - return FMOD5_SoundGroup_SetMaxAudibleBehavior(this.handle, behavior); - } - public RESULT getMaxAudibleBehavior(out SOUNDGROUP_BEHAVIOR behavior) - { - return FMOD5_SoundGroup_GetMaxAudibleBehavior(this.handle, out behavior); - } - public RESULT setMuteFadeSpeed(float speed) - { - return FMOD5_SoundGroup_SetMuteFadeSpeed(this.handle, speed); - } - public RESULT getMuteFadeSpeed(out float speed) - { - return FMOD5_SoundGroup_GetMuteFadeSpeed(this.handle, out speed); - } - public RESULT setVolume(float volume) - { - return FMOD5_SoundGroup_SetVolume(this.handle, volume); - } - public RESULT getVolume(out float volume) - { - return FMOD5_SoundGroup_GetVolume(this.handle, out volume); - } - public RESULT stop() - { - return FMOD5_SoundGroup_Stop(this.handle); - } - - // Information only functions. - public RESULT getName(out string name, int namelen) - { - IntPtr stringMem = Marshal.AllocHGlobal(namelen); - - RESULT result = FMOD5_SoundGroup_GetName(this.handle, stringMem, namelen); - using (StringHelper.ThreadSafeEncoding encoder = StringHelper.GetFreeHelper()) - { - name = encoder.stringFromNative(stringMem); - } - Marshal.FreeHGlobal(stringMem); - - return result; - } - public RESULT getNumSounds(out int numsounds) - { - return FMOD5_SoundGroup_GetNumSounds(this.handle, out numsounds); - } - public RESULT getSound(int index, out Sound sound) - { - return FMOD5_SoundGroup_GetSound(this.handle, index, out sound.handle); - } - public RESULT getNumPlaying(out int numplaying) - { - return FMOD5_SoundGroup_GetNumPlaying(this.handle, out numplaying); - } - - // Userdata set/get. - public RESULT setUserData(IntPtr userdata) - { - return FMOD5_SoundGroup_SetUserData(this.handle, userdata); - } - public RESULT getUserData(out IntPtr userdata) - { - return FMOD5_SoundGroup_GetUserData(this.handle, out userdata); - } - - #region importfunctions - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_SoundGroup_Release (IntPtr soundgroup); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_SoundGroup_GetSystemObject (IntPtr soundgroup, out IntPtr system); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_SoundGroup_SetMaxAudible (IntPtr soundgroup, int maxaudible); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_SoundGroup_GetMaxAudible (IntPtr soundgroup, out int maxaudible); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_SoundGroup_SetMaxAudibleBehavior (IntPtr soundgroup, SOUNDGROUP_BEHAVIOR behavior); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_SoundGroup_GetMaxAudibleBehavior (IntPtr soundgroup, out SOUNDGROUP_BEHAVIOR behavior); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_SoundGroup_SetMuteFadeSpeed (IntPtr soundgroup, float speed); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_SoundGroup_GetMuteFadeSpeed (IntPtr soundgroup, out float speed); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_SoundGroup_SetVolume (IntPtr soundgroup, float volume); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_SoundGroup_GetVolume (IntPtr soundgroup, out float volume); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_SoundGroup_Stop (IntPtr soundgroup); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_SoundGroup_GetName (IntPtr soundgroup, IntPtr name, int namelen); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_SoundGroup_GetNumSounds (IntPtr soundgroup, out int numsounds); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_SoundGroup_GetSound (IntPtr soundgroup, int index, out IntPtr sound); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_SoundGroup_GetNumPlaying (IntPtr soundgroup, out int numplaying); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_SoundGroup_SetUserData (IntPtr soundgroup, IntPtr userdata); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_SoundGroup_GetUserData (IntPtr soundgroup, out IntPtr userdata); - #endregion - - #region wrapperinternal - - public IntPtr handle; - - public bool hasHandle() { return this.handle != IntPtr.Zero; } - public void clearHandle() { this.handle = IntPtr.Zero; } - - #endregion - } - - /* - 'DSP' API - */ - public struct DSP - { - public RESULT release() - { - return FMOD5_DSP_Release(this.handle); - } - public RESULT getSystemObject(out System system) - { - return FMOD5_DSP_GetSystemObject(this.handle, out system.handle); - } - - // Connection / disconnection / input and output enumeration. - public RESULT addInput(DSP input) - { - return FMOD5_DSP_AddInput(this.handle, input.handle, IntPtr.Zero, DSPCONNECTION_TYPE.STANDARD); - } - public RESULT addInput(DSP input, out DSPConnection connection, DSPCONNECTION_TYPE type = DSPCONNECTION_TYPE.STANDARD) - { - return FMOD5_DSP_AddInput(this.handle, input.handle, out connection.handle, type); - } - public RESULT disconnectFrom(DSP target, DSPConnection connection) - { - return FMOD5_DSP_DisconnectFrom(this.handle, target.handle, connection.handle); - } - public RESULT disconnectAll(bool inputs, bool outputs) - { - return FMOD5_DSP_DisconnectAll(this.handle, inputs, outputs); - } - public RESULT getNumInputs(out int numinputs) - { - return FMOD5_DSP_GetNumInputs(this.handle, out numinputs); - } - public RESULT getNumOutputs(out int numoutputs) - { - return FMOD5_DSP_GetNumOutputs(this.handle, out numoutputs); - } - public RESULT getInput(int index, out DSP input, out DSPConnection inputconnection) - { - return FMOD5_DSP_GetInput(this.handle, index, out input.handle, out inputconnection.handle); - } - public RESULT getOutput(int index, out DSP output, out DSPConnection outputconnection) - { - return FMOD5_DSP_GetOutput(this.handle, index, out output.handle, out outputconnection.handle); - } - - // DSP unit control. - public RESULT setActive(bool active) - { - return FMOD5_DSP_SetActive(this.handle, active); - } - public RESULT getActive(out bool active) - { - return FMOD5_DSP_GetActive(this.handle, out active); - } - public RESULT setBypass(bool bypass) - { - return FMOD5_DSP_SetBypass(this.handle, bypass); - } - public RESULT getBypass(out bool bypass) - { - return FMOD5_DSP_GetBypass(this.handle, out bypass); - } - public RESULT setWetDryMix(float prewet, float postwet, float dry) - { - return FMOD5_DSP_SetWetDryMix(this.handle, prewet, postwet, dry); - } - public RESULT getWetDryMix(out float prewet, out float postwet, out float dry) - { - return FMOD5_DSP_GetWetDryMix(this.handle, out prewet, out postwet, out dry); - } - public RESULT setChannelFormat(CHANNELMASK channelmask, int numchannels, SPEAKERMODE source_speakermode) - { - return FMOD5_DSP_SetChannelFormat(this.handle, channelmask, numchannels, source_speakermode); - } - public RESULT getChannelFormat(out CHANNELMASK channelmask, out int numchannels, out SPEAKERMODE source_speakermode) - { - return FMOD5_DSP_GetChannelFormat(this.handle, out channelmask, out numchannels, out source_speakermode); - } - public RESULT getOutputChannelFormat(CHANNELMASK inmask, int inchannels, SPEAKERMODE inspeakermode, out CHANNELMASK outmask, out int outchannels, out SPEAKERMODE outspeakermode) - { - return FMOD5_DSP_GetOutputChannelFormat(this.handle, inmask, inchannels, inspeakermode, out outmask, out outchannels, out outspeakermode); - } - public RESULT reset() - { - return FMOD5_DSP_Reset(this.handle); - } - - // DSP parameter control. - public RESULT setParameterFloat(int index, float value) - { - return FMOD5_DSP_SetParameterFloat(this.handle, index, value); - } - public RESULT setParameterInt(int index, int value) - { - return FMOD5_DSP_SetParameterInt(this.handle, index, value); - } - public RESULT setParameterBool(int index, bool value) - { - return FMOD5_DSP_SetParameterBool(this.handle, index, value); - } - public RESULT setParameterData(int index, byte[] data) - { - return FMOD5_DSP_SetParameterData(this.handle, index, Marshal.UnsafeAddrOfPinnedArrayElement(data, 0), (uint)data.Length); - } - public RESULT getParameterFloat(int index, out float value) - { - return FMOD5_DSP_GetParameterFloat(this.handle, index, out value, IntPtr.Zero, 0); - } - public RESULT getParameterInt(int index, out int value) - { - return FMOD5_DSP_GetParameterInt(this.handle, index, out value, IntPtr.Zero, 0); - } - public RESULT getParameterBool(int index, out bool value) - { - return FMOD5_DSP_GetParameterBool(this.handle, index, out value, IntPtr.Zero, 0); - } - public RESULT getParameterData(int index, out IntPtr data, out uint length) - { - return FMOD5_DSP_GetParameterData(this.handle, index, out data, out length, IntPtr.Zero, 0); - } - public RESULT getNumParameters(out int numparams) - { - return FMOD5_DSP_GetNumParameters(this.handle, out numparams); - } - public RESULT getParameterInfo(int index, out DSP_PARAMETER_DESC desc) - { - IntPtr descPtr; - RESULT result = FMOD5_DSP_GetParameterInfo(this.handle, index, out descPtr); - #if (UNITY_2017_4_OR_NEWER) && !NET_4_6 - desc = (DSP_PARAMETER_DESC)Marshal.PtrToStructure(descPtr, typeof(DSP_PARAMETER_DESC)); - #else - desc = Marshal.PtrToStructure(descPtr); - #endif // (UNITY_2017_4_OR_NEWER) && !NET_4_6 - return result; - } - public RESULT getDataParameterIndex(int datatype, out int index) - { - return FMOD5_DSP_GetDataParameterIndex(this.handle, datatype, out index); - } - public RESULT showConfigDialog(IntPtr hwnd, bool show) - { - return FMOD5_DSP_ShowConfigDialog(this.handle, hwnd, show); - } - - // DSP attributes. - public RESULT getInfo(out string name, out uint version, out int channels, out int configwidth, out int configheight) - { - IntPtr nameMem = Marshal.AllocHGlobal(32); - - RESULT result = FMOD5_DSP_GetInfo(this.handle, nameMem, out version, out channels, out configwidth, out configheight); - using (StringHelper.ThreadSafeEncoding encoder = StringHelper.GetFreeHelper()) - { - name = encoder.stringFromNative(nameMem); - } - Marshal.FreeHGlobal(nameMem); - return result; - } - public RESULT getInfo(out uint version, out int channels, out int configwidth, out int configheight) - { - return FMOD5_DSP_GetInfo(this.handle, IntPtr.Zero, out version, out channels, out configwidth, out configheight); ; - } - public RESULT getType(out DSP_TYPE type) - { - return FMOD5_DSP_GetType(this.handle, out type); - } - public RESULT getIdle(out bool idle) - { - return FMOD5_DSP_GetIdle(this.handle, out idle); - } - - // Userdata set/get. - public RESULT setUserData(IntPtr userdata) - { - return FMOD5_DSP_SetUserData(this.handle, userdata); - } - public RESULT getUserData(out IntPtr userdata) - { - return FMOD5_DSP_GetUserData(this.handle, out userdata); - } - - // Metering. - public RESULT setMeteringEnabled(bool inputEnabled, bool outputEnabled) - { - return FMOD5_DSP_SetMeteringEnabled(this.handle, inputEnabled, outputEnabled); - } - public RESULT getMeteringEnabled(out bool inputEnabled, out bool outputEnabled) - { - return FMOD5_DSP_GetMeteringEnabled(this.handle, out inputEnabled, out outputEnabled); - } - - public RESULT getMeteringInfo(IntPtr zero, out DSP_METERING_INFO outputInfo) - { - return FMOD5_DSP_GetMeteringInfo(this.handle, zero, out outputInfo); - } - public RESULT getMeteringInfo(out DSP_METERING_INFO inputInfo, IntPtr zero) - { - return FMOD5_DSP_GetMeteringInfo(this.handle, out inputInfo, zero); - } - public RESULT getMeteringInfo(out DSP_METERING_INFO inputInfo, out DSP_METERING_INFO outputInfo) - { - return FMOD5_DSP_GetMeteringInfo(this.handle, out inputInfo, out outputInfo); - } - - public RESULT getCPUUsage(out uint exclusive, out uint inclusive) - { - return FMOD5_DSP_GetCPUUsage(this.handle, out exclusive, out inclusive); - } - - #region importfunctions - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_DSP_Release (IntPtr dsp); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_DSP_GetSystemObject (IntPtr dsp, out IntPtr system); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_DSP_AddInput (IntPtr dsp, IntPtr input, IntPtr zero, DSPCONNECTION_TYPE type); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_DSP_AddInput (IntPtr dsp, IntPtr input, out IntPtr connection, DSPCONNECTION_TYPE type); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_DSP_DisconnectFrom (IntPtr dsp, IntPtr target, IntPtr connection); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_DSP_DisconnectAll (IntPtr dsp, bool inputs, bool outputs); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_DSP_GetNumInputs (IntPtr dsp, out int numinputs); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_DSP_GetNumOutputs (IntPtr dsp, out int numoutputs); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_DSP_GetInput (IntPtr dsp, int index, out IntPtr input, out IntPtr inputconnection); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_DSP_GetOutput (IntPtr dsp, int index, out IntPtr output, out IntPtr outputconnection); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_DSP_SetActive (IntPtr dsp, bool active); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_DSP_GetActive (IntPtr dsp, out bool active); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_DSP_SetBypass (IntPtr dsp, bool bypass); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_DSP_GetBypass (IntPtr dsp, out bool bypass); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_DSP_SetWetDryMix (IntPtr dsp, float prewet, float postwet, float dry); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_DSP_GetWetDryMix (IntPtr dsp, out float prewet, out float postwet, out float dry); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_DSP_SetChannelFormat (IntPtr dsp, CHANNELMASK channelmask, int numchannels, SPEAKERMODE source_speakermode); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_DSP_GetChannelFormat (IntPtr dsp, out CHANNELMASK channelmask, out int numchannels, out SPEAKERMODE source_speakermode); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_DSP_GetOutputChannelFormat (IntPtr dsp, CHANNELMASK inmask, int inchannels, SPEAKERMODE inspeakermode, out CHANNELMASK outmask, out int outchannels, out SPEAKERMODE outspeakermode); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_DSP_Reset (IntPtr dsp); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_DSP_SetParameterFloat (IntPtr dsp, int index, float value); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_DSP_SetParameterInt (IntPtr dsp, int index, int value); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_DSP_SetParameterBool (IntPtr dsp, int index, bool value); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_DSP_SetParameterData (IntPtr dsp, int index, IntPtr data, uint length); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_DSP_GetParameterFloat (IntPtr dsp, int index, out float value, IntPtr valuestr, int valuestrlen); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_DSP_GetParameterInt (IntPtr dsp, int index, out int value, IntPtr valuestr, int valuestrlen); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_DSP_GetParameterBool (IntPtr dsp, int index, out bool value, IntPtr valuestr, int valuestrlen); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_DSP_GetParameterData (IntPtr dsp, int index, out IntPtr data, out uint length, IntPtr valuestr, int valuestrlen); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_DSP_GetNumParameters (IntPtr dsp, out int numparams); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_DSP_GetParameterInfo (IntPtr dsp, int index, out IntPtr desc); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_DSP_GetDataParameterIndex (IntPtr dsp, int datatype, out int index); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_DSP_ShowConfigDialog (IntPtr dsp, IntPtr hwnd, bool show); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_DSP_GetInfo (IntPtr dsp, IntPtr name, out uint version, out int channels, out int configwidth, out int configheight); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_DSP_GetType (IntPtr dsp, out DSP_TYPE type); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_DSP_GetIdle (IntPtr dsp, out bool idle); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_DSP_SetUserData (IntPtr dsp, IntPtr userdata); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_DSP_GetUserData (IntPtr dsp, out IntPtr userdata); - [DllImport(VERSION.dll)] - public static extern RESULT FMOD5_DSP_SetMeteringEnabled (IntPtr dsp, bool inputEnabled, bool outputEnabled); - [DllImport(VERSION.dll)] - public static extern RESULT FMOD5_DSP_GetMeteringEnabled (IntPtr dsp, out bool inputEnabled, out bool outputEnabled); - [DllImport(VERSION.dll)] - public static extern RESULT FMOD5_DSP_GetMeteringInfo (IntPtr dsp, IntPtr zero, out DSP_METERING_INFO outputInfo); - [DllImport(VERSION.dll)] - public static extern RESULT FMOD5_DSP_GetMeteringInfo (IntPtr dsp, out DSP_METERING_INFO inputInfo, IntPtr zero); - [DllImport(VERSION.dll)] - public static extern RESULT FMOD5_DSP_GetMeteringInfo (IntPtr dsp, out DSP_METERING_INFO inputInfo, out DSP_METERING_INFO outputInfo); - [DllImport(VERSION.dll)] - public static extern RESULT FMOD5_DSP_GetCPUUsage (IntPtr dsp, out uint exclusive, out uint inclusive); - #endregion - - #region wrapperinternal - - public IntPtr handle; - - public bool hasHandle() { return this.handle != IntPtr.Zero; } - public void clearHandle() { this.handle = IntPtr.Zero; } - - #endregion - } - - /* - 'DSPConnection' API - */ - public struct DSPConnection - { - public RESULT getInput(out DSP input) - { - return FMOD5_DSPConnection_GetInput(this.handle, out input.handle); - } - public RESULT getOutput(out DSP output) - { - return FMOD5_DSPConnection_GetOutput(this.handle, out output.handle); - } - public RESULT setMix(float volume) - { - return FMOD5_DSPConnection_SetMix(this.handle, volume); - } - public RESULT getMix(out float volume) - { - return FMOD5_DSPConnection_GetMix(this.handle, out volume); - } - public RESULT setMixMatrix(float[] matrix, int outchannels, int inchannels, int inchannel_hop = 0) - { - return FMOD5_DSPConnection_SetMixMatrix(this.handle, matrix, outchannels, inchannels, inchannel_hop); - } - public RESULT getMixMatrix(float[] matrix, out int outchannels, out int inchannels, int inchannel_hop = 0) - { - return FMOD5_DSPConnection_GetMixMatrix(this.handle, matrix, out outchannels, out inchannels, inchannel_hop); - } - public RESULT getType(out DSPCONNECTION_TYPE type) - { - return FMOD5_DSPConnection_GetType(this.handle, out type); - } - - // Userdata set/get. - public RESULT setUserData(IntPtr userdata) - { - return FMOD5_DSPConnection_SetUserData(this.handle, userdata); - } - public RESULT getUserData(out IntPtr userdata) - { - return FMOD5_DSPConnection_GetUserData(this.handle, out userdata); - } - - #region importfunctions - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_DSPConnection_GetInput (IntPtr dspconnection, out IntPtr input); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_DSPConnection_GetOutput (IntPtr dspconnection, out IntPtr output); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_DSPConnection_SetMix (IntPtr dspconnection, float volume); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_DSPConnection_GetMix (IntPtr dspconnection, out float volume); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_DSPConnection_SetMixMatrix (IntPtr dspconnection, float[] matrix, int outchannels, int inchannels, int inchannel_hop); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_DSPConnection_GetMixMatrix (IntPtr dspconnection, float[] matrix, out int outchannels, out int inchannels, int inchannel_hop); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_DSPConnection_GetType (IntPtr dspconnection, out DSPCONNECTION_TYPE type); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_DSPConnection_SetUserData (IntPtr dspconnection, IntPtr userdata); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_DSPConnection_GetUserData (IntPtr dspconnection, out IntPtr userdata); - #endregion - - #region wrapperinternal - - public IntPtr handle; - - public bool hasHandle() { return this.handle != IntPtr.Zero; } - public void clearHandle() { this.handle = IntPtr.Zero; } - - #endregion - } - - /* - 'Geometry' API - */ - public struct Geometry - { - public RESULT release() - { - return FMOD5_Geometry_Release(this.handle); - } - - // Polygon manipulation. - public RESULT addPolygon(float directocclusion, float reverbocclusion, bool doublesided, int numvertices, VECTOR[] vertices, out int polygonindex) - { - return FMOD5_Geometry_AddPolygon(this.handle, directocclusion, reverbocclusion, doublesided, numvertices, vertices, out polygonindex); - } - public RESULT getNumPolygons(out int numpolygons) - { - return FMOD5_Geometry_GetNumPolygons(this.handle, out numpolygons); - } - public RESULT getMaxPolygons(out int maxpolygons, out int maxvertices) - { - return FMOD5_Geometry_GetMaxPolygons(this.handle, out maxpolygons, out maxvertices); - } - public RESULT getPolygonNumVertices(int index, out int numvertices) - { - return FMOD5_Geometry_GetPolygonNumVertices(this.handle, index, out numvertices); - } - public RESULT setPolygonVertex(int index, int vertexindex, ref VECTOR vertex) - { - return FMOD5_Geometry_SetPolygonVertex(this.handle, index, vertexindex, ref vertex); - } - public RESULT getPolygonVertex(int index, int vertexindex, out VECTOR vertex) - { - return FMOD5_Geometry_GetPolygonVertex(this.handle, index, vertexindex, out vertex); - } - public RESULT setPolygonAttributes(int index, float directocclusion, float reverbocclusion, bool doublesided) - { - return FMOD5_Geometry_SetPolygonAttributes(this.handle, index, directocclusion, reverbocclusion, doublesided); - } - public RESULT getPolygonAttributes(int index, out float directocclusion, out float reverbocclusion, out bool doublesided) - { - return FMOD5_Geometry_GetPolygonAttributes(this.handle, index, out directocclusion, out reverbocclusion, out doublesided); - } - - // Object manipulation. - public RESULT setActive(bool active) - { - return FMOD5_Geometry_SetActive(this.handle, active); - } - public RESULT getActive(out bool active) - { - return FMOD5_Geometry_GetActive(this.handle, out active); - } - public RESULT setRotation(ref VECTOR forward, ref VECTOR up) - { - return FMOD5_Geometry_SetRotation(this.handle, ref forward, ref up); - } - public RESULT getRotation(out VECTOR forward, out VECTOR up) - { - return FMOD5_Geometry_GetRotation(this.handle, out forward, out up); - } - public RESULT setPosition(ref VECTOR position) - { - return FMOD5_Geometry_SetPosition(this.handle, ref position); - } - public RESULT getPosition(out VECTOR position) - { - return FMOD5_Geometry_GetPosition(this.handle, out position); - } - public RESULT setScale(ref VECTOR scale) - { - return FMOD5_Geometry_SetScale(this.handle, ref scale); - } - public RESULT getScale(out VECTOR scale) - { - return FMOD5_Geometry_GetScale(this.handle, out scale); - } - public RESULT save(IntPtr data, out int datasize) - { - return FMOD5_Geometry_Save(this.handle, data, out datasize); - } - - // Userdata set/get. - public RESULT setUserData(IntPtr userdata) - { - return FMOD5_Geometry_SetUserData(this.handle, userdata); - } - public RESULT getUserData(out IntPtr userdata) - { - return FMOD5_Geometry_GetUserData(this.handle, out userdata); - } - - #region importfunctions - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_Geometry_Release (IntPtr geometry); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_Geometry_AddPolygon (IntPtr geometry, float directocclusion, float reverbocclusion, bool doublesided, int numvertices, VECTOR[] vertices, out int polygonindex); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_Geometry_GetNumPolygons (IntPtr geometry, out int numpolygons); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_Geometry_GetMaxPolygons (IntPtr geometry, out int maxpolygons, out int maxvertices); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_Geometry_GetPolygonNumVertices(IntPtr geometry, int index, out int numvertices); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_Geometry_SetPolygonVertex (IntPtr geometry, int index, int vertexindex, ref VECTOR vertex); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_Geometry_GetPolygonVertex (IntPtr geometry, int index, int vertexindex, out VECTOR vertex); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_Geometry_SetPolygonAttributes (IntPtr geometry, int index, float directocclusion, float reverbocclusion, bool doublesided); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_Geometry_GetPolygonAttributes (IntPtr geometry, int index, out float directocclusion, out float reverbocclusion, out bool doublesided); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_Geometry_SetActive (IntPtr geometry, bool active); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_Geometry_GetActive (IntPtr geometry, out bool active); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_Geometry_SetRotation (IntPtr geometry, ref VECTOR forward, ref VECTOR up); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_Geometry_GetRotation (IntPtr geometry, out VECTOR forward, out VECTOR up); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_Geometry_SetPosition (IntPtr geometry, ref VECTOR position); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_Geometry_GetPosition (IntPtr geometry, out VECTOR position); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_Geometry_SetScale (IntPtr geometry, ref VECTOR scale); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_Geometry_GetScale (IntPtr geometry, out VECTOR scale); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_Geometry_Save (IntPtr geometry, IntPtr data, out int datasize); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_Geometry_SetUserData (IntPtr geometry, IntPtr userdata); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_Geometry_GetUserData (IntPtr geometry, out IntPtr userdata); - #endregion - - #region wrapperinternal - - public IntPtr handle; - - public bool hasHandle() { return this.handle != IntPtr.Zero; } - public void clearHandle() { this.handle = IntPtr.Zero; } - - #endregion - } - - /* - 'Reverb3D' API - */ - public struct Reverb3D - { - public RESULT release() - { - return FMOD5_Reverb3D_Release(this.handle); - } - - // Reverb manipulation. - public RESULT set3DAttributes(ref VECTOR position, float mindistance, float maxdistance) - { - return FMOD5_Reverb3D_Set3DAttributes(this.handle, ref position, mindistance, maxdistance); - } - public RESULT get3DAttributes(ref VECTOR position, ref float mindistance, ref float maxdistance) - { - return FMOD5_Reverb3D_Get3DAttributes(this.handle, ref position, ref mindistance, ref maxdistance); - } - public RESULT setProperties(ref REVERB_PROPERTIES properties) - { - return FMOD5_Reverb3D_SetProperties(this.handle, ref properties); - } - public RESULT getProperties(ref REVERB_PROPERTIES properties) - { - return FMOD5_Reverb3D_GetProperties(this.handle, ref properties); - } - public RESULT setActive(bool active) - { - return FMOD5_Reverb3D_SetActive(this.handle, active); - } - public RESULT getActive(out bool active) - { - return FMOD5_Reverb3D_GetActive(this.handle, out active); - } - - // Userdata set/get. - public RESULT setUserData(IntPtr userdata) - { - return FMOD5_Reverb3D_SetUserData(this.handle, userdata); - } - public RESULT getUserData(out IntPtr userdata) - { - return FMOD5_Reverb3D_GetUserData(this.handle, out userdata); - } - - #region importfunctions - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_Reverb3D_Release (IntPtr reverb3d); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_Reverb3D_Set3DAttributes (IntPtr reverb3d, ref VECTOR position, float mindistance, float maxdistance); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_Reverb3D_Get3DAttributes (IntPtr reverb3d, ref VECTOR position, ref float mindistance, ref float maxdistance); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_Reverb3D_SetProperties (IntPtr reverb3d, ref REVERB_PROPERTIES properties); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_Reverb3D_GetProperties (IntPtr reverb3d, ref REVERB_PROPERTIES properties); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_Reverb3D_SetActive (IntPtr reverb3d, bool active); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_Reverb3D_GetActive (IntPtr reverb3d, out bool active); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_Reverb3D_SetUserData (IntPtr reverb3d, IntPtr userdata); - [DllImport(VERSION.dll)] - private static extern RESULT FMOD5_Reverb3D_GetUserData (IntPtr reverb3d, out IntPtr userdata); - #endregion - - #region wrapperinternal - - public IntPtr handle; - - public bool hasHandle() { return this.handle != IntPtr.Zero; } - public void clearHandle() { this.handle = IntPtr.Zero; } - - #endregion - } - - #region String Helper Functions - [StructLayout(LayoutKind.Sequential)] - public struct StringWrapper - { - IntPtr nativeUtf8Ptr; - - public static implicit operator string(StringWrapper fstring) - { - using (StringHelper.ThreadSafeEncoding encoder = StringHelper.GetFreeHelper()) - { - return encoder.stringFromNative(fstring.nativeUtf8Ptr); - } - } - } - - static class StringHelper - { - public class ThreadSafeEncoding : IDisposable - { - UTF8Encoding encoding = new UTF8Encoding(); - byte[] encodedBuffer = new byte[128]; - char[] decodedBuffer = new char[128]; - bool inUse; - GCHandle gcHandle; - - public bool InUse() { return inUse; } - public void SetInUse() { inUse = true; } - - private int roundUpPowerTwo(int number) - { - int newNumber = 1; - while (newNumber <= number) - { - newNumber *= 2; - } - - return newNumber; - } - - public byte[] byteFromStringUTF8(string s) - { - if (s == null) - { - return null; - } - - int maximumLength = encoding.GetMaxByteCount(s.Length) + 1; // +1 for null terminator - if (maximumLength > encodedBuffer.Length) - { - int encodedLength = encoding.GetByteCount(s) + 1; // +1 for null terminator - if (encodedLength > encodedBuffer.Length) - { - encodedBuffer = new byte[roundUpPowerTwo(encodedLength)]; - } - } - - int byteCount = encoding.GetBytes(s, 0, s.Length, encodedBuffer, 0); - encodedBuffer[byteCount] = 0; // Apply null terminator - - return encodedBuffer; - } - - public IntPtr intptrFromStringUTF8(string s) - { - if (s == null) - { - return IntPtr.Zero; - } - - gcHandle = GCHandle.Alloc(byteFromStringUTF8(s), GCHandleType.Pinned); - return gcHandle.AddrOfPinnedObject(); - } - - public string stringFromNative(IntPtr nativePtr) - { - if (nativePtr == IntPtr.Zero) - { - return ""; - } - - int nativeLen = 0; - while (Marshal.ReadByte(nativePtr, nativeLen) != 0) - { - nativeLen++; - } - - if (nativeLen == 0) - { - return ""; - } - - if (nativeLen > encodedBuffer.Length) - { - encodedBuffer = new byte[roundUpPowerTwo(nativeLen)]; - } - - Marshal.Copy(nativePtr, encodedBuffer, 0, nativeLen); - - int maximumLength = encoding.GetMaxCharCount(nativeLen); - if (maximumLength > decodedBuffer.Length) - { - int decodedLength = encoding.GetCharCount(encodedBuffer, 0, nativeLen); - if (decodedLength > decodedBuffer.Length) - { - decodedBuffer = new char[roundUpPowerTwo(decodedLength)]; - } - } - - int charCount = encoding.GetChars(encodedBuffer, 0, nativeLen, decodedBuffer, 0); - - return new String(decodedBuffer, 0, charCount); - } - - public void Dispose() - { - if (gcHandle.IsAllocated) - { - gcHandle.Free(); - } - lock (encoders) - { - inUse = false; - } - } - } - - static List encoders = new List(1); - - public static ThreadSafeEncoding GetFreeHelper() - { - lock (encoders) - { - ThreadSafeEncoding helper = null; - // Search for not in use helper - for (int i = 0; i < encoders.Count; i++) - { - if (!encoders[i].InUse()) - { - helper = encoders[i]; - break; - } - } - // Otherwise create another helper - if (helper == null) - { - helper = new ThreadSafeEncoding(); - encoders.Add(helper); - } - helper.SetInUse(); - return helper; - } - } - } - - #endregion -} diff --git a/engine/fmodcore/inc/fmod.h b/engine/fmodcore/inc/fmod.h deleted file mode 100644 index 8bdfd74..0000000 --- a/engine/fmodcore/inc/fmod.h +++ /dev/null @@ -1,665 +0,0 @@ -/* ======================================================================================== */ -/* FMOD Core API - C header file. */ -/* Copyright (c), Firelight Technologies Pty, Ltd. 2004-2021. */ -/* */ -/* Use this header in conjunction with fmod_common.h (which contains all the constants / */ -/* callbacks) to develop using the C interface */ -/* */ -/* For more detail visit: */ -/* https://fmod.com/resources/documentation-api?version=2.0&page=core-api.html */ -/* ======================================================================================== */ - -#ifndef _FMOD_H -#define _FMOD_H - -#include "fmod_common.h" - -#ifdef __cplusplus -extern "C" -{ -#endif - -/* - FMOD global system functions (optional). -*/ -FMOD_RESULT F_API FMOD_Memory_Initialize (void *poolmem, int poollen, FMOD_MEMORY_ALLOC_CALLBACK useralloc, FMOD_MEMORY_REALLOC_CALLBACK userrealloc, FMOD_MEMORY_FREE_CALLBACK userfree, FMOD_MEMORY_TYPE memtypeflags); -FMOD_RESULT F_API FMOD_Memory_GetStats (int *currentalloced, int *maxalloced, FMOD_BOOL blocking); -FMOD_RESULT F_API FMOD_Debug_Initialize (FMOD_DEBUG_FLAGS flags, FMOD_DEBUG_MODE mode, FMOD_DEBUG_CALLBACK callback, const char *filename); -FMOD_RESULT F_API FMOD_File_SetDiskBusy (int busy); -FMOD_RESULT F_API FMOD_File_GetDiskBusy (int *busy); - -/* - FMOD System factory functions. Use this to create an FMOD System Instance. below you will see FMOD_System_Init/Close to get started. -*/ -FMOD_RESULT F_API FMOD_System_Create (FMOD_SYSTEM **system); -FMOD_RESULT F_API FMOD_System_Release (FMOD_SYSTEM *system); - -/* - 'System' API -*/ - -/* Setup functions. */ -FMOD_RESULT F_API FMOD_System_SetOutput (FMOD_SYSTEM *system, FMOD_OUTPUTTYPE output); -FMOD_RESULT F_API FMOD_System_GetOutput (FMOD_SYSTEM *system, FMOD_OUTPUTTYPE *output); -FMOD_RESULT F_API FMOD_System_GetNumDrivers (FMOD_SYSTEM *system, int *numdrivers); -FMOD_RESULT F_API FMOD_System_GetDriverInfo (FMOD_SYSTEM *system, int id, char *name, int namelen, FMOD_GUID *guid, int *systemrate, FMOD_SPEAKERMODE *speakermode, int *speakermodechannels); -FMOD_RESULT F_API FMOD_System_SetDriver (FMOD_SYSTEM *system, int driver); -FMOD_RESULT F_API FMOD_System_GetDriver (FMOD_SYSTEM *system, int *driver); -FMOD_RESULT F_API FMOD_System_SetSoftwareChannels (FMOD_SYSTEM *system, int numsoftwarechannels); -FMOD_RESULT F_API FMOD_System_GetSoftwareChannels (FMOD_SYSTEM *system, int *numsoftwarechannels); -FMOD_RESULT F_API FMOD_System_SetSoftwareFormat (FMOD_SYSTEM *system, int samplerate, FMOD_SPEAKERMODE speakermode, int numrawspeakers); -FMOD_RESULT F_API FMOD_System_GetSoftwareFormat (FMOD_SYSTEM *system, int *samplerate, FMOD_SPEAKERMODE *speakermode, int *numrawspeakers); -FMOD_RESULT F_API FMOD_System_SetDSPBufferSize (FMOD_SYSTEM *system, unsigned int bufferlength, int numbuffers); -FMOD_RESULT F_API FMOD_System_GetDSPBufferSize (FMOD_SYSTEM *system, unsigned int *bufferlength, int *numbuffers); -FMOD_RESULT F_API FMOD_System_SetFileSystem (FMOD_SYSTEM *system, FMOD_FILE_OPEN_CALLBACK useropen, FMOD_FILE_CLOSE_CALLBACK userclose, FMOD_FILE_READ_CALLBACK userread, FMOD_FILE_SEEK_CALLBACK userseek, FMOD_FILE_ASYNCREAD_CALLBACK userasyncread, FMOD_FILE_ASYNCCANCEL_CALLBACK userasynccancel, int blockalign); -FMOD_RESULT F_API FMOD_System_AttachFileSystem (FMOD_SYSTEM *system, FMOD_FILE_OPEN_CALLBACK useropen, FMOD_FILE_CLOSE_CALLBACK userclose, FMOD_FILE_READ_CALLBACK userread, FMOD_FILE_SEEK_CALLBACK userseek); -FMOD_RESULT F_API FMOD_System_SetAdvancedSettings (FMOD_SYSTEM *system, FMOD_ADVANCEDSETTINGS *settings); -FMOD_RESULT F_API FMOD_System_GetAdvancedSettings (FMOD_SYSTEM *system, FMOD_ADVANCEDSETTINGS *settings); -FMOD_RESULT F_API FMOD_System_SetCallback (FMOD_SYSTEM *system, FMOD_SYSTEM_CALLBACK callback, FMOD_SYSTEM_CALLBACK_TYPE callbackmask); - -/* Plug-in support. */ -FMOD_RESULT F_API FMOD_System_SetPluginPath (FMOD_SYSTEM *system, const char *path); -FMOD_RESULT F_API FMOD_System_LoadPlugin (FMOD_SYSTEM *system, const char *filename, unsigned int *handle, unsigned int priority); -FMOD_RESULT F_API FMOD_System_UnloadPlugin (FMOD_SYSTEM *system, unsigned int handle); -FMOD_RESULT F_API FMOD_System_GetNumNestedPlugins (FMOD_SYSTEM *system, unsigned int handle, int *count); -FMOD_RESULT F_API FMOD_System_GetNestedPlugin (FMOD_SYSTEM *system, unsigned int handle, int index, unsigned int *nestedhandle); -FMOD_RESULT F_API FMOD_System_GetNumPlugins (FMOD_SYSTEM *system, FMOD_PLUGINTYPE plugintype, int *numplugins); -FMOD_RESULT F_API FMOD_System_GetPluginHandle (FMOD_SYSTEM *system, FMOD_PLUGINTYPE plugintype, int index, unsigned int *handle); -FMOD_RESULT F_API FMOD_System_GetPluginInfo (FMOD_SYSTEM *system, unsigned int handle, FMOD_PLUGINTYPE *plugintype, char *name, int namelen, unsigned int *version); -FMOD_RESULT F_API FMOD_System_SetOutputByPlugin (FMOD_SYSTEM *system, unsigned int handle); -FMOD_RESULT F_API FMOD_System_GetOutputByPlugin (FMOD_SYSTEM *system, unsigned int *handle); -FMOD_RESULT F_API FMOD_System_CreateDSPByPlugin (FMOD_SYSTEM *system, unsigned int handle, FMOD_DSP **dsp); -FMOD_RESULT F_API FMOD_System_GetDSPInfoByPlugin (FMOD_SYSTEM *system, unsigned int handle, const FMOD_DSP_DESCRIPTION **description); -FMOD_RESULT F_API FMOD_System_RegisterCodec (FMOD_SYSTEM *system, FMOD_CODEC_DESCRIPTION *description, unsigned int *handle, unsigned int priority); -FMOD_RESULT F_API FMOD_System_RegisterDSP (FMOD_SYSTEM *system, const FMOD_DSP_DESCRIPTION *description, unsigned int *handle); -FMOD_RESULT F_API FMOD_System_RegisterOutput (FMOD_SYSTEM *system, const FMOD_OUTPUT_DESCRIPTION *description, unsigned int *handle); - -/* Init/Close. */ -FMOD_RESULT F_API FMOD_System_Init (FMOD_SYSTEM *system, int maxchannels, FMOD_INITFLAGS flags, void *extradriverdata); -FMOD_RESULT F_API FMOD_System_Close (FMOD_SYSTEM *system); - -/* General post-init system functions. */ -FMOD_RESULT F_API FMOD_System_Update (FMOD_SYSTEM *system); -FMOD_RESULT F_API FMOD_System_SetSpeakerPosition (FMOD_SYSTEM *system, FMOD_SPEAKER speaker, float x, float y, FMOD_BOOL active); -FMOD_RESULT F_API FMOD_System_GetSpeakerPosition (FMOD_SYSTEM *system, FMOD_SPEAKER speaker, float *x, float *y, FMOD_BOOL *active); -FMOD_RESULT F_API FMOD_System_SetStreamBufferSize (FMOD_SYSTEM *system, unsigned int filebuffersize, FMOD_TIMEUNIT filebuffersizetype); -FMOD_RESULT F_API FMOD_System_GetStreamBufferSize (FMOD_SYSTEM *system, unsigned int *filebuffersize, FMOD_TIMEUNIT *filebuffersizetype); -FMOD_RESULT F_API FMOD_System_Set3DSettings (FMOD_SYSTEM *system, float dopplerscale, float distancefactor, float rolloffscale); -FMOD_RESULT F_API FMOD_System_Get3DSettings (FMOD_SYSTEM *system, float *dopplerscale, float *distancefactor, float *rolloffscale); -FMOD_RESULT F_API FMOD_System_Set3DNumListeners (FMOD_SYSTEM *system, int numlisteners); -FMOD_RESULT F_API FMOD_System_Get3DNumListeners (FMOD_SYSTEM *system, int *numlisteners); -FMOD_RESULT F_API FMOD_System_Set3DListenerAttributes (FMOD_SYSTEM *system, int listener, const FMOD_VECTOR *pos, const FMOD_VECTOR *vel, const FMOD_VECTOR *forward, const FMOD_VECTOR *up); -FMOD_RESULT F_API FMOD_System_Get3DListenerAttributes (FMOD_SYSTEM *system, int listener, FMOD_VECTOR *pos, FMOD_VECTOR *vel, FMOD_VECTOR *forward, FMOD_VECTOR *up); -FMOD_RESULT F_API FMOD_System_Set3DRolloffCallback (FMOD_SYSTEM *system, FMOD_3D_ROLLOFF_CALLBACK callback); -FMOD_RESULT F_API FMOD_System_MixerSuspend (FMOD_SYSTEM *system); -FMOD_RESULT F_API FMOD_System_MixerResume (FMOD_SYSTEM *system); -FMOD_RESULT F_API FMOD_System_GetDefaultMixMatrix (FMOD_SYSTEM *system, FMOD_SPEAKERMODE sourcespeakermode, FMOD_SPEAKERMODE targetspeakermode, float *matrix, int matrixhop); -FMOD_RESULT F_API FMOD_System_GetSpeakerModeChannels (FMOD_SYSTEM *system, FMOD_SPEAKERMODE mode, int *channels); - -/* System information functions. */ -FMOD_RESULT F_API FMOD_System_GetVersion (FMOD_SYSTEM *system, unsigned int *version); -FMOD_RESULT F_API FMOD_System_GetOutputHandle (FMOD_SYSTEM *system, void **handle); -FMOD_RESULT F_API FMOD_System_GetChannelsPlaying (FMOD_SYSTEM *system, int *channels, int *realchannels); -FMOD_RESULT F_API FMOD_System_GetCPUUsage (FMOD_SYSTEM *system, float *dsp, float *stream, float *geometry, float *update, float *total); -FMOD_RESULT F_API FMOD_System_GetFileUsage (FMOD_SYSTEM *system, long long *sampleBytesRead, long long *streamBytesRead, long long *otherBytesRead); - -/* Sound/DSP/Channel/FX creation and retrieval. */ -FMOD_RESULT F_API FMOD_System_CreateSound (FMOD_SYSTEM *system, const char *name_or_data, FMOD_MODE mode, FMOD_CREATESOUNDEXINFO *exinfo, FMOD_SOUND **sound); -FMOD_RESULT F_API FMOD_System_CreateStream (FMOD_SYSTEM *system, const char *name_or_data, FMOD_MODE mode, FMOD_CREATESOUNDEXINFO *exinfo, FMOD_SOUND **sound); -FMOD_RESULT F_API FMOD_System_CreateDSP (FMOD_SYSTEM *system, const FMOD_DSP_DESCRIPTION *description, FMOD_DSP **dsp); -FMOD_RESULT F_API FMOD_System_CreateDSPByType (FMOD_SYSTEM *system, FMOD_DSP_TYPE type, FMOD_DSP **dsp); -FMOD_RESULT F_API FMOD_System_CreateChannelGroup (FMOD_SYSTEM *system, const char *name, FMOD_CHANNELGROUP **channelgroup); -FMOD_RESULT F_API FMOD_System_CreateSoundGroup (FMOD_SYSTEM *system, const char *name, FMOD_SOUNDGROUP **soundgroup); -FMOD_RESULT F_API FMOD_System_CreateReverb3D (FMOD_SYSTEM *system, FMOD_REVERB3D **reverb); -FMOD_RESULT F_API FMOD_System_PlaySound (FMOD_SYSTEM *system, FMOD_SOUND *sound, FMOD_CHANNELGROUP *channelgroup, FMOD_BOOL paused, FMOD_CHANNEL **channel); -FMOD_RESULT F_API FMOD_System_PlayDSP (FMOD_SYSTEM *system, FMOD_DSP *dsp, FMOD_CHANNELGROUP *channelgroup, FMOD_BOOL paused, FMOD_CHANNEL **channel); -FMOD_RESULT F_API FMOD_System_GetChannel (FMOD_SYSTEM *system, int channelid, FMOD_CHANNEL **channel); -FMOD_RESULT F_API FMOD_System_GetMasterChannelGroup (FMOD_SYSTEM *system, FMOD_CHANNELGROUP **channelgroup); -FMOD_RESULT F_API FMOD_System_GetMasterSoundGroup (FMOD_SYSTEM *system, FMOD_SOUNDGROUP **soundgroup); - -/* Routing to ports. */ -FMOD_RESULT F_API FMOD_System_AttachChannelGroupToPort (FMOD_SYSTEM *system, FMOD_PORT_TYPE portType, FMOD_PORT_INDEX portIndex, FMOD_CHANNELGROUP *channelgroup, FMOD_BOOL passThru); -FMOD_RESULT F_API FMOD_System_DetachChannelGroupFromPort(FMOD_SYSTEM *system, FMOD_CHANNELGROUP *channelgroup); - -/* Reverb API. */ -FMOD_RESULT F_API FMOD_System_SetReverbProperties (FMOD_SYSTEM *system, int instance, const FMOD_REVERB_PROPERTIES *prop); -FMOD_RESULT F_API FMOD_System_GetReverbProperties (FMOD_SYSTEM *system, int instance, FMOD_REVERB_PROPERTIES *prop); - -/* System level DSP functionality. */ -FMOD_RESULT F_API FMOD_System_LockDSP (FMOD_SYSTEM *system); -FMOD_RESULT F_API FMOD_System_UnlockDSP (FMOD_SYSTEM *system); - -/* Recording API. */ -FMOD_RESULT F_API FMOD_System_GetRecordNumDrivers (FMOD_SYSTEM *system, int *numdrivers, int *numconnected); -FMOD_RESULT F_API FMOD_System_GetRecordDriverInfo (FMOD_SYSTEM *system, int id, char *name, int namelen, FMOD_GUID *guid, int *systemrate, FMOD_SPEAKERMODE *speakermode, int *speakermodechannels, FMOD_DRIVER_STATE *state); -FMOD_RESULT F_API FMOD_System_GetRecordPosition (FMOD_SYSTEM *system, int id, unsigned int *position); -FMOD_RESULT F_API FMOD_System_RecordStart (FMOD_SYSTEM *system, int id, FMOD_SOUND *sound, FMOD_BOOL loop); -FMOD_RESULT F_API FMOD_System_RecordStop (FMOD_SYSTEM *system, int id); -FMOD_RESULT F_API FMOD_System_IsRecording (FMOD_SYSTEM *system, int id, FMOD_BOOL *recording); - -/* Geometry API. */ -FMOD_RESULT F_API FMOD_System_CreateGeometry (FMOD_SYSTEM *system, int maxpolygons, int maxvertices, FMOD_GEOMETRY **geometry); -FMOD_RESULT F_API FMOD_System_SetGeometrySettings (FMOD_SYSTEM *system, float maxworldsize); -FMOD_RESULT F_API FMOD_System_GetGeometrySettings (FMOD_SYSTEM *system, float *maxworldsize); -FMOD_RESULT F_API FMOD_System_LoadGeometry (FMOD_SYSTEM *system, const void *data, int datasize, FMOD_GEOMETRY **geometry); -FMOD_RESULT F_API FMOD_System_GetGeometryOcclusion (FMOD_SYSTEM *system, const FMOD_VECTOR *listener, const FMOD_VECTOR *source, float *direct, float *reverb); - -/* Network functions. */ -FMOD_RESULT F_API FMOD_System_SetNetworkProxy (FMOD_SYSTEM *system, const char *proxy); -FMOD_RESULT F_API FMOD_System_GetNetworkProxy (FMOD_SYSTEM *system, char *proxy, int proxylen); -FMOD_RESULT F_API FMOD_System_SetNetworkTimeout (FMOD_SYSTEM *system, int timeout); -FMOD_RESULT F_API FMOD_System_GetNetworkTimeout (FMOD_SYSTEM *system, int *timeout); - -/* Userdata set/get. */ -FMOD_RESULT F_API FMOD_System_SetUserData (FMOD_SYSTEM *system, void *userdata); -FMOD_RESULT F_API FMOD_System_GetUserData (FMOD_SYSTEM *system, void **userdata); - -/* Sound API -*/ - -FMOD_RESULT F_API FMOD_Sound_Release (FMOD_SOUND *sound); -FMOD_RESULT F_API FMOD_Sound_GetSystemObject (FMOD_SOUND *sound, FMOD_SYSTEM **system); - -/* - Standard sound manipulation functions. -*/ - -FMOD_RESULT F_API FMOD_Sound_Lock (FMOD_SOUND *sound, unsigned int offset, unsigned int length, void **ptr1, void **ptr2, unsigned int *len1, unsigned int *len2); -FMOD_RESULT F_API FMOD_Sound_Unlock (FMOD_SOUND *sound, void *ptr1, void *ptr2, unsigned int len1, unsigned int len2); -FMOD_RESULT F_API FMOD_Sound_SetDefaults (FMOD_SOUND *sound, float frequency, int priority); -FMOD_RESULT F_API FMOD_Sound_GetDefaults (FMOD_SOUND *sound, float *frequency, int *priority); -FMOD_RESULT F_API FMOD_Sound_Set3DMinMaxDistance (FMOD_SOUND *sound, float min, float max); -FMOD_RESULT F_API FMOD_Sound_Get3DMinMaxDistance (FMOD_SOUND *sound, float *min, float *max); -FMOD_RESULT F_API FMOD_Sound_Set3DConeSettings (FMOD_SOUND *sound, float insideconeangle, float outsideconeangle, float outsidevolume); -FMOD_RESULT F_API FMOD_Sound_Get3DConeSettings (FMOD_SOUND *sound, float *insideconeangle, float *outsideconeangle, float *outsidevolume); -FMOD_RESULT F_API FMOD_Sound_Set3DCustomRolloff (FMOD_SOUND *sound, FMOD_VECTOR *points, int numpoints); -FMOD_RESULT F_API FMOD_Sound_Get3DCustomRolloff (FMOD_SOUND *sound, FMOD_VECTOR **points, int *numpoints); -FMOD_RESULT F_API FMOD_Sound_GetSubSound (FMOD_SOUND *sound, int index, FMOD_SOUND **subsound); -FMOD_RESULT F_API FMOD_Sound_GetSubSoundParent (FMOD_SOUND *sound, FMOD_SOUND **parentsound); -FMOD_RESULT F_API FMOD_Sound_GetName (FMOD_SOUND *sound, char *name, int namelen); -FMOD_RESULT F_API FMOD_Sound_GetLength (FMOD_SOUND *sound, unsigned int *length, FMOD_TIMEUNIT lengthtype); -FMOD_RESULT F_API FMOD_Sound_GetFormat (FMOD_SOUND *sound, FMOD_SOUND_TYPE *type, FMOD_SOUND_FORMAT *format, int *channels, int *bits); -FMOD_RESULT F_API FMOD_Sound_GetNumSubSounds (FMOD_SOUND *sound, int *numsubsounds); -FMOD_RESULT F_API FMOD_Sound_GetNumTags (FMOD_SOUND *sound, int *numtags, int *numtagsupdated); -FMOD_RESULT F_API FMOD_Sound_GetTag (FMOD_SOUND *sound, const char *name, int index, FMOD_TAG *tag); -FMOD_RESULT F_API FMOD_Sound_GetOpenState (FMOD_SOUND *sound, FMOD_OPENSTATE *openstate, unsigned int *percentbuffered, FMOD_BOOL *starving, FMOD_BOOL *diskbusy); -FMOD_RESULT F_API FMOD_Sound_ReadData (FMOD_SOUND *sound, void *buffer, unsigned int length, unsigned int *read); -FMOD_RESULT F_API FMOD_Sound_SeekData (FMOD_SOUND *sound, unsigned int pcm); - -FMOD_RESULT F_API FMOD_Sound_SetSoundGroup (FMOD_SOUND *sound, FMOD_SOUNDGROUP *soundgroup); -FMOD_RESULT F_API FMOD_Sound_GetSoundGroup (FMOD_SOUND *sound, FMOD_SOUNDGROUP **soundgroup); - -/* - Synchronization point API. These points can come from markers embedded in wav files, and can also generate channel callbacks. -*/ - -FMOD_RESULT F_API FMOD_Sound_GetNumSyncPoints (FMOD_SOUND *sound, int *numsyncpoints); -FMOD_RESULT F_API FMOD_Sound_GetSyncPoint (FMOD_SOUND *sound, int index, FMOD_SYNCPOINT **point); -FMOD_RESULT F_API FMOD_Sound_GetSyncPointInfo (FMOD_SOUND *sound, FMOD_SYNCPOINT *point, char *name, int namelen, unsigned int *offset, FMOD_TIMEUNIT offsettype); -FMOD_RESULT F_API FMOD_Sound_AddSyncPoint (FMOD_SOUND *sound, unsigned int offset, FMOD_TIMEUNIT offsettype, const char *name, FMOD_SYNCPOINT **point); -FMOD_RESULT F_API FMOD_Sound_DeleteSyncPoint (FMOD_SOUND *sound, FMOD_SYNCPOINT *point); - -/* - Functions also in Channel class but here they are the 'default' to save having to change it in Channel all the time. -*/ - -FMOD_RESULT F_API FMOD_Sound_SetMode (FMOD_SOUND *sound, FMOD_MODE mode); -FMOD_RESULT F_API FMOD_Sound_GetMode (FMOD_SOUND *sound, FMOD_MODE *mode); -FMOD_RESULT F_API FMOD_Sound_SetLoopCount (FMOD_SOUND *sound, int loopcount); -FMOD_RESULT F_API FMOD_Sound_GetLoopCount (FMOD_SOUND *sound, int *loopcount); -FMOD_RESULT F_API FMOD_Sound_SetLoopPoints (FMOD_SOUND *sound, unsigned int loopstart, FMOD_TIMEUNIT loopstarttype, unsigned int loopend, FMOD_TIMEUNIT loopendtype); -FMOD_RESULT F_API FMOD_Sound_GetLoopPoints (FMOD_SOUND *sound, unsigned int *loopstart, FMOD_TIMEUNIT loopstarttype, unsigned int *loopend, FMOD_TIMEUNIT loopendtype); - -/* - For MOD/S3M/XM/IT/MID sequenced formats only. -*/ - -FMOD_RESULT F_API FMOD_Sound_GetMusicNumChannels (FMOD_SOUND *sound, int *numchannels); -FMOD_RESULT F_API FMOD_Sound_SetMusicChannelVolume (FMOD_SOUND *sound, int channel, float volume); -FMOD_RESULT F_API FMOD_Sound_GetMusicChannelVolume (FMOD_SOUND *sound, int channel, float *volume); -FMOD_RESULT F_API FMOD_Sound_SetMusicSpeed (FMOD_SOUND *sound, float speed); -FMOD_RESULT F_API FMOD_Sound_GetMusicSpeed (FMOD_SOUND *sound, float *speed); - -/* - Userdata set/get. -*/ - -FMOD_RESULT F_API FMOD_Sound_SetUserData (FMOD_SOUND *sound, void *userdata); -FMOD_RESULT F_API FMOD_Sound_GetUserData (FMOD_SOUND *sound, void **userdata); - -/* - 'Channel' API -*/ - -FMOD_RESULT F_API FMOD_Channel_GetSystemObject (FMOD_CHANNEL *channel, FMOD_SYSTEM **system); - -/* - General control functionality for Channels and ChannelGroups. -*/ - -FMOD_RESULT F_API FMOD_Channel_Stop (FMOD_CHANNEL *channel); -FMOD_RESULT F_API FMOD_Channel_SetPaused (FMOD_CHANNEL *channel, FMOD_BOOL paused); -FMOD_RESULT F_API FMOD_Channel_GetPaused (FMOD_CHANNEL *channel, FMOD_BOOL *paused); -FMOD_RESULT F_API FMOD_Channel_SetVolume (FMOD_CHANNEL *channel, float volume); -FMOD_RESULT F_API FMOD_Channel_GetVolume (FMOD_CHANNEL *channel, float *volume); -FMOD_RESULT F_API FMOD_Channel_SetVolumeRamp (FMOD_CHANNEL *channel, FMOD_BOOL ramp); -FMOD_RESULT F_API FMOD_Channel_GetVolumeRamp (FMOD_CHANNEL *channel, FMOD_BOOL *ramp); -FMOD_RESULT F_API FMOD_Channel_GetAudibility (FMOD_CHANNEL *channel, float *audibility); -FMOD_RESULT F_API FMOD_Channel_SetPitch (FMOD_CHANNEL *channel, float pitch); -FMOD_RESULT F_API FMOD_Channel_GetPitch (FMOD_CHANNEL *channel, float *pitch); -FMOD_RESULT F_API FMOD_Channel_SetMute (FMOD_CHANNEL *channel, FMOD_BOOL mute); -FMOD_RESULT F_API FMOD_Channel_GetMute (FMOD_CHANNEL *channel, FMOD_BOOL *mute); -FMOD_RESULT F_API FMOD_Channel_SetReverbProperties (FMOD_CHANNEL *channel, int instance, float wet); -FMOD_RESULT F_API FMOD_Channel_GetReverbProperties (FMOD_CHANNEL *channel, int instance, float *wet); -FMOD_RESULT F_API FMOD_Channel_SetLowPassGain (FMOD_CHANNEL *channel, float gain); -FMOD_RESULT F_API FMOD_Channel_GetLowPassGain (FMOD_CHANNEL *channel, float *gain); -FMOD_RESULT F_API FMOD_Channel_SetMode (FMOD_CHANNEL *channel, FMOD_MODE mode); -FMOD_RESULT F_API FMOD_Channel_GetMode (FMOD_CHANNEL *channel, FMOD_MODE *mode); -FMOD_RESULT F_API FMOD_Channel_SetCallback (FMOD_CHANNEL *channel, FMOD_CHANNELCONTROL_CALLBACK callback); -FMOD_RESULT F_API FMOD_Channel_IsPlaying (FMOD_CHANNEL *channel, FMOD_BOOL *isplaying); - -/* - Note all 'set' functions alter a final matrix, this is why the only get function is getMixMatrix, to avoid other get functions returning incorrect/obsolete values. -*/ - -FMOD_RESULT F_API FMOD_Channel_SetPan (FMOD_CHANNEL *channel, float pan); -FMOD_RESULT F_API FMOD_Channel_SetMixLevelsOutput (FMOD_CHANNEL *channel, float frontleft, float frontright, float center, float lfe, float surroundleft, float surroundright, float backleft, float backright); -FMOD_RESULT F_API FMOD_Channel_SetMixLevelsInput (FMOD_CHANNEL *channel, float *levels, int numlevels); -FMOD_RESULT F_API FMOD_Channel_SetMixMatrix (FMOD_CHANNEL *channel, float *matrix, int outchannels, int inchannels, int inchannel_hop); -FMOD_RESULT F_API FMOD_Channel_GetMixMatrix (FMOD_CHANNEL *channel, float *matrix, int *outchannels, int *inchannels, int inchannel_hop); - -/* - Clock based functionality. -*/ - -FMOD_RESULT F_API FMOD_Channel_GetDSPClock (FMOD_CHANNEL *channel, unsigned long long *dspclock, unsigned long long *parentclock); -FMOD_RESULT F_API FMOD_Channel_SetDelay (FMOD_CHANNEL *channel, unsigned long long dspclock_start, unsigned long long dspclock_end, FMOD_BOOL stopchannels); -FMOD_RESULT F_API FMOD_Channel_GetDelay (FMOD_CHANNEL *channel, unsigned long long *dspclock_start, unsigned long long *dspclock_end, FMOD_BOOL *stopchannels); -FMOD_RESULT F_API FMOD_Channel_AddFadePoint (FMOD_CHANNEL *channel, unsigned long long dspclock, float volume); -FMOD_RESULT F_API FMOD_Channel_SetFadePointRamp (FMOD_CHANNEL *channel, unsigned long long dspclock, float volume); -FMOD_RESULT F_API FMOD_Channel_RemoveFadePoints (FMOD_CHANNEL *channel, unsigned long long dspclock_start, unsigned long long dspclock_end); -FMOD_RESULT F_API FMOD_Channel_GetFadePoints (FMOD_CHANNEL *channel, unsigned int *numpoints, unsigned long long *point_dspclock, float *point_volume); - -/* - DSP effects. -*/ - -FMOD_RESULT F_API FMOD_Channel_GetDSP (FMOD_CHANNEL *channel, int index, FMOD_DSP **dsp); -FMOD_RESULT F_API FMOD_Channel_AddDSP (FMOD_CHANNEL *channel, int index, FMOD_DSP *dsp); -FMOD_RESULT F_API FMOD_Channel_RemoveDSP (FMOD_CHANNEL *channel, FMOD_DSP *dsp); -FMOD_RESULT F_API FMOD_Channel_GetNumDSPs (FMOD_CHANNEL *channel, int *numdsps); -FMOD_RESULT F_API FMOD_Channel_SetDSPIndex (FMOD_CHANNEL *channel, FMOD_DSP *dsp, int index); -FMOD_RESULT F_API FMOD_Channel_GetDSPIndex (FMOD_CHANNEL *channel, FMOD_DSP *dsp, int *index); - -/* - 3D functionality. -*/ - -FMOD_RESULT F_API FMOD_Channel_Set3DAttributes (FMOD_CHANNEL *channel, const FMOD_VECTOR *pos, const FMOD_VECTOR *vel); -FMOD_RESULT F_API FMOD_Channel_Get3DAttributes (FMOD_CHANNEL *channel, FMOD_VECTOR *pos, FMOD_VECTOR *vel); -FMOD_RESULT F_API FMOD_Channel_Set3DMinMaxDistance (FMOD_CHANNEL *channel, float mindistance, float maxdistance); -FMOD_RESULT F_API FMOD_Channel_Get3DMinMaxDistance (FMOD_CHANNEL *channel, float *mindistance, float *maxdistance); -FMOD_RESULT F_API FMOD_Channel_Set3DConeSettings (FMOD_CHANNEL *channel, float insideconeangle, float outsideconeangle, float outsidevolume); -FMOD_RESULT F_API FMOD_Channel_Get3DConeSettings (FMOD_CHANNEL *channel, float *insideconeangle, float *outsideconeangle, float *outsidevolume); -FMOD_RESULT F_API FMOD_Channel_Set3DConeOrientation (FMOD_CHANNEL *channel, FMOD_VECTOR *orientation); -FMOD_RESULT F_API FMOD_Channel_Get3DConeOrientation (FMOD_CHANNEL *channel, FMOD_VECTOR *orientation); -FMOD_RESULT F_API FMOD_Channel_Set3DCustomRolloff (FMOD_CHANNEL *channel, FMOD_VECTOR *points, int numpoints); -FMOD_RESULT F_API FMOD_Channel_Get3DCustomRolloff (FMOD_CHANNEL *channel, FMOD_VECTOR **points, int *numpoints); -FMOD_RESULT F_API FMOD_Channel_Set3DOcclusion (FMOD_CHANNEL *channel, float directocclusion, float reverbocclusion); -FMOD_RESULT F_API FMOD_Channel_Get3DOcclusion (FMOD_CHANNEL *channel, float *directocclusion, float *reverbocclusion); -FMOD_RESULT F_API FMOD_Channel_Set3DSpread (FMOD_CHANNEL *channel, float angle); -FMOD_RESULT F_API FMOD_Channel_Get3DSpread (FMOD_CHANNEL *channel, float *angle); -FMOD_RESULT F_API FMOD_Channel_Set3DLevel (FMOD_CHANNEL *channel, float level); -FMOD_RESULT F_API FMOD_Channel_Get3DLevel (FMOD_CHANNEL *channel, float *level); -FMOD_RESULT F_API FMOD_Channel_Set3DDopplerLevel (FMOD_CHANNEL *channel, float level); -FMOD_RESULT F_API FMOD_Channel_Get3DDopplerLevel (FMOD_CHANNEL *channel, float *level); -FMOD_RESULT F_API FMOD_Channel_Set3DDistanceFilter (FMOD_CHANNEL *channel, FMOD_BOOL custom, float customLevel, float centerFreq); -FMOD_RESULT F_API FMOD_Channel_Get3DDistanceFilter (FMOD_CHANNEL *channel, FMOD_BOOL *custom, float *customLevel, float *centerFreq); - -/* - Userdata set/get. -*/ - -FMOD_RESULT F_API FMOD_Channel_SetUserData (FMOD_CHANNEL *channel, void *userdata); -FMOD_RESULT F_API FMOD_Channel_GetUserData (FMOD_CHANNEL *channel, void **userdata); - -/* - Channel specific control functionality. -*/ - -FMOD_RESULT F_API FMOD_Channel_SetFrequency (FMOD_CHANNEL *channel, float frequency); -FMOD_RESULT F_API FMOD_Channel_GetFrequency (FMOD_CHANNEL *channel, float *frequency); -FMOD_RESULT F_API FMOD_Channel_SetPriority (FMOD_CHANNEL *channel, int priority); -FMOD_RESULT F_API FMOD_Channel_GetPriority (FMOD_CHANNEL *channel, int *priority); -FMOD_RESULT F_API FMOD_Channel_SetPosition (FMOD_CHANNEL *channel, unsigned int position, FMOD_TIMEUNIT postype); -FMOD_RESULT F_API FMOD_Channel_GetPosition (FMOD_CHANNEL *channel, unsigned int *position, FMOD_TIMEUNIT postype); -FMOD_RESULT F_API FMOD_Channel_SetChannelGroup (FMOD_CHANNEL *channel, FMOD_CHANNELGROUP *channelgroup); -FMOD_RESULT F_API FMOD_Channel_GetChannelGroup (FMOD_CHANNEL *channel, FMOD_CHANNELGROUP **channelgroup); -FMOD_RESULT F_API FMOD_Channel_SetLoopCount (FMOD_CHANNEL *channel, int loopcount); -FMOD_RESULT F_API FMOD_Channel_GetLoopCount (FMOD_CHANNEL *channel, int *loopcount); -FMOD_RESULT F_API FMOD_Channel_SetLoopPoints (FMOD_CHANNEL *channel, unsigned int loopstart, FMOD_TIMEUNIT loopstarttype, unsigned int loopend, FMOD_TIMEUNIT loopendtype); -FMOD_RESULT F_API FMOD_Channel_GetLoopPoints (FMOD_CHANNEL *channel, unsigned int *loopstart, FMOD_TIMEUNIT loopstarttype, unsigned int *loopend, FMOD_TIMEUNIT loopendtype); - -/* - Information only functions. -*/ - -FMOD_RESULT F_API FMOD_Channel_IsVirtual (FMOD_CHANNEL *channel, FMOD_BOOL *isvirtual); -FMOD_RESULT F_API FMOD_Channel_GetCurrentSound (FMOD_CHANNEL *channel, FMOD_SOUND **sound); -FMOD_RESULT F_API FMOD_Channel_GetIndex (FMOD_CHANNEL *channel, int *index); - -/* - 'ChannelGroup' API -*/ - -FMOD_RESULT F_API FMOD_ChannelGroup_GetSystemObject (FMOD_CHANNELGROUP *channelgroup, FMOD_SYSTEM **system); - -/* - General control functionality for Channels and ChannelGroups. -*/ - -FMOD_RESULT F_API FMOD_ChannelGroup_Stop (FMOD_CHANNELGROUP *channelgroup); -FMOD_RESULT F_API FMOD_ChannelGroup_SetPaused (FMOD_CHANNELGROUP *channelgroup, FMOD_BOOL paused); -FMOD_RESULT F_API FMOD_ChannelGroup_GetPaused (FMOD_CHANNELGROUP *channelgroup, FMOD_BOOL *paused); -FMOD_RESULT F_API FMOD_ChannelGroup_SetVolume (FMOD_CHANNELGROUP *channelgroup, float volume); -FMOD_RESULT F_API FMOD_ChannelGroup_GetVolume (FMOD_CHANNELGROUP *channelgroup, float *volume); -FMOD_RESULT F_API FMOD_ChannelGroup_SetVolumeRamp (FMOD_CHANNELGROUP *channelgroup, FMOD_BOOL ramp); -FMOD_RESULT F_API FMOD_ChannelGroup_GetVolumeRamp (FMOD_CHANNELGROUP *channelgroup, FMOD_BOOL *ramp); -FMOD_RESULT F_API FMOD_ChannelGroup_GetAudibility (FMOD_CHANNELGROUP *channelgroup, float *audibility); -FMOD_RESULT F_API FMOD_ChannelGroup_SetPitch (FMOD_CHANNELGROUP *channelgroup, float pitch); -FMOD_RESULT F_API FMOD_ChannelGroup_GetPitch (FMOD_CHANNELGROUP *channelgroup, float *pitch); -FMOD_RESULT F_API FMOD_ChannelGroup_SetMute (FMOD_CHANNELGROUP *channelgroup, FMOD_BOOL mute); -FMOD_RESULT F_API FMOD_ChannelGroup_GetMute (FMOD_CHANNELGROUP *channelgroup, FMOD_BOOL *mute); -FMOD_RESULT F_API FMOD_ChannelGroup_SetReverbProperties (FMOD_CHANNELGROUP *channelgroup, int instance, float wet); -FMOD_RESULT F_API FMOD_ChannelGroup_GetReverbProperties (FMOD_CHANNELGROUP *channelgroup, int instance, float *wet); -FMOD_RESULT F_API FMOD_ChannelGroup_SetLowPassGain (FMOD_CHANNELGROUP *channelgroup, float gain); -FMOD_RESULT F_API FMOD_ChannelGroup_GetLowPassGain (FMOD_CHANNELGROUP *channelgroup, float *gain); -FMOD_RESULT F_API FMOD_ChannelGroup_SetMode (FMOD_CHANNELGROUP *channelgroup, FMOD_MODE mode); -FMOD_RESULT F_API FMOD_ChannelGroup_GetMode (FMOD_CHANNELGROUP *channelgroup, FMOD_MODE *mode); -FMOD_RESULT F_API FMOD_ChannelGroup_SetCallback (FMOD_CHANNELGROUP *channelgroup, FMOD_CHANNELCONTROL_CALLBACK callback); -FMOD_RESULT F_API FMOD_ChannelGroup_IsPlaying (FMOD_CHANNELGROUP *channelgroup, FMOD_BOOL *isplaying); - -/* - Note all 'set' functions alter a final matrix, this is why the only get function is getMixMatrix, to avoid other get functions returning incorrect/obsolete values. -*/ - -FMOD_RESULT F_API FMOD_ChannelGroup_SetPan (FMOD_CHANNELGROUP *channelgroup, float pan); -FMOD_RESULT F_API FMOD_ChannelGroup_SetMixLevelsOutput (FMOD_CHANNELGROUP *channelgroup, float frontleft, float frontright, float center, float lfe, float surroundleft, float surroundright, float backleft, float backright); -FMOD_RESULT F_API FMOD_ChannelGroup_SetMixLevelsInput (FMOD_CHANNELGROUP *channelgroup, float *levels, int numlevels); -FMOD_RESULT F_API FMOD_ChannelGroup_SetMixMatrix (FMOD_CHANNELGROUP *channelgroup, float *matrix, int outchannels, int inchannels, int inchannel_hop); -FMOD_RESULT F_API FMOD_ChannelGroup_GetMixMatrix (FMOD_CHANNELGROUP *channelgroup, float *matrix, int *outchannels, int *inchannels, int inchannel_hop); - -/* - Clock based functionality. -*/ - -FMOD_RESULT F_API FMOD_ChannelGroup_GetDSPClock (FMOD_CHANNELGROUP *channelgroup, unsigned long long *dspclock, unsigned long long *parentclock); -FMOD_RESULT F_API FMOD_ChannelGroup_SetDelay (FMOD_CHANNELGROUP *channelgroup, unsigned long long dspclock_start, unsigned long long dspclock_end, FMOD_BOOL stopchannels); -FMOD_RESULT F_API FMOD_ChannelGroup_GetDelay (FMOD_CHANNELGROUP *channelgroup, unsigned long long *dspclock_start, unsigned long long *dspclock_end, FMOD_BOOL *stopchannels); -FMOD_RESULT F_API FMOD_ChannelGroup_AddFadePoint (FMOD_CHANNELGROUP *channelgroup, unsigned long long dspclock, float volume); -FMOD_RESULT F_API FMOD_ChannelGroup_SetFadePointRamp (FMOD_CHANNELGROUP *channelgroup, unsigned long long dspclock, float volume); -FMOD_RESULT F_API FMOD_ChannelGroup_RemoveFadePoints (FMOD_CHANNELGROUP *channelgroup, unsigned long long dspclock_start, unsigned long long dspclock_end); -FMOD_RESULT F_API FMOD_ChannelGroup_GetFadePoints (FMOD_CHANNELGROUP *channelgroup, unsigned int *numpoints, unsigned long long *point_dspclock, float *point_volume); - -/* - DSP effects. -*/ - -FMOD_RESULT F_API FMOD_ChannelGroup_GetDSP (FMOD_CHANNELGROUP *channelgroup, int index, FMOD_DSP **dsp); -FMOD_RESULT F_API FMOD_ChannelGroup_AddDSP (FMOD_CHANNELGROUP *channelgroup, int index, FMOD_DSP *dsp); -FMOD_RESULT F_API FMOD_ChannelGroup_RemoveDSP (FMOD_CHANNELGROUP *channelgroup, FMOD_DSP *dsp); -FMOD_RESULT F_API FMOD_ChannelGroup_GetNumDSPs (FMOD_CHANNELGROUP *channelgroup, int *numdsps); -FMOD_RESULT F_API FMOD_ChannelGroup_SetDSPIndex (FMOD_CHANNELGROUP *channelgroup, FMOD_DSP *dsp, int index); -FMOD_RESULT F_API FMOD_ChannelGroup_GetDSPIndex (FMOD_CHANNELGROUP *channelgroup, FMOD_DSP *dsp, int *index); - -/* - 3D functionality. -*/ - -FMOD_RESULT F_API FMOD_ChannelGroup_Set3DAttributes (FMOD_CHANNELGROUP *channelgroup, const FMOD_VECTOR *pos, const FMOD_VECTOR *vel); -FMOD_RESULT F_API FMOD_ChannelGroup_Get3DAttributes (FMOD_CHANNELGROUP *channelgroup, FMOD_VECTOR *pos, FMOD_VECTOR *vel); -FMOD_RESULT F_API FMOD_ChannelGroup_Set3DMinMaxDistance (FMOD_CHANNELGROUP *channelgroup, float mindistance, float maxdistance); -FMOD_RESULT F_API FMOD_ChannelGroup_Get3DMinMaxDistance (FMOD_CHANNELGROUP *channelgroup, float *mindistance, float *maxdistance); -FMOD_RESULT F_API FMOD_ChannelGroup_Set3DConeSettings (FMOD_CHANNELGROUP *channelgroup, float insideconeangle, float outsideconeangle, float outsidevolume); -FMOD_RESULT F_API FMOD_ChannelGroup_Get3DConeSettings (FMOD_CHANNELGROUP *channelgroup, float *insideconeangle, float *outsideconeangle, float *outsidevolume); -FMOD_RESULT F_API FMOD_ChannelGroup_Set3DConeOrientation(FMOD_CHANNELGROUP *channelgroup, FMOD_VECTOR *orientation); -FMOD_RESULT F_API FMOD_ChannelGroup_Get3DConeOrientation(FMOD_CHANNELGROUP *channelgroup, FMOD_VECTOR *orientation); -FMOD_RESULT F_API FMOD_ChannelGroup_Set3DCustomRolloff (FMOD_CHANNELGROUP *channelgroup, FMOD_VECTOR *points, int numpoints); -FMOD_RESULT F_API FMOD_ChannelGroup_Get3DCustomRolloff (FMOD_CHANNELGROUP *channelgroup, FMOD_VECTOR **points, int *numpoints); -FMOD_RESULT F_API FMOD_ChannelGroup_Set3DOcclusion (FMOD_CHANNELGROUP *channelgroup, float directocclusion, float reverbocclusion); -FMOD_RESULT F_API FMOD_ChannelGroup_Get3DOcclusion (FMOD_CHANNELGROUP *channelgroup, float *directocclusion, float *reverbocclusion); -FMOD_RESULT F_API FMOD_ChannelGroup_Set3DSpread (FMOD_CHANNELGROUP *channelgroup, float angle); -FMOD_RESULT F_API FMOD_ChannelGroup_Get3DSpread (FMOD_CHANNELGROUP *channelgroup, float *angle); -FMOD_RESULT F_API FMOD_ChannelGroup_Set3DLevel (FMOD_CHANNELGROUP *channelgroup, float level); -FMOD_RESULT F_API FMOD_ChannelGroup_Get3DLevel (FMOD_CHANNELGROUP *channelgroup, float *level); -FMOD_RESULT F_API FMOD_ChannelGroup_Set3DDopplerLevel (FMOD_CHANNELGROUP *channelgroup, float level); -FMOD_RESULT F_API FMOD_ChannelGroup_Get3DDopplerLevel (FMOD_CHANNELGROUP *channelgroup, float *level); -FMOD_RESULT F_API FMOD_ChannelGroup_Set3DDistanceFilter (FMOD_CHANNELGROUP *channelgroup, FMOD_BOOL custom, float customLevel, float centerFreq); -FMOD_RESULT F_API FMOD_ChannelGroup_Get3DDistanceFilter (FMOD_CHANNELGROUP *channelgroup, FMOD_BOOL *custom, float *customLevel, float *centerFreq); - -/* - Userdata set/get. -*/ - -FMOD_RESULT F_API FMOD_ChannelGroup_SetUserData (FMOD_CHANNELGROUP *channelgroup, void *userdata); -FMOD_RESULT F_API FMOD_ChannelGroup_GetUserData (FMOD_CHANNELGROUP *channelgroup, void **userdata); - -FMOD_RESULT F_API FMOD_ChannelGroup_Release (FMOD_CHANNELGROUP *channelgroup); - -/* - Nested channel groups. -*/ - -FMOD_RESULT F_API FMOD_ChannelGroup_AddGroup (FMOD_CHANNELGROUP *channelgroup, FMOD_CHANNELGROUP *group, FMOD_BOOL propagatedspclock, FMOD_DSPCONNECTION **connection); -FMOD_RESULT F_API FMOD_ChannelGroup_GetNumGroups (FMOD_CHANNELGROUP *channelgroup, int *numgroups); -FMOD_RESULT F_API FMOD_ChannelGroup_GetGroup (FMOD_CHANNELGROUP *channelgroup, int index, FMOD_CHANNELGROUP **group); -FMOD_RESULT F_API FMOD_ChannelGroup_GetParentGroup (FMOD_CHANNELGROUP *channelgroup, FMOD_CHANNELGROUP **group); - -/* - Information only functions. -*/ - -FMOD_RESULT F_API FMOD_ChannelGroup_GetName (FMOD_CHANNELGROUP *channelgroup, char *name, int namelen); -FMOD_RESULT F_API FMOD_ChannelGroup_GetNumChannels (FMOD_CHANNELGROUP *channelgroup, int *numchannels); -FMOD_RESULT F_API FMOD_ChannelGroup_GetChannel (FMOD_CHANNELGROUP *channelgroup, int index, FMOD_CHANNEL **channel); - -/* - 'SoundGroup' API -*/ - -FMOD_RESULT F_API FMOD_SoundGroup_Release (FMOD_SOUNDGROUP *soundgroup); -FMOD_RESULT F_API FMOD_SoundGroup_GetSystemObject (FMOD_SOUNDGROUP *soundgroup, FMOD_SYSTEM **system); - -/* - SoundGroup control functions. -*/ - -FMOD_RESULT F_API FMOD_SoundGroup_SetMaxAudible (FMOD_SOUNDGROUP *soundgroup, int maxaudible); -FMOD_RESULT F_API FMOD_SoundGroup_GetMaxAudible (FMOD_SOUNDGROUP *soundgroup, int *maxaudible); -FMOD_RESULT F_API FMOD_SoundGroup_SetMaxAudibleBehavior (FMOD_SOUNDGROUP *soundgroup, FMOD_SOUNDGROUP_BEHAVIOR behavior); -FMOD_RESULT F_API FMOD_SoundGroup_GetMaxAudibleBehavior (FMOD_SOUNDGROUP *soundgroup, FMOD_SOUNDGROUP_BEHAVIOR *behavior); -FMOD_RESULT F_API FMOD_SoundGroup_SetMuteFadeSpeed (FMOD_SOUNDGROUP *soundgroup, float speed); -FMOD_RESULT F_API FMOD_SoundGroup_GetMuteFadeSpeed (FMOD_SOUNDGROUP *soundgroup, float *speed); -FMOD_RESULT F_API FMOD_SoundGroup_SetVolume (FMOD_SOUNDGROUP *soundgroup, float volume); -FMOD_RESULT F_API FMOD_SoundGroup_GetVolume (FMOD_SOUNDGROUP *soundgroup, float *volume); -FMOD_RESULT F_API FMOD_SoundGroup_Stop (FMOD_SOUNDGROUP *soundgroup); - -/* - Information only functions. -*/ - -FMOD_RESULT F_API FMOD_SoundGroup_GetName (FMOD_SOUNDGROUP *soundgroup, char *name, int namelen); -FMOD_RESULT F_API FMOD_SoundGroup_GetNumSounds (FMOD_SOUNDGROUP *soundgroup, int *numsounds); -FMOD_RESULT F_API FMOD_SoundGroup_GetSound (FMOD_SOUNDGROUP *soundgroup, int index, FMOD_SOUND **sound); -FMOD_RESULT F_API FMOD_SoundGroup_GetNumPlaying (FMOD_SOUNDGROUP *soundgroup, int *numplaying); - -/* - Userdata set/get. -*/ - -FMOD_RESULT F_API FMOD_SoundGroup_SetUserData (FMOD_SOUNDGROUP *soundgroup, void *userdata); -FMOD_RESULT F_API FMOD_SoundGroup_GetUserData (FMOD_SOUNDGROUP *soundgroup, void **userdata); - -/* - 'DSP' API -*/ - -FMOD_RESULT F_API FMOD_DSP_Release (FMOD_DSP *dsp); -FMOD_RESULT F_API FMOD_DSP_GetSystemObject (FMOD_DSP *dsp, FMOD_SYSTEM **system); - -/* - Connection / disconnection / input and output enumeration. -*/ - -FMOD_RESULT F_API FMOD_DSP_AddInput (FMOD_DSP *dsp, FMOD_DSP *input, FMOD_DSPCONNECTION **connection, FMOD_DSPCONNECTION_TYPE type); -FMOD_RESULT F_API FMOD_DSP_DisconnectFrom (FMOD_DSP *dsp, FMOD_DSP *target, FMOD_DSPCONNECTION *connection); -FMOD_RESULT F_API FMOD_DSP_DisconnectAll (FMOD_DSP *dsp, FMOD_BOOL inputs, FMOD_BOOL outputs); -FMOD_RESULT F_API FMOD_DSP_GetNumInputs (FMOD_DSP *dsp, int *numinputs); -FMOD_RESULT F_API FMOD_DSP_GetNumOutputs (FMOD_DSP *dsp, int *numoutputs); -FMOD_RESULT F_API FMOD_DSP_GetInput (FMOD_DSP *dsp, int index, FMOD_DSP **input, FMOD_DSPCONNECTION **inputconnection); -FMOD_RESULT F_API FMOD_DSP_GetOutput (FMOD_DSP *dsp, int index, FMOD_DSP **output, FMOD_DSPCONNECTION **outputconnection); - -/* - DSP unit control. -*/ - -FMOD_RESULT F_API FMOD_DSP_SetActive (FMOD_DSP *dsp, FMOD_BOOL active); -FMOD_RESULT F_API FMOD_DSP_GetActive (FMOD_DSP *dsp, FMOD_BOOL *active); -FMOD_RESULT F_API FMOD_DSP_SetBypass (FMOD_DSP *dsp, FMOD_BOOL bypass); -FMOD_RESULT F_API FMOD_DSP_GetBypass (FMOD_DSP *dsp, FMOD_BOOL *bypass); -FMOD_RESULT F_API FMOD_DSP_SetWetDryMix (FMOD_DSP *dsp, float prewet, float postwet, float dry); -FMOD_RESULT F_API FMOD_DSP_GetWetDryMix (FMOD_DSP *dsp, float *prewet, float *postwet, float *dry); -FMOD_RESULT F_API FMOD_DSP_SetChannelFormat (FMOD_DSP *dsp, FMOD_CHANNELMASK channelmask, int numchannels, FMOD_SPEAKERMODE source_speakermode); -FMOD_RESULT F_API FMOD_DSP_GetChannelFormat (FMOD_DSP *dsp, FMOD_CHANNELMASK *channelmask, int *numchannels, FMOD_SPEAKERMODE *source_speakermode); -FMOD_RESULT F_API FMOD_DSP_GetOutputChannelFormat (FMOD_DSP *dsp, FMOD_CHANNELMASK inmask, int inchannels, FMOD_SPEAKERMODE inspeakermode, FMOD_CHANNELMASK *outmask, int *outchannels, FMOD_SPEAKERMODE *outspeakermode); -FMOD_RESULT F_API FMOD_DSP_Reset (FMOD_DSP *dsp); - -/* - DSP parameter control. -*/ - -FMOD_RESULT F_API FMOD_DSP_SetParameterFloat (FMOD_DSP *dsp, int index, float value); -FMOD_RESULT F_API FMOD_DSP_SetParameterInt (FMOD_DSP *dsp, int index, int value); -FMOD_RESULT F_API FMOD_DSP_SetParameterBool (FMOD_DSP *dsp, int index, FMOD_BOOL value); -FMOD_RESULT F_API FMOD_DSP_SetParameterData (FMOD_DSP *dsp, int index, void *data, unsigned int length); -FMOD_RESULT F_API FMOD_DSP_GetParameterFloat (FMOD_DSP *dsp, int index, float *value, char *valuestr, int valuestrlen); -FMOD_RESULT F_API FMOD_DSP_GetParameterInt (FMOD_DSP *dsp, int index, int *value, char *valuestr, int valuestrlen); -FMOD_RESULT F_API FMOD_DSP_GetParameterBool (FMOD_DSP *dsp, int index, FMOD_BOOL *value, char *valuestr, int valuestrlen); -FMOD_RESULT F_API FMOD_DSP_GetParameterData (FMOD_DSP *dsp, int index, void **data, unsigned int *length, char *valuestr, int valuestrlen); -FMOD_RESULT F_API FMOD_DSP_GetNumParameters (FMOD_DSP *dsp, int *numparams); -FMOD_RESULT F_API FMOD_DSP_GetParameterInfo (FMOD_DSP *dsp, int index, FMOD_DSP_PARAMETER_DESC **desc); -FMOD_RESULT F_API FMOD_DSP_GetDataParameterIndex (FMOD_DSP *dsp, int datatype, int *index); -FMOD_RESULT F_API FMOD_DSP_ShowConfigDialog (FMOD_DSP *dsp, void *hwnd, FMOD_BOOL show); - -/* - DSP attributes. -*/ - -FMOD_RESULT F_API FMOD_DSP_GetInfo (FMOD_DSP *dsp, char *name, unsigned int *version, int *channels, int *configwidth, int *configheight); -FMOD_RESULT F_API FMOD_DSP_GetType (FMOD_DSP *dsp, FMOD_DSP_TYPE *type); -FMOD_RESULT F_API FMOD_DSP_GetIdle (FMOD_DSP *dsp, FMOD_BOOL *idle); - -/* - Userdata set/get. -*/ - -FMOD_RESULT F_API FMOD_DSP_SetUserData (FMOD_DSP *dsp, void *userdata); -FMOD_RESULT F_API FMOD_DSP_GetUserData (FMOD_DSP *dsp, void **userdata); - -/* - Metering. -*/ - -FMOD_RESULT F_API FMOD_DSP_SetMeteringEnabled (FMOD_DSP *dsp, FMOD_BOOL inputEnabled, FMOD_BOOL outputEnabled); -FMOD_RESULT F_API FMOD_DSP_GetMeteringEnabled (FMOD_DSP *dsp, FMOD_BOOL *inputEnabled, FMOD_BOOL *outputEnabled); -FMOD_RESULT F_API FMOD_DSP_GetMeteringInfo (FMOD_DSP *dsp, FMOD_DSP_METERING_INFO *inputInfo, FMOD_DSP_METERING_INFO *outputInfo); -FMOD_RESULT F_API FMOD_DSP_GetCPUUsage (FMOD_DSP *dsp, unsigned int *exclusive, unsigned int *inclusive); - -/* - 'DSPConnection' API -*/ - -FMOD_RESULT F_API FMOD_DSPConnection_GetInput (FMOD_DSPCONNECTION *dspconnection, FMOD_DSP **input); -FMOD_RESULT F_API FMOD_DSPConnection_GetOutput (FMOD_DSPCONNECTION *dspconnection, FMOD_DSP **output); -FMOD_RESULT F_API FMOD_DSPConnection_SetMix (FMOD_DSPCONNECTION *dspconnection, float volume); -FMOD_RESULT F_API FMOD_DSPConnection_GetMix (FMOD_DSPCONNECTION *dspconnection, float *volume); -FMOD_RESULT F_API FMOD_DSPConnection_SetMixMatrix (FMOD_DSPCONNECTION *dspconnection, float *matrix, int outchannels, int inchannels, int inchannel_hop); -FMOD_RESULT F_API FMOD_DSPConnection_GetMixMatrix (FMOD_DSPCONNECTION *dspconnection, float *matrix, int *outchannels, int *inchannels, int inchannel_hop); -FMOD_RESULT F_API FMOD_DSPConnection_GetType (FMOD_DSPCONNECTION *dspconnection, FMOD_DSPCONNECTION_TYPE *type); - -/* - Userdata set/get. -*/ - -FMOD_RESULT F_API FMOD_DSPConnection_SetUserData (FMOD_DSPCONNECTION *dspconnection, void *userdata); -FMOD_RESULT F_API FMOD_DSPConnection_GetUserData (FMOD_DSPCONNECTION *dspconnection, void **userdata); - -/* - 'Geometry' API -*/ - -FMOD_RESULT F_API FMOD_Geometry_Release (FMOD_GEOMETRY *geometry); - -/* - Polygon manipulation. -*/ - -FMOD_RESULT F_API FMOD_Geometry_AddPolygon (FMOD_GEOMETRY *geometry, float directocclusion, float reverbocclusion, FMOD_BOOL doublesided, int numvertices, const FMOD_VECTOR *vertices, int *polygonindex); -FMOD_RESULT F_API FMOD_Geometry_GetNumPolygons (FMOD_GEOMETRY *geometry, int *numpolygons); -FMOD_RESULT F_API FMOD_Geometry_GetMaxPolygons (FMOD_GEOMETRY *geometry, int *maxpolygons, int *maxvertices); -FMOD_RESULT F_API FMOD_Geometry_GetPolygonNumVertices (FMOD_GEOMETRY *geometry, int index, int *numvertices); -FMOD_RESULT F_API FMOD_Geometry_SetPolygonVertex (FMOD_GEOMETRY *geometry, int index, int vertexindex, const FMOD_VECTOR *vertex); -FMOD_RESULT F_API FMOD_Geometry_GetPolygonVertex (FMOD_GEOMETRY *geometry, int index, int vertexindex, FMOD_VECTOR *vertex); -FMOD_RESULT F_API FMOD_Geometry_SetPolygonAttributes (FMOD_GEOMETRY *geometry, int index, float directocclusion, float reverbocclusion, FMOD_BOOL doublesided); -FMOD_RESULT F_API FMOD_Geometry_GetPolygonAttributes (FMOD_GEOMETRY *geometry, int index, float *directocclusion, float *reverbocclusion, FMOD_BOOL *doublesided); - -/* - Object manipulation. -*/ - -FMOD_RESULT F_API FMOD_Geometry_SetActive (FMOD_GEOMETRY *geometry, FMOD_BOOL active); -FMOD_RESULT F_API FMOD_Geometry_GetActive (FMOD_GEOMETRY *geometry, FMOD_BOOL *active); -FMOD_RESULT F_API FMOD_Geometry_SetRotation (FMOD_GEOMETRY *geometry, const FMOD_VECTOR *forward, const FMOD_VECTOR *up); -FMOD_RESULT F_API FMOD_Geometry_GetRotation (FMOD_GEOMETRY *geometry, FMOD_VECTOR *forward, FMOD_VECTOR *up); -FMOD_RESULT F_API FMOD_Geometry_SetPosition (FMOD_GEOMETRY *geometry, const FMOD_VECTOR *position); -FMOD_RESULT F_API FMOD_Geometry_GetPosition (FMOD_GEOMETRY *geometry, FMOD_VECTOR *position); -FMOD_RESULT F_API FMOD_Geometry_SetScale (FMOD_GEOMETRY *geometry, const FMOD_VECTOR *scale); -FMOD_RESULT F_API FMOD_Geometry_GetScale (FMOD_GEOMETRY *geometry, FMOD_VECTOR *scale); -FMOD_RESULT F_API FMOD_Geometry_Save (FMOD_GEOMETRY *geometry, void *data, int *datasize); - -/* - Userdata set/get. -*/ - -FMOD_RESULT F_API FMOD_Geometry_SetUserData (FMOD_GEOMETRY *geometry, void *userdata); -FMOD_RESULT F_API FMOD_Geometry_GetUserData (FMOD_GEOMETRY *geometry, void **userdata); - -/* - 'Reverb3D' API -*/ - -FMOD_RESULT F_API FMOD_Reverb3D_Release (FMOD_REVERB3D *reverb3d); - -/* - Reverb manipulation. -*/ - -FMOD_RESULT F_API FMOD_Reverb3D_Set3DAttributes (FMOD_REVERB3D *reverb3d, const FMOD_VECTOR *position, float mindistance, float maxdistance); -FMOD_RESULT F_API FMOD_Reverb3D_Get3DAttributes (FMOD_REVERB3D *reverb3d, FMOD_VECTOR *position, float *mindistance, float *maxdistance); -FMOD_RESULT F_API FMOD_Reverb3D_SetProperties (FMOD_REVERB3D *reverb3d, const FMOD_REVERB_PROPERTIES *properties); -FMOD_RESULT F_API FMOD_Reverb3D_GetProperties (FMOD_REVERB3D *reverb3d, FMOD_REVERB_PROPERTIES *properties); -FMOD_RESULT F_API FMOD_Reverb3D_SetActive (FMOD_REVERB3D *reverb3d, FMOD_BOOL active); -FMOD_RESULT F_API FMOD_Reverb3D_GetActive (FMOD_REVERB3D *reverb3d, FMOD_BOOL *active); - -/* - Userdata set/get. -*/ - -FMOD_RESULT F_API FMOD_Reverb3D_SetUserData (FMOD_REVERB3D *reverb3d, void *userdata); -FMOD_RESULT F_API FMOD_Reverb3D_GetUserData (FMOD_REVERB3D *reverb3d, void **userdata); - -#ifdef __cplusplus -} -#endif - -#endif /* _FMOD_H */ diff --git a/engine/fmodcore/inc/fmod.hpp b/engine/fmodcore/inc/fmod.hpp deleted file mode 100644 index d599e01..0000000 --- a/engine/fmodcore/inc/fmod.hpp +++ /dev/null @@ -1,604 +0,0 @@ -/* ======================================================================================== */ -/* FMOD Core API - C++ header file. */ -/* Copyright (c), Firelight Technologies Pty, Ltd. 2004-2021. */ -/* */ -/* Use this header in conjunction with fmod_common.h (which contains all the constants / */ -/* callbacks) to develop using the C++ language. */ -/* */ -/* For more detail visit: */ -/* https://fmod.com/resources/documentation-api?version=2.0&page=core-api.html */ -/* ======================================================================================== */ -#ifndef _FMOD_HPP -#define _FMOD_HPP - -#include "fmod_common.h" -#include "fmod.h" - -/* - FMOD Namespace -*/ -namespace FMOD -{ - class System; - class Sound; - class ChannelControl; - class Channel; - class ChannelGroup; - class SoundGroup; - class DSP; - class DSPConnection; - class Geometry; - class Reverb3D; - - /* - FMOD global system functions (optional). - */ - inline FMOD_RESULT Memory_Initialize (void *poolmem, int poollen, FMOD_MEMORY_ALLOC_CALLBACK useralloc, FMOD_MEMORY_REALLOC_CALLBACK userrealloc, FMOD_MEMORY_FREE_CALLBACK userfree, FMOD_MEMORY_TYPE memtypeflags = FMOD_MEMORY_ALL) { return FMOD_Memory_Initialize(poolmem, poollen, useralloc, userrealloc, userfree, memtypeflags); } - inline FMOD_RESULT Memory_GetStats (int *currentalloced, int *maxalloced, bool blocking = true) { return FMOD_Memory_GetStats(currentalloced, maxalloced, blocking); } - inline FMOD_RESULT Debug_Initialize (FMOD_DEBUG_FLAGS flags, FMOD_DEBUG_MODE mode = FMOD_DEBUG_MODE_TTY, FMOD_DEBUG_CALLBACK callback = 0, const char *filename = 0) { return FMOD_Debug_Initialize(flags, mode, callback, filename); } - inline FMOD_RESULT File_SetDiskBusy (int busy) { return FMOD_File_SetDiskBusy(busy); } - inline FMOD_RESULT File_GetDiskBusy (int *busy) { return FMOD_File_GetDiskBusy(busy); } - - /* - FMOD System factory functions. - */ - inline FMOD_RESULT System_Create (System **system) { return FMOD_System_Create((FMOD_SYSTEM **)system); } - - /* - 'System' API - */ - class System - { - private: - - // Constructor made private so user cannot statically instance a System class. System_Create must be used. - System(); - System(const System &); - - public: - - FMOD_RESULT F_API release (); - - // Setup functions. - FMOD_RESULT F_API setOutput (FMOD_OUTPUTTYPE output); - FMOD_RESULT F_API getOutput (FMOD_OUTPUTTYPE *output); - FMOD_RESULT F_API getNumDrivers (int *numdrivers); - FMOD_RESULT F_API getDriverInfo (int id, char *name, int namelen, FMOD_GUID *guid, int *systemrate, FMOD_SPEAKERMODE *speakermode, int *speakermodechannels); - FMOD_RESULT F_API setDriver (int driver); - FMOD_RESULT F_API getDriver (int *driver); - FMOD_RESULT F_API setSoftwareChannels (int numsoftwarechannels); - FMOD_RESULT F_API getSoftwareChannels (int *numsoftwarechannels); - FMOD_RESULT F_API setSoftwareFormat (int samplerate, FMOD_SPEAKERMODE speakermode, int numrawspeakers); - FMOD_RESULT F_API getSoftwareFormat (int *samplerate, FMOD_SPEAKERMODE *speakermode, int *numrawspeakers); - FMOD_RESULT F_API setDSPBufferSize (unsigned int bufferlength, int numbuffers); - FMOD_RESULT F_API getDSPBufferSize (unsigned int *bufferlength, int *numbuffers); - FMOD_RESULT F_API setFileSystem (FMOD_FILE_OPEN_CALLBACK useropen, FMOD_FILE_CLOSE_CALLBACK userclose, FMOD_FILE_READ_CALLBACK userread, FMOD_FILE_SEEK_CALLBACK userseek, FMOD_FILE_ASYNCREAD_CALLBACK userasyncread, FMOD_FILE_ASYNCCANCEL_CALLBACK userasynccancel, int blockalign); - FMOD_RESULT F_API attachFileSystem (FMOD_FILE_OPEN_CALLBACK useropen, FMOD_FILE_CLOSE_CALLBACK userclose, FMOD_FILE_READ_CALLBACK userread, FMOD_FILE_SEEK_CALLBACK userseek); - FMOD_RESULT F_API setAdvancedSettings (FMOD_ADVANCEDSETTINGS *settings); - FMOD_RESULT F_API getAdvancedSettings (FMOD_ADVANCEDSETTINGS *settings); - FMOD_RESULT F_API setCallback (FMOD_SYSTEM_CALLBACK callback, FMOD_SYSTEM_CALLBACK_TYPE callbackmask = FMOD_SYSTEM_CALLBACK_ALL); - - // Plug-in support. - FMOD_RESULT F_API setPluginPath (const char *path); - FMOD_RESULT F_API loadPlugin (const char *filename, unsigned int *handle, unsigned int priority = 0); - FMOD_RESULT F_API unloadPlugin (unsigned int handle); - FMOD_RESULT F_API getNumNestedPlugins (unsigned int handle, int *count); - FMOD_RESULT F_API getNestedPlugin (unsigned int handle, int index, unsigned int *nestedhandle); - FMOD_RESULT F_API getNumPlugins (FMOD_PLUGINTYPE plugintype, int *numplugins); - FMOD_RESULT F_API getPluginHandle (FMOD_PLUGINTYPE plugintype, int index, unsigned int *handle); - FMOD_RESULT F_API getPluginInfo (unsigned int handle, FMOD_PLUGINTYPE *plugintype, char *name, int namelen, unsigned int *version); - FMOD_RESULT F_API setOutputByPlugin (unsigned int handle); - FMOD_RESULT F_API getOutputByPlugin (unsigned int *handle); - FMOD_RESULT F_API createDSPByPlugin (unsigned int handle, DSP **dsp); - FMOD_RESULT F_API getDSPInfoByPlugin (unsigned int handle, const FMOD_DSP_DESCRIPTION **description); - FMOD_RESULT F_API registerCodec (FMOD_CODEC_DESCRIPTION *description, unsigned int *handle, unsigned int priority = 0); - FMOD_RESULT F_API registerDSP (const FMOD_DSP_DESCRIPTION *description, unsigned int *handle); - FMOD_RESULT F_API registerOutput (const FMOD_OUTPUT_DESCRIPTION *description, unsigned int *handle); - - // Init/Close. - FMOD_RESULT F_API init (int maxchannels, FMOD_INITFLAGS flags, void *extradriverdata); - FMOD_RESULT F_API close (); - - // General post-init system functions. - FMOD_RESULT F_API update (); /* IMPORTANT! CALL THIS ONCE PER FRAME! */ - - FMOD_RESULT F_API setSpeakerPosition (FMOD_SPEAKER speaker, float x, float y, bool active); - FMOD_RESULT F_API getSpeakerPosition (FMOD_SPEAKER speaker, float *x, float *y, bool *active); - FMOD_RESULT F_API setStreamBufferSize (unsigned int filebuffersize, FMOD_TIMEUNIT filebuffersizetype); - FMOD_RESULT F_API getStreamBufferSize (unsigned int *filebuffersize, FMOD_TIMEUNIT *filebuffersizetype); - FMOD_RESULT F_API set3DSettings (float dopplerscale, float distancefactor, float rolloffscale); - FMOD_RESULT F_API get3DSettings (float *dopplerscale, float *distancefactor, float *rolloffscale); - FMOD_RESULT F_API set3DNumListeners (int numlisteners); - FMOD_RESULT F_API get3DNumListeners (int *numlisteners); - FMOD_RESULT F_API set3DListenerAttributes (int listener, const FMOD_VECTOR *pos, const FMOD_VECTOR *vel, const FMOD_VECTOR *forward, const FMOD_VECTOR *up); - FMOD_RESULT F_API get3DListenerAttributes (int listener, FMOD_VECTOR *pos, FMOD_VECTOR *vel, FMOD_VECTOR *forward, FMOD_VECTOR *up); - FMOD_RESULT F_API set3DRolloffCallback (FMOD_3D_ROLLOFF_CALLBACK callback); - FMOD_RESULT F_API mixerSuspend (); - FMOD_RESULT F_API mixerResume (); - FMOD_RESULT F_API getDefaultMixMatrix (FMOD_SPEAKERMODE sourcespeakermode, FMOD_SPEAKERMODE targetspeakermode, float *matrix, int matrixhop); - FMOD_RESULT F_API getSpeakerModeChannels (FMOD_SPEAKERMODE mode, int *channels); - - // System information functions. - FMOD_RESULT F_API getVersion (unsigned int *version); - FMOD_RESULT F_API getOutputHandle (void **handle); - FMOD_RESULT F_API getChannelsPlaying (int *channels, int *realchannels = 0); - FMOD_RESULT F_API getCPUUsage (float *dsp, float *stream, float *geometry, float *update, float *total); - FMOD_RESULT F_API getFileUsage (long long *sampleBytesRead, long long *streamBytesRead, long long *otherBytesRead); - - // Sound/DSP/Channel/FX creation and retrieval. - FMOD_RESULT F_API createSound (const char *name_or_data, FMOD_MODE mode, FMOD_CREATESOUNDEXINFO *exinfo, Sound **sound); - FMOD_RESULT F_API createStream (const char *name_or_data, FMOD_MODE mode, FMOD_CREATESOUNDEXINFO *exinfo, Sound **sound); - FMOD_RESULT F_API createDSP (const FMOD_DSP_DESCRIPTION *description, DSP **dsp); - FMOD_RESULT F_API createDSPByType (FMOD_DSP_TYPE type, DSP **dsp); - FMOD_RESULT F_API createChannelGroup (const char *name, ChannelGroup **channelgroup); - FMOD_RESULT F_API createSoundGroup (const char *name, SoundGroup **soundgroup); - FMOD_RESULT F_API createReverb3D (Reverb3D **reverb); - - FMOD_RESULT F_API playSound (Sound *sound, ChannelGroup *channelgroup, bool paused, Channel **channel); - FMOD_RESULT F_API playDSP (DSP *dsp, ChannelGroup *channelgroup, bool paused, Channel **channel); - FMOD_RESULT F_API getChannel (int channelid, Channel **channel); - FMOD_RESULT F_API getMasterChannelGroup (ChannelGroup **channelgroup); - FMOD_RESULT F_API getMasterSoundGroup (SoundGroup **soundgroup); - - // Routing to ports. - FMOD_RESULT F_API attachChannelGroupToPort (FMOD_PORT_TYPE portType, FMOD_PORT_INDEX portIndex, ChannelGroup *channelgroup, bool passThru = false); - FMOD_RESULT F_API detachChannelGroupFromPort (ChannelGroup *channelgroup); - - // Reverb API. - FMOD_RESULT F_API setReverbProperties (int instance, const FMOD_REVERB_PROPERTIES *prop); - FMOD_RESULT F_API getReverbProperties (int instance, FMOD_REVERB_PROPERTIES *prop); - - // System level DSP functionality. - FMOD_RESULT F_API lockDSP (); - FMOD_RESULT F_API unlockDSP (); - - // Recording API. - FMOD_RESULT F_API getRecordNumDrivers (int *numdrivers, int *numconnected); - FMOD_RESULT F_API getRecordDriverInfo (int id, char *name, int namelen, FMOD_GUID *guid, int *systemrate, FMOD_SPEAKERMODE *speakermode, int *speakermodechannels, FMOD_DRIVER_STATE *state); - FMOD_RESULT F_API getRecordPosition (int id, unsigned int *position); - FMOD_RESULT F_API recordStart (int id, Sound *sound, bool loop); - FMOD_RESULT F_API recordStop (int id); - FMOD_RESULT F_API isRecording (int id, bool *recording); - - // Geometry API. - FMOD_RESULT F_API createGeometry (int maxpolygons, int maxvertices, Geometry **geometry); - FMOD_RESULT F_API setGeometrySettings (float maxworldsize); - FMOD_RESULT F_API getGeometrySettings (float *maxworldsize); - FMOD_RESULT F_API loadGeometry (const void *data, int datasize, Geometry **geometry); - FMOD_RESULT F_API getGeometryOcclusion (const FMOD_VECTOR *listener, const FMOD_VECTOR *source, float *direct, float *reverb); - - // Network functions. - FMOD_RESULT F_API setNetworkProxy (const char *proxy); - FMOD_RESULT F_API getNetworkProxy (char *proxy, int proxylen); - FMOD_RESULT F_API setNetworkTimeout (int timeout); - FMOD_RESULT F_API getNetworkTimeout (int *timeout); - - // Userdata set/get. - FMOD_RESULT F_API setUserData (void *userdata); - FMOD_RESULT F_API getUserData (void **userdata); - }; - - /* - 'Sound' API - */ - class Sound - { - private: - - // Constructor made private so user cannot statically instance a Sound class. Appropriate Sound creation or retrieval function must be used. - Sound(); - Sound(const Sound &); - - public: - - FMOD_RESULT F_API release (); - FMOD_RESULT F_API getSystemObject (System **system); - - // Standard sound manipulation functions. - FMOD_RESULT F_API lock (unsigned int offset, unsigned int length, void **ptr1, void **ptr2, unsigned int *len1, unsigned int *len2); - FMOD_RESULT F_API unlock (void *ptr1, void *ptr2, unsigned int len1, unsigned int len2); - FMOD_RESULT F_API setDefaults (float frequency, int priority); - FMOD_RESULT F_API getDefaults (float *frequency, int *priority); - FMOD_RESULT F_API set3DMinMaxDistance (float min, float max); - FMOD_RESULT F_API get3DMinMaxDistance (float *min, float *max); - FMOD_RESULT F_API set3DConeSettings (float insideconeangle, float outsideconeangle, float outsidevolume); - FMOD_RESULT F_API get3DConeSettings (float *insideconeangle, float *outsideconeangle, float *outsidevolume); - FMOD_RESULT F_API set3DCustomRolloff (FMOD_VECTOR *points, int numpoints); - FMOD_RESULT F_API get3DCustomRolloff (FMOD_VECTOR **points, int *numpoints); - FMOD_RESULT F_API getSubSound (int index, Sound **subsound); - FMOD_RESULT F_API getSubSoundParent (Sound **parentsound); - FMOD_RESULT F_API getName (char *name, int namelen); - FMOD_RESULT F_API getLength (unsigned int *length, FMOD_TIMEUNIT lengthtype); - FMOD_RESULT F_API getFormat (FMOD_SOUND_TYPE *type, FMOD_SOUND_FORMAT *format, int *channels, int *bits); - FMOD_RESULT F_API getNumSubSounds (int *numsubsounds); - FMOD_RESULT F_API getNumTags (int *numtags, int *numtagsupdated); - FMOD_RESULT F_API getTag (const char *name, int index, FMOD_TAG *tag); - FMOD_RESULT F_API getOpenState (FMOD_OPENSTATE *openstate, unsigned int *percentbuffered, bool *starving, bool *diskbusy); - FMOD_RESULT F_API readData (void *buffer, unsigned int length, unsigned int *read); - FMOD_RESULT F_API seekData (unsigned int pcm); - - FMOD_RESULT F_API setSoundGroup (SoundGroup *soundgroup); - FMOD_RESULT F_API getSoundGroup (SoundGroup **soundgroup); - - // Synchronization point API. These points can come from markers embedded in wav files, and can also generate channel callbacks. - FMOD_RESULT F_API getNumSyncPoints (int *numsyncpoints); - FMOD_RESULT F_API getSyncPoint (int index, FMOD_SYNCPOINT **point); - FMOD_RESULT F_API getSyncPointInfo (FMOD_SYNCPOINT *point, char *name, int namelen, unsigned int *offset, FMOD_TIMEUNIT offsettype); - FMOD_RESULT F_API addSyncPoint (unsigned int offset, FMOD_TIMEUNIT offsettype, const char *name, FMOD_SYNCPOINT **point); - FMOD_RESULT F_API deleteSyncPoint (FMOD_SYNCPOINT *point); - - // Functions also in Channel class but here they are the 'default' to save having to change it in Channel all the time. - FMOD_RESULT F_API setMode (FMOD_MODE mode); - FMOD_RESULT F_API getMode (FMOD_MODE *mode); - FMOD_RESULT F_API setLoopCount (int loopcount); - FMOD_RESULT F_API getLoopCount (int *loopcount); - FMOD_RESULT F_API setLoopPoints (unsigned int loopstart, FMOD_TIMEUNIT loopstarttype, unsigned int loopend, FMOD_TIMEUNIT loopendtype); - FMOD_RESULT F_API getLoopPoints (unsigned int *loopstart, FMOD_TIMEUNIT loopstarttype, unsigned int *loopend, FMOD_TIMEUNIT loopendtype); - - // For MOD/S3M/XM/IT/MID sequenced formats only. - FMOD_RESULT F_API getMusicNumChannels (int *numchannels); - FMOD_RESULT F_API setMusicChannelVolume (int channel, float volume); - FMOD_RESULT F_API getMusicChannelVolume (int channel, float *volume); - FMOD_RESULT F_API setMusicSpeed (float speed); - FMOD_RESULT F_API getMusicSpeed (float *speed); - - // Userdata set/get. - FMOD_RESULT F_API setUserData (void *userdata); - FMOD_RESULT F_API getUserData (void **userdata); - }; - - - /* - 'ChannelControl API'. This is a base class for Channel and ChannelGroup so they can share the same functionality. This cannot be used or instansiated explicitly. - */ - class ChannelControl - { - private: - - // Constructor made private so user cannot statically instance a Control class. - ChannelControl(); - ChannelControl(const ChannelControl &); - - public: - - FMOD_RESULT F_API getSystemObject (System **system); - - // General control functionality for Channels and ChannelGroups. - FMOD_RESULT F_API stop (); - FMOD_RESULT F_API setPaused (bool paused); - FMOD_RESULT F_API getPaused (bool *paused); - FMOD_RESULT F_API setVolume (float volume); - FMOD_RESULT F_API getVolume (float *volume); - FMOD_RESULT F_API setVolumeRamp (bool ramp); - FMOD_RESULT F_API getVolumeRamp (bool *ramp); - FMOD_RESULT F_API getAudibility (float *audibility); - FMOD_RESULT F_API setPitch (float pitch); - FMOD_RESULT F_API getPitch (float *pitch); - FMOD_RESULT F_API setMute (bool mute); - FMOD_RESULT F_API getMute (bool *mute); - FMOD_RESULT F_API setReverbProperties (int instance, float wet); - FMOD_RESULT F_API getReverbProperties (int instance, float *wet); - FMOD_RESULT F_API setLowPassGain (float gain); - FMOD_RESULT F_API getLowPassGain (float *gain); - FMOD_RESULT F_API setMode (FMOD_MODE mode); - FMOD_RESULT F_API getMode (FMOD_MODE *mode); - FMOD_RESULT F_API setCallback (FMOD_CHANNELCONTROL_CALLBACK callback); - FMOD_RESULT F_API isPlaying (bool *isplaying); - - // Panning and level adjustment. - // Note all 'set' functions alter a final matrix, this is why the only get function is getMixMatrix, to avoid other get functions returning incorrect/obsolete values. - FMOD_RESULT F_API setPan (float pan); - FMOD_RESULT F_API setMixLevelsOutput (float frontleft, float frontright, float center, float lfe, float surroundleft, float surroundright, float backleft, float backright); - FMOD_RESULT F_API setMixLevelsInput (float *levels, int numlevels); - FMOD_RESULT F_API setMixMatrix (float *matrix, int outchannels, int inchannels, int inchannel_hop = 0); - FMOD_RESULT F_API getMixMatrix (float *matrix, int *outchannels, int *inchannels, int inchannel_hop = 0); - - // Clock based functionality. - FMOD_RESULT F_API getDSPClock (unsigned long long *dspclock, unsigned long long *parentclock); - FMOD_RESULT F_API setDelay (unsigned long long dspclock_start, unsigned long long dspclock_end, bool stopchannels = true); - FMOD_RESULT F_API getDelay (unsigned long long *dspclock_start, unsigned long long *dspclock_end, bool *stopchannels = 0); - FMOD_RESULT F_API addFadePoint (unsigned long long dspclock, float volume); - FMOD_RESULT F_API setFadePointRamp (unsigned long long dspclock, float volume); - FMOD_RESULT F_API removeFadePoints (unsigned long long dspclock_start, unsigned long long dspclock_end); - FMOD_RESULT F_API getFadePoints (unsigned int *numpoints, unsigned long long *point_dspclock, float *point_volume); - - // DSP effects. - FMOD_RESULT F_API getDSP (int index, DSP **dsp); - FMOD_RESULT F_API addDSP (int index, DSP *dsp); - FMOD_RESULT F_API removeDSP (DSP *dsp); - FMOD_RESULT F_API getNumDSPs (int *numdsps); - FMOD_RESULT F_API setDSPIndex (DSP *dsp, int index); - FMOD_RESULT F_API getDSPIndex (DSP *dsp, int *index); - - // 3D functionality. - FMOD_RESULT F_API set3DAttributes (const FMOD_VECTOR *pos, const FMOD_VECTOR *vel); - FMOD_RESULT F_API get3DAttributes (FMOD_VECTOR *pos, FMOD_VECTOR *vel); - FMOD_RESULT F_API set3DMinMaxDistance (float mindistance, float maxdistance); - FMOD_RESULT F_API get3DMinMaxDistance (float *mindistance, float *maxdistance); - FMOD_RESULT F_API set3DConeSettings (float insideconeangle, float outsideconeangle, float outsidevolume); - FMOD_RESULT F_API get3DConeSettings (float *insideconeangle, float *outsideconeangle, float *outsidevolume); - FMOD_RESULT F_API set3DConeOrientation (FMOD_VECTOR *orientation); - FMOD_RESULT F_API get3DConeOrientation (FMOD_VECTOR *orientation); - FMOD_RESULT F_API set3DCustomRolloff (FMOD_VECTOR *points, int numpoints); - FMOD_RESULT F_API get3DCustomRolloff (FMOD_VECTOR **points, int *numpoints); - FMOD_RESULT F_API set3DOcclusion (float directocclusion, float reverbocclusion); - FMOD_RESULT F_API get3DOcclusion (float *directocclusion, float *reverbocclusion); - FMOD_RESULT F_API set3DSpread (float angle); - FMOD_RESULT F_API get3DSpread (float *angle); - FMOD_RESULT F_API set3DLevel (float level); - FMOD_RESULT F_API get3DLevel (float *level); - FMOD_RESULT F_API set3DDopplerLevel (float level); - FMOD_RESULT F_API get3DDopplerLevel (float *level); - FMOD_RESULT F_API set3DDistanceFilter (bool custom, float customLevel, float centerFreq); - FMOD_RESULT F_API get3DDistanceFilter (bool *custom, float *customLevel, float *centerFreq); - - // Userdata set/get. - FMOD_RESULT F_API setUserData (void *userdata); - FMOD_RESULT F_API getUserData (void **userdata); - }; - - /* - 'Channel' API. - */ - class Channel : public ChannelControl - { - private: - - // Constructor made private so user cannot statically instance a Channel class. Appropriate Channel creation or retrieval function must be used. - Channel(); - Channel(const Channel &); - - public: - - // Channel specific control functionality. - FMOD_RESULT F_API setFrequency (float frequency); - FMOD_RESULT F_API getFrequency (float *frequency); - FMOD_RESULT F_API setPriority (int priority); - FMOD_RESULT F_API getPriority (int *priority); - FMOD_RESULT F_API setPosition (unsigned int position, FMOD_TIMEUNIT postype); - FMOD_RESULT F_API getPosition (unsigned int *position, FMOD_TIMEUNIT postype); - FMOD_RESULT F_API setChannelGroup (ChannelGroup *channelgroup); - FMOD_RESULT F_API getChannelGroup (ChannelGroup **channelgroup); - FMOD_RESULT F_API setLoopCount (int loopcount); - FMOD_RESULT F_API getLoopCount (int *loopcount); - FMOD_RESULT F_API setLoopPoints (unsigned int loopstart, FMOD_TIMEUNIT loopstarttype, unsigned int loopend, FMOD_TIMEUNIT loopendtype); - FMOD_RESULT F_API getLoopPoints (unsigned int *loopstart, FMOD_TIMEUNIT loopstarttype, unsigned int *loopend, FMOD_TIMEUNIT loopendtype); - - // Information only functions. - FMOD_RESULT F_API isVirtual (bool *isvirtual); - FMOD_RESULT F_API getCurrentSound (Sound **sound); - FMOD_RESULT F_API getIndex (int *index); - }; - - /* - 'ChannelGroup' API - */ - class ChannelGroup : public ChannelControl - { - private: - - // Constructor made private so user cannot statically instance a ChannelGroup class. Appropriate ChannelGroup creation or retrieval function must be used. - ChannelGroup(); - ChannelGroup(const ChannelGroup &); - - public: - - FMOD_RESULT F_API release (); - - // Nested channel groups. - FMOD_RESULT F_API addGroup (ChannelGroup *group, bool propagatedspclock = true, DSPConnection **connection = 0); - FMOD_RESULT F_API getNumGroups (int *numgroups); - FMOD_RESULT F_API getGroup (int index, ChannelGroup **group); - FMOD_RESULT F_API getParentGroup (ChannelGroup **group); - - // Information only functions. - FMOD_RESULT F_API getName (char *name, int namelen); - FMOD_RESULT F_API getNumChannels (int *numchannels); - FMOD_RESULT F_API getChannel (int index, Channel **channel); - }; - - /* - 'SoundGroup' API - */ - class SoundGroup - { - private: - - // Constructor made private so user cannot statically instance a SoundGroup class. Appropriate SoundGroup creation or retrieval function must be used. - SoundGroup(); - SoundGroup(const SoundGroup &); - - public: - - FMOD_RESULT F_API release (); - FMOD_RESULT F_API getSystemObject (System **system); - - // SoundGroup control functions. - FMOD_RESULT F_API setMaxAudible (int maxaudible); - FMOD_RESULT F_API getMaxAudible (int *maxaudible); - FMOD_RESULT F_API setMaxAudibleBehavior (FMOD_SOUNDGROUP_BEHAVIOR behavior); - FMOD_RESULT F_API getMaxAudibleBehavior (FMOD_SOUNDGROUP_BEHAVIOR *behavior); - FMOD_RESULT F_API setMuteFadeSpeed (float speed); - FMOD_RESULT F_API getMuteFadeSpeed (float *speed); - FMOD_RESULT F_API setVolume (float volume); - FMOD_RESULT F_API getVolume (float *volume); - FMOD_RESULT F_API stop (); - - // Information only functions. - FMOD_RESULT F_API getName (char *name, int namelen); - FMOD_RESULT F_API getNumSounds (int *numsounds); - FMOD_RESULT F_API getSound (int index, Sound **sound); - FMOD_RESULT F_API getNumPlaying (int *numplaying); - - // Userdata set/get. - FMOD_RESULT F_API setUserData (void *userdata); - FMOD_RESULT F_API getUserData (void **userdata); - }; - - /* - 'DSP' API - */ - class DSP - { - private: - - // Constructor made private so user cannot statically instance a DSP class. Appropriate DSP creation or retrieval function must be used. - DSP(); - DSP(const DSP &); - - public: - - FMOD_RESULT F_API release (); - FMOD_RESULT F_API getSystemObject (System **system); - - // Connection / disconnection / input and output enumeration. - FMOD_RESULT F_API addInput (DSP *input, DSPConnection **connection = 0, FMOD_DSPCONNECTION_TYPE type = FMOD_DSPCONNECTION_TYPE_STANDARD); - FMOD_RESULT F_API disconnectFrom (DSP *target, DSPConnection *connection = 0); - FMOD_RESULT F_API disconnectAll (bool inputs, bool outputs); - FMOD_RESULT F_API getNumInputs (int *numinputs); - FMOD_RESULT F_API getNumOutputs (int *numoutputs); - FMOD_RESULT F_API getInput (int index, DSP **input, DSPConnection **inputconnection); - FMOD_RESULT F_API getOutput (int index, DSP **output, DSPConnection **outputconnection); - - // DSP unit control. - FMOD_RESULT F_API setActive (bool active); - FMOD_RESULT F_API getActive (bool *active); - FMOD_RESULT F_API setBypass (bool bypass); - FMOD_RESULT F_API getBypass (bool *bypass); - FMOD_RESULT F_API setWetDryMix (float prewet, float postwet, float dry); - FMOD_RESULT F_API getWetDryMix (float *prewet, float *postwet, float *dry); - FMOD_RESULT F_API setChannelFormat (FMOD_CHANNELMASK channelmask, int numchannels, FMOD_SPEAKERMODE source_speakermode); - FMOD_RESULT F_API getChannelFormat (FMOD_CHANNELMASK *channelmask, int *numchannels, FMOD_SPEAKERMODE *source_speakermode); - FMOD_RESULT F_API getOutputChannelFormat (FMOD_CHANNELMASK inmask, int inchannels, FMOD_SPEAKERMODE inspeakermode, FMOD_CHANNELMASK *outmask, int *outchannels, FMOD_SPEAKERMODE *outspeakermode); - FMOD_RESULT F_API reset (); - - // DSP parameter control. - FMOD_RESULT F_API setParameterFloat (int index, float value); - FMOD_RESULT F_API setParameterInt (int index, int value); - FMOD_RESULT F_API setParameterBool (int index, bool value); - FMOD_RESULT F_API setParameterData (int index, void *data, unsigned int length); - FMOD_RESULT F_API getParameterFloat (int index, float *value, char *valuestr, int valuestrlen); - FMOD_RESULT F_API getParameterInt (int index, int *value, char *valuestr, int valuestrlen); - FMOD_RESULT F_API getParameterBool (int index, bool *value, char *valuestr, int valuestrlen); - FMOD_RESULT F_API getParameterData (int index, void **data, unsigned int *length, char *valuestr, int valuestrlen); - FMOD_RESULT F_API getNumParameters (int *numparams); - FMOD_RESULT F_API getParameterInfo (int index, FMOD_DSP_PARAMETER_DESC **desc); - FMOD_RESULT F_API getDataParameterIndex (int datatype, int *index); - FMOD_RESULT F_API showConfigDialog (void *hwnd, bool show); - - // DSP attributes. - FMOD_RESULT F_API getInfo (char *name, unsigned int *version, int *channels, int *configwidth, int *configheight); - FMOD_RESULT F_API getType (FMOD_DSP_TYPE *type); - FMOD_RESULT F_API getIdle (bool *idle); - - // Userdata set/get. - FMOD_RESULT F_API setUserData (void *userdata); - FMOD_RESULT F_API getUserData (void **userdata); - - // Metering. - FMOD_RESULT F_API setMeteringEnabled (bool inputEnabled, bool outputEnabled); - FMOD_RESULT F_API getMeteringEnabled (bool *inputEnabled, bool *outputEnabled); - FMOD_RESULT F_API getMeteringInfo (FMOD_DSP_METERING_INFO *inputInfo, FMOD_DSP_METERING_INFO *outputInfo); - FMOD_RESULT F_API getCPUUsage (unsigned int *exclusive, unsigned int *inclusive); - }; - - - /* - 'DSPConnection' API - */ - class DSPConnection - { - private: - - // Constructor made private so user cannot statically instance a DSPConnection class. Appropriate DSPConnection creation or retrieval function must be used. - DSPConnection(); - DSPConnection(const DSPConnection &); - - public: - - FMOD_RESULT F_API getInput (DSP **input); - FMOD_RESULT F_API getOutput (DSP **output); - FMOD_RESULT F_API setMix (float volume); - FMOD_RESULT F_API getMix (float *volume); - FMOD_RESULT F_API setMixMatrix (float *matrix, int outchannels, int inchannels, int inchannel_hop = 0); - FMOD_RESULT F_API getMixMatrix (float *matrix, int *outchannels, int *inchannels, int inchannel_hop = 0); - FMOD_RESULT F_API getType (FMOD_DSPCONNECTION_TYPE *type); - - // Userdata set/get. - FMOD_RESULT F_API setUserData (void *userdata); - FMOD_RESULT F_API getUserData (void **userdata); - }; - - - /* - 'Geometry' API - */ - class Geometry - { - private: - - // Constructor made private so user cannot statically instance a Geometry class. Appropriate Geometry creation or retrieval function must be used. - Geometry(); - Geometry(const Geometry &); - - public: - - FMOD_RESULT F_API release (); - - // Polygon manipulation. - FMOD_RESULT F_API addPolygon (float directocclusion, float reverbocclusion, bool doublesided, int numvertices, const FMOD_VECTOR *vertices, int *polygonindex); - FMOD_RESULT F_API getNumPolygons (int *numpolygons); - FMOD_RESULT F_API getMaxPolygons (int *maxpolygons, int *maxvertices); - FMOD_RESULT F_API getPolygonNumVertices (int index, int *numvertices); - FMOD_RESULT F_API setPolygonVertex (int index, int vertexindex, const FMOD_VECTOR *vertex); - FMOD_RESULT F_API getPolygonVertex (int index, int vertexindex, FMOD_VECTOR *vertex); - FMOD_RESULT F_API setPolygonAttributes (int index, float directocclusion, float reverbocclusion, bool doublesided); - FMOD_RESULT F_API getPolygonAttributes (int index, float *directocclusion, float *reverbocclusion, bool *doublesided); - - // Object manipulation. - FMOD_RESULT F_API setActive (bool active); - FMOD_RESULT F_API getActive (bool *active); - FMOD_RESULT F_API setRotation (const FMOD_VECTOR *forward, const FMOD_VECTOR *up); - FMOD_RESULT F_API getRotation (FMOD_VECTOR *forward, FMOD_VECTOR *up); - FMOD_RESULT F_API setPosition (const FMOD_VECTOR *position); - FMOD_RESULT F_API getPosition (FMOD_VECTOR *position); - FMOD_RESULT F_API setScale (const FMOD_VECTOR *scale); - FMOD_RESULT F_API getScale (FMOD_VECTOR *scale); - FMOD_RESULT F_API save (void *data, int *datasize); - - // Userdata set/get. - FMOD_RESULT F_API setUserData (void *userdata); - FMOD_RESULT F_API getUserData (void **userdata); - }; - - - /* - 'Reverb' API - */ - class Reverb3D - { - private: - - // Constructor made private so user cannot statically instance a Reverb3D class. Appropriate Reverb creation or retrieval function must be used. - Reverb3D(); - Reverb3D(const Reverb3D &); - - public: - - FMOD_RESULT F_API release (); - - // Reverb manipulation. - FMOD_RESULT F_API set3DAttributes (const FMOD_VECTOR *position, float mindistance, float maxdistance); - FMOD_RESULT F_API get3DAttributes (FMOD_VECTOR *position, float *mindistance,float *maxdistance); - FMOD_RESULT F_API setProperties (const FMOD_REVERB_PROPERTIES *properties); - FMOD_RESULT F_API getProperties (FMOD_REVERB_PROPERTIES *properties); - FMOD_RESULT F_API setActive (bool active); - FMOD_RESULT F_API getActive (bool *active); - - // Userdata set/get. - FMOD_RESULT F_API setUserData (void *userdata); - FMOD_RESULT F_API getUserData (void **userdata); - }; -} - -#endif diff --git a/engine/fmodcore/inc/fmod_codec.h b/engine/fmodcore/inc/fmod_codec.h deleted file mode 100644 index 252de40..0000000 --- a/engine/fmodcore/inc/fmod_codec.h +++ /dev/null @@ -1,97 +0,0 @@ -/* ======================================================================================== */ -/* FMOD Core API - Codec development header file. */ -/* Copyright (c), Firelight Technologies Pty, Ltd. 2004-2021. */ -/* */ -/* Use this header if you are wanting to develop your own file format plugin to use with */ -/* FMOD's codec system. With this header you can make your own fileformat plugin that FMOD */ -/* can register and use. See the documentation and examples on how to make a working */ -/* plugin. */ -/* */ -/* For more detail visit: */ -/* https://fmod.com/resources/documentation-api?version=2.0&page=core-api.html */ -/* ======================================================================================== */ -#ifndef _FMOD_CODEC_H -#define _FMOD_CODEC_H - -/* - Codec types -*/ -typedef struct FMOD_CODEC_STATE FMOD_CODEC_STATE; -typedef struct FMOD_CODEC_WAVEFORMAT FMOD_CODEC_WAVEFORMAT; - -/* - Codec constants -*/ -#define FMOD_CODEC_WAVEFORMAT_VERSION 3 - -/* - Codec callbacks -*/ -typedef FMOD_RESULT (F_CALLBACK *FMOD_CODEC_OPEN_CALLBACK) (FMOD_CODEC_STATE *codec_state, FMOD_MODE usermode, FMOD_CREATESOUNDEXINFO *userexinfo); -typedef FMOD_RESULT (F_CALLBACK *FMOD_CODEC_CLOSE_CALLBACK) (FMOD_CODEC_STATE *codec_state); -typedef FMOD_RESULT (F_CALLBACK *FMOD_CODEC_READ_CALLBACK) (FMOD_CODEC_STATE *codec_state, void *buffer, unsigned int samples_in, unsigned int *samples_out); -typedef FMOD_RESULT (F_CALLBACK *FMOD_CODEC_GETLENGTH_CALLBACK) (FMOD_CODEC_STATE *codec_state, unsigned int *length, FMOD_TIMEUNIT lengthtype); -typedef FMOD_RESULT (F_CALLBACK *FMOD_CODEC_SETPOSITION_CALLBACK) (FMOD_CODEC_STATE *codec_state, int subsound, unsigned int position, FMOD_TIMEUNIT postype); -typedef FMOD_RESULT (F_CALLBACK *FMOD_CODEC_GETPOSITION_CALLBACK) (FMOD_CODEC_STATE *codec_state, unsigned int *position, FMOD_TIMEUNIT postype); -typedef FMOD_RESULT (F_CALLBACK *FMOD_CODEC_SOUNDCREATE_CALLBACK) (FMOD_CODEC_STATE *codec_state, int subsound, FMOD_SOUND *sound); -typedef FMOD_RESULT (F_CALLBACK *FMOD_CODEC_GETWAVEFORMAT_CALLBACK)(FMOD_CODEC_STATE *codec_state, int index, FMOD_CODEC_WAVEFORMAT *waveformat); - -/* - Codec functions -*/ -typedef FMOD_RESULT (F_CALLBACK *FMOD_CODEC_METADATA_FUNC) (FMOD_CODEC_STATE *codec_state, FMOD_TAGTYPE tagtype, char *name, void *data, unsigned int datalen, FMOD_TAGDATATYPE datatype, int unique); - -/* - Codec structures -*/ -typedef struct FMOD_CODEC_DESCRIPTION -{ - const char *name; - unsigned int version; - int defaultasstream; - FMOD_TIMEUNIT timeunits; - FMOD_CODEC_OPEN_CALLBACK open; - FMOD_CODEC_CLOSE_CALLBACK close; - FMOD_CODEC_READ_CALLBACK read; - FMOD_CODEC_GETLENGTH_CALLBACK getlength; - FMOD_CODEC_SETPOSITION_CALLBACK setposition; - FMOD_CODEC_GETPOSITION_CALLBACK getposition; - FMOD_CODEC_SOUNDCREATE_CALLBACK soundcreate; - FMOD_CODEC_GETWAVEFORMAT_CALLBACK getwaveformat; -} FMOD_CODEC_DESCRIPTION; - -struct FMOD_CODEC_WAVEFORMAT -{ - const char* name; - FMOD_SOUND_FORMAT format; - int channels; - int frequency; - unsigned int lengthbytes; - unsigned int lengthpcm; - unsigned int pcmblocksize; - int loopstart; - int loopend; - FMOD_MODE mode; - FMOD_CHANNELMASK channelmask; - FMOD_CHANNELORDER channelorder; - float peakvolume; -}; - -struct FMOD_CODEC_STATE -{ - int numsubsounds; - FMOD_CODEC_WAVEFORMAT *waveformat; - void *plugindata; - - void *filehandle; - unsigned int filesize; - FMOD_FILE_READ_CALLBACK fileread; - FMOD_FILE_SEEK_CALLBACK fileseek; - FMOD_CODEC_METADATA_FUNC metadata; - - int waveformatversion; -}; - -#endif - - diff --git a/engine/fmodcore/inc/fmod_common.h b/engine/fmodcore/inc/fmod_common.h deleted file mode 100644 index aef3ecd..0000000 --- a/engine/fmodcore/inc/fmod_common.h +++ /dev/null @@ -1,752 +0,0 @@ -/* ======================================================================================== */ -/* FMOD Core API - Common C/C++ header file. */ -/* Copyright (c), Firelight Technologies Pty, Ltd. 2004-2021. */ -/* */ -/* This header is included by fmod.hpp (C++ interface) and fmod.h (C interface) */ -/* */ -/* For more detail visit: */ -/* https://fmod.com/resources/documentation-api?version=2.0&page=core-api-common.html */ -/* ======================================================================================== */ -#ifndef _FMOD_COMMON_H -#define _FMOD_COMMON_H - -/* - Library import helpers -*/ -#if defined(_WIN32) || defined(__CYGWIN__) - #define F_CALL __stdcall -#else - #define F_CALL -#endif - -#if defined(_WIN32) || defined(__CYGWIN__) || defined(__ORBIS__) || defined(F_USE_DECLSPEC) - #define F_EXPORT __declspec(dllexport) -#elif defined(__APPLE__) || defined(__ANDROID__) || defined(__linux__) || defined(F_USE_ATTRIBUTE) - #define F_EXPORT __attribute__((visibility("default"))) -#else - #define F_EXPORT -#endif - -#ifdef DLL_EXPORTS - #define F_API F_EXPORT F_CALL -#else - #define F_API F_CALL -#endif - -#define F_CALLBACK F_CALL - -/* - FMOD core types -*/ -typedef int FMOD_BOOL; -typedef struct FMOD_SYSTEM FMOD_SYSTEM; -typedef struct FMOD_SOUND FMOD_SOUND; -typedef struct FMOD_CHANNELCONTROL FMOD_CHANNELCONTROL; -typedef struct FMOD_CHANNEL FMOD_CHANNEL; -typedef struct FMOD_CHANNELGROUP FMOD_CHANNELGROUP; -typedef struct FMOD_SOUNDGROUP FMOD_SOUNDGROUP; -typedef struct FMOD_REVERB3D FMOD_REVERB3D; -typedef struct FMOD_DSP FMOD_DSP; -typedef struct FMOD_DSPCONNECTION FMOD_DSPCONNECTION; -typedef struct FMOD_POLYGON FMOD_POLYGON; -typedef struct FMOD_GEOMETRY FMOD_GEOMETRY; -typedef struct FMOD_SYNCPOINT FMOD_SYNCPOINT; -typedef struct FMOD_ASYNCREADINFO FMOD_ASYNCREADINFO; -typedef unsigned int FMOD_PORT_TYPE; -typedef unsigned long long FMOD_PORT_INDEX; - -/* - FMOD constants -*/ -#define FMOD_VERSION 0x00020016 /* 0xaaaabbcc -> aaaa = product version, bb = major version, cc = minor version.*/ - -typedef unsigned int FMOD_DEBUG_FLAGS; -#define FMOD_DEBUG_LEVEL_NONE 0x00000000 -#define FMOD_DEBUG_LEVEL_ERROR 0x00000001 -#define FMOD_DEBUG_LEVEL_WARNING 0x00000002 -#define FMOD_DEBUG_LEVEL_LOG 0x00000004 -#define FMOD_DEBUG_TYPE_MEMORY 0x00000100 -#define FMOD_DEBUG_TYPE_FILE 0x00000200 -#define FMOD_DEBUG_TYPE_CODEC 0x00000400 -#define FMOD_DEBUG_TYPE_TRACE 0x00000800 -#define FMOD_DEBUG_DISPLAY_TIMESTAMPS 0x00010000 -#define FMOD_DEBUG_DISPLAY_LINENUMBERS 0x00020000 -#define FMOD_DEBUG_DISPLAY_THREAD 0x00040000 - -typedef unsigned int FMOD_MEMORY_TYPE; -#define FMOD_MEMORY_NORMAL 0x00000000 -#define FMOD_MEMORY_STREAM_FILE 0x00000001 -#define FMOD_MEMORY_STREAM_DECODE 0x00000002 -#define FMOD_MEMORY_SAMPLEDATA 0x00000004 -#define FMOD_MEMORY_DSP_BUFFER 0x00000008 -#define FMOD_MEMORY_PLUGIN 0x00000010 -#define FMOD_MEMORY_PERSISTENT 0x00200000 -#define FMOD_MEMORY_ALL 0xFFFFFFFF - -typedef unsigned int FMOD_INITFLAGS; -#define FMOD_INIT_NORMAL 0x00000000 -#define FMOD_INIT_STREAM_FROM_UPDATE 0x00000001 -#define FMOD_INIT_MIX_FROM_UPDATE 0x00000002 -#define FMOD_INIT_3D_RIGHTHANDED 0x00000004 -#define FMOD_INIT_CHANNEL_LOWPASS 0x00000100 -#define FMOD_INIT_CHANNEL_DISTANCEFILTER 0x00000200 -#define FMOD_INIT_PROFILE_ENABLE 0x00010000 -#define FMOD_INIT_VOL0_BECOMES_VIRTUAL 0x00020000 -#define FMOD_INIT_GEOMETRY_USECLOSEST 0x00040000 -#define FMOD_INIT_PREFER_DOLBY_DOWNMIX 0x00080000 -#define FMOD_INIT_THREAD_UNSAFE 0x00100000 -#define FMOD_INIT_PROFILE_METER_ALL 0x00200000 -#define FMOD_INIT_MEMORY_TRACKING 0x00400000 - -typedef unsigned int FMOD_DRIVER_STATE; -#define FMOD_DRIVER_STATE_CONNECTED 0x00000001 -#define FMOD_DRIVER_STATE_DEFAULT 0x00000002 - -typedef unsigned int FMOD_TIMEUNIT; -#define FMOD_TIMEUNIT_MS 0x00000001 -#define FMOD_TIMEUNIT_PCM 0x00000002 -#define FMOD_TIMEUNIT_PCMBYTES 0x00000004 -#define FMOD_TIMEUNIT_RAWBYTES 0x00000008 -#define FMOD_TIMEUNIT_PCMFRACTION 0x00000010 -#define FMOD_TIMEUNIT_MODORDER 0x00000100 -#define FMOD_TIMEUNIT_MODROW 0x00000200 -#define FMOD_TIMEUNIT_MODPATTERN 0x00000400 - -typedef unsigned int FMOD_SYSTEM_CALLBACK_TYPE; -#define FMOD_SYSTEM_CALLBACK_DEVICELISTCHANGED 0x00000001 -#define FMOD_SYSTEM_CALLBACK_DEVICELOST 0x00000002 -#define FMOD_SYSTEM_CALLBACK_MEMORYALLOCATIONFAILED 0x00000004 -#define FMOD_SYSTEM_CALLBACK_THREADCREATED 0x00000008 -#define FMOD_SYSTEM_CALLBACK_BADDSPCONNECTION 0x00000010 -#define FMOD_SYSTEM_CALLBACK_PREMIX 0x00000020 -#define FMOD_SYSTEM_CALLBACK_POSTMIX 0x00000040 -#define FMOD_SYSTEM_CALLBACK_ERROR 0x00000080 -#define FMOD_SYSTEM_CALLBACK_MIDMIX 0x00000100 -#define FMOD_SYSTEM_CALLBACK_THREADDESTROYED 0x00000200 -#define FMOD_SYSTEM_CALLBACK_PREUPDATE 0x00000400 -#define FMOD_SYSTEM_CALLBACK_POSTUPDATE 0x00000800 -#define FMOD_SYSTEM_CALLBACK_RECORDLISTCHANGED 0x00001000 -#define FMOD_SYSTEM_CALLBACK_ALL 0xFFFFFFFF - -typedef unsigned int FMOD_MODE; -#define FMOD_DEFAULT 0x00000000 -#define FMOD_LOOP_OFF 0x00000001 -#define FMOD_LOOP_NORMAL 0x00000002 -#define FMOD_LOOP_BIDI 0x00000004 -#define FMOD_2D 0x00000008 -#define FMOD_3D 0x00000010 -#define FMOD_CREATESTREAM 0x00000080 -#define FMOD_CREATESAMPLE 0x00000100 -#define FMOD_CREATECOMPRESSEDSAMPLE 0x00000200 -#define FMOD_OPENUSER 0x00000400 -#define FMOD_OPENMEMORY 0x00000800 -#define FMOD_OPENMEMORY_POINT 0x10000000 -#define FMOD_OPENRAW 0x00001000 -#define FMOD_OPENONLY 0x00002000 -#define FMOD_ACCURATETIME 0x00004000 -#define FMOD_MPEGSEARCH 0x00008000 -#define FMOD_NONBLOCKING 0x00010000 -#define FMOD_UNIQUE 0x00020000 -#define FMOD_3D_HEADRELATIVE 0x00040000 -#define FMOD_3D_WORLDRELATIVE 0x00080000 -#define FMOD_3D_INVERSEROLLOFF 0x00100000 -#define FMOD_3D_LINEARROLLOFF 0x00200000 -#define FMOD_3D_LINEARSQUAREROLLOFF 0x00400000 -#define FMOD_3D_INVERSETAPEREDROLLOFF 0x00800000 -#define FMOD_3D_CUSTOMROLLOFF 0x04000000 -#define FMOD_3D_IGNOREGEOMETRY 0x40000000 -#define FMOD_IGNORETAGS 0x02000000 -#define FMOD_LOWMEM 0x08000000 -#define FMOD_VIRTUAL_PLAYFROMSTART 0x80000000 - -typedef unsigned int FMOD_CHANNELMASK; -#define FMOD_CHANNELMASK_FRONT_LEFT 0x00000001 -#define FMOD_CHANNELMASK_FRONT_RIGHT 0x00000002 -#define FMOD_CHANNELMASK_FRONT_CENTER 0x00000004 -#define FMOD_CHANNELMASK_LOW_FREQUENCY 0x00000008 -#define FMOD_CHANNELMASK_SURROUND_LEFT 0x00000010 -#define FMOD_CHANNELMASK_SURROUND_RIGHT 0x00000020 -#define FMOD_CHANNELMASK_BACK_LEFT 0x00000040 -#define FMOD_CHANNELMASK_BACK_RIGHT 0x00000080 -#define FMOD_CHANNELMASK_BACK_CENTER 0x00000100 - -#define FMOD_CHANNELMASK_MONO (FMOD_CHANNELMASK_FRONT_LEFT) -#define FMOD_CHANNELMASK_STEREO (FMOD_CHANNELMASK_FRONT_LEFT | FMOD_CHANNELMASK_FRONT_RIGHT) -#define FMOD_CHANNELMASK_LRC (FMOD_CHANNELMASK_FRONT_LEFT | FMOD_CHANNELMASK_FRONT_RIGHT | FMOD_CHANNELMASK_FRONT_CENTER) -#define FMOD_CHANNELMASK_QUAD (FMOD_CHANNELMASK_FRONT_LEFT | FMOD_CHANNELMASK_FRONT_RIGHT | FMOD_CHANNELMASK_SURROUND_LEFT | FMOD_CHANNELMASK_SURROUND_RIGHT) -#define FMOD_CHANNELMASK_SURROUND (FMOD_CHANNELMASK_FRONT_LEFT | FMOD_CHANNELMASK_FRONT_RIGHT | FMOD_CHANNELMASK_FRONT_CENTER | FMOD_CHANNELMASK_SURROUND_LEFT | FMOD_CHANNELMASK_SURROUND_RIGHT) -#define FMOD_CHANNELMASK_5POINT1 (FMOD_CHANNELMASK_FRONT_LEFT | FMOD_CHANNELMASK_FRONT_RIGHT | FMOD_CHANNELMASK_FRONT_CENTER | FMOD_CHANNELMASK_LOW_FREQUENCY | FMOD_CHANNELMASK_SURROUND_LEFT | FMOD_CHANNELMASK_SURROUND_RIGHT) -#define FMOD_CHANNELMASK_5POINT1_REARS (FMOD_CHANNELMASK_FRONT_LEFT | FMOD_CHANNELMASK_FRONT_RIGHT | FMOD_CHANNELMASK_FRONT_CENTER | FMOD_CHANNELMASK_LOW_FREQUENCY | FMOD_CHANNELMASK_BACK_LEFT | FMOD_CHANNELMASK_BACK_RIGHT) -#define FMOD_CHANNELMASK_7POINT0 (FMOD_CHANNELMASK_FRONT_LEFT | FMOD_CHANNELMASK_FRONT_RIGHT | FMOD_CHANNELMASK_FRONT_CENTER | FMOD_CHANNELMASK_SURROUND_LEFT | FMOD_CHANNELMASK_SURROUND_RIGHT | FMOD_CHANNELMASK_BACK_LEFT | FMOD_CHANNELMASK_BACK_RIGHT) -#define FMOD_CHANNELMASK_7POINT1 (FMOD_CHANNELMASK_FRONT_LEFT | FMOD_CHANNELMASK_FRONT_RIGHT | FMOD_CHANNELMASK_FRONT_CENTER | FMOD_CHANNELMASK_LOW_FREQUENCY | FMOD_CHANNELMASK_SURROUND_LEFT | FMOD_CHANNELMASK_SURROUND_RIGHT | FMOD_CHANNELMASK_BACK_LEFT | FMOD_CHANNELMASK_BACK_RIGHT) - -/* Preset for FMOD_REVERB_PROPERTIES */ -#define FMOD_PRESET_OFF { 1000, 7, 11, 5000, 100, 100, 100, 250, 0, 20, 96, -80.0f } -#define FMOD_PRESET_GENERIC { 1500, 7, 11, 5000, 83, 100, 100, 250, 0, 14500, 96, -8.0f } -#define FMOD_PRESET_PADDEDCELL { 170, 1, 2, 5000, 10, 100, 100, 250, 0, 160, 84, -7.8f } -#define FMOD_PRESET_ROOM { 400, 2, 3, 5000, 83, 100, 100, 250, 0, 6050, 88, -9.4f } -#define FMOD_PRESET_BATHROOM { 1500, 7, 11, 5000, 54, 100, 60, 250, 0, 2900, 83, 0.5f } -#define FMOD_PRESET_LIVINGROOM { 500, 3, 4, 5000, 10, 100, 100, 250, 0, 160, 58, -19.0f } -#define FMOD_PRESET_STONEROOM { 2300, 12, 17, 5000, 64, 100, 100, 250, 0, 7800, 71, -8.5f } -#define FMOD_PRESET_AUDITORIUM { 4300, 20, 30, 5000, 59, 100, 100, 250, 0, 5850, 64, -11.7f } -#define FMOD_PRESET_CONCERTHALL { 3900, 20, 29, 5000, 70, 100, 100, 250, 0, 5650, 80, -9.8f } -#define FMOD_PRESET_CAVE { 2900, 15, 22, 5000, 100, 100, 100, 250, 0, 20000, 59, -11.3f } -#define FMOD_PRESET_ARENA { 7200, 20, 30, 5000, 33, 100, 100, 250, 0, 4500, 80, -9.6f } -#define FMOD_PRESET_HANGAR { 10000, 20, 30, 5000, 23, 100, 100, 250, 0, 3400, 72, -7.4f } -#define FMOD_PRESET_CARPETTEDHALLWAY { 300, 2, 30, 5000, 10, 100, 100, 250, 0, 500, 56, -24.0f } -#define FMOD_PRESET_HALLWAY { 1500, 7, 11, 5000, 59, 100, 100, 250, 0, 7800, 87, -5.5f } -#define FMOD_PRESET_STONECORRIDOR { 270, 13, 20, 5000, 79, 100, 100, 250, 0, 9000, 86, -6.0f } -#define FMOD_PRESET_ALLEY { 1500, 7, 11, 5000, 86, 100, 100, 250, 0, 8300, 80, -9.8f } -#define FMOD_PRESET_FOREST { 1500, 162, 88, 5000, 54, 79, 100, 250, 0, 760, 94, -12.3f } -#define FMOD_PRESET_CITY { 1500, 7, 11, 5000, 67, 50, 100, 250, 0, 4050, 66, -26.0f } -#define FMOD_PRESET_MOUNTAINS { 1500, 300, 100, 5000, 21, 27, 100, 250, 0, 1220, 82, -24.0f } -#define FMOD_PRESET_QUARRY { 1500, 61, 25, 5000, 83, 100, 100, 250, 0, 3400, 100, -5.0f } -#define FMOD_PRESET_PLAIN { 1500, 179, 100, 5000, 50, 21, 100, 250, 0, 1670, 65, -28.0f } -#define FMOD_PRESET_PARKINGLOT { 1700, 8, 12, 5000, 100, 100, 100, 250, 0, 20000, 56, -19.5f } -#define FMOD_PRESET_SEWERPIPE { 2800, 14, 21, 5000, 14, 80, 60, 250, 0, 3400, 66, 1.2f } -#define FMOD_PRESET_UNDERWATER { 1500, 7, 11, 5000, 10, 100, 100, 250, 0, 500, 92, 7.0f } - -#define FMOD_MAX_CHANNEL_WIDTH 32 -#define FMOD_MAX_SYSTEMS 8 -#define FMOD_MAX_LISTENERS 8 -#define FMOD_REVERB_MAXINSTANCES 4 -#define FMOD_PORT_INDEX_NONE 0xFFFFFFFFFFFFFFFF - -typedef enum FMOD_RESULT -{ - FMOD_OK, - FMOD_ERR_BADCOMMAND, - FMOD_ERR_CHANNEL_ALLOC, - FMOD_ERR_CHANNEL_STOLEN, - FMOD_ERR_DMA, - FMOD_ERR_DSP_CONNECTION, - FMOD_ERR_DSP_DONTPROCESS, - FMOD_ERR_DSP_FORMAT, - FMOD_ERR_DSP_INUSE, - FMOD_ERR_DSP_NOTFOUND, - FMOD_ERR_DSP_RESERVED, - FMOD_ERR_DSP_SILENCE, - FMOD_ERR_DSP_TYPE, - FMOD_ERR_FILE_BAD, - FMOD_ERR_FILE_COULDNOTSEEK, - FMOD_ERR_FILE_DISKEJECTED, - FMOD_ERR_FILE_EOF, - FMOD_ERR_FILE_ENDOFDATA, - FMOD_ERR_FILE_NOTFOUND, - FMOD_ERR_FORMAT, - FMOD_ERR_HEADER_MISMATCH, - FMOD_ERR_HTTP, - FMOD_ERR_HTTP_ACCESS, - FMOD_ERR_HTTP_PROXY_AUTH, - FMOD_ERR_HTTP_SERVER_ERROR, - FMOD_ERR_HTTP_TIMEOUT, - FMOD_ERR_INITIALIZATION, - FMOD_ERR_INITIALIZED, - FMOD_ERR_INTERNAL, - FMOD_ERR_INVALID_FLOAT, - FMOD_ERR_INVALID_HANDLE, - FMOD_ERR_INVALID_PARAM, - FMOD_ERR_INVALID_POSITION, - FMOD_ERR_INVALID_SPEAKER, - FMOD_ERR_INVALID_SYNCPOINT, - FMOD_ERR_INVALID_THREAD, - FMOD_ERR_INVALID_VECTOR, - FMOD_ERR_MAXAUDIBLE, - FMOD_ERR_MEMORY, - FMOD_ERR_MEMORY_CANTPOINT, - FMOD_ERR_NEEDS3D, - FMOD_ERR_NEEDSHARDWARE, - FMOD_ERR_NET_CONNECT, - FMOD_ERR_NET_SOCKET_ERROR, - FMOD_ERR_NET_URL, - FMOD_ERR_NET_WOULD_BLOCK, - FMOD_ERR_NOTREADY, - FMOD_ERR_OUTPUT_ALLOCATED, - FMOD_ERR_OUTPUT_CREATEBUFFER, - FMOD_ERR_OUTPUT_DRIVERCALL, - FMOD_ERR_OUTPUT_FORMAT, - FMOD_ERR_OUTPUT_INIT, - FMOD_ERR_OUTPUT_NODRIVERS, - FMOD_ERR_PLUGIN, - FMOD_ERR_PLUGIN_MISSING, - FMOD_ERR_PLUGIN_RESOURCE, - FMOD_ERR_PLUGIN_VERSION, - FMOD_ERR_RECORD, - FMOD_ERR_REVERB_CHANNELGROUP, - FMOD_ERR_REVERB_INSTANCE, - FMOD_ERR_SUBSOUNDS, - FMOD_ERR_SUBSOUND_ALLOCATED, - FMOD_ERR_SUBSOUND_CANTMOVE, - FMOD_ERR_TAGNOTFOUND, - FMOD_ERR_TOOMANYCHANNELS, - FMOD_ERR_TRUNCATED, - FMOD_ERR_UNIMPLEMENTED, - FMOD_ERR_UNINITIALIZED, - FMOD_ERR_UNSUPPORTED, - FMOD_ERR_VERSION, - FMOD_ERR_EVENT_ALREADY_LOADED, - FMOD_ERR_EVENT_LIVEUPDATE_BUSY, - FMOD_ERR_EVENT_LIVEUPDATE_MISMATCH, - FMOD_ERR_EVENT_LIVEUPDATE_TIMEOUT, - FMOD_ERR_EVENT_NOTFOUND, - FMOD_ERR_STUDIO_UNINITIALIZED, - FMOD_ERR_STUDIO_NOT_LOADED, - FMOD_ERR_INVALID_STRING, - FMOD_ERR_ALREADY_LOCKED, - FMOD_ERR_NOT_LOCKED, - FMOD_ERR_RECORD_DISCONNECTED, - FMOD_ERR_TOOMANYSAMPLES, - - FMOD_RESULT_FORCEINT = 65536 -} FMOD_RESULT; - -typedef enum FMOD_CHANNELCONTROL_TYPE -{ - FMOD_CHANNELCONTROL_CHANNEL, - FMOD_CHANNELCONTROL_CHANNELGROUP, - - FMOD_CHANNELCONTROL_MAX, - FMOD_CHANNELCONTROL_FORCEINT = 65536 -} FMOD_CHANNELCONTROL_TYPE; - -typedef enum FMOD_OUTPUTTYPE -{ - FMOD_OUTPUTTYPE_AUTODETECT, - FMOD_OUTPUTTYPE_UNKNOWN, - FMOD_OUTPUTTYPE_NOSOUND, - FMOD_OUTPUTTYPE_WAVWRITER, - FMOD_OUTPUTTYPE_NOSOUND_NRT, - FMOD_OUTPUTTYPE_WAVWRITER_NRT, - FMOD_OUTPUTTYPE_WASAPI, - FMOD_OUTPUTTYPE_ASIO, - FMOD_OUTPUTTYPE_PULSEAUDIO, - FMOD_OUTPUTTYPE_ALSA, - FMOD_OUTPUTTYPE_COREAUDIO, - FMOD_OUTPUTTYPE_AUDIOTRACK, - FMOD_OUTPUTTYPE_OPENSL, - FMOD_OUTPUTTYPE_AUDIOOUT, - FMOD_OUTPUTTYPE_AUDIO3D, - FMOD_OUTPUTTYPE_WEBAUDIO, - FMOD_OUTPUTTYPE_NNAUDIO, - FMOD_OUTPUTTYPE_WINSONIC, - FMOD_OUTPUTTYPE_AAUDIO, - - FMOD_OUTPUTTYPE_MAX, - FMOD_OUTPUTTYPE_FORCEINT = 65536 -} FMOD_OUTPUTTYPE; - -typedef enum FMOD_DEBUG_MODE -{ - FMOD_DEBUG_MODE_TTY, - FMOD_DEBUG_MODE_FILE, - FMOD_DEBUG_MODE_CALLBACK, - - FMOD_DEBUG_MODE_FORCEINT = 65536 -} FMOD_DEBUG_MODE; - -typedef enum FMOD_SPEAKERMODE -{ - FMOD_SPEAKERMODE_DEFAULT, - FMOD_SPEAKERMODE_RAW, - FMOD_SPEAKERMODE_MONO, - FMOD_SPEAKERMODE_STEREO, - FMOD_SPEAKERMODE_QUAD, - FMOD_SPEAKERMODE_SURROUND, - FMOD_SPEAKERMODE_5POINT1, - FMOD_SPEAKERMODE_7POINT1, - FMOD_SPEAKERMODE_7POINT1POINT4, - - FMOD_SPEAKERMODE_MAX, - FMOD_SPEAKERMODE_FORCEINT = 65536 -} FMOD_SPEAKERMODE; - -typedef enum FMOD_SPEAKER -{ - FMOD_SPEAKER_NONE = -1, - FMOD_SPEAKER_FRONT_LEFT = 0, - FMOD_SPEAKER_FRONT_RIGHT, - FMOD_SPEAKER_FRONT_CENTER, - FMOD_SPEAKER_LOW_FREQUENCY, - FMOD_SPEAKER_SURROUND_LEFT, - FMOD_SPEAKER_SURROUND_RIGHT, - FMOD_SPEAKER_BACK_LEFT, - FMOD_SPEAKER_BACK_RIGHT, - FMOD_SPEAKER_TOP_FRONT_LEFT, - FMOD_SPEAKER_TOP_FRONT_RIGHT, - FMOD_SPEAKER_TOP_BACK_LEFT, - FMOD_SPEAKER_TOP_BACK_RIGHT, - - FMOD_SPEAKER_MAX, - FMOD_SPEAKER_FORCEINT = 65536 -} FMOD_SPEAKER; - -typedef enum FMOD_CHANNELORDER -{ - FMOD_CHANNELORDER_DEFAULT, - FMOD_CHANNELORDER_WAVEFORMAT, - FMOD_CHANNELORDER_PROTOOLS, - FMOD_CHANNELORDER_ALLMONO, - FMOD_CHANNELORDER_ALLSTEREO, - FMOD_CHANNELORDER_ALSA, - - FMOD_CHANNELORDER_MAX, - FMOD_CHANNELORDER_FORCEINT = 65536 -} FMOD_CHANNELORDER; - -typedef enum FMOD_PLUGINTYPE -{ - FMOD_PLUGINTYPE_OUTPUT, - FMOD_PLUGINTYPE_CODEC, - FMOD_PLUGINTYPE_DSP, - - FMOD_PLUGINTYPE_MAX, - FMOD_PLUGINTYPE_FORCEINT = 65536 -} FMOD_PLUGINTYPE; - -typedef enum FMOD_SOUND_TYPE -{ - FMOD_SOUND_TYPE_UNKNOWN, - FMOD_SOUND_TYPE_AIFF, - FMOD_SOUND_TYPE_ASF, - FMOD_SOUND_TYPE_DLS, - FMOD_SOUND_TYPE_FLAC, - FMOD_SOUND_TYPE_FSB, - FMOD_SOUND_TYPE_IT, - FMOD_SOUND_TYPE_MIDI, - FMOD_SOUND_TYPE_MOD, - FMOD_SOUND_TYPE_MPEG, - FMOD_SOUND_TYPE_OGGVORBIS, - FMOD_SOUND_TYPE_PLAYLIST, - FMOD_SOUND_TYPE_RAW, - FMOD_SOUND_TYPE_S3M, - FMOD_SOUND_TYPE_USER, - FMOD_SOUND_TYPE_WAV, - FMOD_SOUND_TYPE_XM, - FMOD_SOUND_TYPE_XMA, - FMOD_SOUND_TYPE_AUDIOQUEUE, - FMOD_SOUND_TYPE_AT9, - FMOD_SOUND_TYPE_VORBIS, - FMOD_SOUND_TYPE_MEDIA_FOUNDATION, - FMOD_SOUND_TYPE_MEDIACODEC, - FMOD_SOUND_TYPE_FADPCM, - FMOD_SOUND_TYPE_OPUS, - - FMOD_SOUND_TYPE_MAX, - FMOD_SOUND_TYPE_FORCEINT = 65536 -} FMOD_SOUND_TYPE; - -typedef enum FMOD_SOUND_FORMAT -{ - FMOD_SOUND_FORMAT_NONE, - FMOD_SOUND_FORMAT_PCM8, - FMOD_SOUND_FORMAT_PCM16, - FMOD_SOUND_FORMAT_PCM24, - FMOD_SOUND_FORMAT_PCM32, - FMOD_SOUND_FORMAT_PCMFLOAT, - FMOD_SOUND_FORMAT_BITSTREAM, - - FMOD_SOUND_FORMAT_MAX, - FMOD_SOUND_FORMAT_FORCEINT = 65536 -} FMOD_SOUND_FORMAT; - -typedef enum FMOD_OPENSTATE -{ - FMOD_OPENSTATE_READY, - FMOD_OPENSTATE_LOADING, - FMOD_OPENSTATE_ERROR, - FMOD_OPENSTATE_CONNECTING, - FMOD_OPENSTATE_BUFFERING, - FMOD_OPENSTATE_SEEKING, - FMOD_OPENSTATE_PLAYING, - FMOD_OPENSTATE_SETPOSITION, - - FMOD_OPENSTATE_MAX, - FMOD_OPENSTATE_FORCEINT = 65536 -} FMOD_OPENSTATE; - -typedef enum FMOD_SOUNDGROUP_BEHAVIOR -{ - FMOD_SOUNDGROUP_BEHAVIOR_FAIL, - FMOD_SOUNDGROUP_BEHAVIOR_MUTE, - FMOD_SOUNDGROUP_BEHAVIOR_STEALLOWEST, - - FMOD_SOUNDGROUP_BEHAVIOR_MAX, - FMOD_SOUNDGROUP_BEHAVIOR_FORCEINT = 65536 -} FMOD_SOUNDGROUP_BEHAVIOR; - -typedef enum FMOD_CHANNELCONTROL_CALLBACK_TYPE -{ - FMOD_CHANNELCONTROL_CALLBACK_END, - FMOD_CHANNELCONTROL_CALLBACK_VIRTUALVOICE, - FMOD_CHANNELCONTROL_CALLBACK_SYNCPOINT, - FMOD_CHANNELCONTROL_CALLBACK_OCCLUSION, - - FMOD_CHANNELCONTROL_CALLBACK_MAX, - FMOD_CHANNELCONTROL_CALLBACK_FORCEINT = 65536 -} FMOD_CHANNELCONTROL_CALLBACK_TYPE; - -typedef enum FMOD_CHANNELCONTROL_DSP_INDEX -{ - FMOD_CHANNELCONTROL_DSP_HEAD = -1, - FMOD_CHANNELCONTROL_DSP_FADER = -2, - FMOD_CHANNELCONTROL_DSP_TAIL = -3, - - FMOD_CHANNELCONTROL_DSP_FORCEINT = 65536 -} FMOD_CHANNELCONTROL_DSP_INDEX; - -typedef enum FMOD_ERRORCALLBACK_INSTANCETYPE -{ - FMOD_ERRORCALLBACK_INSTANCETYPE_NONE, - FMOD_ERRORCALLBACK_INSTANCETYPE_SYSTEM, - FMOD_ERRORCALLBACK_INSTANCETYPE_CHANNEL, - FMOD_ERRORCALLBACK_INSTANCETYPE_CHANNELGROUP, - FMOD_ERRORCALLBACK_INSTANCETYPE_CHANNELCONTROL, - FMOD_ERRORCALLBACK_INSTANCETYPE_SOUND, - FMOD_ERRORCALLBACK_INSTANCETYPE_SOUNDGROUP, - FMOD_ERRORCALLBACK_INSTANCETYPE_DSP, - FMOD_ERRORCALLBACK_INSTANCETYPE_DSPCONNECTION, - FMOD_ERRORCALLBACK_INSTANCETYPE_GEOMETRY, - FMOD_ERRORCALLBACK_INSTANCETYPE_REVERB3D, - FMOD_ERRORCALLBACK_INSTANCETYPE_STUDIO_SYSTEM, - FMOD_ERRORCALLBACK_INSTANCETYPE_STUDIO_EVENTDESCRIPTION, - FMOD_ERRORCALLBACK_INSTANCETYPE_STUDIO_EVENTINSTANCE, - FMOD_ERRORCALLBACK_INSTANCETYPE_STUDIO_PARAMETERINSTANCE, - FMOD_ERRORCALLBACK_INSTANCETYPE_STUDIO_BUS, - FMOD_ERRORCALLBACK_INSTANCETYPE_STUDIO_VCA, - FMOD_ERRORCALLBACK_INSTANCETYPE_STUDIO_BANK, - FMOD_ERRORCALLBACK_INSTANCETYPE_STUDIO_COMMANDREPLAY, - - FMOD_ERRORCALLBACK_INSTANCETYPE_FORCEINT = 65536 -} FMOD_ERRORCALLBACK_INSTANCETYPE; - -typedef enum FMOD_DSP_RESAMPLER -{ - FMOD_DSP_RESAMPLER_DEFAULT, - FMOD_DSP_RESAMPLER_NOINTERP, - FMOD_DSP_RESAMPLER_LINEAR, - FMOD_DSP_RESAMPLER_CUBIC, - FMOD_DSP_RESAMPLER_SPLINE, - - FMOD_DSP_RESAMPLER_MAX, - FMOD_DSP_RESAMPLER_FORCEINT = 65536 -} FMOD_DSP_RESAMPLER; - -typedef enum FMOD_DSPCONNECTION_TYPE -{ - FMOD_DSPCONNECTION_TYPE_STANDARD, - FMOD_DSPCONNECTION_TYPE_SIDECHAIN, - FMOD_DSPCONNECTION_TYPE_SEND, - FMOD_DSPCONNECTION_TYPE_SEND_SIDECHAIN, - - FMOD_DSPCONNECTION_TYPE_MAX, - FMOD_DSPCONNECTION_TYPE_FORCEINT = 65536 -} FMOD_DSPCONNECTION_TYPE; - -typedef enum FMOD_TAGTYPE -{ - FMOD_TAGTYPE_UNKNOWN, - FMOD_TAGTYPE_ID3V1, - FMOD_TAGTYPE_ID3V2, - FMOD_TAGTYPE_VORBISCOMMENT, - FMOD_TAGTYPE_SHOUTCAST, - FMOD_TAGTYPE_ICECAST, - FMOD_TAGTYPE_ASF, - FMOD_TAGTYPE_MIDI, - FMOD_TAGTYPE_PLAYLIST, - FMOD_TAGTYPE_FMOD, - FMOD_TAGTYPE_USER, - - FMOD_TAGTYPE_MAX, - FMOD_TAGTYPE_FORCEINT = 65536 -} FMOD_TAGTYPE; - -typedef enum FMOD_TAGDATATYPE -{ - FMOD_TAGDATATYPE_BINARY, - FMOD_TAGDATATYPE_INT, - FMOD_TAGDATATYPE_FLOAT, - FMOD_TAGDATATYPE_STRING, - FMOD_TAGDATATYPE_STRING_UTF16, - FMOD_TAGDATATYPE_STRING_UTF16BE, - FMOD_TAGDATATYPE_STRING_UTF8, - - FMOD_TAGDATATYPE_MAX, - FMOD_TAGDATATYPE_FORCEINT = 65536 -} FMOD_TAGDATATYPE; - -/* - FMOD callbacks -*/ -typedef FMOD_RESULT (F_CALL *FMOD_DEBUG_CALLBACK) (FMOD_DEBUG_FLAGS flags, const char *file, int line, const char* func, const char* message); -typedef FMOD_RESULT (F_CALL *FMOD_SYSTEM_CALLBACK) (FMOD_SYSTEM *system, FMOD_SYSTEM_CALLBACK_TYPE type, void *commanddata1, void* commanddata2, void *userdata); -typedef FMOD_RESULT (F_CALL *FMOD_CHANNELCONTROL_CALLBACK) (FMOD_CHANNELCONTROL *channelcontrol, FMOD_CHANNELCONTROL_TYPE controltype, FMOD_CHANNELCONTROL_CALLBACK_TYPE callbacktype, void *commanddata1, void *commanddata2); -typedef FMOD_RESULT (F_CALL *FMOD_SOUND_NONBLOCK_CALLBACK) (FMOD_SOUND *sound, FMOD_RESULT result); -typedef FMOD_RESULT (F_CALL *FMOD_SOUND_PCMREAD_CALLBACK) (FMOD_SOUND *sound, void *data, unsigned int datalen); -typedef FMOD_RESULT (F_CALL *FMOD_SOUND_PCMSETPOS_CALLBACK) (FMOD_SOUND *sound, int subsound, unsigned int position, FMOD_TIMEUNIT postype); -typedef FMOD_RESULT (F_CALL *FMOD_FILE_OPEN_CALLBACK) (const char *name, unsigned int *filesize, void **handle, void *userdata); -typedef FMOD_RESULT (F_CALL *FMOD_FILE_CLOSE_CALLBACK) (void *handle, void *userdata); -typedef FMOD_RESULT (F_CALL *FMOD_FILE_READ_CALLBACK) (void *handle, void *buffer, unsigned int sizebytes, unsigned int *bytesread, void *userdata); -typedef FMOD_RESULT (F_CALL *FMOD_FILE_SEEK_CALLBACK) (void *handle, unsigned int pos, void *userdata); -typedef FMOD_RESULT (F_CALL *FMOD_FILE_ASYNCREAD_CALLBACK) (FMOD_ASYNCREADINFO *info, void *userdata); -typedef FMOD_RESULT (F_CALL *FMOD_FILE_ASYNCCANCEL_CALLBACK)(FMOD_ASYNCREADINFO *info, void *userdata); -typedef void (F_CALL *FMOD_FILE_ASYNCDONE_FUNC) (FMOD_ASYNCREADINFO *info, FMOD_RESULT result); -typedef void* (F_CALL *FMOD_MEMORY_ALLOC_CALLBACK) (unsigned int size, FMOD_MEMORY_TYPE type, const char *sourcestr); -typedef void* (F_CALL *FMOD_MEMORY_REALLOC_CALLBACK) (void *ptr, unsigned int size, FMOD_MEMORY_TYPE type, const char *sourcestr); -typedef void (F_CALL *FMOD_MEMORY_FREE_CALLBACK) (void *ptr, FMOD_MEMORY_TYPE type, const char *sourcestr); -typedef float (F_CALL *FMOD_3D_ROLLOFF_CALLBACK) (FMOD_CHANNELCONTROL *channelcontrol, float distance); - -/* - FMOD structs -*/ -struct FMOD_ASYNCREADINFO -{ - void *handle; - unsigned int offset; - unsigned int sizebytes; - int priority; - void *userdata; - void *buffer; - unsigned int bytesread; - FMOD_FILE_ASYNCDONE_FUNC done; -}; - -typedef struct FMOD_VECTOR -{ - float x; - float y; - float z; -} FMOD_VECTOR; - -typedef struct FMOD_3D_ATTRIBUTES -{ - FMOD_VECTOR position; - FMOD_VECTOR velocity; - FMOD_VECTOR forward; - FMOD_VECTOR up; -} FMOD_3D_ATTRIBUTES; - -typedef struct FMOD_GUID -{ - unsigned int Data1; - unsigned short Data2; - unsigned short Data3; - unsigned char Data4[8]; -} FMOD_GUID; - -typedef struct FMOD_PLUGINLIST -{ - FMOD_PLUGINTYPE type; - void *description; -} FMOD_PLUGINLIST; - -typedef struct FMOD_ADVANCEDSETTINGS -{ - int cbSize; - int maxMPEGCodecs; - int maxADPCMCodecs; - int maxXMACodecs; - int maxVorbisCodecs; - int maxAT9Codecs; - int maxFADPCMCodecs; - int maxPCMCodecs; - int ASIONumChannels; - char **ASIOChannelList; - FMOD_SPEAKER *ASIOSpeakerList; - float vol0virtualvol; - unsigned int defaultDecodeBufferSize; - unsigned short profilePort; - unsigned int geometryMaxFadeTime; - float distanceFilterCenterFreq; - int reverb3Dinstance; - int DSPBufferPoolSize; - unsigned int stackSizeStream; - unsigned int stackSizeNonBlocking; - unsigned int stackSizeMixer; - FMOD_DSP_RESAMPLER resamplerMethod; - unsigned int commandQueueSize; - unsigned int randomSeed; -} FMOD_ADVANCEDSETTINGS; - -typedef struct FMOD_TAG -{ - FMOD_TAGTYPE type; - FMOD_TAGDATATYPE datatype; - char *name; - void *data; - unsigned int datalen; - FMOD_BOOL updated; -} FMOD_TAG; - -typedef struct FMOD_CREATESOUNDEXINFO -{ - int cbsize; - unsigned int length; - unsigned int fileoffset; - int numchannels; - int defaultfrequency; - FMOD_SOUND_FORMAT format; - unsigned int decodebuffersize; - int initialsubsound; - int numsubsounds; - int *inclusionlist; - int inclusionlistnum; - FMOD_SOUND_PCMREAD_CALLBACK pcmreadcallback; - FMOD_SOUND_PCMSETPOS_CALLBACK pcmsetposcallback; - FMOD_SOUND_NONBLOCK_CALLBACK nonblockcallback; - const char *dlsname; - const char *encryptionkey; - int maxpolyphony; - void *userdata; - FMOD_SOUND_TYPE suggestedsoundtype; - FMOD_FILE_OPEN_CALLBACK fileuseropen; - FMOD_FILE_CLOSE_CALLBACK fileuserclose; - FMOD_FILE_READ_CALLBACK fileuserread; - FMOD_FILE_SEEK_CALLBACK fileuserseek; - FMOD_FILE_ASYNCREAD_CALLBACK fileuserasyncread; - FMOD_FILE_ASYNCCANCEL_CALLBACK fileuserasynccancel; - void *fileuserdata; - int filebuffersize; - FMOD_CHANNELORDER channelorder; - FMOD_SOUNDGROUP *initialsoundgroup; - unsigned int initialseekposition; - FMOD_TIMEUNIT initialseekpostype; - int ignoresetfilesystem; - unsigned int audioqueuepolicy; - unsigned int minmidigranularity; - int nonblockthreadid; - FMOD_GUID *fsbguid; -} FMOD_CREATESOUNDEXINFO; - -typedef struct FMOD_REVERB_PROPERTIES -{ - float DecayTime; - float EarlyDelay; - float LateDelay; - float HFReference; - float HFDecayRatio; - float Diffusion; - float Density; - float LowShelfFrequency; - float LowShelfGain; - float HighCut; - float EarlyLateMix; - float WetLevel; -} FMOD_REVERB_PROPERTIES; - -typedef struct FMOD_ERRORCALLBACK_INFO -{ - FMOD_RESULT result; - FMOD_ERRORCALLBACK_INSTANCETYPE instancetype; - void *instance; - const char *functionname; - const char *functionparams; -} FMOD_ERRORCALLBACK_INFO; - -/* - FMOD optional headers for plugin development -*/ -#include "fmod_codec.h" -#include "fmod_dsp.h" -#include "fmod_output.h" - -#endif diff --git a/engine/fmodcore/inc/fmod_dsp.cs b/engine/fmodcore/inc/fmod_dsp.cs deleted file mode 100644 index 436de56..0000000 --- a/engine/fmodcore/inc/fmod_dsp.cs +++ /dev/null @@ -1,846 +0,0 @@ -/* ======================================================================================== */ -/* FMOD Core API - DSP header file. */ -/* Copyright (c), Firelight Technologies Pty, Ltd. 2004-2021. */ -/* */ -/* Use this header if you are wanting to develop your own DSP plugin to use with FMODs */ -/* dsp system. With this header you can make your own DSP plugin that FMOD can */ -/* register and use. See the documentation and examples on how to make a working plugin. */ -/* */ -/* For more detail visit: */ -/* https://fmod.com/resources/documentation-api?version=2.0&page=plugin-api-dsp.html */ -/* =========================================================================================*/ - -using System; -using System.Text; -using System.Runtime.InteropServices; - -namespace FMOD -{ - [StructLayout(LayoutKind.Sequential)] - public struct DSP_BUFFER_ARRAY - { - public int numbuffers; - public int[] buffernumchannels; - public CHANNELMASK[] bufferchannelmask; - public IntPtr[] buffers; - public SPEAKERMODE speakermode; - } - - public enum DSP_PROCESS_OPERATION - { - PROCESS_PERFORM = 0, - PROCESS_QUERY - } - - [StructLayout(LayoutKind.Sequential)] - public struct COMPLEX - { - public float real; - public float imag; - } - - public enum DSP_PAN_SURROUND_FLAGS - { - DEFAULT = 0, - ROTATION_NOT_BIASED = 1, - } - - - /* - DSP callbacks - */ - public delegate RESULT DSP_CREATECALLBACK (ref DSP_STATE dsp_state); - public delegate RESULT DSP_RELEASECALLBACK (ref DSP_STATE dsp_state); - public delegate RESULT DSP_RESETCALLBACK (ref DSP_STATE dsp_state); - public delegate RESULT DSP_SETPOSITIONCALLBACK (ref DSP_STATE dsp_state, uint pos); - public delegate RESULT DSP_READCALLBACK (ref DSP_STATE dsp_state, IntPtr inbuffer, IntPtr outbuffer, uint length, int inchannels, ref int outchannels); - public delegate RESULT DSP_SHOULDIPROCESS_CALLBACK (ref DSP_STATE dsp_state, bool inputsidle, uint length, CHANNELMASK inmask, int inchannels, SPEAKERMODE speakermode); - public delegate RESULT DSP_PROCESS_CALLBACK (ref DSP_STATE dsp_state, uint length, ref DSP_BUFFER_ARRAY inbufferarray, ref DSP_BUFFER_ARRAY outbufferarray, bool inputsidle, DSP_PROCESS_OPERATION op); - public delegate RESULT DSP_SETPARAM_FLOAT_CALLBACK (ref DSP_STATE dsp_state, int index, float value); - public delegate RESULT DSP_SETPARAM_INT_CALLBACK (ref DSP_STATE dsp_state, int index, int value); - public delegate RESULT DSP_SETPARAM_BOOL_CALLBACK (ref DSP_STATE dsp_state, int index, bool value); - public delegate RESULT DSP_SETPARAM_DATA_CALLBACK (ref DSP_STATE dsp_state, int index, IntPtr data, uint length); - public delegate RESULT DSP_GETPARAM_FLOAT_CALLBACK (ref DSP_STATE dsp_state, int index, ref float value, IntPtr valuestr); - public delegate RESULT DSP_GETPARAM_INT_CALLBACK (ref DSP_STATE dsp_state, int index, ref int value, IntPtr valuestr); - public delegate RESULT DSP_GETPARAM_BOOL_CALLBACK (ref DSP_STATE dsp_state, int index, ref bool value, IntPtr valuestr); - public delegate RESULT DSP_GETPARAM_DATA_CALLBACK (ref DSP_STATE dsp_state, int index, ref IntPtr data, ref uint length, IntPtr valuestr); - public delegate RESULT DSP_SYSTEM_REGISTER_CALLBACK (ref DSP_STATE dsp_state); - public delegate RESULT DSP_SYSTEM_DEREGISTER_CALLBACK (ref DSP_STATE dsp_state); - public delegate RESULT DSP_SYSTEM_MIX_CALLBACK (ref DSP_STATE dsp_state, int stage); - - - /* - DSP functions - */ - public delegate IntPtr DSP_ALLOC_FUNC (uint size, MEMORY_TYPE type, StringWrapper sourcestr); - public delegate IntPtr DSP_REALLOC_FUNC (IntPtr ptr, uint size, MEMORY_TYPE type, StringWrapper sourcestr); - public delegate void DSP_FREE_FUNC (IntPtr ptr, MEMORY_TYPE type, StringWrapper sourcestr); - public delegate void DSP_LOG_FUNC (DEBUG_FLAGS level, StringWrapper file, int line, StringWrapper function, StringWrapper format); - public delegate RESULT DSP_GETSAMPLERATE_FUNC (ref DSP_STATE dsp_state, ref int rate); - public delegate RESULT DSP_GETBLOCKSIZE_FUNC (ref DSP_STATE dsp_state, ref uint blocksize); - public delegate RESULT DSP_GETSPEAKERMODE_FUNC (ref DSP_STATE dsp_state, ref int speakermode_mixer, ref int speakermode_output); - public delegate RESULT DSP_GETCLOCK_FUNC (ref DSP_STATE dsp_state, out ulong clock, out uint offset, out uint length); - public delegate RESULT DSP_GETLISTENERATTRIBUTES_FUNC (ref DSP_STATE dsp_state, ref int numlisteners, IntPtr attributes); - public delegate RESULT DSP_GETUSERDATA_FUNC (ref DSP_STATE dsp_state, out IntPtr userdata); - public delegate RESULT DSP_DFT_FFTREAL_FUNC (ref DSP_STATE dsp_state, int size, IntPtr signal, IntPtr dft, IntPtr window, int signalhop); - public delegate RESULT DSP_DFT_IFFTREAL_FUNC (ref DSP_STATE dsp_state, int size, IntPtr dft, IntPtr signal, IntPtr window, int signalhop); - public delegate RESULT DSP_PAN_SUMMONOMATRIX_FUNC (ref DSP_STATE dsp_state, int sourceSpeakerMode, float lowFrequencyGain, float overallGain, IntPtr matrix); - public delegate RESULT DSP_PAN_SUMSTEREOMATRIX_FUNC (ref DSP_STATE dsp_state, int sourceSpeakerMode, float pan, float lowFrequencyGain, float overallGain, int matrixHop, IntPtr matrix); - public delegate RESULT DSP_PAN_SUMSURROUNDMATRIX_FUNC (ref DSP_STATE dsp_state, int sourceSpeakerMode, int targetSpeakerMode, float direction, float extent, float rotation, float lowFrequencyGain, float overallGain, int matrixHop, IntPtr matrix, DSP_PAN_SURROUND_FLAGS flags); - public delegate RESULT DSP_PAN_SUMMONOTOSURROUNDMATRIX_FUNC (ref DSP_STATE dsp_state, int targetSpeakerMode, float direction, float extent, float lowFrequencyGain, float overallGain, int matrixHop, IntPtr matrix); - public delegate RESULT DSP_PAN_SUMSTEREOTOSURROUNDMATRIX_FUNC (ref DSP_STATE dsp_state, int targetSpeakerMode, float direction, float extent, float rotation, float lowFrequencyGain, float overallGain, int matrixHop, IntPtr matrix); - public delegate RESULT DSP_PAN_GETROLLOFFGAIN_FUNC (ref DSP_STATE dsp_state, DSP_PAN_3D_ROLLOFF_TYPE rolloff, float distance, float mindistance, float maxdistance, out float gain); - - - public enum DSP_TYPE : int - { - UNKNOWN, - MIXER, - OSCILLATOR, - LOWPASS, - ITLOWPASS, - HIGHPASS, - ECHO, - FADER, - FLANGE, - DISTORTION, - NORMALIZE, - LIMITER, - PARAMEQ, - PITCHSHIFT, - CHORUS, - VSTPLUGIN, - WINAMPPLUGIN, - ITECHO, - COMPRESSOR, - SFXREVERB, - LOWPASS_SIMPLE, - DELAY, - TREMOLO, - LADSPAPLUGIN, - SEND, - RETURN, - HIGHPASS_SIMPLE, - PAN, - THREE_EQ, - FFT, - LOUDNESS_METER, - ENVELOPEFOLLOWER, - CONVOLUTIONREVERB, - CHANNELMIX, - TRANSCEIVER, - OBJECTPAN, - MULTIBAND_EQ, - MAX - } - - public enum DSP_PARAMETER_TYPE - { - FLOAT = 0, - INT, - BOOL, - DATA, - MAX - } - - public enum DSP_PARAMETER_FLOAT_MAPPING_TYPE - { - DSP_PARAMETER_FLOAT_MAPPING_TYPE_LINEAR = 0, - DSP_PARAMETER_FLOAT_MAPPING_TYPE_AUTO, - DSP_PARAMETER_FLOAT_MAPPING_TYPE_PIECEWISE_LINEAR, - } - - [StructLayout(LayoutKind.Sequential)] - public struct DSP_PARAMETER_FLOAT_MAPPING_PIECEWISE_LINEAR - { - public int numpoints; - public IntPtr pointparamvalues; - public IntPtr pointpositions; - } - - [StructLayout(LayoutKind.Sequential)] - public struct DSP_PARAMETER_FLOAT_MAPPING - { - public DSP_PARAMETER_FLOAT_MAPPING_TYPE type; - public DSP_PARAMETER_FLOAT_MAPPING_PIECEWISE_LINEAR piecewiselinearmapping; - } - - - [StructLayout(LayoutKind.Sequential)] - public struct DSP_PARAMETER_DESC_FLOAT - { - public float min; - public float max; - public float defaultval; - public DSP_PARAMETER_FLOAT_MAPPING mapping; - } - - [StructLayout(LayoutKind.Sequential)] - public struct DSP_PARAMETER_DESC_INT - { - public int min; - public int max; - public int defaultval; - public bool goestoinf; - public IntPtr valuenames; - } - - [StructLayout(LayoutKind.Sequential)] - public struct DSP_PARAMETER_DESC_BOOL - { - public bool defaultval; - public IntPtr valuenames; - } - - [StructLayout(LayoutKind.Sequential)] - public struct DSP_PARAMETER_DESC_DATA - { - public int datatype; - } - - [StructLayout(LayoutKind.Explicit)] - public struct DSP_PARAMETER_DESC_UNION - { - [FieldOffset(0)] - public DSP_PARAMETER_DESC_FLOAT floatdesc; - [FieldOffset(0)] - public DSP_PARAMETER_DESC_INT intdesc; - [FieldOffset(0)] - public DSP_PARAMETER_DESC_BOOL booldesc; - [FieldOffset(0)] - public DSP_PARAMETER_DESC_DATA datadesc; - } - - [StructLayout(LayoutKind.Sequential)] - public struct DSP_PARAMETER_DESC - { - public DSP_PARAMETER_TYPE type; - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] - public byte[] name; - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] - public byte[] label; - public string description; - - public DSP_PARAMETER_DESC_UNION desc; - } - - public enum DSP_PARAMETER_DATA_TYPE - { - DSP_PARAMETER_DATA_TYPE_USER = 0, - DSP_PARAMETER_DATA_TYPE_OVERALLGAIN = -1, - DSP_PARAMETER_DATA_TYPE_3DATTRIBUTES = -2, - DSP_PARAMETER_DATA_TYPE_SIDECHAIN = -3, - DSP_PARAMETER_DATA_TYPE_FFT = -4, - DSP_PARAMETER_DATA_TYPE_3DATTRIBUTES_MULTI = -5 - } - - [StructLayout(LayoutKind.Sequential)] - public struct DSP_PARAMETER_OVERALLGAIN - { - public float linear_gain; - public float linear_gain_additive; - } - - [StructLayout(LayoutKind.Sequential)] - public struct DSP_PARAMETER_3DATTRIBUTES - { - public ATTRIBUTES_3D relative; - public ATTRIBUTES_3D absolute; - } - - [StructLayout(LayoutKind.Sequential)] - public struct DSP_PARAMETER_3DATTRIBUTES_MULTI - { - public int numlisteners; - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)] - public ATTRIBUTES_3D[] relative; - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)] - public float[] weight; - public ATTRIBUTES_3D absolute; - } - - [StructLayout(LayoutKind.Sequential)] - public struct DSP_PARAMETER_SIDECHAIN - { - public int sidechainenable; - } - - [StructLayout(LayoutKind.Sequential)] - public struct DSP_PARAMETER_FFT - { - public int length; - public int numchannels; - - [MarshalAs(UnmanagedType.ByValArray,SizeConst=32)] - private IntPtr[] spectrum_internal; - - public float[][] spectrum - { - get - { - var buffer = new float[numchannels][]; - - for (int i = 0; i < numchannels; ++i) - { - buffer[i] = new float[length]; - Marshal.Copy(spectrum_internal[i], buffer[i], 0, length); - } - - return buffer; - } - } - - public void getSpectrum(ref float[][] buffer) - { - int bufferLength = Math.Min(buffer.Length, numchannels); - for (int i = 0; i < bufferLength; ++i) - { - getSpectrum(i, ref buffer[i]); - } - } - - public void getSpectrum(int channel, ref float[] buffer) - { - int bufferLength = Math.Min(buffer.Length, length); - Marshal.Copy(spectrum_internal[channel], buffer, 0, bufferLength); - } - } - - [StructLayout(LayoutKind.Sequential)] - public struct DSP_DESCRIPTION - { - public uint pluginsdkversion; - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)] - public byte[] name; - public uint version; - public int numinputbuffers; - public int numoutputbuffers; - public DSP_CREATECALLBACK create; - public DSP_RELEASECALLBACK release; - public DSP_RESETCALLBACK reset; - public DSP_READCALLBACK read; - public DSP_PROCESS_CALLBACK process; - public DSP_SETPOSITIONCALLBACK setposition; - - public int numparameters; - public IntPtr paramdesc; - public DSP_SETPARAM_FLOAT_CALLBACK setparameterfloat; - public DSP_SETPARAM_INT_CALLBACK setparameterint; - public DSP_SETPARAM_BOOL_CALLBACK setparameterbool; - public DSP_SETPARAM_DATA_CALLBACK setparameterdata; - public DSP_GETPARAM_FLOAT_CALLBACK getparameterfloat; - public DSP_GETPARAM_INT_CALLBACK getparameterint; - public DSP_GETPARAM_BOOL_CALLBACK getparameterbool; - public DSP_GETPARAM_DATA_CALLBACK getparameterdata; - public DSP_SHOULDIPROCESS_CALLBACK shouldiprocess; - public IntPtr userdata; - - public DSP_SYSTEM_REGISTER_CALLBACK sys_register; - public DSP_SYSTEM_DEREGISTER_CALLBACK sys_deregister; - public DSP_SYSTEM_MIX_CALLBACK sys_mix; - } - - [StructLayout(LayoutKind.Sequential)] - public struct DSP_STATE_DFT_FUNCTIONS - { - public DSP_DFT_FFTREAL_FUNC fftreal; - public DSP_DFT_IFFTREAL_FUNC inversefftreal; - } - - [StructLayout(LayoutKind.Sequential)] - public struct DSP_STATE_PAN_FUNCTIONS - { - public DSP_PAN_SUMMONOMATRIX_FUNC summonomatrix; - public DSP_PAN_SUMSTEREOMATRIX_FUNC sumstereomatrix; - public DSP_PAN_SUMSURROUNDMATRIX_FUNC sumsurroundmatrix; - public DSP_PAN_SUMMONOTOSURROUNDMATRIX_FUNC summonotosurroundmatrix; - public DSP_PAN_SUMSTEREOTOSURROUNDMATRIX_FUNC sumstereotosurroundmatrix; - public DSP_PAN_GETROLLOFFGAIN_FUNC getrolloffgain; - } - - [StructLayout(LayoutKind.Sequential)] - public struct DSP_STATE_FUNCTIONS - { - public DSP_ALLOC_FUNC alloc; - public DSP_REALLOC_FUNC realloc; - public DSP_FREE_FUNC free; - public DSP_GETSAMPLERATE_FUNC getsamplerate; - public DSP_GETBLOCKSIZE_FUNC getblocksize; - public IntPtr dft; - public IntPtr pan; - public DSP_GETSPEAKERMODE_FUNC getspeakermode; - public DSP_GETCLOCK_FUNC getclock; - public DSP_GETLISTENERATTRIBUTES_FUNC getlistenerattributes; - public DSP_LOG_FUNC log; - public DSP_GETUSERDATA_FUNC getuserdata; - } - - [StructLayout(LayoutKind.Sequential)] - public struct DSP_STATE - { - public IntPtr instance; - public IntPtr plugindata; - public uint channelmask; - public int source_speakermode; - public IntPtr sidechaindata; - public int sidechainchannels; - public IntPtr functions; - public int systemobject; - } - - [StructLayout(LayoutKind.Sequential)] - public struct DSP_METERING_INFO - { - public int numsamples; - [MarshalAs(UnmanagedType.ByValArray, SizeConst=32)] - public float[] peaklevel; - [MarshalAs(UnmanagedType.ByValArray, SizeConst=32)] - public float[] rmslevel; - public short numchannels; - } - - /* - ============================================================================================================== - - FMOD built in effect parameters. - Use DSP::setParameter with these enums for the 'index' parameter. - - ============================================================================================================== - */ - - public enum DSP_OSCILLATOR : int - { - TYPE, - RATE - } - - public enum DSP_LOWPASS : int - { - CUTOFF, - RESONANCE - } - - public enum DSP_ITLOWPASS : int - { - CUTOFF, - RESONANCE - } - - public enum DSP_HIGHPASS : int - { - CUTOFF, - RESONANCE - } - - public enum DSP_ECHO : int - { - DELAY, - FEEDBACK, - DRYLEVEL, - WETLEVEL - } - - public enum DSP_FADER : int - { - GAIN, - OVERALL_GAIN, - } - - public enum DSP_DELAY : int - { - CH0, - CH1, - CH2, - CH3, - CH4, - CH5, - CH6, - CH7, - CH8, - CH9, - CH10, - CH11, - CH12, - CH13, - CH14, - CH15, - MAXDELAY, - } - - public enum DSP_FLANGE : int - { - MIX, - DEPTH, - RATE - } - - public enum DSP_TREMOLO : int - { - FREQUENCY, - DEPTH, - SHAPE, - SKEW, - DUTY, - SQUARE, - PHASE, - SPREAD - } - - public enum DSP_DISTORTION : int - { - LEVEL - } - - public enum DSP_NORMALIZE : int - { - FADETIME, - THRESHHOLD, - MAXAMP - } - - public enum DSP_LIMITER : int - { - RELEASETIME, - CEILING, - MAXIMIZERGAIN, - MODE, - } - - public enum DSP_PARAMEQ : int - { - CENTER, - BANDWIDTH, - GAIN - } - - public enum DSP_MULTIBAND_EQ : int - { - A_FILTER, - A_FREQUENCY, - A_Q, - A_GAIN, - B_FILTER, - B_FREQUENCY, - B_Q, - B_GAIN, - C_FILTER, - C_FREQUENCY, - C_Q, - C_GAIN, - D_FILTER, - D_FREQUENCY, - D_Q, - D_GAIN, - E_FILTER, - E_FREQUENCY, - E_Q, - E_GAIN, - } - - public enum DSP_MULTIBAND_EQ_FILTER_TYPE : int - { - DISABLED, - LOWPASS_12DB, - LOWPASS_24DB, - LOWPASS_48DB, - HIGHPASS_12DB, - HIGHPASS_24DB, - HIGHPASS_48DB, - LOWSHELF, - HIGHSHELF, - PEAKING, - BANDPASS, - NOTCH, - ALLPASS, - } - - public enum DSP_PITCHSHIFT : int - { - PITCH, - FFTSIZE, - OVERLAP, - MAXCHANNELS - } - - public enum DSP_CHORUS : int - { - MIX, - RATE, - DEPTH, - } - - public enum DSP_ITECHO : int - { - WETDRYMIX, - FEEDBACK, - LEFTDELAY, - RIGHTDELAY, - PANDELAY - } - - public enum DSP_COMPRESSOR : int - { - THRESHOLD, - RATIO, - ATTACK, - RELEASE, - GAINMAKEUP, - USESIDECHAIN, - LINKED - } - - public enum DSP_SFXREVERB : int - { - DECAYTIME, - EARLYDELAY, - LATEDELAY, - HFREFERENCE, - HFDECAYRATIO, - DIFFUSION, - DENSITY, - LOWSHELFFREQUENCY, - LOWSHELFGAIN, - HIGHCUT, - EARLYLATEMIX, - WETLEVEL, - DRYLEVEL - } - - public enum DSP_LOWPASS_SIMPLE : int - { - CUTOFF - } - - public enum DSP_SEND : int - { - RETURNID, - LEVEL, - } - - public enum DSP_RETURN : int - { - ID, - INPUT_SPEAKER_MODE - } - - public enum DSP_HIGHPASS_SIMPLE : int - { - CUTOFF - } - - public enum DSP_PAN_2D_STEREO_MODE_TYPE : int - { - DISTRIBUTED, - DISCRETE - } - - public enum DSP_PAN_MODE_TYPE : int - { - MONO, - STEREO, - SURROUND - } - - public enum DSP_PAN_3D_ROLLOFF_TYPE : int - { - LINEARSQUARED, - LINEAR, - INVERSE, - INVERSETAPERED, - CUSTOM - } - - public enum DSP_PAN_3D_EXTENT_MODE_TYPE : int - { - AUTO, - USER, - OFF - } - - public enum DSP_PAN : int - { - MODE, - _2D_STEREO_POSITION, - _2D_DIRECTION, - _2D_EXTENT, - _2D_ROTATION, - _2D_LFE_LEVEL, - _2D_STEREO_MODE, - _2D_STEREO_SEPARATION, - _2D_STEREO_AXIS, - ENABLED_SPEAKERS, - _3D_POSITION, - _3D_ROLLOFF, - _3D_MIN_DISTANCE, - _3D_MAX_DISTANCE, - _3D_EXTENT_MODE, - _3D_SOUND_SIZE, - _3D_MIN_EXTENT, - _3D_PAN_BLEND, - LFE_UPMIX_ENABLED, - OVERALL_GAIN, - SURROUND_SPEAKER_MODE, - _2D_HEIGHT_BLEND, - } - - public enum DSP_THREE_EQ_CROSSOVERSLOPE_TYPE : int - { - _12DB, - _24DB, - _48DB - } - - public enum DSP_THREE_EQ : int - { - LOWGAIN, - MIDGAIN, - HIGHGAIN, - LOWCROSSOVER, - HIGHCROSSOVER, - CROSSOVERSLOPE - } - - public enum DSP_FFT_WINDOW : int - { - RECT, - TRIANGLE, - HAMMING, - HANNING, - BLACKMAN, - BLACKMANHARRIS - } - - public enum DSP_FFT : int - { - WINDOWSIZE, - WINDOWTYPE, - SPECTRUMDATA, - DOMINANT_FREQ - } - - public enum DSP_ENVELOPEFOLLOWER : int - { - ATTACK, - RELEASE, - ENVELOPE, - USESIDECHAIN - } - - public enum DSP_CONVOLUTION_REVERB : int - { - IR, - WET, - DRY, - LINKED - } - - public enum DSP_CHANNELMIX_OUTPUT : int - { - DEFAULT, - ALLMONO, - ALLSTEREO, - ALLQUAD, - ALL5POINT1, - ALL7POINT1, - ALLLFE, - ALL7POINT1POINT4 - } - - public enum DSP_CHANNELMIX : int - { - OUTPUTGROUPING, - GAIN_CH0, - GAIN_CH1, - GAIN_CH2, - GAIN_CH3, - GAIN_CH4, - GAIN_CH5, - GAIN_CH6, - GAIN_CH7, - GAIN_CH8, - GAIN_CH9, - GAIN_CH10, - GAIN_CH11, - GAIN_CH12, - GAIN_CH13, - GAIN_CH14, - GAIN_CH15, - GAIN_CH16, - GAIN_CH17, - GAIN_CH18, - GAIN_CH19, - GAIN_CH20, - GAIN_CH21, - GAIN_CH22, - GAIN_CH23, - GAIN_CH24, - GAIN_CH25, - GAIN_CH26, - GAIN_CH27, - GAIN_CH28, - GAIN_CH29, - GAIN_CH30, - GAIN_CH31, - OUTPUT_CH0, - OUTPUT_CH1, - OUTPUT_CH2, - OUTPUT_CH3, - OUTPUT_CH4, - OUTPUT_CH5, - OUTPUT_CH6, - OUTPUT_CH7, - OUTPUT_CH8, - OUTPUT_CH9, - OUTPUT_CH10, - OUTPUT_CH11, - OUTPUT_CH12, - OUTPUT_CH13, - OUTPUT_CH14, - OUTPUT_CH15, - OUTPUT_CH16, - OUTPUT_CH17, - OUTPUT_CH18, - OUTPUT_CH19, - OUTPUT_CH20, - OUTPUT_CH21, - OUTPUT_CH22, - OUTPUT_CH23, - OUTPUT_CH24, - OUTPUT_CH25, - OUTPUT_CH26, - OUTPUT_CH27, - OUTPUT_CH28, - OUTPUT_CH29, - OUTPUT_CH30, - OUTPUT_CH31, - } - - public enum DSP_TRANSCEIVER_SPEAKERMODE : int - { - AUTO = -1, - MONO = 0, - STEREO, - SURROUND, - } - - public enum DSP_TRANSCEIVER : int - { - TRANSMIT, - GAIN, - CHANNEL, - TRANSMITSPEAKERMODE - } - - public enum DSP_OBJECTPAN : int - { - _3D_POSITION, - _3D_ROLLOFF, - _3D_MIN_DISTANCE, - _3D_MAX_DISTANCE, - _3D_EXTENT_MODE, - _3D_SOUND_SIZE, - _3D_MIN_EXTENT, - OVERALL_GAIN, - OUTPUTGAIN - } -} diff --git a/engine/fmodcore/inc/fmod_dsp.h b/engine/fmodcore/inc/fmod_dsp.h deleted file mode 100644 index c95d5ae..0000000 --- a/engine/fmodcore/inc/fmod_dsp.h +++ /dev/null @@ -1,414 +0,0 @@ -/* ======================================================================================== */ -/* FMOD Core API - DSP header file. */ -/* Copyright (c), Firelight Technologies Pty, Ltd. 2004-2021. */ -/* */ -/* Use this header if you are wanting to develop your own DSP plugin to use with FMODs */ -/* dsp system. With this header you can make your own DSP plugin that FMOD can */ -/* register and use. See the documentation and examples on how to make a working plugin. */ -/* */ -/* For more detail visit: */ -/* https://fmod.com/resources/documentation-api?version=2.0&page=plugin-api-dsp.html */ -/* =========================================================================================*/ -#ifndef _FMOD_DSP_H -#define _FMOD_DSP_H - -#include "fmod_dsp_effects.h" - -typedef struct FMOD_DSP_STATE FMOD_DSP_STATE; -typedef struct FMOD_DSP_BUFFER_ARRAY FMOD_DSP_BUFFER_ARRAY; -typedef struct FMOD_COMPLEX FMOD_COMPLEX; - -/* - DSP Constants -*/ -#define FMOD_PLUGIN_SDK_VERSION 110 -#define FMOD_DSP_GETPARAM_VALUESTR_LENGTH 32 - -typedef enum -{ - FMOD_DSP_PROCESS_PERFORM, - FMOD_DSP_PROCESS_QUERY -} FMOD_DSP_PROCESS_OPERATION; - -typedef enum FMOD_DSP_PAN_SURROUND_FLAGS -{ - FMOD_DSP_PAN_SURROUND_DEFAULT = 0, - FMOD_DSP_PAN_SURROUND_ROTATION_NOT_BIASED = 1, - - FMOD_DSP_PAN_SURROUND_FLAGS_FORCEINT = 65536 -} FMOD_DSP_PAN_SURROUND_FLAGS; - -typedef enum -{ - FMOD_DSP_PARAMETER_TYPE_FLOAT, - FMOD_DSP_PARAMETER_TYPE_INT, - FMOD_DSP_PARAMETER_TYPE_BOOL, - FMOD_DSP_PARAMETER_TYPE_DATA, - - FMOD_DSP_PARAMETER_TYPE_MAX, - FMOD_DSP_PARAMETER_TYPE_FORCEINT = 65536 -} FMOD_DSP_PARAMETER_TYPE; - -typedef enum -{ - FMOD_DSP_PARAMETER_FLOAT_MAPPING_TYPE_LINEAR, - FMOD_DSP_PARAMETER_FLOAT_MAPPING_TYPE_AUTO, - FMOD_DSP_PARAMETER_FLOAT_MAPPING_TYPE_PIECEWISE_LINEAR, - - FMOD_DSP_PARAMETER_FLOAT_MAPPING_TYPE_FORCEINT = 65536 -} FMOD_DSP_PARAMETER_FLOAT_MAPPING_TYPE; - -typedef enum -{ - FMOD_DSP_PARAMETER_DATA_TYPE_USER = 0, - FMOD_DSP_PARAMETER_DATA_TYPE_OVERALLGAIN = -1, - FMOD_DSP_PARAMETER_DATA_TYPE_3DATTRIBUTES = -2, - FMOD_DSP_PARAMETER_DATA_TYPE_SIDECHAIN = -3, - FMOD_DSP_PARAMETER_DATA_TYPE_FFT = -4, - FMOD_DSP_PARAMETER_DATA_TYPE_3DATTRIBUTES_MULTI = -5, -} FMOD_DSP_PARAMETER_DATA_TYPE; - -/* - DSP Callbacks -*/ -typedef FMOD_RESULT (F_CALL *FMOD_DSP_CREATE_CALLBACK) (FMOD_DSP_STATE *dsp_state); -typedef FMOD_RESULT (F_CALL *FMOD_DSP_RELEASE_CALLBACK) (FMOD_DSP_STATE *dsp_state); -typedef FMOD_RESULT (F_CALL *FMOD_DSP_RESET_CALLBACK) (FMOD_DSP_STATE *dsp_state); -typedef FMOD_RESULT (F_CALL *FMOD_DSP_READ_CALLBACK) (FMOD_DSP_STATE *dsp_state, float *inbuffer, float *outbuffer, unsigned int length, int inchannels, int *outchannels); -typedef FMOD_RESULT (F_CALL *FMOD_DSP_PROCESS_CALLBACK) (FMOD_DSP_STATE *dsp_state, unsigned int length, const FMOD_DSP_BUFFER_ARRAY *inbufferarray, FMOD_DSP_BUFFER_ARRAY *outbufferarray, FMOD_BOOL inputsidle, FMOD_DSP_PROCESS_OPERATION op); -typedef FMOD_RESULT (F_CALL *FMOD_DSP_SETPOSITION_CALLBACK) (FMOD_DSP_STATE *dsp_state, unsigned int pos); -typedef FMOD_RESULT (F_CALL *FMOD_DSP_SHOULDIPROCESS_CALLBACK) (FMOD_DSP_STATE *dsp_state, FMOD_BOOL inputsidle, unsigned int length, FMOD_CHANNELMASK inmask, int inchannels, FMOD_SPEAKERMODE speakermode); -typedef FMOD_RESULT (F_CALL *FMOD_DSP_SETPARAM_FLOAT_CALLBACK) (FMOD_DSP_STATE *dsp_state, int index, float value); -typedef FMOD_RESULT (F_CALL *FMOD_DSP_SETPARAM_INT_CALLBACK) (FMOD_DSP_STATE *dsp_state, int index, int value); -typedef FMOD_RESULT (F_CALL *FMOD_DSP_SETPARAM_BOOL_CALLBACK) (FMOD_DSP_STATE *dsp_state, int index, FMOD_BOOL value); -typedef FMOD_RESULT (F_CALL *FMOD_DSP_SETPARAM_DATA_CALLBACK) (FMOD_DSP_STATE *dsp_state, int index, void *data, unsigned int length); -typedef FMOD_RESULT (F_CALL *FMOD_DSP_GETPARAM_FLOAT_CALLBACK) (FMOD_DSP_STATE *dsp_state, int index, float *value, char *valuestr); -typedef FMOD_RESULT (F_CALL *FMOD_DSP_GETPARAM_INT_CALLBACK) (FMOD_DSP_STATE *dsp_state, int index, int *value, char *valuestr); -typedef FMOD_RESULT (F_CALL *FMOD_DSP_GETPARAM_BOOL_CALLBACK) (FMOD_DSP_STATE *dsp_state, int index, FMOD_BOOL *value, char *valuestr); -typedef FMOD_RESULT (F_CALL *FMOD_DSP_GETPARAM_DATA_CALLBACK) (FMOD_DSP_STATE *dsp_state, int index, void **data, unsigned int *length, char *valuestr); -typedef FMOD_RESULT (F_CALL *FMOD_DSP_SYSTEM_REGISTER_CALLBACK) (FMOD_DSP_STATE *dsp_state); -typedef FMOD_RESULT (F_CALL *FMOD_DSP_SYSTEM_DEREGISTER_CALLBACK) (FMOD_DSP_STATE *dsp_state); -typedef FMOD_RESULT (F_CALL *FMOD_DSP_SYSTEM_MIX_CALLBACK) (FMOD_DSP_STATE *dsp_state, int stage); - -/* - DSP Functions -*/ -typedef void * (F_CALL *FMOD_DSP_ALLOC_FUNC) (unsigned int size, FMOD_MEMORY_TYPE type, const char *sourcestr); -typedef void * (F_CALL *FMOD_DSP_REALLOC_FUNC) (void *ptr, unsigned int size, FMOD_MEMORY_TYPE type, const char *sourcestr); -typedef void (F_CALL *FMOD_DSP_FREE_FUNC) (void *ptr, FMOD_MEMORY_TYPE type, const char *sourcestr); -typedef void (F_CALL *FMOD_DSP_LOG_FUNC) (FMOD_DEBUG_FLAGS level, const char *file, int line, const char *function, const char *string, ...); -typedef FMOD_RESULT (F_CALL *FMOD_DSP_GETSAMPLERATE_FUNC) (FMOD_DSP_STATE *dsp_state, int *rate); -typedef FMOD_RESULT (F_CALL *FMOD_DSP_GETBLOCKSIZE_FUNC) (FMOD_DSP_STATE *dsp_state, unsigned int *blocksize); -typedef FMOD_RESULT (F_CALL *FMOD_DSP_GETSPEAKERMODE_FUNC) (FMOD_DSP_STATE *dsp_state, FMOD_SPEAKERMODE *speakermode_mixer, FMOD_SPEAKERMODE *speakermode_output); -typedef FMOD_RESULT (F_CALL *FMOD_DSP_GETCLOCK_FUNC) (FMOD_DSP_STATE *dsp_state, unsigned long long *clock, unsigned int *offset, unsigned int *length); -typedef FMOD_RESULT (F_CALL *FMOD_DSP_GETLISTENERATTRIBUTES_FUNC) (FMOD_DSP_STATE *dsp_state, int *numlisteners, FMOD_3D_ATTRIBUTES *attributes); -typedef FMOD_RESULT (F_CALL *FMOD_DSP_GETUSERDATA_FUNC) (FMOD_DSP_STATE *dsp_state, void **userdata); -typedef FMOD_RESULT (F_CALL *FMOD_DSP_DFT_FFTREAL_FUNC) (FMOD_DSP_STATE *dsp_state, int size, const float *signal, FMOD_COMPLEX* dft, const float *window, int signalhop); -typedef FMOD_RESULT (F_CALL *FMOD_DSP_DFT_IFFTREAL_FUNC) (FMOD_DSP_STATE *dsp_state, int size, const FMOD_COMPLEX *dft, float* signal, const float *window, int signalhop); -typedef FMOD_RESULT (F_CALL *FMOD_DSP_PAN_SUMMONOMATRIX_FUNC) (FMOD_DSP_STATE *dsp_state, FMOD_SPEAKERMODE sourceSpeakerMode, float lowFrequencyGain, float overallGain, float *matrix); -typedef FMOD_RESULT (F_CALL *FMOD_DSP_PAN_SUMSTEREOMATRIX_FUNC) (FMOD_DSP_STATE *dsp_state, FMOD_SPEAKERMODE sourceSpeakerMode, float pan, float lowFrequencyGain, float overallGain, int matrixHop, float *matrix); -typedef FMOD_RESULT (F_CALL *FMOD_DSP_PAN_SUMSURROUNDMATRIX_FUNC) (FMOD_DSP_STATE *dsp_state, FMOD_SPEAKERMODE sourceSpeakerMode, FMOD_SPEAKERMODE targetSpeakerMode, float direction, float extent, float rotation, float lowFrequencyGain, float overallGain, int matrixHop, float *matrix, FMOD_DSP_PAN_SURROUND_FLAGS flags); -typedef FMOD_RESULT (F_CALL *FMOD_DSP_PAN_SUMMONOTOSURROUNDMATRIX_FUNC) (FMOD_DSP_STATE *dsp_state, FMOD_SPEAKERMODE targetSpeakerMode, float direction, float extent, float lowFrequencyGain, float overallGain, int matrixHop, float *matrix); -typedef FMOD_RESULT (F_CALL *FMOD_DSP_PAN_SUMSTEREOTOSURROUNDMATRIX_FUNC) (FMOD_DSP_STATE *dsp_state, FMOD_SPEAKERMODE targetSpeakerMode, float direction, float extent, float rotation, float lowFrequencyGain, float overallGain, int matrixHop, float *matrix); -typedef FMOD_RESULT (F_CALL *FMOD_DSP_PAN_GETROLLOFFGAIN_FUNC) (FMOD_DSP_STATE *dsp_state, FMOD_DSP_PAN_3D_ROLLOFF_TYPE rolloff, float distance, float mindistance, float maxdistance, float *gain); - -/* - DSP Structures -*/ -struct FMOD_DSP_BUFFER_ARRAY -{ - int numbuffers; - int *buffernumchannels; - FMOD_CHANNELMASK *bufferchannelmask; - float **buffers; - FMOD_SPEAKERMODE speakermode; -}; - -struct FMOD_COMPLEX -{ - float real; - float imag; -}; - -typedef struct FMOD_DSP_PARAMETER_FLOAT_MAPPING_PIECEWISE_LINEAR -{ - int numpoints; - float *pointparamvalues; - float *pointpositions; -} FMOD_DSP_PARAMETER_FLOAT_MAPPING_PIECEWISE_LINEAR; - -typedef struct FMOD_DSP_PARAMETER_FLOAT_MAPPING -{ - FMOD_DSP_PARAMETER_FLOAT_MAPPING_TYPE type; - FMOD_DSP_PARAMETER_FLOAT_MAPPING_PIECEWISE_LINEAR piecewiselinearmapping; -} FMOD_DSP_PARAMETER_FLOAT_MAPPING; - -typedef struct FMOD_DSP_PARAMETER_DESC_FLOAT -{ - float min; - float max; - float defaultval; - FMOD_DSP_PARAMETER_FLOAT_MAPPING mapping; -} FMOD_DSP_PARAMETER_DESC_FLOAT; - -typedef struct FMOD_DSP_PARAMETER_DESC_INT -{ - int min; - int max; - int defaultval; - FMOD_BOOL goestoinf; - const char* const* valuenames; -} FMOD_DSP_PARAMETER_DESC_INT; - -typedef struct FMOD_DSP_PARAMETER_DESC_BOOL -{ - FMOD_BOOL defaultval; - const char* const* valuenames; -} FMOD_DSP_PARAMETER_DESC_BOOL; - -typedef struct FMOD_DSP_PARAMETER_DESC_DATA -{ - int datatype; -} FMOD_DSP_PARAMETER_DESC_DATA; - -typedef struct FMOD_DSP_PARAMETER_DESC -{ - FMOD_DSP_PARAMETER_TYPE type; - char name[16]; - char label[16]; - const char *description; - - union - { - FMOD_DSP_PARAMETER_DESC_FLOAT floatdesc; - FMOD_DSP_PARAMETER_DESC_INT intdesc; - FMOD_DSP_PARAMETER_DESC_BOOL booldesc; - FMOD_DSP_PARAMETER_DESC_DATA datadesc; - }; -} FMOD_DSP_PARAMETER_DESC; - -typedef struct FMOD_DSP_PARAMETER_OVERALLGAIN -{ - float linear_gain; - float linear_gain_additive; -} FMOD_DSP_PARAMETER_OVERALLGAIN; - -typedef struct FMOD_DSP_PARAMETER_3DATTRIBUTES -{ - FMOD_3D_ATTRIBUTES relative; - FMOD_3D_ATTRIBUTES absolute; -} FMOD_DSP_PARAMETER_3DATTRIBUTES; - -typedef struct FMOD_DSP_PARAMETER_3DATTRIBUTES_MULTI -{ - int numlisteners; - FMOD_3D_ATTRIBUTES relative[FMOD_MAX_LISTENERS]; - float weight[FMOD_MAX_LISTENERS]; - FMOD_3D_ATTRIBUTES absolute; -} FMOD_DSP_PARAMETER_3DATTRIBUTES_MULTI; - -typedef struct FMOD_DSP_PARAMETER_SIDECHAIN -{ - FMOD_BOOL sidechainenable; -} FMOD_DSP_PARAMETER_SIDECHAIN; - -typedef struct FMOD_DSP_PARAMETER_FFT -{ - int length; - int numchannels; - float *spectrum[32]; -} FMOD_DSP_PARAMETER_FFT; - -typedef struct FMOD_DSP_DESCRIPTION -{ - unsigned int pluginsdkversion; - char name[32]; - unsigned int version; - int numinputbuffers; - int numoutputbuffers; - FMOD_DSP_CREATE_CALLBACK create; - FMOD_DSP_RELEASE_CALLBACK release; - FMOD_DSP_RESET_CALLBACK reset; - FMOD_DSP_READ_CALLBACK read; - FMOD_DSP_PROCESS_CALLBACK process; - FMOD_DSP_SETPOSITION_CALLBACK setposition; - - int numparameters; - FMOD_DSP_PARAMETER_DESC **paramdesc; - FMOD_DSP_SETPARAM_FLOAT_CALLBACK setparameterfloat; - FMOD_DSP_SETPARAM_INT_CALLBACK setparameterint; - FMOD_DSP_SETPARAM_BOOL_CALLBACK setparameterbool; - FMOD_DSP_SETPARAM_DATA_CALLBACK setparameterdata; - FMOD_DSP_GETPARAM_FLOAT_CALLBACK getparameterfloat; - FMOD_DSP_GETPARAM_INT_CALLBACK getparameterint; - FMOD_DSP_GETPARAM_BOOL_CALLBACK getparameterbool; - FMOD_DSP_GETPARAM_DATA_CALLBACK getparameterdata; - FMOD_DSP_SHOULDIPROCESS_CALLBACK shouldiprocess; - void *userdata; - - FMOD_DSP_SYSTEM_REGISTER_CALLBACK sys_register; - FMOD_DSP_SYSTEM_DEREGISTER_CALLBACK sys_deregister; - FMOD_DSP_SYSTEM_MIX_CALLBACK sys_mix; - -} FMOD_DSP_DESCRIPTION; - -typedef struct FMOD_DSP_STATE_DFT_FUNCTIONS -{ - FMOD_DSP_DFT_FFTREAL_FUNC fftreal; - FMOD_DSP_DFT_IFFTREAL_FUNC inversefftreal; -} FMOD_DSP_STATE_DFT_FUNCTIONS; - -typedef struct FMOD_DSP_STATE_PAN_FUNCTIONS -{ - FMOD_DSP_PAN_SUMMONOMATRIX_FUNC summonomatrix; - FMOD_DSP_PAN_SUMSTEREOMATRIX_FUNC sumstereomatrix; - FMOD_DSP_PAN_SUMSURROUNDMATRIX_FUNC sumsurroundmatrix; - FMOD_DSP_PAN_SUMMONOTOSURROUNDMATRIX_FUNC summonotosurroundmatrix; - FMOD_DSP_PAN_SUMSTEREOTOSURROUNDMATRIX_FUNC sumstereotosurroundmatrix; - FMOD_DSP_PAN_GETROLLOFFGAIN_FUNC getrolloffgain; -} FMOD_DSP_STATE_PAN_FUNCTIONS; - -typedef struct FMOD_DSP_STATE_FUNCTIONS -{ - FMOD_DSP_ALLOC_FUNC alloc; - FMOD_DSP_REALLOC_FUNC realloc; - FMOD_DSP_FREE_FUNC free; - FMOD_DSP_GETSAMPLERATE_FUNC getsamplerate; - FMOD_DSP_GETBLOCKSIZE_FUNC getblocksize; - FMOD_DSP_STATE_DFT_FUNCTIONS *dft; - FMOD_DSP_STATE_PAN_FUNCTIONS *pan; - FMOD_DSP_GETSPEAKERMODE_FUNC getspeakermode; - FMOD_DSP_GETCLOCK_FUNC getclock; - FMOD_DSP_GETLISTENERATTRIBUTES_FUNC getlistenerattributes; - FMOD_DSP_LOG_FUNC log; - FMOD_DSP_GETUSERDATA_FUNC getuserdata; -} FMOD_DSP_STATE_FUNCTIONS; - -struct FMOD_DSP_STATE -{ - void *instance; - void *plugindata; - FMOD_CHANNELMASK channelmask; - FMOD_SPEAKERMODE source_speakermode; - float *sidechaindata; - int sidechainchannels; - FMOD_DSP_STATE_FUNCTIONS *functions; - int systemobject; -}; - -typedef struct FMOD_DSP_METERING_INFO -{ - int numsamples; - float peaklevel[32]; - float rmslevel[32]; - short numchannels; -} FMOD_DSP_METERING_INFO; - -/* - DSP Macros -*/ -#define FMOD_DSP_INIT_PARAMDESC_FLOAT(_paramstruct, _name, _label, _description, _min, _max, _defaultval) \ - memset(&(_paramstruct), 0, sizeof(_paramstruct)); \ - (_paramstruct).type = FMOD_DSP_PARAMETER_TYPE_FLOAT; \ - strncpy((_paramstruct).name, _name, 15); \ - strncpy((_paramstruct).label, _label, 15); \ - (_paramstruct).description = _description; \ - (_paramstruct).floatdesc.min = _min; \ - (_paramstruct).floatdesc.max = _max; \ - (_paramstruct).floatdesc.defaultval = _defaultval; \ - (_paramstruct).floatdesc.mapping.type = FMOD_DSP_PARAMETER_FLOAT_MAPPING_TYPE_AUTO; - -#define FMOD_DSP_INIT_PARAMDESC_FLOAT_WITH_MAPPING(_paramstruct, _name, _label, _description, _defaultval, _values, _positions); \ - memset(&(_paramstruct), 0, sizeof(_paramstruct)); \ - (_paramstruct).type = FMOD_DSP_PARAMETER_TYPE_FLOAT; \ - strncpy((_paramstruct).name, _name , 15); \ - strncpy((_paramstruct).label, _label, 15); \ - (_paramstruct).description = _description; \ - (_paramstruct).floatdesc.min = _values[0]; \ - (_paramstruct).floatdesc.max = _values[sizeof(_values) / sizeof(float) - 1]; \ - (_paramstruct).floatdesc.defaultval = _defaultval; \ - (_paramstruct).floatdesc.mapping.type = FMOD_DSP_PARAMETER_FLOAT_MAPPING_TYPE_PIECEWISE_LINEAR; \ - (_paramstruct).floatdesc.mapping.piecewiselinearmapping.numpoints = sizeof(_values) / sizeof(float); \ - (_paramstruct).floatdesc.mapping.piecewiselinearmapping.pointparamvalues = _values; \ - (_paramstruct).floatdesc.mapping.piecewiselinearmapping.pointpositions = _positions; - -#define FMOD_DSP_INIT_PARAMDESC_INT(_paramstruct, _name, _label, _description, _min, _max, _defaultval, _goestoinf, _valuenames) \ - memset(&(_paramstruct), 0, sizeof(_paramstruct)); \ - (_paramstruct).type = FMOD_DSP_PARAMETER_TYPE_INT; \ - strncpy((_paramstruct).name, _name , 15); \ - strncpy((_paramstruct).label, _label, 15); \ - (_paramstruct).description = _description; \ - (_paramstruct).intdesc.min = _min; \ - (_paramstruct).intdesc.max = _max; \ - (_paramstruct).intdesc.defaultval = _defaultval; \ - (_paramstruct).intdesc.goestoinf = _goestoinf; \ - (_paramstruct).intdesc.valuenames = _valuenames; - -#define FMOD_DSP_INIT_PARAMDESC_INT_ENUMERATED(_paramstruct, _name, _label, _description, _defaultval, _valuenames) \ - memset(&(_paramstruct), 0, sizeof(_paramstruct)); \ - (_paramstruct).type = FMOD_DSP_PARAMETER_TYPE_INT; \ - strncpy((_paramstruct).name, _name , 15); \ - strncpy((_paramstruct).label, _label, 15); \ - (_paramstruct).description = _description; \ - (_paramstruct).intdesc.min = 0; \ - (_paramstruct).intdesc.max = sizeof(_valuenames) / sizeof(char*) - 1; \ - (_paramstruct).intdesc.defaultval = _defaultval; \ - (_paramstruct).intdesc.goestoinf = false; \ - (_paramstruct).intdesc.valuenames = _valuenames; - -#define FMOD_DSP_INIT_PARAMDESC_BOOL(_paramstruct, _name, _label, _description, _defaultval, _valuenames) \ - memset(&(_paramstruct), 0, sizeof(_paramstruct)); \ - (_paramstruct).type = FMOD_DSP_PARAMETER_TYPE_BOOL; \ - strncpy((_paramstruct).name, _name , 15); \ - strncpy((_paramstruct).label, _label, 15); \ - (_paramstruct).description = _description; \ - (_paramstruct).booldesc.defaultval = _defaultval; \ - (_paramstruct).booldesc.valuenames = _valuenames; - -#define FMOD_DSP_INIT_PARAMDESC_DATA(_paramstruct, _name, _label, _description, _datatype) \ - memset(&(_paramstruct), 0, sizeof(_paramstruct)); \ - (_paramstruct).type = FMOD_DSP_PARAMETER_TYPE_DATA; \ - strncpy((_paramstruct).name, _name , 15); \ - strncpy((_paramstruct).label, _label, 15); \ - (_paramstruct).description = _description; \ - (_paramstruct).datadesc.datatype = _datatype; - -#define FMOD_DSP_ALLOC(_state, _size) \ - (_state)->functions->alloc(_size, FMOD_MEMORY_NORMAL, __FILE__) -#define FMOD_DSP_REALLOC(_state, _ptr, _size) \ - (_state)->functions->realloc(_ptr, _size, FMOD_MEMORY_NORMAL, __FILE__) -#define FMOD_DSP_FREE(_state, _ptr) \ - (_state)->functions->free(_ptr, FMOD_MEMORY_NORMAL, __FILE__) -#define FMOD_DSP_LOG(_state, _level, _location, _format, ...) \ - (_state)->functions->log(_level, __FILE__, __LINE__, _location, _format, __VA_ARGS__) -#define FMOD_DSP_GETSAMPLERATE(_state, _rate) \ - (_state)->functions->getsamplerate(_state, _rate) -#define FMOD_DSP_GETBLOCKSIZE(_state, _blocksize) \ - (_state)->functions->getblocksize(_state, _blocksize) -#define FMOD_DSP_GETSPEAKERMODE(_state, _speakermodemix, _speakermodeout) \ - (_state)->functions->getspeakermode(_state, _speakermodemix, _speakermodeout) -#define FMOD_DSP_GETCLOCK(_state, _clock, _offset, _length) \ - (_state)->functions->getclock(_state, _clock, _offset, _length) -#define FMOD_DSP_GETLISTENERATTRIBUTES(_state, _numlisteners, _attributes) \ - (_state)->functions->getlistenerattributes(_state, _numlisteners, _attributes) -#define FMOD_DSP_GETUSERDATA(_state, _userdata) \ - (_state)->functions->getuserdata(_state, _userdata) -#define FMOD_DSP_DFT_FFTREAL(_state, _size, _signal, _dft, _window, _signalhop) \ - (_state)->functions->dft->fftreal(_state, _size, _signal, _dft, _window, _signalhop) -#define FMOD_DSP_DFT_IFFTREAL(_state, _size, _dft, _signal, _window, _signalhop) \ - (_state)->functions->dft->inversefftreal(_state, _size, _dft, _signal, _window, _signalhop) -#define FMOD_DSP_PAN_SUMMONOMATRIX(_state, _sourcespeakermode, _lowfrequencygain, _overallgain, _matrix) \ - (_state)->functions->pan->summonomatrix(_state, _sourcespeakermode, _lowfrequencygain, _overallgain, _matrix) -#define FMOD_DSP_PAN_SUMSTEREOMATRIX(_state, _sourcespeakermode, _pan, _lowfrequencygain, _overallgain, _matrixhop, _matrix) \ - (_state)->functions->pan->sumstereomatrix(_state, _sourcespeakermode, _pan, _lowfrequencygain, _overallgain, _matrixhop, _matrix) -#define FMOD_DSP_PAN_SUMSURROUNDMATRIX(_state, _sourcespeakermode, _targetspeakermode, _direction, _extent, _rotation, _lowfrequencygain, _overallgain, _matrixhop, _matrix, _flags) \ - (_state)->functions->pan->sumsurroundmatrix(_state, _sourcespeakermode, _targetspeakermode, _direction, _extent, _rotation, _lowfrequencygain, _overallgain, _matrixhop, _matrix, _flags) -#define FMOD_DSP_PAN_SUMMONOTOSURROUNDMATRIX(_state, _targetspeakermode, _direction, _extent, _lowfrequencygain, _overallgain, _matrixhop, _matrix) \ - (_state)->functions->pan->summonotosurroundmatrix(_state, _targetspeakermode, _direction, _extent, _lowfrequencygain, _overallgain, _matrixhop, _matrix) -#define FMOD_DSP_PAN_SUMSTEREOTOSURROUNDMATRIX(_state, _targetspeakermode, _direction, _extent, _rotation, _lowfrequencygain, _overallgain, matrixhop, _matrix) \ - (_state)->functions->pan->sumstereotosurroundmatrix(_state, _targetspeakermode, _direction, _extent, _rotation, _lowfrequencygain, _overallgain, matrixhop, _matrix) -#define FMOD_DSP_PAN_GETROLLOFFGAIN(_state, _rolloff, _distance, _mindistance, _maxdistance, _gain) \ - (_state)->functions->pan->getrolloffgain(_state, _rolloff, _distance, _mindistance, _maxdistance, _gain) - -#endif - diff --git a/engine/fmodcore/inc/fmod_dsp_effects.h b/engine/fmodcore/inc/fmod_dsp_effects.h deleted file mode 100644 index 079337c..0000000 --- a/engine/fmodcore/inc/fmod_dsp_effects.h +++ /dev/null @@ -1,537 +0,0 @@ -/* ============================================================================================================= */ -/* FMOD Core API - Built-in effects header file. */ -/* Copyright (c), Firelight Technologies Pty, Ltd. 2004-2021. */ -/* */ -/* In this header you can find parameter structures for FMOD system registered DSP effects */ -/* and generators. */ -/* */ -/* For more detail visit: */ -/* https://fmod.com/resources/documentation-api?version=2.0&page=core-api-common-dsp-effects.html#fmod_dsp_type */ -/* ============================================================================================================= */ - -#ifndef _FMOD_DSP_EFFECTS_H -#define _FMOD_DSP_EFFECTS_H - -typedef enum -{ - FMOD_DSP_TYPE_UNKNOWN, - FMOD_DSP_TYPE_MIXER, - FMOD_DSP_TYPE_OSCILLATOR, - FMOD_DSP_TYPE_LOWPASS, - FMOD_DSP_TYPE_ITLOWPASS, - FMOD_DSP_TYPE_HIGHPASS, - FMOD_DSP_TYPE_ECHO, - FMOD_DSP_TYPE_FADER, - FMOD_DSP_TYPE_FLANGE, - FMOD_DSP_TYPE_DISTORTION, - FMOD_DSP_TYPE_NORMALIZE, - FMOD_DSP_TYPE_LIMITER, - FMOD_DSP_TYPE_PARAMEQ, - FMOD_DSP_TYPE_PITCHSHIFT, - FMOD_DSP_TYPE_CHORUS, - FMOD_DSP_TYPE_VSTPLUGIN, - FMOD_DSP_TYPE_WINAMPPLUGIN, - FMOD_DSP_TYPE_ITECHO, - FMOD_DSP_TYPE_COMPRESSOR, - FMOD_DSP_TYPE_SFXREVERB, - FMOD_DSP_TYPE_LOWPASS_SIMPLE, - FMOD_DSP_TYPE_DELAY, - FMOD_DSP_TYPE_TREMOLO, - FMOD_DSP_TYPE_LADSPAPLUGIN, - FMOD_DSP_TYPE_SEND, - FMOD_DSP_TYPE_RETURN, - FMOD_DSP_TYPE_HIGHPASS_SIMPLE, - FMOD_DSP_TYPE_PAN, - FMOD_DSP_TYPE_THREE_EQ, - FMOD_DSP_TYPE_FFT, - FMOD_DSP_TYPE_LOUDNESS_METER, - FMOD_DSP_TYPE_ENVELOPEFOLLOWER, - FMOD_DSP_TYPE_CONVOLUTIONREVERB, - FMOD_DSP_TYPE_CHANNELMIX, - FMOD_DSP_TYPE_TRANSCEIVER, - FMOD_DSP_TYPE_OBJECTPAN, - FMOD_DSP_TYPE_MULTIBAND_EQ, - - FMOD_DSP_TYPE_MAX, - FMOD_DSP_TYPE_FORCEINT = 65536 /* Makes sure this enum is signed 32bit. */ -} FMOD_DSP_TYPE; - -/* - =================================================================================================== - - FMOD built in effect parameters. - Use DSP::setParameter with these enums for the 'index' parameter. - - =================================================================================================== -*/ - -typedef enum -{ - FMOD_DSP_OSCILLATOR_TYPE, - FMOD_DSP_OSCILLATOR_RATE -} FMOD_DSP_OSCILLATOR; - - -typedef enum -{ - FMOD_DSP_LOWPASS_CUTOFF, - FMOD_DSP_LOWPASS_RESONANCE -} FMOD_DSP_LOWPASS; - - -typedef enum -{ - FMOD_DSP_ITLOWPASS_CUTOFF, - FMOD_DSP_ITLOWPASS_RESONANCE -} FMOD_DSP_ITLOWPASS; - - -typedef enum -{ - FMOD_DSP_HIGHPASS_CUTOFF, - FMOD_DSP_HIGHPASS_RESONANCE -} FMOD_DSP_HIGHPASS; - - -typedef enum -{ - FMOD_DSP_ECHO_DELAY, - FMOD_DSP_ECHO_FEEDBACK, - FMOD_DSP_ECHO_DRYLEVEL, - FMOD_DSP_ECHO_WETLEVEL -} FMOD_DSP_ECHO; - - -typedef enum FMOD_DSP_FADER -{ - FMOD_DSP_FADER_GAIN, - FMOD_DSP_FADER_OVERALL_GAIN, -} FMOD_DSP_FADER; - - -typedef enum -{ - FMOD_DSP_FLANGE_MIX, - FMOD_DSP_FLANGE_DEPTH, - FMOD_DSP_FLANGE_RATE -} FMOD_DSP_FLANGE; - - -typedef enum -{ - FMOD_DSP_DISTORTION_LEVEL -} FMOD_DSP_DISTORTION; - - -typedef enum -{ - FMOD_DSP_NORMALIZE_FADETIME, - FMOD_DSP_NORMALIZE_THRESHHOLD, - FMOD_DSP_NORMALIZE_MAXAMP -} FMOD_DSP_NORMALIZE; - - -typedef enum -{ - FMOD_DSP_LIMITER_RELEASETIME, - FMOD_DSP_LIMITER_CEILING, - FMOD_DSP_LIMITER_MAXIMIZERGAIN, - FMOD_DSP_LIMITER_MODE, -} FMOD_DSP_LIMITER; - - -typedef enum -{ - FMOD_DSP_PARAMEQ_CENTER, - FMOD_DSP_PARAMEQ_BANDWIDTH, - FMOD_DSP_PARAMEQ_GAIN -} FMOD_DSP_PARAMEQ; - - -typedef enum FMOD_DSP_MULTIBAND_EQ -{ - FMOD_DSP_MULTIBAND_EQ_A_FILTER, - FMOD_DSP_MULTIBAND_EQ_A_FREQUENCY, - FMOD_DSP_MULTIBAND_EQ_A_Q, - FMOD_DSP_MULTIBAND_EQ_A_GAIN, - FMOD_DSP_MULTIBAND_EQ_B_FILTER, - FMOD_DSP_MULTIBAND_EQ_B_FREQUENCY, - FMOD_DSP_MULTIBAND_EQ_B_Q, - FMOD_DSP_MULTIBAND_EQ_B_GAIN, - FMOD_DSP_MULTIBAND_EQ_C_FILTER, - FMOD_DSP_MULTIBAND_EQ_C_FREQUENCY, - FMOD_DSP_MULTIBAND_EQ_C_Q, - FMOD_DSP_MULTIBAND_EQ_C_GAIN, - FMOD_DSP_MULTIBAND_EQ_D_FILTER, - FMOD_DSP_MULTIBAND_EQ_D_FREQUENCY, - FMOD_DSP_MULTIBAND_EQ_D_Q, - FMOD_DSP_MULTIBAND_EQ_D_GAIN, - FMOD_DSP_MULTIBAND_EQ_E_FILTER, - FMOD_DSP_MULTIBAND_EQ_E_FREQUENCY, - FMOD_DSP_MULTIBAND_EQ_E_Q, - FMOD_DSP_MULTIBAND_EQ_E_GAIN, -} FMOD_DSP_MULTIBAND_EQ; - - -typedef enum FMOD_DSP_MULTIBAND_EQ_FILTER_TYPE -{ - FMOD_DSP_MULTIBAND_EQ_FILTER_DISABLED, - FMOD_DSP_MULTIBAND_EQ_FILTER_LOWPASS_12DB, - FMOD_DSP_MULTIBAND_EQ_FILTER_LOWPASS_24DB, - FMOD_DSP_MULTIBAND_EQ_FILTER_LOWPASS_48DB, - FMOD_DSP_MULTIBAND_EQ_FILTER_HIGHPASS_12DB, - FMOD_DSP_MULTIBAND_EQ_FILTER_HIGHPASS_24DB, - FMOD_DSP_MULTIBAND_EQ_FILTER_HIGHPASS_48DB, - FMOD_DSP_MULTIBAND_EQ_FILTER_LOWSHELF, - FMOD_DSP_MULTIBAND_EQ_FILTER_HIGHSHELF, - FMOD_DSP_MULTIBAND_EQ_FILTER_PEAKING, - FMOD_DSP_MULTIBAND_EQ_FILTER_BANDPASS, - FMOD_DSP_MULTIBAND_EQ_FILTER_NOTCH, - FMOD_DSP_MULTIBAND_EQ_FILTER_ALLPASS, -} FMOD_DSP_MULTIBAND_EQ_FILTER_TYPE; - - -typedef enum -{ - FMOD_DSP_PITCHSHIFT_PITCH, - FMOD_DSP_PITCHSHIFT_FFTSIZE, - FMOD_DSP_PITCHSHIFT_OVERLAP, - FMOD_DSP_PITCHSHIFT_MAXCHANNELS -} FMOD_DSP_PITCHSHIFT; - - -typedef enum -{ - FMOD_DSP_CHORUS_MIX, - FMOD_DSP_CHORUS_RATE, - FMOD_DSP_CHORUS_DEPTH, -} FMOD_DSP_CHORUS; - - -typedef enum -{ - FMOD_DSP_ITECHO_WETDRYMIX, - FMOD_DSP_ITECHO_FEEDBACK, - FMOD_DSP_ITECHO_LEFTDELAY, - FMOD_DSP_ITECHO_RIGHTDELAY, - FMOD_DSP_ITECHO_PANDELAY -} FMOD_DSP_ITECHO; - -typedef enum -{ - FMOD_DSP_COMPRESSOR_THRESHOLD, - FMOD_DSP_COMPRESSOR_RATIO, - FMOD_DSP_COMPRESSOR_ATTACK, - FMOD_DSP_COMPRESSOR_RELEASE, - FMOD_DSP_COMPRESSOR_GAINMAKEUP, - FMOD_DSP_COMPRESSOR_USESIDECHAIN, - FMOD_DSP_COMPRESSOR_LINKED -} FMOD_DSP_COMPRESSOR; - -typedef enum -{ - FMOD_DSP_SFXREVERB_DECAYTIME, - FMOD_DSP_SFXREVERB_EARLYDELAY, - FMOD_DSP_SFXREVERB_LATEDELAY, - FMOD_DSP_SFXREVERB_HFREFERENCE, - FMOD_DSP_SFXREVERB_HFDECAYRATIO, - FMOD_DSP_SFXREVERB_DIFFUSION, - FMOD_DSP_SFXREVERB_DENSITY, - FMOD_DSP_SFXREVERB_LOWSHELFFREQUENCY, - FMOD_DSP_SFXREVERB_LOWSHELFGAIN, - FMOD_DSP_SFXREVERB_HIGHCUT, - FMOD_DSP_SFXREVERB_EARLYLATEMIX, - FMOD_DSP_SFXREVERB_WETLEVEL, - FMOD_DSP_SFXREVERB_DRYLEVEL -} FMOD_DSP_SFXREVERB; - -typedef enum -{ - FMOD_DSP_LOWPASS_SIMPLE_CUTOFF -} FMOD_DSP_LOWPASS_SIMPLE; - - -typedef enum -{ - FMOD_DSP_DELAY_CH0, - FMOD_DSP_DELAY_CH1, - FMOD_DSP_DELAY_CH2, - FMOD_DSP_DELAY_CH3, - FMOD_DSP_DELAY_CH4, - FMOD_DSP_DELAY_CH5, - FMOD_DSP_DELAY_CH6, - FMOD_DSP_DELAY_CH7, - FMOD_DSP_DELAY_CH8, - FMOD_DSP_DELAY_CH9, - FMOD_DSP_DELAY_CH10, - FMOD_DSP_DELAY_CH11, - FMOD_DSP_DELAY_CH12, - FMOD_DSP_DELAY_CH13, - FMOD_DSP_DELAY_CH14, - FMOD_DSP_DELAY_CH15, - FMOD_DSP_DELAY_MAXDELAY -} FMOD_DSP_DELAY; - - -typedef enum -{ - FMOD_DSP_TREMOLO_FREQUENCY, - FMOD_DSP_TREMOLO_DEPTH, - FMOD_DSP_TREMOLO_SHAPE, - FMOD_DSP_TREMOLO_SKEW, - FMOD_DSP_TREMOLO_DUTY, - FMOD_DSP_TREMOLO_SQUARE, - FMOD_DSP_TREMOLO_PHASE, - FMOD_DSP_TREMOLO_SPREAD -} FMOD_DSP_TREMOLO; - - -typedef enum -{ - FMOD_DSP_SEND_RETURNID, - FMOD_DSP_SEND_LEVEL, -} FMOD_DSP_SEND; - - -typedef enum -{ - FMOD_DSP_RETURN_ID, - FMOD_DSP_RETURN_INPUT_SPEAKER_MODE -} FMOD_DSP_RETURN; - - -typedef enum -{ - FMOD_DSP_HIGHPASS_SIMPLE_CUTOFF -} FMOD_DSP_HIGHPASS_SIMPLE; - - -typedef enum -{ - FMOD_DSP_PAN_2D_STEREO_MODE_DISTRIBUTED, - FMOD_DSP_PAN_2D_STEREO_MODE_DISCRETE -} FMOD_DSP_PAN_2D_STEREO_MODE_TYPE; - - -typedef enum -{ - FMOD_DSP_PAN_MODE_MONO, - FMOD_DSP_PAN_MODE_STEREO, - FMOD_DSP_PAN_MODE_SURROUND -} FMOD_DSP_PAN_MODE_TYPE; - - -typedef enum -{ - FMOD_DSP_PAN_3D_ROLLOFF_LINEARSQUARED, - FMOD_DSP_PAN_3D_ROLLOFF_LINEAR, - FMOD_DSP_PAN_3D_ROLLOFF_INVERSE, - FMOD_DSP_PAN_3D_ROLLOFF_INVERSETAPERED, - FMOD_DSP_PAN_3D_ROLLOFF_CUSTOM -} FMOD_DSP_PAN_3D_ROLLOFF_TYPE; - - -typedef enum -{ - FMOD_DSP_PAN_3D_EXTENT_MODE_AUTO, - FMOD_DSP_PAN_3D_EXTENT_MODE_USER, - FMOD_DSP_PAN_3D_EXTENT_MODE_OFF -} FMOD_DSP_PAN_3D_EXTENT_MODE_TYPE; - - -typedef enum -{ - FMOD_DSP_PAN_MODE, - FMOD_DSP_PAN_2D_STEREO_POSITION, - FMOD_DSP_PAN_2D_DIRECTION, - FMOD_DSP_PAN_2D_EXTENT, - FMOD_DSP_PAN_2D_ROTATION, - FMOD_DSP_PAN_2D_LFE_LEVEL, - FMOD_DSP_PAN_2D_STEREO_MODE, - FMOD_DSP_PAN_2D_STEREO_SEPARATION, - FMOD_DSP_PAN_2D_STEREO_AXIS, - FMOD_DSP_PAN_ENABLED_SPEAKERS, - FMOD_DSP_PAN_3D_POSITION, - FMOD_DSP_PAN_3D_ROLLOFF, - FMOD_DSP_PAN_3D_MIN_DISTANCE, - FMOD_DSP_PAN_3D_MAX_DISTANCE, - FMOD_DSP_PAN_3D_EXTENT_MODE, - FMOD_DSP_PAN_3D_SOUND_SIZE, - FMOD_DSP_PAN_3D_MIN_EXTENT, - FMOD_DSP_PAN_3D_PAN_BLEND, - FMOD_DSP_PAN_LFE_UPMIX_ENABLED, - FMOD_DSP_PAN_OVERALL_GAIN, - FMOD_DSP_PAN_SURROUND_SPEAKER_MODE, - FMOD_DSP_PAN_2D_HEIGHT_BLEND, -} FMOD_DSP_PAN; - - -typedef enum -{ - FMOD_DSP_THREE_EQ_CROSSOVERSLOPE_12DB, - FMOD_DSP_THREE_EQ_CROSSOVERSLOPE_24DB, - FMOD_DSP_THREE_EQ_CROSSOVERSLOPE_48DB -} FMOD_DSP_THREE_EQ_CROSSOVERSLOPE_TYPE; - - -typedef enum -{ - FMOD_DSP_THREE_EQ_LOWGAIN, - FMOD_DSP_THREE_EQ_MIDGAIN, - FMOD_DSP_THREE_EQ_HIGHGAIN, - FMOD_DSP_THREE_EQ_LOWCROSSOVER, - FMOD_DSP_THREE_EQ_HIGHCROSSOVER, - FMOD_DSP_THREE_EQ_CROSSOVERSLOPE -} FMOD_DSP_THREE_EQ; - - -typedef enum -{ - FMOD_DSP_FFT_WINDOW_RECT, - FMOD_DSP_FFT_WINDOW_TRIANGLE, - FMOD_DSP_FFT_WINDOW_HAMMING, - FMOD_DSP_FFT_WINDOW_HANNING, - FMOD_DSP_FFT_WINDOW_BLACKMAN, - FMOD_DSP_FFT_WINDOW_BLACKMANHARRIS -} FMOD_DSP_FFT_WINDOW; - - -typedef enum -{ - FMOD_DSP_FFT_WINDOWSIZE, - FMOD_DSP_FFT_WINDOWTYPE, - FMOD_DSP_FFT_SPECTRUMDATA, - FMOD_DSP_FFT_DOMINANT_FREQ -} FMOD_DSP_FFT; - - -typedef enum -{ - FMOD_DSP_ENVELOPEFOLLOWER_ATTACK, - FMOD_DSP_ENVELOPEFOLLOWER_RELEASE, - FMOD_DSP_ENVELOPEFOLLOWER_ENVELOPE, - FMOD_DSP_ENVELOPEFOLLOWER_USESIDECHAIN -} FMOD_DSP_ENVELOPEFOLLOWER; - -typedef enum -{ - FMOD_DSP_CONVOLUTION_REVERB_PARAM_IR, - FMOD_DSP_CONVOLUTION_REVERB_PARAM_WET, - FMOD_DSP_CONVOLUTION_REVERB_PARAM_DRY, - FMOD_DSP_CONVOLUTION_REVERB_PARAM_LINKED -} FMOD_DSP_CONVOLUTION_REVERB; - -typedef enum -{ - FMOD_DSP_CHANNELMIX_OUTPUT_DEFAULT, - FMOD_DSP_CHANNELMIX_OUTPUT_ALLMONO, - FMOD_DSP_CHANNELMIX_OUTPUT_ALLSTEREO, - FMOD_DSP_CHANNELMIX_OUTPUT_ALLQUAD, - FMOD_DSP_CHANNELMIX_OUTPUT_ALL5POINT1, - FMOD_DSP_CHANNELMIX_OUTPUT_ALL7POINT1, - FMOD_DSP_CHANNELMIX_OUTPUT_ALLLFE, - FMOD_DSP_CHANNELMIX_OUTPUT_ALL7POINT1POINT4 -} FMOD_DSP_CHANNELMIX_OUTPUT; - -typedef enum -{ - FMOD_DSP_CHANNELMIX_OUTPUTGROUPING, - FMOD_DSP_CHANNELMIX_GAIN_CH0, - FMOD_DSP_CHANNELMIX_GAIN_CH1, - FMOD_DSP_CHANNELMIX_GAIN_CH2, - FMOD_DSP_CHANNELMIX_GAIN_CH3, - FMOD_DSP_CHANNELMIX_GAIN_CH4, - FMOD_DSP_CHANNELMIX_GAIN_CH5, - FMOD_DSP_CHANNELMIX_GAIN_CH6, - FMOD_DSP_CHANNELMIX_GAIN_CH7, - FMOD_DSP_CHANNELMIX_GAIN_CH8, - FMOD_DSP_CHANNELMIX_GAIN_CH9, - FMOD_DSP_CHANNELMIX_GAIN_CH10, - FMOD_DSP_CHANNELMIX_GAIN_CH11, - FMOD_DSP_CHANNELMIX_GAIN_CH12, - FMOD_DSP_CHANNELMIX_GAIN_CH13, - FMOD_DSP_CHANNELMIX_GAIN_CH14, - FMOD_DSP_CHANNELMIX_GAIN_CH15, - FMOD_DSP_CHANNELMIX_GAIN_CH16, - FMOD_DSP_CHANNELMIX_GAIN_CH17, - FMOD_DSP_CHANNELMIX_GAIN_CH18, - FMOD_DSP_CHANNELMIX_GAIN_CH19, - FMOD_DSP_CHANNELMIX_GAIN_CH20, - FMOD_DSP_CHANNELMIX_GAIN_CH21, - FMOD_DSP_CHANNELMIX_GAIN_CH22, - FMOD_DSP_CHANNELMIX_GAIN_CH23, - FMOD_DSP_CHANNELMIX_GAIN_CH24, - FMOD_DSP_CHANNELMIX_GAIN_CH25, - FMOD_DSP_CHANNELMIX_GAIN_CH26, - FMOD_DSP_CHANNELMIX_GAIN_CH27, - FMOD_DSP_CHANNELMIX_GAIN_CH28, - FMOD_DSP_CHANNELMIX_GAIN_CH29, - FMOD_DSP_CHANNELMIX_GAIN_CH30, - FMOD_DSP_CHANNELMIX_GAIN_CH31, - FMOD_DSP_CHANNELMIX_OUTPUT_CH0, - FMOD_DSP_CHANNELMIX_OUTPUT_CH1, - FMOD_DSP_CHANNELMIX_OUTPUT_CH2, - FMOD_DSP_CHANNELMIX_OUTPUT_CH3, - FMOD_DSP_CHANNELMIX_OUTPUT_CH4, - FMOD_DSP_CHANNELMIX_OUTPUT_CH5, - FMOD_DSP_CHANNELMIX_OUTPUT_CH6, - FMOD_DSP_CHANNELMIX_OUTPUT_CH7, - FMOD_DSP_CHANNELMIX_OUTPUT_CH8, - FMOD_DSP_CHANNELMIX_OUTPUT_CH9, - FMOD_DSP_CHANNELMIX_OUTPUT_CH10, - FMOD_DSP_CHANNELMIX_OUTPUT_CH11, - FMOD_DSP_CHANNELMIX_OUTPUT_CH12, - FMOD_DSP_CHANNELMIX_OUTPUT_CH13, - FMOD_DSP_CHANNELMIX_OUTPUT_CH14, - FMOD_DSP_CHANNELMIX_OUTPUT_CH15, - FMOD_DSP_CHANNELMIX_OUTPUT_CH16, - FMOD_DSP_CHANNELMIX_OUTPUT_CH17, - FMOD_DSP_CHANNELMIX_OUTPUT_CH18, - FMOD_DSP_CHANNELMIX_OUTPUT_CH19, - FMOD_DSP_CHANNELMIX_OUTPUT_CH20, - FMOD_DSP_CHANNELMIX_OUTPUT_CH21, - FMOD_DSP_CHANNELMIX_OUTPUT_CH22, - FMOD_DSP_CHANNELMIX_OUTPUT_CH23, - FMOD_DSP_CHANNELMIX_OUTPUT_CH24, - FMOD_DSP_CHANNELMIX_OUTPUT_CH25, - FMOD_DSP_CHANNELMIX_OUTPUT_CH26, - FMOD_DSP_CHANNELMIX_OUTPUT_CH27, - FMOD_DSP_CHANNELMIX_OUTPUT_CH28, - FMOD_DSP_CHANNELMIX_OUTPUT_CH29, - FMOD_DSP_CHANNELMIX_OUTPUT_CH30, - FMOD_DSP_CHANNELMIX_OUTPUT_CH31 -} FMOD_DSP_CHANNELMIX; - -typedef enum -{ - FMOD_DSP_TRANSCEIVER_SPEAKERMODE_AUTO = -1, - FMOD_DSP_TRANSCEIVER_SPEAKERMODE_MONO = 0, - FMOD_DSP_TRANSCEIVER_SPEAKERMODE_STEREO, - FMOD_DSP_TRANSCEIVER_SPEAKERMODE_SURROUND, -} FMOD_DSP_TRANSCEIVER_SPEAKERMODE; - - -typedef enum -{ - FMOD_DSP_TRANSCEIVER_TRANSMIT, - FMOD_DSP_TRANSCEIVER_GAIN, - FMOD_DSP_TRANSCEIVER_CHANNEL, - FMOD_DSP_TRANSCEIVER_TRANSMITSPEAKERMODE -} FMOD_DSP_TRANSCEIVER; - - -typedef enum -{ - FMOD_DSP_OBJECTPAN_3D_POSITION, - FMOD_DSP_OBJECTPAN_3D_ROLLOFF, - FMOD_DSP_OBJECTPAN_3D_MIN_DISTANCE, - FMOD_DSP_OBJECTPAN_3D_MAX_DISTANCE, - FMOD_DSP_OBJECTPAN_3D_EXTENT_MODE, - FMOD_DSP_OBJECTPAN_3D_SOUND_SIZE, - FMOD_DSP_OBJECTPAN_3D_MIN_EXTENT, - FMOD_DSP_OBJECTPAN_OVERALL_GAIN, - FMOD_DSP_OBJECTPAN_OUTPUTGAIN -} FMOD_DSP_OBJECTPAN; - -#endif - diff --git a/engine/fmodcore/inc/fmod_errors.cs b/engine/fmodcore/inc/fmod_errors.cs deleted file mode 100644 index e7b9cd2..0000000 --- a/engine/fmodcore/inc/fmod_errors.cs +++ /dev/null @@ -1,106 +0,0 @@ -/* ============================================================================================== */ -/* FMOD Core / Studio API - Error string header file. */ -/* Copyright (c), Firelight Technologies Pty, Ltd. 2004-2021. */ -/* */ -/* Use this header if you want to store or display a string version / english explanation */ -/* of the FMOD error codes. */ -/* */ -/* For more detail visit: */ -/* https://fmod.com/resources/documentation-api?version=2.0&page=core-api-common.html#fmod_result */ -/* =============================================================================================== */ - -namespace FMOD -{ - public class Error - { - public static string String(FMOD.RESULT errcode) - { - switch (errcode) - { - case FMOD.RESULT.OK: return "No errors."; - case FMOD.RESULT.ERR_BADCOMMAND: return "Tried to call a function on a data type that does not allow this type of functionality (ie calling Sound::lock on a streaming sound)."; - case FMOD.RESULT.ERR_CHANNEL_ALLOC: return "Error trying to allocate a channel."; - case FMOD.RESULT.ERR_CHANNEL_STOLEN: return "The specified channel has been reused to play another sound."; - case FMOD.RESULT.ERR_DMA: return "DMA Failure. See debug output for more information."; - case FMOD.RESULT.ERR_DSP_CONNECTION: return "DSP connection error. Connection possibly caused a cyclic dependency or connected dsps with incompatible buffer counts."; - case FMOD.RESULT.ERR_DSP_DONTPROCESS: return "DSP return code from a DSP process query callback. Tells mixer not to call the process callback and therefore not consume CPU. Use this to optimize the DSP graph."; - case FMOD.RESULT.ERR_DSP_FORMAT: return "DSP Format error. A DSP unit may have attempted to connect to this network with the wrong format, or a matrix may have been set with the wrong size if the target unit has a specified channel map."; - case FMOD.RESULT.ERR_DSP_INUSE: return "DSP is already in the mixer's DSP network. It must be removed before being reinserted or released."; - case FMOD.RESULT.ERR_DSP_NOTFOUND: return "DSP connection error. Couldn't find the DSP unit specified."; - case FMOD.RESULT.ERR_DSP_RESERVED: return "DSP operation error. Cannot perform operation on this DSP as it is reserved by the system."; - case FMOD.RESULT.ERR_DSP_SILENCE: return "DSP return code from a DSP process query callback. Tells mixer silence would be produced from read, so go idle and not consume CPU. Use this to optimize the DSP graph."; - case FMOD.RESULT.ERR_DSP_TYPE: return "DSP operation cannot be performed on a DSP of this type."; - case FMOD.RESULT.ERR_FILE_BAD: return "Error loading file."; - case FMOD.RESULT.ERR_FILE_COULDNOTSEEK: return "Couldn't perform seek operation. This is a limitation of the medium (ie netstreams) or the file format."; - case FMOD.RESULT.ERR_FILE_DISKEJECTED: return "Media was ejected while reading."; - case FMOD.RESULT.ERR_FILE_EOF: return "End of file unexpectedly reached while trying to read essential data (truncated?)."; - case FMOD.RESULT.ERR_FILE_ENDOFDATA: return "End of current chunk reached while trying to read data."; - case FMOD.RESULT.ERR_FILE_NOTFOUND: return "File not found."; - case FMOD.RESULT.ERR_FORMAT: return "Unsupported file or audio format."; - case FMOD.RESULT.ERR_HEADER_MISMATCH: return "There is a version mismatch between the FMOD header and either the FMOD Studio library or the FMOD Low Level library."; - case FMOD.RESULT.ERR_HTTP: return "A HTTP error occurred. This is a catch-all for HTTP errors not listed elsewhere."; - case FMOD.RESULT.ERR_HTTP_ACCESS: return "The specified resource requires authentication or is forbidden."; - case FMOD.RESULT.ERR_HTTP_PROXY_AUTH: return "Proxy authentication is required to access the specified resource."; - case FMOD.RESULT.ERR_HTTP_SERVER_ERROR: return "A HTTP server error occurred."; - case FMOD.RESULT.ERR_HTTP_TIMEOUT: return "The HTTP request timed out."; - case FMOD.RESULT.ERR_INITIALIZATION: return "FMOD was not initialized correctly to support this function."; - case FMOD.RESULT.ERR_INITIALIZED: return "Cannot call this command after System::init."; - case FMOD.RESULT.ERR_INTERNAL: return "An error occurred that wasn't supposed to. Contact support."; - case FMOD.RESULT.ERR_INVALID_FLOAT: return "Value passed in was a NaN, Inf or denormalized float."; - case FMOD.RESULT.ERR_INVALID_HANDLE: return "An invalid object handle was used."; - case FMOD.RESULT.ERR_INVALID_PARAM: return "An invalid parameter was passed to this function."; - case FMOD.RESULT.ERR_INVALID_POSITION: return "An invalid seek position was passed to this function."; - case FMOD.RESULT.ERR_INVALID_SPEAKER: return "An invalid speaker was passed to this function based on the current speaker mode."; - case FMOD.RESULT.ERR_INVALID_SYNCPOINT: return "The syncpoint did not come from this sound handle."; - case FMOD.RESULT.ERR_INVALID_THREAD: return "Tried to call a function on a thread that is not supported."; - case FMOD.RESULT.ERR_INVALID_VECTOR: return "The vectors passed in are not unit length, or perpendicular."; - case FMOD.RESULT.ERR_MAXAUDIBLE: return "Reached maximum audible playback count for this sound's soundgroup."; - case FMOD.RESULT.ERR_MEMORY: return "Not enough memory or resources."; - case FMOD.RESULT.ERR_MEMORY_CANTPOINT: return "Can't use FMOD_OPENMEMORY_POINT on non PCM source data, or non mp3/xma/adpcm data if FMOD_CREATECOMPRESSEDSAMPLE was used."; - case FMOD.RESULT.ERR_NEEDS3D: return "Tried to call a command on a 2d sound when the command was meant for 3d sound."; - case FMOD.RESULT.ERR_NEEDSHARDWARE: return "Tried to use a feature that requires hardware support."; - case FMOD.RESULT.ERR_NET_CONNECT: return "Couldn't connect to the specified host."; - case FMOD.RESULT.ERR_NET_SOCKET_ERROR: return "A socket error occurred. This is a catch-all for socket-related errors not listed elsewhere."; - case FMOD.RESULT.ERR_NET_URL: return "The specified URL couldn't be resolved."; - case FMOD.RESULT.ERR_NET_WOULD_BLOCK: return "Operation on a non-blocking socket could not complete immediately."; - case FMOD.RESULT.ERR_NOTREADY: return "Operation could not be performed because specified sound/DSP connection is not ready."; - case FMOD.RESULT.ERR_OUTPUT_ALLOCATED: return "Error initializing output device, but more specifically, the output device is already in use and cannot be reused."; - case FMOD.RESULT.ERR_OUTPUT_CREATEBUFFER: return "Error creating hardware sound buffer."; - case FMOD.RESULT.ERR_OUTPUT_DRIVERCALL: return "A call to a standard soundcard driver failed, which could possibly mean a bug in the driver or resources were missing or exhausted."; - case FMOD.RESULT.ERR_OUTPUT_FORMAT: return "Soundcard does not support the specified format."; - case FMOD.RESULT.ERR_OUTPUT_INIT: return "Error initializing output device."; - case FMOD.RESULT.ERR_OUTPUT_NODRIVERS: return "The output device has no drivers installed. If pre-init, FMOD_OUTPUT_NOSOUND is selected as the output mode. If post-init, the function just fails."; - case FMOD.RESULT.ERR_PLUGIN: return "An unspecified error has been returned from a plugin."; - case FMOD.RESULT.ERR_PLUGIN_MISSING: return "A requested output, dsp unit type or codec was not available."; - case FMOD.RESULT.ERR_PLUGIN_RESOURCE: return "A resource that the plugin requires cannot be found. (ie the DLS file for MIDI playback)"; - case FMOD.RESULT.ERR_PLUGIN_VERSION: return "A plugin was built with an unsupported SDK version."; - case FMOD.RESULT.ERR_RECORD: return "An error occurred trying to initialize the recording device."; - case FMOD.RESULT.ERR_REVERB_CHANNELGROUP: return "Reverb properties cannot be set on this channel because a parent channelgroup owns the reverb connection."; - case FMOD.RESULT.ERR_REVERB_INSTANCE: return "Specified instance in FMOD_REVERB_PROPERTIES couldn't be set. Most likely because it is an invalid instance number or the reverb doesn't exist."; - case FMOD.RESULT.ERR_SUBSOUNDS: return "The error occurred because the sound referenced contains subsounds when it shouldn't have, or it doesn't contain subsounds when it should have. The operation may also not be able to be performed on a parent sound."; - case FMOD.RESULT.ERR_SUBSOUND_ALLOCATED: return "This subsound is already being used by another sound, you cannot have more than one parent to a sound. Null out the other parent's entry first."; - case FMOD.RESULT.ERR_SUBSOUND_CANTMOVE: return "Shared subsounds cannot be replaced or moved from their parent stream, such as when the parent stream is an FSB file."; - case FMOD.RESULT.ERR_TAGNOTFOUND: return "The specified tag could not be found or there are no tags."; - case FMOD.RESULT.ERR_TOOMANYCHANNELS: return "The sound created exceeds the allowable input channel count. This can be increased using the 'maxinputchannels' parameter in System::setSoftwareFormat."; - case FMOD.RESULT.ERR_TRUNCATED: return "The retrieved string is too long to fit in the supplied buffer and has been truncated."; - case FMOD.RESULT.ERR_UNIMPLEMENTED: return "Something in FMOD hasn't been implemented when it should be! contact support!"; - case FMOD.RESULT.ERR_UNINITIALIZED: return "This command failed because System::init or System::setDriver was not called."; - case FMOD.RESULT.ERR_UNSUPPORTED: return "A command issued was not supported by this object. Possibly a plugin without certain callbacks specified."; - case FMOD.RESULT.ERR_VERSION: return "The version number of this file format is not supported."; - case FMOD.RESULT.ERR_EVENT_ALREADY_LOADED: return "The specified bank has already been loaded."; - case FMOD.RESULT.ERR_EVENT_LIVEUPDATE_BUSY: return "The live update connection failed due to the game already being connected."; - case FMOD.RESULT.ERR_EVENT_LIVEUPDATE_MISMATCH: return "The live update connection failed due to the game data being out of sync with the tool."; - case FMOD.RESULT.ERR_EVENT_LIVEUPDATE_TIMEOUT: return "The live update connection timed out."; - case FMOD.RESULT.ERR_EVENT_NOTFOUND: return "The requested event, bus or vca could not be found."; - case FMOD.RESULT.ERR_STUDIO_UNINITIALIZED: return "The Studio::System object is not yet initialized."; - case FMOD.RESULT.ERR_STUDIO_NOT_LOADED: return "The specified resource is not loaded, so it can't be unloaded."; - case FMOD.RESULT.ERR_INVALID_STRING: return "An invalid string was passed to this function."; - case FMOD.RESULT.ERR_ALREADY_LOCKED: return "The specified resource is already locked."; - case FMOD.RESULT.ERR_NOT_LOCKED: return "The specified resource is not locked, so it can't be unlocked."; - case FMOD.RESULT.ERR_RECORD_DISCONNECTED: return "The specified recording driver has been disconnected."; - case FMOD.RESULT.ERR_TOOMANYSAMPLES: return "The length provided exceed the allowable limit."; - default: return "Unknown error."; - } - } - } -} diff --git a/engine/fmodcore/inc/fmod_errors.h b/engine/fmodcore/inc/fmod_errors.h deleted file mode 100644 index ea17340..0000000 --- a/engine/fmodcore/inc/fmod_errors.h +++ /dev/null @@ -1,110 +0,0 @@ -/* ============================================================================================== */ -/* FMOD Core / Studio API - Error string header file. */ -/* Copyright (c), Firelight Technologies Pty, Ltd. 2004-2021. */ -/* */ -/* Use this header if you want to store or display a string version / english explanation */ -/* of the FMOD error codes. */ -/* */ -/* For more detail visit: */ -/* https://fmod.com/resources/documentation-api?version=2.0&page=core-api-common.html#fmod_result */ -/* =============================================================================================== */ -#ifndef _FMOD_ERRORS_H -#define _FMOD_ERRORS_H - -#include "fmod.h" - -#ifdef __GNUC__ -static const char *FMOD_ErrorString(FMOD_RESULT errcode) __attribute__((unused)); -#endif - -static const char *FMOD_ErrorString(FMOD_RESULT errcode) -{ - switch (errcode) - { - case FMOD_OK: return "No errors."; - case FMOD_ERR_BADCOMMAND: return "Tried to call a function on a data type that does not allow this type of functionality (ie calling Sound::lock on a streaming sound)."; - case FMOD_ERR_CHANNEL_ALLOC: return "Error trying to allocate a channel."; - case FMOD_ERR_CHANNEL_STOLEN: return "The specified channel has been reused to play another sound."; - case FMOD_ERR_DMA: return "DMA Failure. See debug output for more information."; - case FMOD_ERR_DSP_CONNECTION: return "DSP connection error. Connection possibly caused a cyclic dependency or connected dsps with incompatible buffer counts."; - case FMOD_ERR_DSP_DONTPROCESS: return "DSP return code from a DSP process query callback. Tells mixer not to call the process callback and therefore not consume CPU. Use this to optimize the DSP graph."; - case FMOD_ERR_DSP_FORMAT: return "DSP Format error. A DSP unit may have attempted to connect to this network with the wrong format, or a matrix may have been set with the wrong size if the target unit has a specified channel map."; - case FMOD_ERR_DSP_INUSE: return "DSP is already in the mixer's DSP network. It must be removed before being reinserted or released."; - case FMOD_ERR_DSP_NOTFOUND: return "DSP connection error. Couldn't find the DSP unit specified."; - case FMOD_ERR_DSP_RESERVED: return "DSP operation error. Cannot perform operation on this DSP as it is reserved by the system."; - case FMOD_ERR_DSP_SILENCE: return "DSP return code from a DSP process query callback. Tells mixer silence would be produced from read, so go idle and not consume CPU. Use this to optimize the DSP graph."; - case FMOD_ERR_DSP_TYPE: return "DSP operation cannot be performed on a DSP of this type."; - case FMOD_ERR_FILE_BAD: return "Error loading file."; - case FMOD_ERR_FILE_COULDNOTSEEK: return "Couldn't perform seek operation. This is a limitation of the medium (ie netstreams) or the file format."; - case FMOD_ERR_FILE_DISKEJECTED: return "Media was ejected while reading."; - case FMOD_ERR_FILE_EOF: return "End of file unexpectedly reached while trying to read essential data (truncated?)."; - case FMOD_ERR_FILE_ENDOFDATA: return "End of current chunk reached while trying to read data."; - case FMOD_ERR_FILE_NOTFOUND: return "File not found."; - case FMOD_ERR_FORMAT: return "Unsupported file or audio format."; - case FMOD_ERR_HEADER_MISMATCH: return "There is a version mismatch between the FMOD header and either the FMOD Studio library or the FMOD Low Level library."; - case FMOD_ERR_HTTP: return "A HTTP error occurred. This is a catch-all for HTTP errors not listed elsewhere."; - case FMOD_ERR_HTTP_ACCESS: return "The specified resource requires authentication or is forbidden."; - case FMOD_ERR_HTTP_PROXY_AUTH: return "Proxy authentication is required to access the specified resource."; - case FMOD_ERR_HTTP_SERVER_ERROR: return "A HTTP server error occurred."; - case FMOD_ERR_HTTP_TIMEOUT: return "The HTTP request timed out."; - case FMOD_ERR_INITIALIZATION: return "FMOD was not initialized correctly to support this function."; - case FMOD_ERR_INITIALIZED: return "Cannot call this command after System::init."; - case FMOD_ERR_INTERNAL: return "An error occurred that wasn't supposed to. Contact support."; - case FMOD_ERR_INVALID_FLOAT: return "Value passed in was a NaN, Inf or denormalized float."; - case FMOD_ERR_INVALID_HANDLE: return "An invalid object handle was used."; - case FMOD_ERR_INVALID_PARAM: return "An invalid parameter was passed to this function."; - case FMOD_ERR_INVALID_POSITION: return "An invalid seek position was passed to this function."; - case FMOD_ERR_INVALID_SPEAKER: return "An invalid speaker was passed to this function based on the current speaker mode."; - case FMOD_ERR_INVALID_SYNCPOINT: return "The syncpoint did not come from this sound handle."; - case FMOD_ERR_INVALID_THREAD: return "Tried to call a function on a thread that is not supported."; - case FMOD_ERR_INVALID_VECTOR: return "The vectors passed in are not unit length, or perpendicular."; - case FMOD_ERR_MAXAUDIBLE: return "Reached maximum audible playback count for this sound's soundgroup."; - case FMOD_ERR_MEMORY: return "Not enough memory or resources."; - case FMOD_ERR_MEMORY_CANTPOINT: return "Can't use FMOD_OPENMEMORY_POINT on non PCM source data, or non mp3/xma/adpcm data if FMOD_CREATECOMPRESSEDSAMPLE was used."; - case FMOD_ERR_NEEDS3D: return "Tried to call a command on a 2d sound when the command was meant for 3d sound."; - case FMOD_ERR_NEEDSHARDWARE: return "Tried to use a feature that requires hardware support."; - case FMOD_ERR_NET_CONNECT: return "Couldn't connect to the specified host."; - case FMOD_ERR_NET_SOCKET_ERROR: return "A socket error occurred. This is a catch-all for socket-related errors not listed elsewhere."; - case FMOD_ERR_NET_URL: return "The specified URL couldn't be resolved."; - case FMOD_ERR_NET_WOULD_BLOCK: return "Operation on a non-blocking socket could not complete immediately."; - case FMOD_ERR_NOTREADY: return "Operation could not be performed because specified sound/DSP connection is not ready."; - case FMOD_ERR_OUTPUT_ALLOCATED: return "Error initializing output device, but more specifically, the output device is already in use and cannot be reused."; - case FMOD_ERR_OUTPUT_CREATEBUFFER: return "Error creating hardware sound buffer."; - case FMOD_ERR_OUTPUT_DRIVERCALL: return "A call to a standard soundcard driver failed, which could possibly mean a bug in the driver or resources were missing or exhausted."; - case FMOD_ERR_OUTPUT_FORMAT: return "Soundcard does not support the specified format."; - case FMOD_ERR_OUTPUT_INIT: return "Error initializing output device."; - case FMOD_ERR_OUTPUT_NODRIVERS: return "The output device has no drivers installed. If pre-init, FMOD_OUTPUT_NOSOUND is selected as the output mode. If post-init, the function just fails."; - case FMOD_ERR_PLUGIN: return "An unspecified error has been returned from a plugin."; - case FMOD_ERR_PLUGIN_MISSING: return "A requested output, dsp unit type or codec was not available."; - case FMOD_ERR_PLUGIN_RESOURCE: return "A resource that the plugin requires cannot be found. (ie the DLS file for MIDI playback)"; - case FMOD_ERR_PLUGIN_VERSION: return "A plugin was built with an unsupported SDK version."; - case FMOD_ERR_RECORD: return "An error occurred trying to initialize the recording device."; - case FMOD_ERR_REVERB_CHANNELGROUP: return "Reverb properties cannot be set on this channel because a parent channelgroup owns the reverb connection."; - case FMOD_ERR_REVERB_INSTANCE: return "Specified instance in FMOD_REVERB_PROPERTIES couldn't be set. Most likely because it is an invalid instance number or the reverb doesn't exist."; - case FMOD_ERR_SUBSOUNDS: return "The error occurred because the sound referenced contains subsounds when it shouldn't have, or it doesn't contain subsounds when it should have. The operation may also not be able to be performed on a parent sound."; - case FMOD_ERR_SUBSOUND_ALLOCATED: return "This subsound is already being used by another sound, you cannot have more than one parent to a sound. Null out the other parent's entry first."; - case FMOD_ERR_SUBSOUND_CANTMOVE: return "Shared subsounds cannot be replaced or moved from their parent stream, such as when the parent stream is an FSB file."; - case FMOD_ERR_TAGNOTFOUND: return "The specified tag could not be found or there are no tags."; - case FMOD_ERR_TOOMANYCHANNELS: return "The sound created exceeds the allowable input channel count. This can be increased using the 'maxinputchannels' parameter in System::setSoftwareFormat."; - case FMOD_ERR_TRUNCATED: return "The retrieved string is too long to fit in the supplied buffer and has been truncated."; - case FMOD_ERR_UNIMPLEMENTED: return "Something in FMOD hasn't been implemented when it should be! contact support!"; - case FMOD_ERR_UNINITIALIZED: return "This command failed because System::init or System::setDriver was not called."; - case FMOD_ERR_UNSUPPORTED: return "A command issued was not supported by this object. Possibly a plugin without certain callbacks specified."; - case FMOD_ERR_VERSION: return "The version number of this file format is not supported."; - case FMOD_ERR_EVENT_ALREADY_LOADED: return "The specified bank has already been loaded."; - case FMOD_ERR_EVENT_LIVEUPDATE_BUSY: return "The live update connection failed due to the game already being connected."; - case FMOD_ERR_EVENT_LIVEUPDATE_MISMATCH: return "The live update connection failed due to the game data being out of sync with the tool."; - case FMOD_ERR_EVENT_LIVEUPDATE_TIMEOUT: return "The live update connection timed out."; - case FMOD_ERR_EVENT_NOTFOUND: return "The requested event, parameter, bus or vca could not be found."; - case FMOD_ERR_STUDIO_UNINITIALIZED: return "The Studio::System object is not yet initialized."; - case FMOD_ERR_STUDIO_NOT_LOADED: return "The specified resource is not loaded, so it can't be unloaded."; - case FMOD_ERR_INVALID_STRING: return "An invalid string was passed to this function."; - case FMOD_ERR_ALREADY_LOCKED: return "The specified resource is already locked."; - case FMOD_ERR_NOT_LOCKED: return "The specified resource is not locked, so it can't be unlocked."; - case FMOD_ERR_RECORD_DISCONNECTED: return "The specified recording driver has been disconnected."; - case FMOD_ERR_TOOMANYSAMPLES: return "The length provided exceeds the allowable limit."; - default : return "Unknown error."; - }; -} - -#endif diff --git a/engine/fmodcore/inc/fmod_output.h b/engine/fmodcore/inc/fmod_output.h deleted file mode 100644 index 9739eb8..0000000 --- a/engine/fmodcore/inc/fmod_output.h +++ /dev/null @@ -1,129 +0,0 @@ -/* ======================================================================================== */ -/* FMOD Core API - output development header file. */ -/* Copyright (c), Firelight Technologies Pty, Ltd. 2004-2021. */ -/* */ -/* Use this header if you are wanting to develop your own output plugin to use with */ -/* FMOD's output system. With this header you can make your own output plugin that FMOD */ -/* can register and use. See the documentation and examples on how to make a working */ -/* plugin. */ -/* */ -/* For more detail visit: */ -/* https://fmod.com/resources/documentation-api?version=2.0&page=plugin-api-output.html */ -/* ======================================================================================== */ -#ifndef _FMOD_OUTPUT_H -#define _FMOD_OUTPUT_H - -typedef struct FMOD_OUTPUT_STATE FMOD_OUTPUT_STATE; -typedef struct FMOD_OUTPUT_OBJECT3DINFO FMOD_OUTPUT_OBJECT3DINFO; - -/* - Output constants -*/ -#define FMOD_OUTPUT_PLUGIN_VERSION 4 - -typedef unsigned int FMOD_OUTPUT_METHOD; -#define FMOD_OUTPUT_METHOD_MIX_DIRECT 0 -#define FMOD_OUTPUT_METHOD_POLLING 1 -#define FMOD_OUTPUT_METHOD_MIX_BUFFERED 2 - -/* - Output callbacks -*/ -typedef FMOD_RESULT (F_CALL *FMOD_OUTPUT_GETNUMDRIVERS_CALLBACK) (FMOD_OUTPUT_STATE *output_state, int *numdrivers); -typedef FMOD_RESULT (F_CALL *FMOD_OUTPUT_GETDRIVERINFO_CALLBACK) (FMOD_OUTPUT_STATE *output_state, int id, char *name, int namelen, FMOD_GUID *guid, int *systemrate, FMOD_SPEAKERMODE *speakermode, int *speakermodechannels); -typedef FMOD_RESULT (F_CALL *FMOD_OUTPUT_INIT_CALLBACK) (FMOD_OUTPUT_STATE *output_state, int selecteddriver, FMOD_INITFLAGS flags, int *outputrate, FMOD_SPEAKERMODE *speakermode, int *speakermodechannels, FMOD_SOUND_FORMAT *outputformat, int dspbufferlength, int dspnumbuffers, void *extradriverdata); -typedef FMOD_RESULT (F_CALL *FMOD_OUTPUT_START_CALLBACK) (FMOD_OUTPUT_STATE *output_state); -typedef FMOD_RESULT (F_CALL *FMOD_OUTPUT_STOP_CALLBACK) (FMOD_OUTPUT_STATE *output_state); -typedef FMOD_RESULT (F_CALL *FMOD_OUTPUT_CLOSE_CALLBACK) (FMOD_OUTPUT_STATE *output_state); -typedef FMOD_RESULT (F_CALL *FMOD_OUTPUT_UPDATE_CALLBACK) (FMOD_OUTPUT_STATE *output_state); -typedef FMOD_RESULT (F_CALL *FMOD_OUTPUT_GETHANDLE_CALLBACK) (FMOD_OUTPUT_STATE *output_state, void **handle); -typedef FMOD_RESULT (F_CALL *FMOD_OUTPUT_GETPOSITION_CALLBACK) (FMOD_OUTPUT_STATE *output_state, unsigned int *pcm); -typedef FMOD_RESULT (F_CALL *FMOD_OUTPUT_LOCK_CALLBACK) (FMOD_OUTPUT_STATE *output_state, unsigned int offset, unsigned int length, void **ptr1, void **ptr2, unsigned int *len1, unsigned int *len2); -typedef FMOD_RESULT (F_CALL *FMOD_OUTPUT_UNLOCK_CALLBACK) (FMOD_OUTPUT_STATE *output_state, void *ptr1, void *ptr2, unsigned int len1, unsigned int len2); -typedef FMOD_RESULT (F_CALL *FMOD_OUTPUT_MIXER_CALLBACK) (FMOD_OUTPUT_STATE *output_state); -typedef FMOD_RESULT (F_CALL *FMOD_OUTPUT_OBJECT3DGETINFO_CALLBACK) (FMOD_OUTPUT_STATE *output_state, int *maxhardwareobjects); -typedef FMOD_RESULT (F_CALL *FMOD_OUTPUT_OBJECT3DALLOC_CALLBACK) (FMOD_OUTPUT_STATE *output_state, void **object3d); -typedef FMOD_RESULT (F_CALL *FMOD_OUTPUT_OBJECT3DFREE_CALLBACK) (FMOD_OUTPUT_STATE *output_state, void *object3d); -typedef FMOD_RESULT (F_CALL *FMOD_OUTPUT_OBJECT3DUPDATE_CALLBACK) (FMOD_OUTPUT_STATE *output_state, void *object3d, const FMOD_OUTPUT_OBJECT3DINFO *info); -typedef FMOD_RESULT (F_CALL *FMOD_OUTPUT_OPENPORT_CALLBACK) (FMOD_OUTPUT_STATE *output_state, FMOD_PORT_TYPE portType, FMOD_PORT_INDEX portIndex, int *portId, int *portRate, int *portChannels, FMOD_SOUND_FORMAT *portFormat); -typedef FMOD_RESULT (F_CALL *FMOD_OUTPUT_CLOSEPORT_CALLBACK) (FMOD_OUTPUT_STATE *output_state, int portId); -typedef FMOD_RESULT (F_CALL *FMOD_OUTPUT_DEVICELISTCHANGED_CALLBACK)(FMOD_OUTPUT_STATE *output_state); - -/* - Output functions -*/ -typedef FMOD_RESULT (F_CALL *FMOD_OUTPUT_READFROMMIXER_FUNC) (FMOD_OUTPUT_STATE *output_state, void *buffer, unsigned int length); -typedef FMOD_RESULT (F_CALL *FMOD_OUTPUT_COPYPORT_FUNC) (FMOD_OUTPUT_STATE *output_state, int portId, void *buffer, unsigned int length); -typedef FMOD_RESULT (F_CALL *FMOD_OUTPUT_REQUESTRESET_FUNC) (FMOD_OUTPUT_STATE *output_state); -typedef void * (F_CALL *FMOD_OUTPUT_ALLOC_FUNC) (unsigned int size, unsigned int align, const char *file, int line); -typedef void (F_CALL *FMOD_OUTPUT_FREE_FUNC) (void *ptr, const char *file, int line); -typedef void (F_CALL *FMOD_OUTPUT_LOG_FUNC) (FMOD_DEBUG_FLAGS level, const char *file, int line, const char *function, const char *string, ...); - -/* - Output structures -*/ -typedef struct FMOD_OUTPUT_DESCRIPTION -{ - unsigned int apiversion; - const char *name; - unsigned int version; - FMOD_OUTPUT_METHOD polling; /* This will become "method" on the next major version */ - FMOD_OUTPUT_GETNUMDRIVERS_CALLBACK getnumdrivers; - FMOD_OUTPUT_GETDRIVERINFO_CALLBACK getdriverinfo; - FMOD_OUTPUT_INIT_CALLBACK init; - FMOD_OUTPUT_START_CALLBACK start; - FMOD_OUTPUT_STOP_CALLBACK stop; - FMOD_OUTPUT_CLOSE_CALLBACK close; - FMOD_OUTPUT_UPDATE_CALLBACK update; - FMOD_OUTPUT_GETHANDLE_CALLBACK gethandle; - FMOD_OUTPUT_GETPOSITION_CALLBACK getposition; - FMOD_OUTPUT_LOCK_CALLBACK lock; - FMOD_OUTPUT_UNLOCK_CALLBACK unlock; - FMOD_OUTPUT_MIXER_CALLBACK mixer; - FMOD_OUTPUT_OBJECT3DGETINFO_CALLBACK object3dgetinfo; - FMOD_OUTPUT_OBJECT3DALLOC_CALLBACK object3dalloc; - FMOD_OUTPUT_OBJECT3DFREE_CALLBACK object3dfree; - FMOD_OUTPUT_OBJECT3DUPDATE_CALLBACK object3dupdate; - FMOD_OUTPUT_OPENPORT_CALLBACK openport; - FMOD_OUTPUT_CLOSEPORT_CALLBACK closeport; - FMOD_OUTPUT_DEVICELISTCHANGED_CALLBACK devicelistchanged; -} FMOD_OUTPUT_DESCRIPTION; - -struct FMOD_OUTPUT_STATE -{ - void *plugindata; - FMOD_OUTPUT_READFROMMIXER_FUNC readfrommixer; - FMOD_OUTPUT_ALLOC_FUNC alloc; - FMOD_OUTPUT_FREE_FUNC free; - FMOD_OUTPUT_LOG_FUNC log; - FMOD_OUTPUT_COPYPORT_FUNC copyport; - FMOD_OUTPUT_REQUESTRESET_FUNC requestreset; -}; - -struct FMOD_OUTPUT_OBJECT3DINFO -{ - float *buffer; - unsigned int bufferlength; - FMOD_VECTOR position; - float gain; - float spread; - float priority; -}; - -/* - Output macros -*/ -#define FMOD_OUTPUT_READFROMMIXER(_state, _buffer, _length) \ - (_state)->readfrommixer(_state, _buffer, _length) -#define FMOD_OUTPUT_ALLOC(_state, _size, _align) \ - (_state)->alloc(_size, _align, __FILE__, __LINE__) -#define FMOD_OUTPUT_FREE(_state, _ptr) \ - (_state)->free(_ptr, __FILE__, __LINE__) -#define FMOD_OUTPUT_LOG(_state, _level, _location, _format, ...) \ - (_state)->log(_level, __FILE__, __LINE__, _location, _format, __VA_ARGS__) -#define FMOD_OUTPUT_COPYPORT(_state, _id, _buffer, _length) \ - (_state)->copyport(_state, _id, _buffer, _length) -#define FMOD_OUTPUT_REQUESTRESET(_state) \ - (_state)->requestreset(_state) - -#endif /* _FMOD_OUTPUT_H */ diff --git a/engine/fmodcore/lib/x64/fmod.dll b/engine/fmodcore/lib/x64/fmod.dll deleted file mode 100644 index 3abd24e..0000000 Binary files a/engine/fmodcore/lib/x64/fmod.dll and /dev/null differ diff --git a/engine/fmodcore/lib/x64/fmodL.dll b/engine/fmodcore/lib/x64/fmodL.dll deleted file mode 100644 index a935eb3..0000000 Binary files a/engine/fmodcore/lib/x64/fmodL.dll and /dev/null differ diff --git a/engine/fmodcore/lib/x64/fmodL_vc.lib b/engine/fmodcore/lib/x64/fmodL_vc.lib deleted file mode 100644 index 7dd3934..0000000 Binary files a/engine/fmodcore/lib/x64/fmodL_vc.lib and /dev/null differ diff --git a/engine/fmodcore/lib/x64/fmod_vc.lib b/engine/fmodcore/lib/x64/fmod_vc.lib deleted file mode 100644 index 04c9f5c..0000000 Binary files a/engine/fmodcore/lib/x64/fmod_vc.lib and /dev/null differ diff --git a/engine/fmodcore/lib/x86/fmod.dll b/engine/fmodcore/lib/x86/fmod.dll deleted file mode 100644 index a26ad77..0000000 Binary files a/engine/fmodcore/lib/x86/fmod.dll and /dev/null differ diff --git a/engine/fmodcore/lib/x86/fmodL.dll b/engine/fmodcore/lib/x86/fmodL.dll deleted file mode 100644 index ad00614..0000000 Binary files a/engine/fmodcore/lib/x86/fmodL.dll and /dev/null differ diff --git a/engine/fmodcore/lib/x86/fmodL_vc.lib b/engine/fmodcore/lib/x86/fmodL_vc.lib deleted file mode 100644 index 8923d46..0000000 Binary files a/engine/fmodcore/lib/x86/fmodL_vc.lib and /dev/null differ diff --git a/engine/fmodcore/lib/x86/fmod_vc.lib b/engine/fmodcore/lib/x86/fmod_vc.lib deleted file mode 100644 index 974a6a9..0000000 Binary files a/engine/fmodcore/lib/x86/fmod_vc.lib and /dev/null differ diff --git a/engine/fmodcore/lib/x86/libfmod.a b/engine/fmodcore/lib/x86/libfmod.a deleted file mode 100644 index f8a5ec3..0000000 Binary files a/engine/fmodcore/lib/x86/libfmod.a and /dev/null differ diff --git a/engine/fmodcore/lib/x86/libfmodL.a b/engine/fmodcore/lib/x86/libfmodL.a deleted file mode 100644 index a7fa035..0000000 Binary files a/engine/fmodcore/lib/x86/libfmodL.a and /dev/null differ diff --git a/engine/jpeg-6/README b/engine/jpeg-6/README deleted file mode 100644 index 86cc206..0000000 --- a/engine/jpeg-6/README +++ /dev/null @@ -1,385 +0,0 @@ -The Independent JPEG Group's JPEG software -========================================== - -README for release 6b of 27-Mar-1998 -==================================== - -This distribution contains the sixth public release of the Independent JPEG -Group's free JPEG software. You are welcome to redistribute this software and -to use it for any purpose, subject to the conditions under LEGAL ISSUES, below. - -Serious users of this software (particularly those incorporating it into -larger programs) should contact IJG at jpeg-info@uunet.uu.net to be added to -our electronic mailing list. Mailing list members are notified of updates -and have a chance to participate in technical discussions, etc. - -This software is the work of Tom Lane, Philip Gladstone, Jim Boucher, -Lee Crocker, Julian Minguillon, Luis Ortiz, George Phillips, Davide Rossi, -Guido Vollbeding, Ge' Weijers, and other members of the Independent JPEG -Group. - -IJG is not affiliated with the official ISO JPEG standards committee. - - -DOCUMENTATION ROADMAP -===================== - -This file contains the following sections: - -OVERVIEW General description of JPEG and the IJG software. -LEGAL ISSUES Copyright, lack of warranty, terms of distribution. -REFERENCES Where to learn more about JPEG. -ARCHIVE LOCATIONS Where to find newer versions of this software. -RELATED SOFTWARE Other stuff you should get. -FILE FORMAT WARS Software *not* to get. -TO DO Plans for future IJG releases. - -Other documentation files in the distribution are: - -User documentation: - install.doc How to configure and install the IJG software. - usage.doc Usage instructions for cjpeg, djpeg, jpegtran, - rdjpgcom, and wrjpgcom. - *.1 Unix-style man pages for programs (same info as usage.doc). - wizard.doc Advanced usage instructions for JPEG wizards only. - change.log Version-to-version change highlights. -Programmer and internal documentation: - libjpeg.doc How to use the JPEG library in your own programs. - example.c Sample code for calling the JPEG library. - structure.doc Overview of the JPEG library's internal structure. - filelist.doc Road map of IJG files. - coderules.doc Coding style rules --- please read if you contribute code. - -Please read at least the files install.doc and usage.doc. Useful information -can also be found in the JPEG FAQ (Frequently Asked Questions) article. See -ARCHIVE LOCATIONS below to find out where to obtain the FAQ article. - -If you want to understand how the JPEG code works, we suggest reading one or -more of the REFERENCES, then looking at the documentation files (in roughly -the order listed) before diving into the code. - - -OVERVIEW -======== - -This package contains C software to implement JPEG image compression and -decompression. JPEG (pronounced "jay-peg") is a standardized compression -method for full-color and gray-scale images. JPEG is intended for compressing -"real-world" scenes; line drawings, cartoons and other non-realistic images -are not its strong suit. JPEG is lossy, meaning that the output image is not -exactly identical to the input image. Hence you must not use JPEG if you -have to have identical output bits. However, on typical photographic images, -very good compression levels can be obtained with no visible change, and -remarkably high compression levels are possible if you can tolerate a -low-quality image. For more details, see the references, or just experiment -with various compression settings. - -This software implements JPEG baseline, extended-sequential, and progressive -compression processes. Provision is made for supporting all variants of these -processes, although some uncommon parameter settings aren't implemented yet. -For legal reasons, we are not distributing code for the arithmetic-coding -variants of JPEG; see LEGAL ISSUES. We have made no provision for supporting -the hierarchical or lossless processes defined in the standard. - -We provide a set of library routines for reading and writing JPEG image files, -plus two sample applications "cjpeg" and "djpeg", which use the library to -perform conversion between JPEG and some other popular image file formats. -The library is intended to be reused in other applications. - -In order to support file conversion and viewing software, we have included -considerable functionality beyond the bare JPEG coding/decoding capability; -for example, the color quantization modules are not strictly part of JPEG -decoding, but they are essential for output to colormapped file formats or -colormapped displays. These extra functions can be compiled out of the -library if not required for a particular application. We have also included -"jpegtran", a utility for lossless transcoding between different JPEG -processes, and "rdjpgcom" and "wrjpgcom", two simple applications for -inserting and extracting textual comments in JFIF files. - -The emphasis in designing this software has been on achieving portability and -flexibility, while also making it fast enough to be useful. In particular, -the software is not intended to be read as a tutorial on JPEG. (See the -REFERENCES section for introductory material.) Rather, it is intended to -be reliable, portable, industrial-strength code. We do not claim to have -achieved that goal in every aspect of the software, but we strive for it. - -We welcome the use of this software as a component of commercial products. -No royalty is required, but we do ask for an acknowledgement in product -documentation, as described under LEGAL ISSUES. - - -LEGAL ISSUES -============ - -In plain English: - -1. We don't promise that this software works. (But if you find any bugs, - please let us know!) -2. You can use this software for whatever you want. You don't have to pay us. -3. You may not pretend that you wrote this software. If you use it in a - program, you must acknowledge somewhere in your documentation that - you've used the IJG code. - -In legalese: - -The authors make NO WARRANTY or representation, either express or implied, -with respect to this software, its quality, accuracy, merchantability, or -fitness for a particular purpose. This software is provided "AS IS", and you, -its user, assume the entire risk as to its quality and accuracy. - -This software is copyright (C) 1991-1998, Thomas G. Lane. -All Rights Reserved except as specified below. - -Permission is hereby granted to use, copy, modify, and distribute this -software (or portions thereof) for any purpose, without fee, subject to these -conditions: -(1) If any part of the source code for this software is distributed, then this -README file must be included, with this copyright and no-warranty notice -unaltered; and any additions, deletions, or changes to the original files -must be clearly indicated in accompanying documentation. -(2) If only executable code is distributed, then the accompanying -documentation must state that "this software is based in part on the work of -the Independent JPEG Group". -(3) Permission for use of this software is granted only if the user accepts -full responsibility for any undesirable consequences; the authors accept -NO LIABILITY for damages of any kind. - -These conditions apply to any software derived from or based on the IJG code, -not just to the unmodified library. If you use our work, you ought to -acknowledge us. - -Permission is NOT granted for the use of any IJG author's name or company name -in advertising or publicity relating to this software or products derived from -it. This software may be referred to only as "the Independent JPEG Group's -software". - -We specifically permit and encourage the use of this software as the basis of -commercial products, provided that all warranty or liability claims are -assumed by the product vendor. - - -ansi2knr.c is included in this distribution by permission of L. Peter Deutsch, -sole proprietor of its copyright holder, Aladdin Enterprises of Menlo Park, CA. -ansi2knr.c is NOT covered by the above copyright and conditions, but instead -by the usual distribution terms of the Free Software Foundation; principally, -that you must include source code if you redistribute it. (See the file -ansi2knr.c for full details.) However, since ansi2knr.c is not needed as part -of any program generated from the IJG code, this does not limit you more than -the foregoing paragraphs do. - -The Unix configuration script "configure" was produced with GNU Autoconf. -It is copyright by the Free Software Foundation but is freely distributable. -The same holds for its supporting scripts (config.guess, config.sub, -ltconfig, ltmain.sh). Another support script, install-sh, is copyright -by M.I.T. but is also freely distributable. - -It appears that the arithmetic coding option of the JPEG spec is covered by -patents owned by IBM, AT&T, and Mitsubishi. Hence arithmetic coding cannot -legally be used without obtaining one or more licenses. For this reason, -support for arithmetic coding has been removed from the free JPEG software. -(Since arithmetic coding provides only a marginal gain over the unpatented -Huffman mode, it is unlikely that very many implementations will support it.) -So far as we are aware, there are no patent restrictions on the remaining -code. - -The IJG distribution formerly included code to read and write GIF files. -To avoid entanglement with the Unisys LZW patent, GIF reading support has -been removed altogether, and the GIF writer has been simplified to produce -"uncompressed GIFs". This technique does not use the LZW algorithm; the -resulting GIF files are larger than usual, but are readable by all standard -GIF decoders. - -We are required to state that - "The Graphics Interchange Format(c) is the Copyright property of - CompuServe Incorporated. GIF(sm) is a Service Mark property of - CompuServe Incorporated." - - -REFERENCES -========== - -We highly recommend reading one or more of these references before trying to -understand the innards of the JPEG software. - -The best short technical introduction to the JPEG compression algorithm is - Wallace, Gregory K. "The JPEG Still Picture Compression Standard", - Communications of the ACM, April 1991 (vol. 34 no. 4), pp. 30-44. -(Adjacent articles in that issue discuss MPEG motion picture compression, -applications of JPEG, and related topics.) If you don't have the CACM issue -handy, a PostScript file containing a revised version of Wallace's article is -available at ftp://ftp.uu.net/graphics/jpeg/wallace.ps.gz. The file (actually -a preprint for an article that appeared in IEEE Trans. Consumer Electronics) -omits the sample images that appeared in CACM, but it includes corrections -and some added material. Note: the Wallace article is copyright ACM and IEEE, -and it may not be used for commercial purposes. - -A somewhat less technical, more leisurely introduction to JPEG can be found in -"The Data Compression Book" by Mark Nelson and Jean-loup Gailly, published by -M&T Books (New York), 2nd ed. 1996, ISBN 1-55851-434-1. This book provides -good explanations and example C code for a multitude of compression methods -including JPEG. It is an excellent source if you are comfortable reading C -code but don't know much about data compression in general. The book's JPEG -sample code is far from industrial-strength, but when you are ready to look -at a full implementation, you've got one here... - -The best full description of JPEG is the textbook "JPEG Still Image Data -Compression Standard" by William B. Pennebaker and Joan L. Mitchell, published -by Van Nostrand Reinhold, 1993, ISBN 0-442-01272-1. Price US$59.95, 638 pp. -The book includes the complete text of the ISO JPEG standards (DIS 10918-1 -and draft DIS 10918-2). This is by far the most complete exposition of JPEG -in existence, and we highly recommend it. - -The JPEG standard itself is not available electronically; you must order a -paper copy through ISO or ITU. (Unless you feel a need to own a certified -official copy, we recommend buying the Pennebaker and Mitchell book instead; -it's much cheaper and includes a great deal of useful explanatory material.) -In the USA, copies of the standard may be ordered from ANSI Sales at (212) -642-4900, or from Global Engineering Documents at (800) 854-7179. (ANSI -doesn't take credit card orders, but Global does.) It's not cheap: as of -1992, ANSI was charging $95 for Part 1 and $47 for Part 2, plus 7% -shipping/handling. The standard is divided into two parts, Part 1 being the -actual specification, while Part 2 covers compliance testing methods. Part 1 -is titled "Digital Compression and Coding of Continuous-tone Still Images, -Part 1: Requirements and guidelines" and has document numbers ISO/IEC IS -10918-1, ITU-T T.81. Part 2 is titled "Digital Compression and Coding of -Continuous-tone Still Images, Part 2: Compliance testing" and has document -numbers ISO/IEC IS 10918-2, ITU-T T.83. - -Some extensions to the original JPEG standard are defined in JPEG Part 3, -a newer ISO standard numbered ISO/IEC IS 10918-3 and ITU-T T.84. IJG -currently does not support any Part 3 extensions. - -The JPEG standard does not specify all details of an interchangeable file -format. For the omitted details we follow the "JFIF" conventions, revision -1.02. A copy of the JFIF spec is available from: - Literature Department - C-Cube Microsystems, Inc. - 1778 McCarthy Blvd. - Milpitas, CA 95035 - phone (408) 944-6300, fax (408) 944-6314 -A PostScript version of this document is available by FTP at -ftp://ftp.uu.net/graphics/jpeg/jfif.ps.gz. There is also a plain text -version at ftp://ftp.uu.net/graphics/jpeg/jfif.txt.gz, but it is missing -the figures. - -The TIFF 6.0 file format specification can be obtained by FTP from -ftp://ftp.sgi.com/graphics/tiff/TIFF6.ps.gz. The JPEG incorporation scheme -found in the TIFF 6.0 spec of 3-June-92 has a number of serious problems. -IJG does not recommend use of the TIFF 6.0 design (TIFF Compression tag 6). -Instead, we recommend the JPEG design proposed by TIFF Technical Note #2 -(Compression tag 7). Copies of this Note can be obtained from ftp.sgi.com or -from ftp://ftp.uu.net/graphics/jpeg/. It is expected that the next revision -of the TIFF spec will replace the 6.0 JPEG design with the Note's design. -Although IJG's own code does not support TIFF/JPEG, the free libtiff library -uses our library to implement TIFF/JPEG per the Note. libtiff is available -from ftp://ftp.sgi.com/graphics/tiff/. - - -ARCHIVE LOCATIONS -================= - -The "official" archive site for this software is ftp.uu.net (Internet -address 192.48.96.9). The most recent released version can always be found -there in directory graphics/jpeg. This particular version will be archived -as ftp://ftp.uu.net/graphics/jpeg/jpegsrc.v6b.tar.gz. If you don't have -direct Internet access, UUNET's archives are also available via UUCP; contact -help@uunet.uu.net for information on retrieving files that way. - -Numerous Internet sites maintain copies of the UUNET files. However, only -ftp.uu.net is guaranteed to have the latest official version. - -You can also obtain this software in DOS-compatible "zip" archive format from -the SimTel archives (ftp://ftp.simtel.net/pub/simtelnet/msdos/graphics/), or -on CompuServe in the Graphics Support forum (GO CIS:GRAPHSUP), library 12 -"JPEG Tools". Again, these versions may sometimes lag behind the ftp.uu.net -release. - -The JPEG FAQ (Frequently Asked Questions) article is a useful source of -general information about JPEG. It is updated constantly and therefore is -not included in this distribution. The FAQ is posted every two weeks to -Usenet newsgroups comp.graphics.misc, news.answers, and other groups. -It is available on the World Wide Web at http://www.faqs.org/faqs/jpeg-faq/ -and other news.answers archive sites, including the official news.answers -archive at rtfm.mit.edu: ftp://rtfm.mit.edu/pub/usenet/news.answers/jpeg-faq/. -If you don't have Web or FTP access, send e-mail to mail-server@rtfm.mit.edu -with body - send usenet/news.answers/jpeg-faq/part1 - send usenet/news.answers/jpeg-faq/part2 - - -RELATED SOFTWARE -================ - -Numerous viewing and image manipulation programs now support JPEG. (Quite a -few of them use this library to do so.) The JPEG FAQ described above lists -some of the more popular free and shareware viewers, and tells where to -obtain them on Internet. - -If you are on a Unix machine, we highly recommend Jef Poskanzer's free -PBMPLUS software, which provides many useful operations on PPM-format image -files. In particular, it can convert PPM images to and from a wide range of -other formats, thus making cjpeg/djpeg considerably more useful. The latest -version is distributed by the NetPBM group, and is available from numerous -sites, notably ftp://wuarchive.wustl.edu/graphics/graphics/packages/NetPBM/. -Unfortunately PBMPLUS/NETPBM is not nearly as portable as the IJG software is; -you are likely to have difficulty making it work on any non-Unix machine. - -A different free JPEG implementation, written by the PVRG group at Stanford, -is available from ftp://havefun.stanford.edu/pub/jpeg/. This program -is designed for research and experimentation rather than production use; -it is slower, harder to use, and less portable than the IJG code, but it -is easier to read and modify. Also, the PVRG code supports lossless JPEG, -which we do not. (On the other hand, it doesn't do progressive JPEG.) - - -FILE FORMAT WARS -================ - -Some JPEG programs produce files that are not compatible with our library. -The root of the problem is that the ISO JPEG committee failed to specify a -concrete file format. Some vendors "filled in the blanks" on their own, -creating proprietary formats that no one else could read. (For example, none -of the early commercial JPEG implementations for the Macintosh were able to -exchange compressed files.) - -The file format we have adopted is called JFIF (see REFERENCES). This format -has been agreed to by a number of major commercial JPEG vendors, and it has -become the de facto standard. JFIF is a minimal or "low end" representation. -We recommend the use of TIFF/JPEG (TIFF revision 6.0 as modified by TIFF -Technical Note #2) for "high end" applications that need to record a lot of -additional data about an image. TIFF/JPEG is fairly new and not yet widely -supported, unfortunately. - -The upcoming JPEG Part 3 standard defines a file format called SPIFF. -SPIFF is interoperable with JFIF, in the sense that most JFIF decoders should -be able to read the most common variant of SPIFF. SPIFF has some technical -advantages over JFIF, but its major claim to fame is simply that it is an -official standard rather than an informal one. At this point it is unclear -whether SPIFF will supersede JFIF or whether JFIF will remain the de-facto -standard. IJG intends to support SPIFF once the standard is frozen, but we -have not decided whether it should become our default output format or not. -(In any case, our decoder will remain capable of reading JFIF indefinitely.) - -Various proprietary file formats incorporating JPEG compression also exist. -We have little or no sympathy for the existence of these formats. Indeed, -one of the original reasons for developing this free software was to help -force convergence on common, open format standards for JPEG files. Don't -use a proprietary file format! - - -TO DO -===== - -The major thrust for v7 will probably be improvement of visual quality. -The current method for scaling the quantization tables is known not to be -very good at low Q values. We also intend to investigate block boundary -smoothing, "poor man's variable quantization", and other means of improving -quality-vs-file-size performance without sacrificing compatibility. - -In future versions, we are considering supporting some of the upcoming JPEG -Part 3 extensions --- principally, variable quantization and the SPIFF file -format. - -As always, speeding things up is of great interest. - -Please send bug reports, offers of help, etc. to jpeg-info@uunet.uu.net. diff --git a/engine/jpeg-6/jcapimin.c b/engine/jpeg-6/jcapimin.c deleted file mode 100644 index 1cd9736..0000000 --- a/engine/jpeg-6/jcapimin.c +++ /dev/null @@ -1,228 +0,0 @@ -/* - * jcapimin.c - * - * Copyright (C) 1994-1995, Thomas G. Lane. - * This file is part of the Independent JPEG Group's software. - * For conditions of distribution and use, see the accompanying README file. - * - * This file contains application interface code for the compression half - * of the JPEG library. These are the "minimum" API routines that may be - * needed in either the normal full-compression case or the transcoding-only - * case. - * - * Most of the routines intended to be called directly by an application - * are in this file or in jcapistd.c. But also see jcparam.c for - * parameter-setup helper routines, jcomapi.c for routines shared by - * compression and decompression, and jctrans.c for the transcoding case. - */ - -#define JPEG_INTERNALS -#include "jinclude.h" -#include "jpeglib.h" - - -/* - * Initialization of a JPEG compression object. - * The error manager must already be set up (in case memory manager fails). - */ - -GLOBAL void -jpeg_create_compress (j_compress_ptr cinfo) -{ - int i; - - /* For debugging purposes, zero the whole master structure. - * But error manager pointer is already there, so save and restore it. - */ - { - struct jpeg_error_mgr * err = cinfo->err; - MEMZERO(cinfo, SIZEOF(struct jpeg_compress_struct)); - cinfo->err = err; - } - cinfo->is_decompressor = FALSE; - - /* Initialize a memory manager instance for this object */ - jinit_memory_mgr((j_common_ptr) cinfo); - - /* Zero out pointers to permanent structures. */ - cinfo->progress = NULL; - cinfo->dest = NULL; - - cinfo->comp_info = NULL; - - for (i = 0; i < NUM_QUANT_TBLS; i++) - cinfo->quant_tbl_ptrs[i] = NULL; - - for (i = 0; i < NUM_HUFF_TBLS; i++) { - cinfo->dc_huff_tbl_ptrs[i] = NULL; - cinfo->ac_huff_tbl_ptrs[i] = NULL; - } - - cinfo->input_gamma = 1.0; /* in case application forgets */ - - /* OK, I'm ready */ - cinfo->global_state = CSTATE_START; -} - - -/* - * Destruction of a JPEG compression object - */ - -GLOBAL void -jpeg_destroy_compress (j_compress_ptr cinfo) -{ - jpeg_destroy((j_common_ptr) cinfo); /* use common routine */ -} - - -/* - * Abort processing of a JPEG compression operation, - * but don't destroy the object itself. - */ - -GLOBAL void -jpeg_abort_compress (j_compress_ptr cinfo) -{ - jpeg_abort((j_common_ptr) cinfo); /* use common routine */ -} - - -/* - * Forcibly suppress or un-suppress all quantization and Huffman tables. - * Marks all currently defined tables as already written (if suppress) - * or not written (if !suppress). This will control whether they get emitted - * by a subsequent jpeg_start_compress call. - * - * This routine is exported for use by applications that want to produce - * abbreviated JPEG datastreams. It logically belongs in jcparam.c, but - * since it is called by jpeg_start_compress, we put it here --- otherwise - * jcparam.o would be linked whether the application used it or not. - */ - -GLOBAL void -jpeg_suppress_tables (j_compress_ptr cinfo, boolean suppress) -{ - int i; - JQUANT_TBL * qtbl; - JHUFF_TBL * htbl; - - for (i = 0; i < NUM_QUANT_TBLS; i++) { - if ((qtbl = cinfo->quant_tbl_ptrs[i]) != NULL) - qtbl->sent_table = suppress; - } - - for (i = 0; i < NUM_HUFF_TBLS; i++) { - if ((htbl = cinfo->dc_huff_tbl_ptrs[i]) != NULL) - htbl->sent_table = suppress; - if ((htbl = cinfo->ac_huff_tbl_ptrs[i]) != NULL) - htbl->sent_table = suppress; - } -} - - -/* - * Finish JPEG compression. - * - * If a multipass operating mode was selected, this may do a great deal of - * work including most of the actual output. - */ - -GLOBAL void -jpeg_finish_compress (j_compress_ptr cinfo) -{ - JDIMENSION iMCU_row; - - if (cinfo->global_state == CSTATE_SCANNING || - cinfo->global_state == CSTATE_RAW_OK) { - /* Terminate first pass */ - if (cinfo->next_scanline < cinfo->image_height) - ERREXIT(cinfo, JERR_TOO_LITTLE_DATA); - (*cinfo->master->finish_pass) (cinfo); - } else if (cinfo->global_state != CSTATE_WRCOEFS) - ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); - /* Perform any remaining passes */ - while (! cinfo->master->is_last_pass) { - (*cinfo->master->prepare_for_pass) (cinfo); - for (iMCU_row = 0; iMCU_row < cinfo->total_iMCU_rows; iMCU_row++) { - if (cinfo->progress != NULL) { - cinfo->progress->pass_counter = (long) iMCU_row; - cinfo->progress->pass_limit = (long) cinfo->total_iMCU_rows; - (*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo); - } - /* We bypass the main controller and invoke coef controller directly; - * all work is being done from the coefficient buffer. - */ - if (! (*cinfo->coef->compress_data) (cinfo, (JSAMPIMAGE) NULL)) - ERREXIT(cinfo, JERR_CANT_SUSPEND); - } - (*cinfo->master->finish_pass) (cinfo); - } - /* Write EOI, do final cleanup */ - (*cinfo->marker->write_file_trailer) (cinfo); - (*cinfo->dest->term_destination) (cinfo); - /* We can use jpeg_abort to release memory and reset global_state */ - jpeg_abort((j_common_ptr) cinfo); -} - - -/* - * Write a special marker. - * This is only recommended for writing COM or APPn markers. - * Must be called after jpeg_start_compress() and before - * first call to jpeg_write_scanlines() or jpeg_write_raw_data(). - */ - -GLOBAL void -jpeg_write_marker (j_compress_ptr cinfo, int marker, - const JOCTET *dataptr, unsigned int datalen) -{ - if (cinfo->next_scanline != 0 || - (cinfo->global_state != CSTATE_SCANNING && - cinfo->global_state != CSTATE_RAW_OK && - cinfo->global_state != CSTATE_WRCOEFS)) - ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); - - (*cinfo->marker->write_any_marker) (cinfo, marker, dataptr, datalen); -} - - -/* - * Alternate compression function: just write an abbreviated table file. - * Before calling this, all parameters and a data destination must be set up. - * - * To produce a pair of files containing abbreviated tables and abbreviated - * image data, one would proceed as follows: - * - * initialize JPEG object - * set JPEG parameters - * set destination to table file - * jpeg_write_tables(cinfo); - * set destination to image file - * jpeg_start_compress(cinfo, FALSE); - * write data... - * jpeg_finish_compress(cinfo); - * - * jpeg_write_tables has the side effect of marking all tables written - * (same as jpeg_suppress_tables(..., TRUE)). Thus a subsequent start_compress - * will not re-emit the tables unless it is passed write_all_tables=TRUE. - */ - -GLOBAL void -jpeg_write_tables (j_compress_ptr cinfo) -{ - if (cinfo->global_state != CSTATE_START) - ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); - - /* (Re)initialize error mgr and destination modules */ - (*cinfo->err->reset_error_mgr) ((j_common_ptr) cinfo); - (*cinfo->dest->init_destination) (cinfo); - /* Initialize the marker writer ... bit of a crock to do it here. */ - jinit_marker_writer(cinfo); - /* Write them tables! */ - (*cinfo->marker->write_tables_only) (cinfo); - /* And clean up. */ - (*cinfo->dest->term_destination) (cinfo); - /* We can use jpeg_abort to release memory. */ - jpeg_abort((j_common_ptr) cinfo); -} diff --git a/engine/jpeg-6/jcapistd.c b/engine/jpeg-6/jcapistd.c deleted file mode 100644 index b99e560..0000000 --- a/engine/jpeg-6/jcapistd.c +++ /dev/null @@ -1,161 +0,0 @@ -/* - * jcapistd.c - * - * Copyright (C) 1994-1995, Thomas G. Lane. - * This file is part of the Independent JPEG Group's software. - * For conditions of distribution and use, see the accompanying README file. - * - * This file contains application interface code for the compression half - * of the JPEG library. These are the "standard" API routines that are - * used in the normal full-compression case. They are not used by a - * transcoding-only application. Note that if an application links in - * jpeg_start_compress, it will end up linking in the entire compressor. - * We thus must separate this file from jcapimin.c to avoid linking the - * whole compression library into a transcoder. - */ - -#define JPEG_INTERNALS -#include "jinclude.h" -#include "jpeglib.h" - - -/* - * Compression initialization. - * Before calling this, all parameters and a data destination must be set up. - * - * We require a write_all_tables parameter as a failsafe check when writing - * multiple datastreams from the same compression object. Since prior runs - * will have left all the tables marked sent_table=TRUE, a subsequent run - * would emit an abbreviated stream (no tables) by default. This may be what - * is wanted, but for safety's sake it should not be the default behavior: - * programmers should have to make a deliberate choice to emit abbreviated - * images. Therefore the documentation and examples should encourage people - * to pass write_all_tables=TRUE; then it will take active thought to do the - * wrong thing. - */ - -GLOBAL void -jpeg_start_compress (j_compress_ptr cinfo, boolean write_all_tables) -{ - if (cinfo->global_state != CSTATE_START) - ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); - - if (write_all_tables) - jpeg_suppress_tables(cinfo, FALSE); /* mark all tables to be written */ - - /* (Re)initialize error mgr and destination modules */ - (*cinfo->err->reset_error_mgr) ((j_common_ptr) cinfo); - (*cinfo->dest->init_destination) (cinfo); - /* Perform master selection of active modules */ - jinit_compress_master(cinfo); - /* Set up for the first pass */ - (*cinfo->master->prepare_for_pass) (cinfo); - /* Ready for application to drive first pass through jpeg_write_scanlines - * or jpeg_write_raw_data. - */ - cinfo->next_scanline = 0; - cinfo->global_state = (cinfo->raw_data_in ? CSTATE_RAW_OK : CSTATE_SCANNING); -} - - -/* - * Write some scanlines of data to the JPEG compressor. - * - * The return value will be the number of lines actually written. - * This should be less than the supplied num_lines only in case that - * the data destination module has requested suspension of the compressor, - * or if more than image_height scanlines are passed in. - * - * Note: we warn about excess calls to jpeg_write_scanlines() since - * this likely signals an application programmer error. However, - * excess scanlines passed in the last valid call are *silently* ignored, - * so that the application need not adjust num_lines for end-of-image - * when using a multiple-scanline buffer. - */ - -GLOBAL JDIMENSION -jpeg_write_scanlines (j_compress_ptr cinfo, JSAMPARRAY scanlines, - JDIMENSION num_lines) -{ - JDIMENSION row_ctr, rows_left; - - if (cinfo->global_state != CSTATE_SCANNING) - ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); - if (cinfo->next_scanline >= cinfo->image_height) - WARNMS(cinfo, JWRN_TOO_MUCH_DATA); - - /* Call progress monitor hook if present */ - if (cinfo->progress != NULL) { - cinfo->progress->pass_counter = (long) cinfo->next_scanline; - cinfo->progress->pass_limit = (long) cinfo->image_height; - (*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo); - } - - /* Give master control module another chance if this is first call to - * jpeg_write_scanlines. This lets output of the frame/scan headers be - * delayed so that application can write COM, etc, markers between - * jpeg_start_compress and jpeg_write_scanlines. - */ - if (cinfo->master->call_pass_startup) - (*cinfo->master->pass_startup) (cinfo); - - /* Ignore any extra scanlines at bottom of image. */ - rows_left = cinfo->image_height - cinfo->next_scanline; - if (num_lines > rows_left) - num_lines = rows_left; - - row_ctr = 0; - (*cinfo->main->process_data) (cinfo, scanlines, &row_ctr, num_lines); - cinfo->next_scanline += row_ctr; - return row_ctr; -} - - -/* - * Alternate entry point to write raw data. - * Processes exactly one iMCU row per call, unless suspended. - */ - -GLOBAL JDIMENSION -jpeg_write_raw_data (j_compress_ptr cinfo, JSAMPIMAGE data, - JDIMENSION num_lines) -{ - JDIMENSION lines_per_iMCU_row; - - if (cinfo->global_state != CSTATE_RAW_OK) - ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); - if (cinfo->next_scanline >= cinfo->image_height) { - WARNMS(cinfo, JWRN_TOO_MUCH_DATA); - return 0; - } - - /* Call progress monitor hook if present */ - if (cinfo->progress != NULL) { - cinfo->progress->pass_counter = (long) cinfo->next_scanline; - cinfo->progress->pass_limit = (long) cinfo->image_height; - (*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo); - } - - /* Give master control module another chance if this is first call to - * jpeg_write_raw_data. This lets output of the frame/scan headers be - * delayed so that application can write COM, etc, markers between - * jpeg_start_compress and jpeg_write_raw_data. - */ - if (cinfo->master->call_pass_startup) - (*cinfo->master->pass_startup) (cinfo); - - /* Verify that at least one iMCU row has been passed. */ - lines_per_iMCU_row = cinfo->max_v_samp_factor * DCTSIZE; - if (num_lines < lines_per_iMCU_row) - ERREXIT(cinfo, JERR_BUFFER_SIZE); - - /* Directly compress the row. */ - if (! (*cinfo->coef->compress_data) (cinfo, data)) { - /* If compressor did not consume the whole row, suspend processing. */ - return 0; - } - - /* OK, we processed one iMCU row. */ - cinfo->next_scanline += lines_per_iMCU_row; - return lines_per_iMCU_row; -} diff --git a/engine/jpeg-6/jccoefct.c b/engine/jpeg-6/jccoefct.c deleted file mode 100644 index ea3169b..0000000 --- a/engine/jpeg-6/jccoefct.c +++ /dev/null @@ -1,448 +0,0 @@ -/* - * jccoefct.c - * - * Copyright (C) 1994-1995, Thomas G. Lane. - * This file is part of the Independent JPEG Group's software. - * For conditions of distribution and use, see the accompanying README file. - * - * This file contains the coefficient buffer controller for compression. - * This controller is the top level of the JPEG compressor proper. - * The coefficient buffer lies between forward-DCT and entropy encoding steps. - */ - -#define JPEG_INTERNALS -#include "jinclude.h" -#include "jpeglib.h" - - -/* We use a full-image coefficient buffer when doing Huffman optimization, - * and also for writing multiple-scan JPEG files. In all cases, the DCT - * step is run during the first pass, and subsequent passes need only read - * the buffered coefficients. - */ -#ifdef ENTROPY_OPT_SUPPORTED -#define FULL_COEF_BUFFER_SUPPORTED -#else -#ifdef C_MULTISCAN_FILES_SUPPORTED -#define FULL_COEF_BUFFER_SUPPORTED -#endif -#endif - - -/* Private buffer controller object */ - -typedef struct { - struct jpeg_c_coef_controller pub; /* public fields */ - - JDIMENSION iMCU_row_num; /* iMCU row # within image */ - JDIMENSION mcu_ctr; /* counts MCUs processed in current row */ - int MCU_vert_offset; /* counts MCU rows within iMCU row */ - int MCU_rows_per_iMCU_row; /* number of such rows needed */ - - /* For single-pass compression, it's sufficient to buffer just one MCU - * (although this may prove a bit slow in practice). We allocate a - * workspace of C_MAX_BLOCKS_IN_MCU coefficient blocks, and reuse it for each - * MCU constructed and sent. (On 80x86, the workspace is FAR even though - * it's not really very big; this is to keep the module interfaces unchanged - * when a large coefficient buffer is necessary.) - * In multi-pass modes, this array points to the current MCU's blocks - * within the virtual arrays. - */ - JBLOCKROW MCU_buffer[C_MAX_BLOCKS_IN_MCU]; - - /* In multi-pass modes, we need a virtual block array for each component. */ - jvirt_barray_ptr whole_image[MAX_COMPONENTS]; -} my_coef_controller; - -typedef my_coef_controller * my_coef_ptr; - - -/* Forward declarations */ -METHODDEF boolean compress_data - JPP((j_compress_ptr cinfo, JSAMPIMAGE input_buf)); -#ifdef FULL_COEF_BUFFER_SUPPORTED -METHODDEF boolean compress_first_pass - JPP((j_compress_ptr cinfo, JSAMPIMAGE input_buf)); -METHODDEF boolean compress_output - JPP((j_compress_ptr cinfo, JSAMPIMAGE input_buf)); -#endif - - -LOCAL void -start_iMCU_row (j_compress_ptr cinfo) -/* Reset within-iMCU-row counters for a new row */ -{ - my_coef_ptr coef = (my_coef_ptr) cinfo->coef; - - /* In an interleaved scan, an MCU row is the same as an iMCU row. - * In a noninterleaved scan, an iMCU row has v_samp_factor MCU rows. - * But at the bottom of the image, process only what's left. - */ - if (cinfo->comps_in_scan > 1) { - coef->MCU_rows_per_iMCU_row = 1; - } else { - if (coef->iMCU_row_num < (cinfo->total_iMCU_rows-1)) - coef->MCU_rows_per_iMCU_row = cinfo->cur_comp_info[0]->v_samp_factor; - else - coef->MCU_rows_per_iMCU_row = cinfo->cur_comp_info[0]->last_row_height; - } - - coef->mcu_ctr = 0; - coef->MCU_vert_offset = 0; -} - - -/* - * Initialize for a processing pass. - */ - -METHODDEF void -start_pass_coef (j_compress_ptr cinfo, J_BUF_MODE pass_mode) -{ - my_coef_ptr coef = (my_coef_ptr) cinfo->coef; - - coef->iMCU_row_num = 0; - start_iMCU_row(cinfo); - - switch (pass_mode) { - case JBUF_PASS_THRU: - if (coef->whole_image[0] != NULL) - ERREXIT(cinfo, JERR_BAD_BUFFER_MODE); - coef->pub.compress_data = compress_data; - break; -#ifdef FULL_COEF_BUFFER_SUPPORTED - case JBUF_SAVE_AND_PASS: - if (coef->whole_image[0] == NULL) - ERREXIT(cinfo, JERR_BAD_BUFFER_MODE); - coef->pub.compress_data = compress_first_pass; - break; - case JBUF_CRANK_DEST: - if (coef->whole_image[0] == NULL) - ERREXIT(cinfo, JERR_BAD_BUFFER_MODE); - coef->pub.compress_data = compress_output; - break; -#endif - default: - ERREXIT(cinfo, JERR_BAD_BUFFER_MODE); - break; - } -} - - -/* - * Process some data in the single-pass case. - * We process the equivalent of one fully interleaved MCU row ("iMCU" row) - * per call, ie, v_samp_factor block rows for each component in the image. - * Returns TRUE if the iMCU row is completed, FALSE if suspended. - * - * NB: input_buf contains a plane for each component in image. - * For single pass, this is the same as the components in the scan. - */ - -METHODDEF boolean -compress_data (j_compress_ptr cinfo, JSAMPIMAGE input_buf) -{ - my_coef_ptr coef = (my_coef_ptr) cinfo->coef; - JDIMENSION MCU_col_num; /* index of current MCU within row */ - JDIMENSION last_MCU_col = cinfo->MCUs_per_row - 1; - JDIMENSION last_iMCU_row = cinfo->total_iMCU_rows - 1; - int blkn, bi, ci, yindex, yoffset, blockcnt; - JDIMENSION ypos, xpos; - jpeg_component_info *compptr; - - /* Loop to write as much as one whole iMCU row */ - for (yoffset = coef->MCU_vert_offset; yoffset < coef->MCU_rows_per_iMCU_row; - yoffset++) { - for (MCU_col_num = coef->mcu_ctr; MCU_col_num <= last_MCU_col; - MCU_col_num++) { - /* Determine where data comes from in input_buf and do the DCT thing. - * Each call on forward_DCT processes a horizontal row of DCT blocks - * as wide as an MCU; we rely on having allocated the MCU_buffer[] blocks - * sequentially. Dummy blocks at the right or bottom edge are filled in - * specially. The data in them does not matter for image reconstruction, - * so we fill them with values that will encode to the smallest amount of - * data, viz: all zeroes in the AC entries, DC entries equal to previous - * block's DC value. (Thanks to Thomas Kinsman for this idea.) - */ - blkn = 0; - for (ci = 0; ci < cinfo->comps_in_scan; ci++) { - compptr = cinfo->cur_comp_info[ci]; - blockcnt = (MCU_col_num < last_MCU_col) ? compptr->MCU_width - : compptr->last_col_width; - xpos = MCU_col_num * compptr->MCU_sample_width; - ypos = yoffset * DCTSIZE; /* ypos == (yoffset+yindex) * DCTSIZE */ - for (yindex = 0; yindex < compptr->MCU_height; yindex++) { - if (coef->iMCU_row_num < last_iMCU_row || - yoffset+yindex < compptr->last_row_height) { - (*cinfo->fdct->forward_DCT) (cinfo, compptr, - input_buf[ci], coef->MCU_buffer[blkn], - ypos, xpos, (JDIMENSION) blockcnt); - if (blockcnt < compptr->MCU_width) { - /* Create some dummy blocks at the right edge of the image. */ - jzero_far((void FAR *) coef->MCU_buffer[blkn + blockcnt], - (compptr->MCU_width - blockcnt) * SIZEOF(JBLOCK)); - for (bi = blockcnt; bi < compptr->MCU_width; bi++) { - coef->MCU_buffer[blkn+bi][0][0] = coef->MCU_buffer[blkn+bi-1][0][0]; - } - } - } else { - /* Create a row of dummy blocks at the bottom of the image. */ - jzero_far((void FAR *) coef->MCU_buffer[blkn], - compptr->MCU_width * SIZEOF(JBLOCK)); - for (bi = 0; bi < compptr->MCU_width; bi++) { - coef->MCU_buffer[blkn+bi][0][0] = coef->MCU_buffer[blkn-1][0][0]; - } - } - blkn += compptr->MCU_width; - ypos += DCTSIZE; - } - } - /* Try to write the MCU. In event of a suspension failure, we will - * re-DCT the MCU on restart (a bit inefficient, could be fixed...) - */ - if (! (*cinfo->entropy->encode_mcu) (cinfo, coef->MCU_buffer)) { - /* Suspension forced; update state counters and exit */ - coef->MCU_vert_offset = yoffset; - coef->mcu_ctr = MCU_col_num; - return FALSE; - } - } - /* Completed an MCU row, but perhaps not an iMCU row */ - coef->mcu_ctr = 0; - } - /* Completed the iMCU row, advance counters for next one */ - coef->iMCU_row_num++; - start_iMCU_row(cinfo); - return TRUE; -} - - -#ifdef FULL_COEF_BUFFER_SUPPORTED - -/* - * Process some data in the first pass of a multi-pass case. - * We process the equivalent of one fully interleaved MCU row ("iMCU" row) - * per call, ie, v_samp_factor block rows for each component in the image. - * This amount of data is read from the source buffer, DCT'd and quantized, - * and saved into the virtual arrays. We also generate suitable dummy blocks - * as needed at the right and lower edges. (The dummy blocks are constructed - * in the virtual arrays, which have been padded appropriately.) This makes - * it possible for subsequent passes not to worry about real vs. dummy blocks. - * - * We must also emit the data to the entropy encoder. This is conveniently - * done by calling compress_output() after we've loaded the current strip - * of the virtual arrays. - * - * NB: input_buf contains a plane for each component in image. All - * components are DCT'd and loaded into the virtual arrays in this pass. - * However, it may be that only a subset of the components are emitted to - * the entropy encoder during this first pass; be careful about looking - * at the scan-dependent variables (MCU dimensions, etc). - */ - -METHODDEF boolean -compress_first_pass (j_compress_ptr cinfo, JSAMPIMAGE input_buf) -{ - my_coef_ptr coef = (my_coef_ptr) cinfo->coef; - JDIMENSION last_iMCU_row = cinfo->total_iMCU_rows - 1; - JDIMENSION blocks_across, MCUs_across, MCUindex; - int bi, ci, h_samp_factor, block_row, block_rows, ndummy; - JCOEF lastDC; - jpeg_component_info *compptr; - JBLOCKARRAY buffer; - JBLOCKROW thisblockrow, lastblockrow; - - for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; - ci++, compptr++) { - /* Align the virtual buffer for this component. */ - buffer = (*cinfo->mem->access_virt_barray) - ((j_common_ptr) cinfo, coef->whole_image[ci], - coef->iMCU_row_num * compptr->v_samp_factor, - (JDIMENSION) compptr->v_samp_factor, TRUE); - /* Count non-dummy DCT block rows in this iMCU row. */ - if (coef->iMCU_row_num < last_iMCU_row) - block_rows = compptr->v_samp_factor; - else { - /* NB: can't use last_row_height here, since may not be set! */ - block_rows = (int) (compptr->height_in_blocks % compptr->v_samp_factor); - if (block_rows == 0) block_rows = compptr->v_samp_factor; - } - blocks_across = compptr->width_in_blocks; - h_samp_factor = compptr->h_samp_factor; - /* Count number of dummy blocks to be added at the right margin. */ - ndummy = (int) (blocks_across % h_samp_factor); - if (ndummy > 0) - ndummy = h_samp_factor - ndummy; - /* Perform DCT for all non-dummy blocks in this iMCU row. Each call - * on forward_DCT processes a complete horizontal row of DCT blocks. - */ - for (block_row = 0; block_row < block_rows; block_row++) { - thisblockrow = buffer[block_row]; - (*cinfo->fdct->forward_DCT) (cinfo, compptr, - input_buf[ci], thisblockrow, - (JDIMENSION) (block_row * DCTSIZE), - (JDIMENSION) 0, blocks_across); - if (ndummy > 0) { - /* Create dummy blocks at the right edge of the image. */ - thisblockrow += blocks_across; /* => first dummy block */ - jzero_far((void FAR *) thisblockrow, ndummy * SIZEOF(JBLOCK)); - lastDC = thisblockrow[-1][0]; - for (bi = 0; bi < ndummy; bi++) { - thisblockrow[bi][0] = lastDC; - } - } - } - /* If at end of image, create dummy block rows as needed. - * The tricky part here is that within each MCU, we want the DC values - * of the dummy blocks to match the last real block's DC value. - * This squeezes a few more bytes out of the resulting file... - */ - if (coef->iMCU_row_num == last_iMCU_row) { - blocks_across += ndummy; /* include lower right corner */ - MCUs_across = blocks_across / h_samp_factor; - for (block_row = block_rows; block_row < compptr->v_samp_factor; - block_row++) { - thisblockrow = buffer[block_row]; - lastblockrow = buffer[block_row-1]; - jzero_far((void FAR *) thisblockrow, - (size_t) (blocks_across * SIZEOF(JBLOCK))); - for (MCUindex = 0; MCUindex < MCUs_across; MCUindex++) { - lastDC = lastblockrow[h_samp_factor-1][0]; - for (bi = 0; bi < h_samp_factor; bi++) { - thisblockrow[bi][0] = lastDC; - } - thisblockrow += h_samp_factor; /* advance to next MCU in row */ - lastblockrow += h_samp_factor; - } - } - } - } - /* NB: compress_output will increment iMCU_row_num if successful. - * A suspension return will result in redoing all the work above next time. - */ - - /* Emit data to the entropy encoder, sharing code with subsequent passes */ - return compress_output(cinfo, input_buf); -} - - -/* - * Process some data in subsequent passes of a multi-pass case. - * We process the equivalent of one fully interleaved MCU row ("iMCU" row) - * per call, ie, v_samp_factor block rows for each component in the scan. - * The data is obtained from the virtual arrays and fed to the entropy coder. - * Returns TRUE if the iMCU row is completed, FALSE if suspended. - * - * NB: input_buf is ignored; it is likely to be a NULL pointer. - */ - -METHODDEF boolean -compress_output (j_compress_ptr cinfo, JSAMPIMAGE input_buf) -{ - my_coef_ptr coef = (my_coef_ptr) cinfo->coef; - JDIMENSION MCU_col_num; /* index of current MCU within row */ - int blkn, ci, xindex, yindex, yoffset; - JDIMENSION start_col; - JBLOCKARRAY buffer[MAX_COMPS_IN_SCAN]; - JBLOCKROW buffer_ptr; - jpeg_component_info *compptr; - - /* Align the virtual buffers for the components used in this scan. - * NB: during first pass, this is safe only because the buffers will - * already be aligned properly, so jmemmgr.c won't need to do any I/O. - */ - for (ci = 0; ci < cinfo->comps_in_scan; ci++) { - compptr = cinfo->cur_comp_info[ci]; - buffer[ci] = (*cinfo->mem->access_virt_barray) - ((j_common_ptr) cinfo, coef->whole_image[compptr->component_index], - coef->iMCU_row_num * compptr->v_samp_factor, - (JDIMENSION) compptr->v_samp_factor, FALSE); - } - - /* Loop to process one whole iMCU row */ - for (yoffset = coef->MCU_vert_offset; yoffset < coef->MCU_rows_per_iMCU_row; - yoffset++) { - for (MCU_col_num = coef->mcu_ctr; MCU_col_num < cinfo->MCUs_per_row; - MCU_col_num++) { - /* Construct list of pointers to DCT blocks belonging to this MCU */ - blkn = 0; /* index of current DCT block within MCU */ - for (ci = 0; ci < cinfo->comps_in_scan; ci++) { - compptr = cinfo->cur_comp_info[ci]; - start_col = MCU_col_num * compptr->MCU_width; - for (yindex = 0; yindex < compptr->MCU_height; yindex++) { - buffer_ptr = buffer[ci][yindex+yoffset] + start_col; - for (xindex = 0; xindex < compptr->MCU_width; xindex++) { - coef->MCU_buffer[blkn++] = buffer_ptr++; - } - } - } - /* Try to write the MCU. */ - if (! (*cinfo->entropy->encode_mcu) (cinfo, coef->MCU_buffer)) { - /* Suspension forced; update state counters and exit */ - coef->MCU_vert_offset = yoffset; - coef->mcu_ctr = MCU_col_num; - return FALSE; - } - } - /* Completed an MCU row, but perhaps not an iMCU row */ - coef->mcu_ctr = 0; - } - /* Completed the iMCU row, advance counters for next one */ - coef->iMCU_row_num++; - start_iMCU_row(cinfo); - return TRUE; -} - -#endif /* FULL_COEF_BUFFER_SUPPORTED */ - - -/* - * Initialize coefficient buffer controller. - */ - -GLOBAL void -jinit_c_coef_controller (j_compress_ptr cinfo, boolean need_full_buffer) -{ - my_coef_ptr coef; - - coef = (my_coef_ptr) - (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, - SIZEOF(my_coef_controller)); - cinfo->coef = (struct jpeg_c_coef_controller *) coef; - coef->pub.start_pass = start_pass_coef; - - /* Create the coefficient buffer. */ - if (need_full_buffer) { -#ifdef FULL_COEF_BUFFER_SUPPORTED - /* Allocate a full-image virtual array for each component, */ - /* padded to a multiple of samp_factor DCT blocks in each direction. */ - int ci; - jpeg_component_info *compptr; - - for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; - ci++, compptr++) { - coef->whole_image[ci] = (*cinfo->mem->request_virt_barray) - ((j_common_ptr) cinfo, JPOOL_IMAGE, FALSE, - (JDIMENSION) jround_up((long) compptr->width_in_blocks, - (long) compptr->h_samp_factor), - (JDIMENSION) jround_up((long) compptr->height_in_blocks, - (long) compptr->v_samp_factor), - (JDIMENSION) compptr->v_samp_factor); - } -#else - ERREXIT(cinfo, JERR_BAD_BUFFER_MODE); -#endif - } else { - /* We only need a single-MCU buffer. */ - JBLOCKROW buffer; - int i; - - buffer = (JBLOCKROW) - (*cinfo->mem->alloc_large) ((j_common_ptr) cinfo, JPOOL_IMAGE, - C_MAX_BLOCKS_IN_MCU * SIZEOF(JBLOCK)); - for (i = 0; i < C_MAX_BLOCKS_IN_MCU; i++) { - coef->MCU_buffer[i] = buffer + i; - } - coef->whole_image[0] = NULL; /* flag for no virtual arrays */ - } -} diff --git a/engine/jpeg-6/jccolor.c b/engine/jpeg-6/jccolor.c deleted file mode 100644 index 6707911..0000000 --- a/engine/jpeg-6/jccolor.c +++ /dev/null @@ -1,459 +0,0 @@ -/* - * jccolor.c - * - * Copyright (C) 1991-1994, Thomas G. Lane. - * This file is part of the Independent JPEG Group's software. - * For conditions of distribution and use, see the accompanying README file. - * - * This file contains input colorspace conversion routines. - */ - -#define JPEG_INTERNALS -#include "jinclude.h" -#include "jpeglib.h" - - -/* Private subobject */ - -typedef struct { - struct jpeg_color_converter pub; /* public fields */ - - /* Private state for RGB->YCC conversion */ - INT32 * rgb_ycc_tab; /* => table for RGB to YCbCr conversion */ -} my_color_converter; - -typedef my_color_converter * my_cconvert_ptr; - - -/**************** RGB -> YCbCr conversion: most common case **************/ - -/* - * YCbCr is defined per CCIR 601-1, except that Cb and Cr are - * normalized to the range 0..MAXJSAMPLE rather than -0.5 .. 0.5. - * The conversion equations to be implemented are therefore - * Y = 0.29900 * R + 0.58700 * G + 0.11400 * B - * Cb = -0.16874 * R - 0.33126 * G + 0.50000 * B + CENTERJSAMPLE - * Cr = 0.50000 * R - 0.41869 * G - 0.08131 * B + CENTERJSAMPLE - * (These numbers are derived from TIFF 6.0 section 21, dated 3-June-92.) - * Note: older versions of the IJG code used a zero offset of MAXJSAMPLE/2, - * rather than CENTERJSAMPLE, for Cb and Cr. This gave equal positive and - * negative swings for Cb/Cr, but meant that grayscale values (Cb=Cr=0) - * were not represented exactly. Now we sacrifice exact representation of - * maximum red and maximum blue in order to get exact grayscales. - * - * To avoid floating-point arithmetic, we represent the fractional constants - * as integers scaled up by 2^16 (about 4 digits precision); we have to divide - * the products by 2^16, with appropriate rounding, to get the correct answer. - * - * For even more speed, we avoid doing any multiplications in the inner loop - * by precalculating the constants times R,G,B for all possible values. - * For 8-bit JSAMPLEs this is very reasonable (only 256 entries per table); - * for 12-bit samples it is still acceptable. It's not very reasonable for - * 16-bit samples, but if you want lossless storage you shouldn't be changing - * colorspace anyway. - * The CENTERJSAMPLE offsets and the rounding fudge-factor of 0.5 are included - * in the tables to save adding them separately in the inner loop. - */ - -#define SCALEBITS 16 /* speediest right-shift on some machines */ -#define CBCR_OFFSET ((INT32) CENTERJSAMPLE << SCALEBITS) -#define ONE_HALF ((INT32) 1 << (SCALEBITS-1)) -#define FIX(x) ((INT32) ((x) * (1L< Y section */ -#define G_Y_OFF (1*(MAXJSAMPLE+1)) /* offset to G => Y section */ -#define B_Y_OFF (2*(MAXJSAMPLE+1)) /* etc. */ -#define R_CB_OFF (3*(MAXJSAMPLE+1)) -#define G_CB_OFF (4*(MAXJSAMPLE+1)) -#define B_CB_OFF (5*(MAXJSAMPLE+1)) -#define R_CR_OFF B_CB_OFF /* B=>Cb, R=>Cr are the same */ -#define G_CR_OFF (6*(MAXJSAMPLE+1)) -#define B_CR_OFF (7*(MAXJSAMPLE+1)) -#define TABLE_SIZE (8*(MAXJSAMPLE+1)) - - -/* - * Initialize for RGB->YCC colorspace conversion. - */ - -METHODDEF void -rgb_ycc_start (j_compress_ptr cinfo) -{ - my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert; - INT32 * rgb_ycc_tab; - INT32 i; - - /* Allocate and fill in the conversion tables. */ - cconvert->rgb_ycc_tab = rgb_ycc_tab = (INT32 *) - (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, - (TABLE_SIZE * SIZEOF(INT32))); - - for (i = 0; i <= MAXJSAMPLE; i++) { - rgb_ycc_tab[i+R_Y_OFF] = FIX(0.29900) * i; - rgb_ycc_tab[i+G_Y_OFF] = FIX(0.58700) * i; - rgb_ycc_tab[i+B_Y_OFF] = FIX(0.11400) * i + ONE_HALF; - rgb_ycc_tab[i+R_CB_OFF] = (-FIX(0.16874)) * i; - rgb_ycc_tab[i+G_CB_OFF] = (-FIX(0.33126)) * i; - /* We use a rounding fudge-factor of 0.5-epsilon for Cb and Cr. - * This ensures that the maximum output will round to MAXJSAMPLE - * not MAXJSAMPLE+1, and thus that we don't have to range-limit. - */ - rgb_ycc_tab[i+B_CB_OFF] = FIX(0.50000) * i + CBCR_OFFSET + ONE_HALF-1; -/* B=>Cb and R=>Cr tables are the same - rgb_ycc_tab[i+R_CR_OFF] = FIX(0.50000) * i + CBCR_OFFSET + ONE_HALF-1; -*/ - rgb_ycc_tab[i+G_CR_OFF] = (-FIX(0.41869)) * i; - rgb_ycc_tab[i+B_CR_OFF] = (-FIX(0.08131)) * i; - } -} - - -/* - * Convert some rows of samples to the JPEG colorspace. - * - * Note that we change from the application's interleaved-pixel format - * to our internal noninterleaved, one-plane-per-component format. - * The input buffer is therefore three times as wide as the output buffer. - * - * A starting row offset is provided only for the output buffer. The caller - * can easily adjust the passed input_buf value to accommodate any row - * offset required on that side. - */ - -METHODDEF void -rgb_ycc_convert (j_compress_ptr cinfo, - JSAMPARRAY input_buf, JSAMPIMAGE output_buf, - JDIMENSION output_row, int num_rows) -{ - my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert; - register int r, g, b; - register INT32 * ctab = cconvert->rgb_ycc_tab; - register JSAMPROW inptr; - register JSAMPROW outptr0, outptr1, outptr2; - register JDIMENSION col; - JDIMENSION num_cols = cinfo->image_width; - - while (--num_rows >= 0) { - inptr = *input_buf++; - outptr0 = output_buf[0][output_row]; - outptr1 = output_buf[1][output_row]; - outptr2 = output_buf[2][output_row]; - output_row++; - for (col = 0; col < num_cols; col++) { - r = GETJSAMPLE(inptr[RGB_RED]); - g = GETJSAMPLE(inptr[RGB_GREEN]); - b = GETJSAMPLE(inptr[RGB_BLUE]); - inptr += RGB_PIXELSIZE; - /* If the inputs are 0..MAXJSAMPLE, the outputs of these equations - * must be too; we do not need an explicit range-limiting operation. - * Hence the value being shifted is never negative, and we don't - * need the general RIGHT_SHIFT macro. - */ - /* Y */ - outptr0[col] = (JSAMPLE) - ((ctab[r+R_Y_OFF] + ctab[g+G_Y_OFF] + ctab[b+B_Y_OFF]) - >> SCALEBITS); - /* Cb */ - outptr1[col] = (JSAMPLE) - ((ctab[r+R_CB_OFF] + ctab[g+G_CB_OFF] + ctab[b+B_CB_OFF]) - >> SCALEBITS); - /* Cr */ - outptr2[col] = (JSAMPLE) - ((ctab[r+R_CR_OFF] + ctab[g+G_CR_OFF] + ctab[b+B_CR_OFF]) - >> SCALEBITS); - } - } -} - - -/**************** Cases other than RGB -> YCbCr **************/ - - -/* - * Convert some rows of samples to the JPEG colorspace. - * This version handles RGB->grayscale conversion, which is the same - * as the RGB->Y portion of RGB->YCbCr. - * We assume rgb_ycc_start has been called (we only use the Y tables). - */ - -METHODDEF void -rgb_gray_convert (j_compress_ptr cinfo, - JSAMPARRAY input_buf, JSAMPIMAGE output_buf, - JDIMENSION output_row, int num_rows) -{ - my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert; - register int r, g, b; - register INT32 * ctab = cconvert->rgb_ycc_tab; - register JSAMPROW inptr; - register JSAMPROW outptr; - register JDIMENSION col; - JDIMENSION num_cols = cinfo->image_width; - - while (--num_rows >= 0) { - inptr = *input_buf++; - outptr = output_buf[0][output_row]; - output_row++; - for (col = 0; col < num_cols; col++) { - r = GETJSAMPLE(inptr[RGB_RED]); - g = GETJSAMPLE(inptr[RGB_GREEN]); - b = GETJSAMPLE(inptr[RGB_BLUE]); - inptr += RGB_PIXELSIZE; - /* Y */ - outptr[col] = (JSAMPLE) - ((ctab[r+R_Y_OFF] + ctab[g+G_Y_OFF] + ctab[b+B_Y_OFF]) - >> SCALEBITS); - } - } -} - - -/* - * Convert some rows of samples to the JPEG colorspace. - * This version handles Adobe-style CMYK->YCCK conversion, - * where we convert R=1-C, G=1-M, and B=1-Y to YCbCr using the same - * conversion as above, while passing K (black) unchanged. - * We assume rgb_ycc_start has been called. - */ - -METHODDEF void -cmyk_ycck_convert (j_compress_ptr cinfo, - JSAMPARRAY input_buf, JSAMPIMAGE output_buf, - JDIMENSION output_row, int num_rows) -{ - my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert; - register int r, g, b; - register INT32 * ctab = cconvert->rgb_ycc_tab; - register JSAMPROW inptr; - register JSAMPROW outptr0, outptr1, outptr2, outptr3; - register JDIMENSION col; - JDIMENSION num_cols = cinfo->image_width; - - while (--num_rows >= 0) { - inptr = *input_buf++; - outptr0 = output_buf[0][output_row]; - outptr1 = output_buf[1][output_row]; - outptr2 = output_buf[2][output_row]; - outptr3 = output_buf[3][output_row]; - output_row++; - for (col = 0; col < num_cols; col++) { - r = MAXJSAMPLE - GETJSAMPLE(inptr[0]); - g = MAXJSAMPLE - GETJSAMPLE(inptr[1]); - b = MAXJSAMPLE - GETJSAMPLE(inptr[2]); - /* K passes through as-is */ - outptr3[col] = inptr[3]; /* don't need GETJSAMPLE here */ - inptr += 4; - /* If the inputs are 0..MAXJSAMPLE, the outputs of these equations - * must be too; we do not need an explicit range-limiting operation. - * Hence the value being shifted is never negative, and we don't - * need the general RIGHT_SHIFT macro. - */ - /* Y */ - outptr0[col] = (JSAMPLE) - ((ctab[r+R_Y_OFF] + ctab[g+G_Y_OFF] + ctab[b+B_Y_OFF]) - >> SCALEBITS); - /* Cb */ - outptr1[col] = (JSAMPLE) - ((ctab[r+R_CB_OFF] + ctab[g+G_CB_OFF] + ctab[b+B_CB_OFF]) - >> SCALEBITS); - /* Cr */ - outptr2[col] = (JSAMPLE) - ((ctab[r+R_CR_OFF] + ctab[g+G_CR_OFF] + ctab[b+B_CR_OFF]) - >> SCALEBITS); - } - } -} - - -/* - * Convert some rows of samples to the JPEG colorspace. - * This version handles grayscale output with no conversion. - * The source can be either plain grayscale or YCbCr (since Y == gray). - */ - -METHODDEF void -grayscale_convert (j_compress_ptr cinfo, - JSAMPARRAY input_buf, JSAMPIMAGE output_buf, - JDIMENSION output_row, int num_rows) -{ - register JSAMPROW inptr; - register JSAMPROW outptr; - register JDIMENSION col; - JDIMENSION num_cols = cinfo->image_width; - int instride = cinfo->input_components; - - while (--num_rows >= 0) { - inptr = *input_buf++; - outptr = output_buf[0][output_row]; - output_row++; - for (col = 0; col < num_cols; col++) { - outptr[col] = inptr[0]; /* don't need GETJSAMPLE() here */ - inptr += instride; - } - } -} - - -/* - * Convert some rows of samples to the JPEG colorspace. - * This version handles multi-component colorspaces without conversion. - * We assume input_components == num_components. - */ - -METHODDEF void -null_convert (j_compress_ptr cinfo, - JSAMPARRAY input_buf, JSAMPIMAGE output_buf, - JDIMENSION output_row, int num_rows) -{ - register JSAMPROW inptr; - register JSAMPROW outptr; - register JDIMENSION col; - register int ci; - int nc = cinfo->num_components; - JDIMENSION num_cols = cinfo->image_width; - - while (--num_rows >= 0) { - /* It seems fastest to make a separate pass for each component. */ - for (ci = 0; ci < nc; ci++) { - inptr = *input_buf; - outptr = output_buf[ci][output_row]; - for (col = 0; col < num_cols; col++) { - outptr[col] = inptr[ci]; /* don't need GETJSAMPLE() here */ - inptr += nc; - } - } - input_buf++; - output_row++; - } -} - - -/* - * Empty method for start_pass. - */ - -METHODDEF void -null_method (j_compress_ptr cinfo) -{ - /* no work needed */ -} - - -/* - * Module initialization routine for input colorspace conversion. - */ - -GLOBAL void -jinit_color_converter (j_compress_ptr cinfo) -{ - my_cconvert_ptr cconvert; - - cconvert = (my_cconvert_ptr) - (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, - SIZEOF(my_color_converter)); - cinfo->cconvert = (struct jpeg_color_converter *) cconvert; - /* set start_pass to null method until we find out differently */ - cconvert->pub.start_pass = null_method; - - /* Make sure input_components agrees with in_color_space */ - switch (cinfo->in_color_space) { - case JCS_GRAYSCALE: - if (cinfo->input_components != 1) - ERREXIT(cinfo, JERR_BAD_IN_COLORSPACE); - break; - - case JCS_RGB: -#if RGB_PIXELSIZE != 3 - if (cinfo->input_components != RGB_PIXELSIZE) - ERREXIT(cinfo, JERR_BAD_IN_COLORSPACE); - break; -#endif /* else share code with YCbCr */ - - case JCS_YCbCr: - if (cinfo->input_components != 3) - ERREXIT(cinfo, JERR_BAD_IN_COLORSPACE); - break; - - case JCS_CMYK: - case JCS_YCCK: - if (cinfo->input_components != 4) - ERREXIT(cinfo, JERR_BAD_IN_COLORSPACE); - break; - - default: /* JCS_UNKNOWN can be anything */ - if (cinfo->input_components < 1) - ERREXIT(cinfo, JERR_BAD_IN_COLORSPACE); - break; - } - - /* Check num_components, set conversion method based on requested space */ - switch (cinfo->jpeg_color_space) { - case JCS_GRAYSCALE: - if (cinfo->num_components != 1) - ERREXIT(cinfo, JERR_BAD_J_COLORSPACE); - if (cinfo->in_color_space == JCS_GRAYSCALE) - cconvert->pub.color_convert = grayscale_convert; - else if (cinfo->in_color_space == JCS_RGB) { - cconvert->pub.start_pass = rgb_ycc_start; - cconvert->pub.color_convert = rgb_gray_convert; - } else if (cinfo->in_color_space == JCS_YCbCr) - cconvert->pub.color_convert = grayscale_convert; - else - ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL); - break; - - case JCS_RGB: - if (cinfo->num_components != 3) - ERREXIT(cinfo, JERR_BAD_J_COLORSPACE); - if (cinfo->in_color_space == JCS_RGB && RGB_PIXELSIZE == 3) - cconvert->pub.color_convert = null_convert; - else - ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL); - break; - - case JCS_YCbCr: - if (cinfo->num_components != 3) - ERREXIT(cinfo, JERR_BAD_J_COLORSPACE); - if (cinfo->in_color_space == JCS_RGB) { - cconvert->pub.start_pass = rgb_ycc_start; - cconvert->pub.color_convert = rgb_ycc_convert; - } else if (cinfo->in_color_space == JCS_YCbCr) - cconvert->pub.color_convert = null_convert; - else - ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL); - break; - - case JCS_CMYK: - if (cinfo->num_components != 4) - ERREXIT(cinfo, JERR_BAD_J_COLORSPACE); - if (cinfo->in_color_space == JCS_CMYK) - cconvert->pub.color_convert = null_convert; - else - ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL); - break; - - case JCS_YCCK: - if (cinfo->num_components != 4) - ERREXIT(cinfo, JERR_BAD_J_COLORSPACE); - if (cinfo->in_color_space == JCS_CMYK) { - cconvert->pub.start_pass = rgb_ycc_start; - cconvert->pub.color_convert = cmyk_ycck_convert; - } else if (cinfo->in_color_space == JCS_YCCK) - cconvert->pub.color_convert = null_convert; - else - ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL); - break; - - default: /* allow null conversion of JCS_UNKNOWN */ - if (cinfo->jpeg_color_space != cinfo->in_color_space || - cinfo->num_components != cinfo->input_components) - ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL); - cconvert->pub.color_convert = null_convert; - break; - } -} diff --git a/engine/jpeg-6/jcdctmgr.c b/engine/jpeg-6/jcdctmgr.c deleted file mode 100644 index f31a96f..0000000 --- a/engine/jpeg-6/jcdctmgr.c +++ /dev/null @@ -1,391 +0,0 @@ -/* - * jcdctmgr.c - * - * Copyright (C) 1994-1995, Thomas G. Lane. - * This file is part of the Independent JPEG Group's software. - * For conditions of distribution and use, see the accompanying README file. - * - * This file contains the forward-DCT management logic. - * This code selects a particular DCT implementation to be used, - * and it performs related housekeeping chores including coefficient - * quantization. - */ - -#define JPEG_INTERNALS -#include "jinclude.h" -#include "jpeglib.h" -#include "jdct.h" /* Private declarations for DCT subsystem */ - - -/* Private subobject for this module */ - -typedef struct { - struct jpeg_forward_dct pub; /* public fields */ - - /* Pointer to the DCT routine actually in use */ - forward_DCT_method_ptr do_dct; - - /* The actual post-DCT divisors --- not identical to the quant table - * entries, because of scaling (especially for an unnormalized DCT). - * Each table is given in normal array order; note that this must - * be converted from the zigzag order of the quantization tables. - */ - DCTELEM * divisors[NUM_QUANT_TBLS]; - -#ifdef DCT_FLOAT_SUPPORTED - /* Same as above for the floating-point case. */ - float_DCT_method_ptr do_float_dct; - FAST_FLOAT * float_divisors[NUM_QUANT_TBLS]; -#endif -} my_fdct_controller; - -typedef my_fdct_controller * my_fdct_ptr; - - -/* - * Initialize for a processing pass. - * Verify that all referenced Q-tables are present, and set up - * the divisor table for each one. - * In the current implementation, DCT of all components is done during - * the first pass, even if only some components will be output in the - * first scan. Hence all components should be examined here. - */ - -METHODDEF void -start_pass_fdctmgr (j_compress_ptr cinfo) -{ - my_fdct_ptr fdct = (my_fdct_ptr) cinfo->fdct; - int ci, qtblno, i; - jpeg_component_info *compptr; - JQUANT_TBL * qtbl; -#ifdef DCT_ISLOW_SUPPORTED - DCTELEM * dtbl; -#endif - - for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; - ci++, compptr++) { - qtblno = compptr->quant_tbl_no; - /* Make sure specified quantization table is present */ - if (qtblno < 0 || qtblno >= NUM_QUANT_TBLS || - cinfo->quant_tbl_ptrs[qtblno] == NULL) - ERREXIT1(cinfo, JERR_NO_QUANT_TABLE, qtblno); - qtbl = cinfo->quant_tbl_ptrs[qtblno]; - /* Compute divisors for this quant table */ - /* We may do this more than once for same table, but it's not a big deal */ - switch (cinfo->dct_method) { -#ifdef DCT_ISLOW_SUPPORTED - case JDCT_ISLOW: - /* For LL&M IDCT method, divisors are equal to raw quantization - * coefficients multiplied by 8 (to counteract scaling). - */ - if (fdct->divisors[qtblno] == NULL) { - fdct->divisors[qtblno] = (DCTELEM *) - (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, - DCTSIZE2 * SIZEOF(DCTELEM)); - } - dtbl = fdct->divisors[qtblno]; - for (i = 0; i < DCTSIZE2; i++) { - dtbl[i] = ((DCTELEM) qtbl->quantval[jpeg_zigzag_order[i]]) << 3; - } - break; -#endif -#ifdef DCT_IFAST_SUPPORTED - case JDCT_IFAST: - { - /* For AA&N IDCT method, divisors are equal to quantization - * coefficients scaled by scalefactor[row]*scalefactor[col], where - * scalefactor[0] = 1 - * scalefactor[k] = cos(k*PI/16) * sqrt(2) for k=1..7 - * We apply a further scale factor of 8. - */ -#define CONST_BITS 14 - static const INT16 aanscales[DCTSIZE2] = { - /* precomputed values scaled up by 14 bits: in natural order */ - 16384, 22725, 21407, 19266, 16384, 12873, 8867, 4520, - 22725, 31521, 29692, 26722, 22725, 17855, 12299, 6270, - 21407, 29692, 27969, 25172, 21407, 16819, 11585, 5906, - 19266, 26722, 25172, 22654, 19266, 15137, 10426, 5315, - 16384, 22725, 21407, 19266, 16384, 12873, 8867, 4520, - 12873, 17855, 16819, 15137, 12873, 10114, 6967, 3552, - 8867, 12299, 11585, 10426, 8867, 6967, 4799, 2446, - 4520, 6270, 5906, 5315, 4520, 3552, 2446, 1247 - }; - SHIFT_TEMPS - - if (fdct->divisors[qtblno] == NULL) { - fdct->divisors[qtblno] = (DCTELEM *) - (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, - DCTSIZE2 * SIZEOF(DCTELEM)); - } - dtbl = fdct->divisors[qtblno]; - for (i = 0; i < DCTSIZE2; i++) { - dtbl[i] = (DCTELEM) - DESCALE(MULTIPLY16V16((INT32) qtbl->quantval[jpeg_zigzag_order[i]], - (INT32) aanscales[i]), - CONST_BITS-3); - } - } - break; -#endif -#ifdef DCT_FLOAT_SUPPORTED - case JDCT_FLOAT: - { - /* For float AA&N IDCT method, divisors are equal to quantization - * coefficients scaled by scalefactor[row]*scalefactor[col], where - * scalefactor[0] = 1 - * scalefactor[k] = cos(k*PI/16) * sqrt(2) for k=1..7 - * We apply a further scale factor of 8. - * What's actually stored is 1/divisor so that the inner loop can - * use a multiplication rather than a division. - */ - FAST_FLOAT * fdtbl; - int row, col; - static const double aanscalefactor[DCTSIZE] = { - 1.0, 1.387039845, 1.306562965, 1.175875602, - 1.0, 0.785694958, 0.541196100, 0.275899379 - }; - - if (fdct->float_divisors[qtblno] == NULL) { - fdct->float_divisors[qtblno] = (FAST_FLOAT *) - (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, - DCTSIZE2 * SIZEOF(FAST_FLOAT)); - } - fdtbl = fdct->float_divisors[qtblno]; - i = 0; - for (row = 0; row < DCTSIZE; row++) { - for (col = 0; col < DCTSIZE; col++) { - fdtbl[i] = (FAST_FLOAT) - (1.0 / (((double) qtbl->quantval[jpeg_zigzag_order[i]] * - aanscalefactor[row] * aanscalefactor[col] * 8.0))); - i++; - } - } - } - break; -#endif - default: - ERREXIT(cinfo, JERR_NOT_COMPILED); - break; - } - } -} - - -/* - * Perform forward DCT on one or more blocks of a component. - * - * The input samples are taken from the sample_data[] array starting at - * position start_row/start_col, and moving to the right for any additional - * blocks. The quantized coefficients are returned in coef_blocks[]. - */ - -#if 0 // bk001204 -METHODDEF void -forward_DCT (j_compress_ptr cinfo, jpeg_component_info * compptr, - JSAMPARRAY sample_data, JBLOCKROW coef_blocks, - JDIMENSION start_row, JDIMENSION start_col, - JDIMENSION num_blocks) -/* This version is used for integer DCT implementations. */ -{ - /* This routine is heavily used, so it's worth coding it tightly. */ - my_fdct_ptr fdct = (my_fdct_ptr) cinfo->fdct; - forward_DCT_method_ptr do_dct = fdct->do_dct; - DCTELEM * divisors = fdct->divisors[compptr->quant_tbl_no]; - DCTELEM workspace[DCTSIZE2]; /* work area for FDCT subroutine */ - JDIMENSION bi; - - sample_data += start_row; /* fold in the vertical offset once */ - - for (bi = 0; bi < num_blocks; bi++, start_col += DCTSIZE) { - /* Load data into workspace, applying unsigned->signed conversion */ - { register DCTELEM *workspaceptr; - register JSAMPROW elemptr; - register int elemr; - - workspaceptr = workspace; - for (elemr = 0; elemr < DCTSIZE; elemr++) { - elemptr = sample_data[elemr] + start_col; -#if DCTSIZE == 8 /* unroll the inner loop */ - *workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE; - *workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE; - *workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE; - *workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE; - *workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE; - *workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE; - *workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE; - *workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE; -#else - { register int elemc; - for (elemc = DCTSIZE; elemc > 0; elemc--) { - *workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE; - } - } -#endif - } - } - - /* Perform the DCT */ - (*do_dct) (workspace); - - /* Quantize/descale the coefficients, and store into coef_blocks[] */ - { register DCTELEM temp, qval; - register int i; - register JCOEFPTR output_ptr = coef_blocks[bi]; - - for (i = 0; i < DCTSIZE2; i++) { - qval = divisors[i]; - temp = workspace[i]; - /* Divide the coefficient value by qval, ensuring proper rounding. - * Since C does not specify the direction of rounding for negative - * quotients, we have to force the dividend positive for portability. - * - * In most files, at least half of the output values will be zero - * (at default quantization settings, more like three-quarters...) - * so we should ensure that this case is fast. On many machines, - * a comparison is enough cheaper than a divide to make a special test - * a win. Since both inputs will be nonnegative, we need only test - * for a < b to discover whether a/b is 0. - * If your machine's division is fast enough, define FAST_DIVIDE. - */ -#ifdef FAST_DIVIDE -#define DIVIDE_BY(a,b) a /= b -#else -#define DIVIDE_BY(a,b) if (a >= b) a /= b; else a = 0 -#endif - if (temp < 0) { - temp = -temp; - temp += qval>>1; /* for rounding */ - DIVIDE_BY(temp, qval); - temp = -temp; - } else { - temp += qval>>1; /* for rounding */ - DIVIDE_BY(temp, qval); - } - output_ptr[i] = (JCOEF) temp; - } - } - } -} -#endif // 0 - -#ifdef DCT_FLOAT_SUPPORTED - -METHODDEF void -forward_DCT_float (j_compress_ptr cinfo, jpeg_component_info * compptr, - JSAMPARRAY sample_data, JBLOCKROW coef_blocks, - JDIMENSION start_row, JDIMENSION start_col, - JDIMENSION num_blocks) -/* This version is used for floating-point DCT implementations. */ -{ - /* This routine is heavily used, so it's worth coding it tightly. */ - my_fdct_ptr fdct = (my_fdct_ptr) cinfo->fdct; - float_DCT_method_ptr do_dct = fdct->do_float_dct; - FAST_FLOAT * divisors = fdct->float_divisors[compptr->quant_tbl_no]; - FAST_FLOAT workspace[DCTSIZE2]; /* work area for FDCT subroutine */ - JDIMENSION bi; - - sample_data += start_row; /* fold in the vertical offset once */ - - for (bi = 0; bi < num_blocks; bi++, start_col += DCTSIZE) { - /* Load data into workspace, applying unsigned->signed conversion */ - { register FAST_FLOAT *workspaceptr; - register JSAMPROW elemptr; - register int elemr; - - workspaceptr = workspace; - for (elemr = 0; elemr < DCTSIZE; elemr++) { - elemptr = sample_data[elemr] + start_col; -#if DCTSIZE == 8 /* unroll the inner loop */ - *workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE); - *workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE); - *workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE); - *workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE); - *workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE); - *workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE); - *workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE); - *workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE); -#else - { register int elemc; - for (elemc = DCTSIZE; elemc > 0; elemc--) { - *workspaceptr++ = (FAST_FLOAT) - (GETJSAMPLE(*elemptr++) - CENTERJSAMPLE); - } - } -#endif - } - } - - /* Perform the DCT */ - (*do_dct) (workspace); - - /* Quantize/descale the coefficients, and store into coef_blocks[] */ - { register FAST_FLOAT temp; - register int i; - register JCOEFPTR output_ptr = coef_blocks[bi]; - - for (i = 0; i < DCTSIZE2; i++) { - /* Apply the quantization and scaling factor */ - temp = workspace[i] * divisors[i]; - /* Round to nearest integer. - * Since C does not specify the direction of rounding for negative - * quotients, we have to force the dividend positive for portability. - * The maximum coefficient size is +-16K (for 12-bit data), so this - * code should work for either 16-bit or 32-bit ints. - */ - output_ptr[i] = (JCOEF) ((int) (temp + (FAST_FLOAT) 16384.5) - 16384); - } - } - } -} - -#endif /* DCT_FLOAT_SUPPORTED */ - - -/* - * Initialize FDCT manager. - */ - -GLOBAL void -jinit_forward_dct (j_compress_ptr cinfo) -{ - my_fdct_ptr fdct; - int i; - - fdct = (my_fdct_ptr) - (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, - SIZEOF(my_fdct_controller)); - cinfo->fdct = (struct jpeg_forward_dct *) fdct; - fdct->pub.start_pass = start_pass_fdctmgr; - - switch (cinfo->dct_method) { -#ifdef DCT_ISLOW_SUPPORTED - case JDCT_ISLOW: - fdct->pub.forward_DCT = forward_DCT; - fdct->do_dct = jpeg_fdct_islow; - break; -#endif -#ifdef DCT_IFAST_SUPPORTED - case JDCT_IFAST: - fdct->pub.forward_DCT = forward_DCT; - fdct->do_dct = jpeg_fdct_ifast; - break; -#endif -#ifdef DCT_FLOAT_SUPPORTED - case JDCT_FLOAT: - fdct->pub.forward_DCT = forward_DCT_float; - fdct->do_float_dct = jpeg_fdct_float; - break; -#endif - default: - ERREXIT(cinfo, JERR_NOT_COMPILED); - break; - } - - /* Mark divisor tables unallocated */ - for (i = 0; i < NUM_QUANT_TBLS; i++) { - fdct->divisors[i] = NULL; -#ifdef DCT_FLOAT_SUPPORTED - fdct->float_divisors[i] = NULL; -#endif - } -} diff --git a/engine/jpeg-6/jchuff.c b/engine/jpeg-6/jchuff.c deleted file mode 100644 index 59f7865..0000000 --- a/engine/jpeg-6/jchuff.c +++ /dev/null @@ -1,846 +0,0 @@ -/* - * jchuff.c - * - * Copyright (C) 1991-1995, Thomas G. Lane. - * This file is part of the Independent JPEG Group's software. - * For conditions of distribution and use, see the accompanying README file. - * - * This file contains Huffman entropy encoding routines. - * - * Much of the complexity here has to do with supporting output suspension. - * If the data destination module demands suspension, we want to be able to - * back up to the start of the current MCU. To do this, we copy state - * variables into local working storage, and update them back to the - * permanent JPEG objects only upon successful completion of an MCU. - */ - -#define JPEG_INTERNALS -#include "jinclude.h" -#include "jpeglib.h" -#include "jchuff.h" /* Declarations shared with jcphuff.c */ - - -/* Expanded entropy encoder object for Huffman encoding. - * - * The savable_state subrecord contains fields that change within an MCU, - * but must not be updated permanently until we complete the MCU. - */ - -typedef struct { - INT32 put_buffer; /* current bit-accumulation buffer */ - int put_bits; /* # of bits now in it */ - int last_dc_val[MAX_COMPS_IN_SCAN]; /* last DC coef for each component */ -} savable_state; - -/* This macro is to work around compilers with missing or broken - * structure assignment. You'll need to fix this code if you have - * such a compiler and you change MAX_COMPS_IN_SCAN. - */ - -#ifndef NO_STRUCT_ASSIGN -#define ASSIGN_STATE(dest,src) ((dest) = (src)) -#else -#if MAX_COMPS_IN_SCAN == 4 -#define ASSIGN_STATE(dest,src) \ - ((dest).put_buffer = (src).put_buffer, \ - (dest).put_bits = (src).put_bits, \ - (dest).last_dc_val[0] = (src).last_dc_val[0], \ - (dest).last_dc_val[1] = (src).last_dc_val[1], \ - (dest).last_dc_val[2] = (src).last_dc_val[2], \ - (dest).last_dc_val[3] = (src).last_dc_val[3]) -#endif -#endif - - -typedef struct { - struct jpeg_entropy_encoder pub; /* public fields */ - - savable_state saved; /* Bit buffer & DC state at start of MCU */ - - /* These fields are NOT loaded into local working state. */ - unsigned int restarts_to_go; /* MCUs left in this restart interval */ - int next_restart_num; /* next restart number to write (0-7) */ - - /* Pointers to derived tables (these workspaces have image lifespan) */ - c_derived_tbl * dc_derived_tbls[NUM_HUFF_TBLS]; - c_derived_tbl * ac_derived_tbls[NUM_HUFF_TBLS]; - -#ifdef ENTROPY_OPT_SUPPORTED /* Statistics tables for optimization */ - long * dc_count_ptrs[NUM_HUFF_TBLS]; - long * ac_count_ptrs[NUM_HUFF_TBLS]; -#endif -} huff_entropy_encoder; - -typedef huff_entropy_encoder * huff_entropy_ptr; - -/* Working state while writing an MCU. - * This struct contains all the fields that are needed by subroutines. - */ - -typedef struct { - JOCTET * next_output_byte; /* => next byte to write in buffer */ - size_t free_in_buffer; /* # of byte spaces remaining in buffer */ - savable_state cur; /* Current bit buffer & DC state */ - j_compress_ptr cinfo; /* dump_buffer needs access to this */ -} working_state; - - -/* Forward declarations */ -METHODDEF boolean encode_mcu_huff JPP((j_compress_ptr cinfo, - JBLOCKROW *MCU_data)); -METHODDEF void finish_pass_huff JPP((j_compress_ptr cinfo)); -#ifdef ENTROPY_OPT_SUPPORTED -METHODDEF boolean encode_mcu_gather JPP((j_compress_ptr cinfo, - JBLOCKROW *MCU_data)); -METHODDEF void finish_pass_gather JPP((j_compress_ptr cinfo)); -#endif - - -/* - * Initialize for a Huffman-compressed scan. - * If gather_statistics is TRUE, we do not output anything during the scan, - * just count the Huffman symbols used and generate Huffman code tables. - */ - -METHODDEF void -start_pass_huff (j_compress_ptr cinfo, boolean gather_statistics) -{ - huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy; - int ci, dctbl, actbl; - jpeg_component_info * compptr; - - if (gather_statistics) { -#ifdef ENTROPY_OPT_SUPPORTED - entropy->pub.encode_mcu = encode_mcu_gather; - entropy->pub.finish_pass = finish_pass_gather; -#else - ERREXIT(cinfo, JERR_NOT_COMPILED); -#endif - } else { - entropy->pub.encode_mcu = encode_mcu_huff; - entropy->pub.finish_pass = finish_pass_huff; - } - - for (ci = 0; ci < cinfo->comps_in_scan; ci++) { - compptr = cinfo->cur_comp_info[ci]; - dctbl = compptr->dc_tbl_no; - actbl = compptr->ac_tbl_no; - /* Make sure requested tables are present */ - /* (In gather mode, tables need not be allocated yet) */ - if (dctbl < 0 || dctbl >= NUM_HUFF_TBLS || - (cinfo->dc_huff_tbl_ptrs[dctbl] == NULL && !gather_statistics)) - ERREXIT1(cinfo, JERR_NO_HUFF_TABLE, dctbl); - if (actbl < 0 || actbl >= NUM_HUFF_TBLS || - (cinfo->ac_huff_tbl_ptrs[actbl] == NULL && !gather_statistics)) - ERREXIT1(cinfo, JERR_NO_HUFF_TABLE, actbl); - if (gather_statistics) { -#ifdef ENTROPY_OPT_SUPPORTED - /* Allocate and zero the statistics tables */ - /* Note that jpeg_gen_optimal_table expects 257 entries in each table! */ - if (entropy->dc_count_ptrs[dctbl] == NULL) - entropy->dc_count_ptrs[dctbl] = (long *) - (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, - 257 * SIZEOF(long)); - MEMZERO(entropy->dc_count_ptrs[dctbl], 257 * SIZEOF(long)); - if (entropy->ac_count_ptrs[actbl] == NULL) - entropy->ac_count_ptrs[actbl] = (long *) - (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, - 257 * SIZEOF(long)); - MEMZERO(entropy->ac_count_ptrs[actbl], 257 * SIZEOF(long)); -#endif - } else { - /* Compute derived values for Huffman tables */ - /* We may do this more than once for a table, but it's not expensive */ - jpeg_make_c_derived_tbl(cinfo, cinfo->dc_huff_tbl_ptrs[dctbl], - & entropy->dc_derived_tbls[dctbl]); - jpeg_make_c_derived_tbl(cinfo, cinfo->ac_huff_tbl_ptrs[actbl], - & entropy->ac_derived_tbls[actbl]); - } - /* Initialize DC predictions to 0 */ - entropy->saved.last_dc_val[ci] = 0; - } - - /* Initialize bit buffer to empty */ - entropy->saved.put_buffer = 0; - entropy->saved.put_bits = 0; - - /* Initialize restart stuff */ - entropy->restarts_to_go = cinfo->restart_interval; - entropy->next_restart_num = 0; -} - - -/* - * Compute the derived values for a Huffman table. - * Note this is also used by jcphuff.c. - */ - -GLOBAL void -jpeg_make_c_derived_tbl (j_compress_ptr cinfo, JHUFF_TBL * htbl, - c_derived_tbl ** pdtbl) -{ - c_derived_tbl *dtbl; - int p, i, l, lastp, si; - char huffsize[257]; - unsigned int huffcode[257]; - unsigned int code; - - /* Allocate a workspace if we haven't already done so. */ - if (*pdtbl == NULL) - *pdtbl = (c_derived_tbl *) - (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, - SIZEOF(c_derived_tbl)); - dtbl = *pdtbl; - - /* Figure C.1: make table of Huffman code length for each symbol */ - /* Note that this is in code-length order. */ - - p = 0; - for (l = 1; l <= 16; l++) { - for (i = 1; i <= (int) htbl->bits[l]; i++) - huffsize[p++] = (char) l; - } - huffsize[p] = 0; - lastp = p; - - /* Figure C.2: generate the codes themselves */ - /* Note that this is in code-length order. */ - - code = 0; - si = huffsize[0]; - p = 0; - while (huffsize[p]) { - while (((int) huffsize[p]) == si) { - huffcode[p++] = code; - code++; - } - code <<= 1; - si++; - } - - /* Figure C.3: generate encoding tables */ - /* These are code and size indexed by symbol value */ - - /* Set any codeless symbols to have code length 0; - * this allows emit_bits to detect any attempt to emit such symbols. - */ - MEMZERO(dtbl->ehufsi, SIZEOF(dtbl->ehufsi)); - - for (p = 0; p < lastp; p++) { - dtbl->ehufco[htbl->huffval[p]] = huffcode[p]; - dtbl->ehufsi[htbl->huffval[p]] = huffsize[p]; - } -} - - -/* Outputting bytes to the file */ - -/* Emit a byte, taking 'action' if must suspend. */ -#define emit_byte(state,val,action) \ - { *(state)->next_output_byte++ = (JOCTET) (val); \ - if (--(state)->free_in_buffer == 0) \ - if (! dump_buffer(state)) \ - { action; } } - - -LOCAL boolean -dump_buffer (working_state * state) -/* Empty the output buffer; return TRUE if successful, FALSE if must suspend */ -{ - struct jpeg_destination_mgr * dest = state->cinfo->dest; - - if (! (*dest->empty_output_buffer) (state->cinfo)) - return FALSE; - /* After a successful buffer dump, must reset buffer pointers */ - state->next_output_byte = dest->next_output_byte; - state->free_in_buffer = dest->free_in_buffer; - return TRUE; -} - - -/* Outputting bits to the file */ - -/* Only the right 24 bits of put_buffer are used; the valid bits are - * left-justified in this part. At most 16 bits can be passed to emit_bits - * in one call, and we never retain more than 7 bits in put_buffer - * between calls, so 24 bits are sufficient. - */ - -INLINE -LOCAL boolean -emit_bits (working_state * state, unsigned int code, int size) -/* Emit some bits; return TRUE if successful, FALSE if must suspend */ -{ - /* This routine is heavily used, so it's worth coding tightly. */ - register INT32 put_buffer = (INT32) code; - register int put_bits = state->cur.put_bits; - - /* if size is 0, caller used an invalid Huffman table entry */ - if (size == 0) - ERREXIT(state->cinfo, JERR_HUFF_MISSING_CODE); - - put_buffer &= (((INT32) 1)<cur.put_buffer; /* and merge with old buffer contents */ - - while (put_bits >= 8) { - int c = (int) ((put_buffer >> 16) & 0xFF); - - emit_byte(state, c, return FALSE); - if (c == 0xFF) { /* need to stuff a zero byte? */ - emit_byte(state, 0, return FALSE); - } - put_buffer <<= 8; - put_bits -= 8; - } - - state->cur.put_buffer = put_buffer; /* update state variables */ - state->cur.put_bits = put_bits; - - return TRUE; -} - - -LOCAL boolean -flush_bits (working_state * state) -{ - if (! emit_bits(state, 0x7F, 7)) /* fill any partial byte with ones */ - return FALSE; - state->cur.put_buffer = 0; /* and reset bit-buffer to empty */ - state->cur.put_bits = 0; - return TRUE; -} - - -/* Encode a single block's worth of coefficients */ - -LOCAL boolean -encode_one_block (working_state * state, JCOEFPTR block, int last_dc_val, - c_derived_tbl *dctbl, c_derived_tbl *actbl) -{ - register int temp, temp2; - register int nbits; - register int k, r, i; - - /* Encode the DC coefficient difference per section F.1.2.1 */ - - temp = temp2 = block[0] - last_dc_val; - - if (temp < 0) { - temp = -temp; /* temp is abs value of input */ - /* For a negative input, want temp2 = bitwise complement of abs(input) */ - /* This code assumes we are on a two's complement machine */ - temp2--; - } - - /* Find the number of bits needed for the magnitude of the coefficient */ - nbits = 0; - while (temp) { - nbits++; - temp >>= 1; - } - - /* Emit the Huffman-coded symbol for the number of bits */ - if (! emit_bits(state, dctbl->ehufco[nbits], dctbl->ehufsi[nbits])) - return FALSE; - - /* Emit that number of bits of the value, if positive, */ - /* or the complement of its magnitude, if negative. */ - if (nbits) /* emit_bits rejects calls with size 0 */ - if (! emit_bits(state, (unsigned int) temp2, nbits)) - return FALSE; - - /* Encode the AC coefficients per section F.1.2.2 */ - - r = 0; /* r = run length of zeros */ - - for (k = 1; k < DCTSIZE2; k++) { - if ((temp = block[jpeg_natural_order[k]]) == 0) { - r++; - } else { - /* if run length > 15, must emit special run-length-16 codes (0xF0) */ - while (r > 15) { - if (! emit_bits(state, actbl->ehufco[0xF0], actbl->ehufsi[0xF0])) - return FALSE; - r -= 16; - } - - temp2 = temp; - if (temp < 0) { - temp = -temp; /* temp is abs value of input */ - /* This code assumes we are on a two's complement machine */ - temp2--; - } - - /* Find the number of bits needed for the magnitude of the coefficient */ - nbits = 1; /* there must be at least one 1 bit */ - while ((temp >>= 1)) - nbits++; - - /* Emit Huffman symbol for run length / number of bits */ - i = (r << 4) + nbits; - if (! emit_bits(state, actbl->ehufco[i], actbl->ehufsi[i])) - return FALSE; - - /* Emit that number of bits of the value, if positive, */ - /* or the complement of its magnitude, if negative. */ - if (! emit_bits(state, (unsigned int) temp2, nbits)) - return FALSE; - - r = 0; - } - } - - /* If the last coef(s) were zero, emit an end-of-block code */ - if (r > 0) - if (! emit_bits(state, actbl->ehufco[0], actbl->ehufsi[0])) - return FALSE; - - return TRUE; -} - - -/* - * Emit a restart marker & resynchronize predictions. - */ - -LOCAL boolean -emit_restart (working_state * state, int restart_num) -{ - int ci; - - if (! flush_bits(state)) - return FALSE; - - emit_byte(state, 0xFF, return FALSE); - emit_byte(state, JPEG_RST0 + restart_num, return FALSE); - - /* Re-initialize DC predictions to 0 */ - for (ci = 0; ci < state->cinfo->comps_in_scan; ci++) - state->cur.last_dc_val[ci] = 0; - - /* The restart counter is not updated until we successfully write the MCU. */ - - return TRUE; -} - - -/* - * Encode and output one MCU's worth of Huffman-compressed coefficients. - */ - -METHODDEF boolean -encode_mcu_huff (j_compress_ptr cinfo, JBLOCKROW *MCU_data) -{ - huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy; - working_state state; - int blkn, ci; - jpeg_component_info * compptr; - - /* Load up working state */ - state.next_output_byte = cinfo->dest->next_output_byte; - state.free_in_buffer = cinfo->dest->free_in_buffer; - ASSIGN_STATE(state.cur, entropy->saved); - state.cinfo = cinfo; - - /* Emit restart marker if needed */ - if (cinfo->restart_interval) { - if (entropy->restarts_to_go == 0) - if (! emit_restart(&state, entropy->next_restart_num)) - return FALSE; - } - - /* Encode the MCU data blocks */ - for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) { - ci = cinfo->MCU_membership[blkn]; - compptr = cinfo->cur_comp_info[ci]; - if (! encode_one_block(&state, - MCU_data[blkn][0], state.cur.last_dc_val[ci], - entropy->dc_derived_tbls[compptr->dc_tbl_no], - entropy->ac_derived_tbls[compptr->ac_tbl_no])) - return FALSE; - /* Update last_dc_val */ - state.cur.last_dc_val[ci] = MCU_data[blkn][0][0]; - } - - /* Completed MCU, so update state */ - cinfo->dest->next_output_byte = state.next_output_byte; - cinfo->dest->free_in_buffer = state.free_in_buffer; - ASSIGN_STATE(entropy->saved, state.cur); - - /* Update restart-interval state too */ - if (cinfo->restart_interval) { - if (entropy->restarts_to_go == 0) { - entropy->restarts_to_go = cinfo->restart_interval; - entropy->next_restart_num++; - entropy->next_restart_num &= 7; - } - entropy->restarts_to_go--; - } - - return TRUE; -} - - -/* - * Finish up at the end of a Huffman-compressed scan. - */ - -METHODDEF void -finish_pass_huff (j_compress_ptr cinfo) -{ - huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy; - working_state state; - - /* Load up working state ... flush_bits needs it */ - state.next_output_byte = cinfo->dest->next_output_byte; - state.free_in_buffer = cinfo->dest->free_in_buffer; - ASSIGN_STATE(state.cur, entropy->saved); - state.cinfo = cinfo; - - /* Flush out the last data */ - if (! flush_bits(&state)) - ERREXIT(cinfo, JERR_CANT_SUSPEND); - - /* Update state */ - cinfo->dest->next_output_byte = state.next_output_byte; - cinfo->dest->free_in_buffer = state.free_in_buffer; - ASSIGN_STATE(entropy->saved, state.cur); -} - - -/* - * Huffman coding optimization. - * - * This actually is optimization, in the sense that we find the best possible - * Huffman table(s) for the given data. We first scan the supplied data and - * count the number of uses of each symbol that is to be Huffman-coded. - * (This process must agree with the code above.) Then we build an - * optimal Huffman coding tree for the observed counts. - * - * The JPEG standard requires Huffman codes to be no more than 16 bits long. - * If some symbols have a very small but nonzero probability, the Huffman tree - * must be adjusted to meet the code length restriction. We currently use - * the adjustment method suggested in the JPEG spec. This method is *not* - * optimal; it may not choose the best possible limited-length code. But - * since the symbols involved are infrequently used, it's not clear that - * going to extra trouble is worthwhile. - */ - -#ifdef ENTROPY_OPT_SUPPORTED - - -/* Process a single block's worth of coefficients */ - -LOCAL void -htest_one_block (JCOEFPTR block, int last_dc_val, - long dc_counts[], long ac_counts[]) -{ - register int temp; - register int nbits; - register int k, r; - - /* Encode the DC coefficient difference per section F.1.2.1 */ - - temp = block[0] - last_dc_val; - if (temp < 0) - temp = -temp; - - /* Find the number of bits needed for the magnitude of the coefficient */ - nbits = 0; - while (temp) { - nbits++; - temp >>= 1; - } - - /* Count the Huffman symbol for the number of bits */ - dc_counts[nbits]++; - - /* Encode the AC coefficients per section F.1.2.2 */ - - r = 0; /* r = run length of zeros */ - - for (k = 1; k < DCTSIZE2; k++) { - if ((temp = block[jpeg_natural_order[k]]) == 0) { - r++; - } else { - /* if run length > 15, must emit special run-length-16 codes (0xF0) */ - while (r > 15) { - ac_counts[0xF0]++; - r -= 16; - } - - /* Find the number of bits needed for the magnitude of the coefficient */ - if (temp < 0) - temp = -temp; - - /* Find the number of bits needed for the magnitude of the coefficient */ - nbits = 1; /* there must be at least one 1 bit */ - while ((temp >>= 1)) - nbits++; - - /* Count Huffman symbol for run length / number of bits */ - ac_counts[(r << 4) + nbits]++; - - r = 0; - } - } - - /* If the last coef(s) were zero, emit an end-of-block code */ - if (r > 0) - ac_counts[0]++; -} - - -/* - * Trial-encode one MCU's worth of Huffman-compressed coefficients. - * No data is actually output, so no suspension return is possible. - */ - -METHODDEF boolean -encode_mcu_gather (j_compress_ptr cinfo, JBLOCKROW *MCU_data) -{ - huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy; - int blkn, ci; - jpeg_component_info * compptr; - - /* Take care of restart intervals if needed */ - if (cinfo->restart_interval) { - if (entropy->restarts_to_go == 0) { - /* Re-initialize DC predictions to 0 */ - for (ci = 0; ci < cinfo->comps_in_scan; ci++) - entropy->saved.last_dc_val[ci] = 0; - /* Update restart state */ - entropy->restarts_to_go = cinfo->restart_interval; - } - entropy->restarts_to_go--; - } - - for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) { - ci = cinfo->MCU_membership[blkn]; - compptr = cinfo->cur_comp_info[ci]; - htest_one_block(MCU_data[blkn][0], entropy->saved.last_dc_val[ci], - entropy->dc_count_ptrs[compptr->dc_tbl_no], - entropy->ac_count_ptrs[compptr->ac_tbl_no]); - entropy->saved.last_dc_val[ci] = MCU_data[blkn][0][0]; - } - - return TRUE; -} - - -/* - * Generate the optimal coding for the given counts, fill htbl. - * Note this is also used by jcphuff.c. - */ - -GLOBAL void -jpeg_gen_optimal_table (j_compress_ptr cinfo, JHUFF_TBL * htbl, long freq[]) -{ -#define MAX_CLEN 32 /* assumed maximum initial code length */ - UINT8 bits[MAX_CLEN+1]; /* bits[k] = # of symbols with code length k */ - int codesize[257]; /* codesize[k] = code length of symbol k */ - int others[257]; /* next symbol in current branch of tree */ - int c1, c2; - int p, i, j; - long v; - - /* This algorithm is explained in section K.2 of the JPEG standard */ - - MEMZERO(bits, SIZEOF(bits)); - MEMZERO(codesize, SIZEOF(codesize)); - for (i = 0; i < 257; i++) - others[i] = -1; /* init links to empty */ - - freq[256] = 1; /* make sure there is a nonzero count */ - /* Including the pseudo-symbol 256 in the Huffman procedure guarantees - * that no real symbol is given code-value of all ones, because 256 - * will be placed in the largest codeword category. - */ - - /* Huffman's basic algorithm to assign optimal code lengths to symbols */ - - for (;;) { - /* Find the smallest nonzero frequency, set c1 = its symbol */ - /* In case of ties, take the larger symbol number */ - c1 = -1; - v = 1000000000L; - for (i = 0; i <= 256; i++) { - if (freq[i] && freq[i] <= v) { - v = freq[i]; - c1 = i; - } - } - - /* Find the next smallest nonzero frequency, set c2 = its symbol */ - /* In case of ties, take the larger symbol number */ - c2 = -1; - v = 1000000000L; - for (i = 0; i <= 256; i++) { - if (freq[i] && freq[i] <= v && i != c1) { - v = freq[i]; - c2 = i; - } - } - - /* Done if we've merged everything into one frequency */ - if (c2 < 0) - break; - - /* Else merge the two counts/trees */ - freq[c1] += freq[c2]; - freq[c2] = 0; - - /* Increment the codesize of everything in c1's tree branch */ - codesize[c1]++; - while (others[c1] >= 0) { - c1 = others[c1]; - codesize[c1]++; - } - - others[c1] = c2; /* chain c2 onto c1's tree branch */ - - /* Increment the codesize of everything in c2's tree branch */ - codesize[c2]++; - while (others[c2] >= 0) { - c2 = others[c2]; - codesize[c2]++; - } - } - - /* Now count the number of symbols of each code length */ - for (i = 0; i <= 256; i++) { - if (codesize[i]) { - /* The JPEG standard seems to think that this can't happen, */ - /* but I'm paranoid... */ - if (codesize[i] > MAX_CLEN) - ERREXIT(cinfo, JERR_HUFF_CLEN_OVERFLOW); - - bits[codesize[i]]++; - } - } - - /* JPEG doesn't allow symbols with code lengths over 16 bits, so if the pure - * Huffman procedure assigned any such lengths, we must adjust the coding. - * Here is what the JPEG spec says about how this next bit works: - * Since symbols are paired for the longest Huffman code, the symbols are - * removed from this length category two at a time. The prefix for the pair - * (which is one bit shorter) is allocated to one of the pair; then, - * skipping the BITS entry for that prefix length, a code word from the next - * shortest nonzero BITS entry is converted into a prefix for two code words - * one bit longer. - */ - - for (i = MAX_CLEN; i > 16; i--) { - while (bits[i] > 0) { - j = i - 2; /* find length of new prefix to be used */ - while (bits[j] == 0) - j--; - - bits[i] -= 2; /* remove two symbols */ - bits[i-1]++; /* one goes in this length */ - bits[j+1] += 2; /* two new symbols in this length */ - bits[j]--; /* symbol of this length is now a prefix */ - } - } - - /* Remove the count for the pseudo-symbol 256 from the largest codelength */ - while (bits[i] == 0) /* find largest codelength still in use */ - i--; - bits[i]--; - - /* Return final symbol counts (only for lengths 0..16) */ - MEMCOPY(htbl->bits, bits, SIZEOF(htbl->bits)); - - /* Return a list of the symbols sorted by code length */ - /* It's not real clear to me why we don't need to consider the codelength - * changes made above, but the JPEG spec seems to think this works. - */ - p = 0; - for (i = 1; i <= MAX_CLEN; i++) { - for (j = 0; j <= 255; j++) { - if (codesize[j] == i) { - htbl->huffval[p] = (UINT8) j; - p++; - } - } - } - - /* Set sent_table FALSE so updated table will be written to JPEG file. */ - htbl->sent_table = FALSE; -} - - -/* - * Finish up a statistics-gathering pass and create the new Huffman tables. - */ - -METHODDEF void -finish_pass_gather (j_compress_ptr cinfo) -{ - huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy; - int ci, dctbl, actbl; - jpeg_component_info * compptr; - JHUFF_TBL **htblptr; - boolean did_dc[NUM_HUFF_TBLS]; - boolean did_ac[NUM_HUFF_TBLS]; - - /* It's important not to apply jpeg_gen_optimal_table more than once - * per table, because it clobbers the input frequency counts! - */ - MEMZERO(did_dc, SIZEOF(did_dc)); - MEMZERO(did_ac, SIZEOF(did_ac)); - - for (ci = 0; ci < cinfo->comps_in_scan; ci++) { - compptr = cinfo->cur_comp_info[ci]; - dctbl = compptr->dc_tbl_no; - actbl = compptr->ac_tbl_no; - if (! did_dc[dctbl]) { - htblptr = & cinfo->dc_huff_tbl_ptrs[dctbl]; - if (*htblptr == NULL) - *htblptr = jpeg_alloc_huff_table((j_common_ptr) cinfo); - jpeg_gen_optimal_table(cinfo, *htblptr, entropy->dc_count_ptrs[dctbl]); - did_dc[dctbl] = TRUE; - } - if (! did_ac[actbl]) { - htblptr = & cinfo->ac_huff_tbl_ptrs[actbl]; - if (*htblptr == NULL) - *htblptr = jpeg_alloc_huff_table((j_common_ptr) cinfo); - jpeg_gen_optimal_table(cinfo, *htblptr, entropy->ac_count_ptrs[actbl]); - did_ac[actbl] = TRUE; - } - } -} - - -#endif /* ENTROPY_OPT_SUPPORTED */ - - -/* - * Module initialization routine for Huffman entropy encoding. - */ - -GLOBAL void -jinit_huff_encoder (j_compress_ptr cinfo) -{ - huff_entropy_ptr entropy; - int i; - - entropy = (huff_entropy_ptr) - (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, - SIZEOF(huff_entropy_encoder)); - cinfo->entropy = (struct jpeg_entropy_encoder *) entropy; - entropy->pub.start_pass = start_pass_huff; - - /* Mark tables unallocated */ - for (i = 0; i < NUM_HUFF_TBLS; i++) { - entropy->dc_derived_tbls[i] = entropy->ac_derived_tbls[i] = NULL; -#ifdef ENTROPY_OPT_SUPPORTED - entropy->dc_count_ptrs[i] = entropy->ac_count_ptrs[i] = NULL; -#endif - } -} diff --git a/engine/jpeg-6/jchuff.h b/engine/jpeg-6/jchuff.h deleted file mode 100644 index f43d571..0000000 --- a/engine/jpeg-6/jchuff.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * jchuff.h - * - * Copyright (C) 1991-1995, Thomas G. Lane. - * This file is part of the Independent JPEG Group's software. - * For conditions of distribution and use, see the accompanying README file. - * - * This file contains declarations for Huffman entropy encoding routines - * that are shared between the sequential encoder (jchuff.c) and the - * progressive encoder (jcphuff.c). No other modules need to see these. - */ - -/* Derived data constructed for each Huffman table */ - -typedef struct { - unsigned int ehufco[256]; /* code for each symbol */ - char ehufsi[256]; /* length of code for each symbol */ - /* If no code has been allocated for a symbol S, ehufsi[S] contains 0 */ -} c_derived_tbl; - -/* Short forms of external names for systems with brain-damaged linkers. */ - -#ifdef NEED_SHORT_EXTERNAL_NAMES -#define jpeg_make_c_derived_tbl jMkCDerived -#define jpeg_gen_optimal_table jGenOptTbl -#endif /* NEED_SHORT_EXTERNAL_NAMES */ - -/* Expand a Huffman table definition into the derived format */ -EXTERN void jpeg_make_c_derived_tbl JPP((j_compress_ptr cinfo, - JHUFF_TBL * htbl, c_derived_tbl ** pdtbl)); - -/* Generate an optimal table definition given the specified counts */ -EXTERN void jpeg_gen_optimal_table JPP((j_compress_ptr cinfo, - JHUFF_TBL * htbl, long freq[])); diff --git a/engine/jpeg-6/jcinit.c b/engine/jpeg-6/jcinit.c deleted file mode 100644 index 2cc82b2..0000000 --- a/engine/jpeg-6/jcinit.c +++ /dev/null @@ -1,72 +0,0 @@ -/* - * jcinit.c - * - * Copyright (C) 1991-1995, Thomas G. Lane. - * This file is part of the Independent JPEG Group's software. - * For conditions of distribution and use, see the accompanying README file. - * - * This file contains initialization logic for the JPEG compressor. - * This routine is in charge of selecting the modules to be executed and - * making an initialization call to each one. - * - * Logically, this code belongs in jcmaster.c. It's split out because - * linking this routine implies linking the entire compression library. - * For a transcoding-only application, we want to be able to use jcmaster.c - * without linking in the whole library. - */ - -#define JPEG_INTERNALS -#include "jinclude.h" -#include "jpeglib.h" - - -/* - * Master selection of compression modules. - * This is done once at the start of processing an image. We determine - * which modules will be used and give them appropriate initialization calls. - */ - -GLOBAL void -jinit_compress_master (j_compress_ptr cinfo) -{ - /* Initialize master control (includes parameter checking/processing) */ - jinit_c_master_control(cinfo, FALSE /* full compression */); - - /* Preprocessing */ - if (! cinfo->raw_data_in) { - jinit_color_converter(cinfo); - jinit_downsampler(cinfo); - jinit_c_prep_controller(cinfo, FALSE /* never need full buffer here */); - } - /* Forward DCT */ - jinit_forward_dct(cinfo); - /* Entropy encoding: either Huffman or arithmetic coding. */ - if (cinfo->arith_code) { - ERREXIT(cinfo, JERR_ARITH_NOTIMPL); - } else { - if (cinfo->progressive_mode) { -#ifdef C_PROGRESSIVE_SUPPORTED - jinit_phuff_encoder(cinfo); -#else - ERREXIT(cinfo, JERR_NOT_COMPILED); -#endif - } else - jinit_huff_encoder(cinfo); - } - - /* Need a full-image coefficient buffer in any multi-pass mode. */ - jinit_c_coef_controller(cinfo, - (cinfo->num_scans > 1 || cinfo->optimize_coding)); - jinit_c_main_controller(cinfo, FALSE /* never need full buffer here */); - - jinit_marker_writer(cinfo); - - /* We can now tell the memory manager to allocate virtual arrays. */ - (*cinfo->mem->realize_virt_arrays) ((j_common_ptr) cinfo); - - /* Write the datastream header (SOI) immediately. - * Frame and scan headers are postponed till later. - * This lets application insert special markers after the SOI. - */ - (*cinfo->marker->write_file_header) (cinfo); -} diff --git a/engine/jpeg-6/jcmainct.c b/engine/jpeg-6/jcmainct.c deleted file mode 100644 index 42a02d0..0000000 --- a/engine/jpeg-6/jcmainct.c +++ /dev/null @@ -1,296 +0,0 @@ -/* - * jcmainct.c - * - * Copyright (C) 1994-1995, Thomas G. Lane. - * This file is part of the Independent JPEG Group's software. - * For conditions of distribution and use, see the accompanying README file. - * - * This file contains the main buffer controller for compression. - * The main buffer lies between the pre-processor and the JPEG - * compressor proper; it holds downsampled data in the JPEG colorspace. - */ - -#define JPEG_INTERNALS -#include "jinclude.h" -#include "jpeglib.h" - - -/* Note: currently, there is no operating mode in which a full-image buffer - * is needed at this step. If there were, that mode could not be used with - * "raw data" input, since this module is bypassed in that case. However, - * we've left the code here for possible use in special applications. - */ -#undef FULL_MAIN_BUFFER_SUPPORTED - - -/* Private buffer controller object */ - -typedef struct { - struct jpeg_c_main_controller pub; /* public fields */ - - JDIMENSION cur_iMCU_row; /* number of current iMCU row */ - JDIMENSION rowgroup_ctr; /* counts row groups received in iMCU row */ - boolean suspended; /* remember if we suspended output */ - J_BUF_MODE pass_mode; /* current operating mode */ - - /* If using just a strip buffer, this points to the entire set of buffers - * (we allocate one for each component). In the full-image case, this - * points to the currently accessible strips of the virtual arrays. - */ - JSAMPARRAY buffer[MAX_COMPONENTS]; - -#ifdef FULL_MAIN_BUFFER_SUPPORTED - /* If using full-image storage, this array holds pointers to virtual-array - * control blocks for each component. Unused if not full-image storage. - */ - jvirt_sarray_ptr whole_image[MAX_COMPONENTS]; -#endif -} my_main_controller; - -typedef my_main_controller * my_main_ptr; - - -/* Forward declarations */ -METHODDEF void process_data_simple_main - JPP((j_compress_ptr cinfo, JSAMPARRAY input_buf, - JDIMENSION *in_row_ctr, JDIMENSION in_rows_avail)); -#ifdef FULL_MAIN_BUFFER_SUPPORTED -METHODDEF void process_data_buffer_main - JPP((j_compress_ptr cinfo, JSAMPARRAY input_buf, - JDIMENSION *in_row_ctr, JDIMENSION in_rows_avail)); -#endif - - -/* - * Initialize for a processing pass. - */ - -METHODDEF void -start_pass_main (j_compress_ptr cinfo, J_BUF_MODE pass_mode) -{ - // bk001204 - don't use main... - my_main_ptr jmain = (my_main_ptr) cinfo->main; - - /* Do nothing in raw-data mode. */ - if (cinfo->raw_data_in) - return; - - jmain->cur_iMCU_row = 0; /* initialize counters */ - jmain->rowgroup_ctr = 0; - jmain->suspended = FALSE; - jmain->pass_mode = pass_mode; /* save mode for use by process_data */ - - switch (pass_mode) { - case JBUF_PASS_THRU: -#ifdef FULL_MAIN_BUFFER_SUPPORTED - if (jmain->whole_image[0] != NULL) - ERREXIT(cinfo, JERR_BAD_BUFFER_MODE); -#endif - jmain->pub.process_data = process_data_simple_main; - break; -#ifdef FULL_MAIN_BUFFER_SUPPORTED - case JBUF_SAVE_SOURCE: - case JBUF_CRANK_DEST: - case JBUF_SAVE_AND_PASS: - if (jmain->whole_image[0] == NULL) - ERREXIT(cinfo, JERR_BAD_BUFFER_MODE); - jmain->pub.process_data = process_data_buffer_main; - break; -#endif - default: - ERREXIT(cinfo, JERR_BAD_BUFFER_MODE); - break; - } -} - - -/* - * Process some data. - * This routine handles the simple pass-through mode, - * where we have only a strip buffer. - */ - -METHODDEF void -process_data_simple_main (j_compress_ptr cinfo, - JSAMPARRAY input_buf, JDIMENSION *in_row_ctr, - JDIMENSION in_rows_avail) -{ - // bk001204 - don't use main - my_main_ptr jmain = (my_main_ptr) cinfo->main; - - while (jmain->cur_iMCU_row < cinfo->total_iMCU_rows) { - /* Read input data if we haven't filled the main buffer yet */ - if (jmain->rowgroup_ctr < DCTSIZE) - (*cinfo->prep->pre_process_data) (cinfo, - input_buf, in_row_ctr, in_rows_avail, - jmain->buffer, &jmain->rowgroup_ctr, - (JDIMENSION) DCTSIZE); - - /* If we don't have a full iMCU row buffered, return to application for - * more data. Note that preprocessor will always pad to fill the iMCU row - * at the bottom of the image. - */ - if (jmain->rowgroup_ctr != DCTSIZE) - return; - - /* Send the completed row to the compressor */ - if (! (*cinfo->coef->compress_data) (cinfo, jmain->buffer)) { - /* If compressor did not consume the whole row, then we must need to - * suspend processing and return to the application. In this situation - * we pretend we didn't yet consume the last input row; otherwise, if - * it happened to be the last row of the image, the application would - * think we were done. - */ - if (! jmain->suspended) { - (*in_row_ctr)--; - jmain->suspended = TRUE; - } - return; - } - /* We did finish the row. Undo our little suspension hack if a previous - * call suspended; then mark the main buffer empty. - */ - if (jmain->suspended) { - (*in_row_ctr)++; - jmain->suspended = FALSE; - } - jmain->rowgroup_ctr = 0; - jmain->cur_iMCU_row++; - } -} - - -#ifdef FULL_MAIN_BUFFER_SUPPORTED - -/* - * Process some data. - * This routine handles all of the modes that use a full-size buffer. - */ - -METHODDEF void -process_data_buffer_main (j_compress_ptr cinfo, - JSAMPARRAY input_buf, JDIMENSION *in_row_ctr, - JDIMENSION in_rows_avail) -{ - my_main_ptr main = (my_main_ptr) cinfo->main; - int ci; - jpeg_component_info *compptr; - boolean writing = (main->pass_mode != JBUF_CRANK_DEST); - - while (main->cur_iMCU_row < cinfo->total_iMCU_rows) { - /* Realign the virtual buffers if at the start of an iMCU row. */ - if (main->rowgroup_ctr == 0) { - for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; - ci++, compptr++) { - main->buffer[ci] = (*cinfo->mem->access_virt_sarray) - ((j_common_ptr) cinfo, main->whole_image[ci], - main->cur_iMCU_row * (compptr->v_samp_factor * DCTSIZE), - (JDIMENSION) (compptr->v_samp_factor * DCTSIZE), writing); - } - /* In a read pass, pretend we just read some source data. */ - if (! writing) { - *in_row_ctr += cinfo->max_v_samp_factor * DCTSIZE; - main->rowgroup_ctr = DCTSIZE; - } - } - - /* If a write pass, read input data until the current iMCU row is full. */ - /* Note: preprocessor will pad if necessary to fill the last iMCU row. */ - if (writing) { - (*cinfo->prep->pre_process_data) (cinfo, - input_buf, in_row_ctr, in_rows_avail, - main->buffer, &main->rowgroup_ctr, - (JDIMENSION) DCTSIZE); - /* Return to application if we need more data to fill the iMCU row. */ - if (main->rowgroup_ctr < DCTSIZE) - return; - } - - /* Emit data, unless this is a sink-only pass. */ - if (main->pass_mode != JBUF_SAVE_SOURCE) { - if (! (*cinfo->coef->compress_data) (cinfo, main->buffer)) { - /* If compressor did not consume the whole row, then we must need to - * suspend processing and return to the application. In this situation - * we pretend we didn't yet consume the last input row; otherwise, if - * it happened to be the last row of the image, the application would - * think we were done. - */ - if (! main->suspended) { - (*in_row_ctr)--; - main->suspended = TRUE; - } - return; - } - /* We did finish the row. Undo our little suspension hack if a previous - * call suspended; then mark the main buffer empty. - */ - if (main->suspended) { - (*in_row_ctr)++; - main->suspended = FALSE; - } - } - - /* If get here, we are done with this iMCU row. Mark buffer empty. */ - main->rowgroup_ctr = 0; - main->cur_iMCU_row++; - } -} - -#endif /* FULL_MAIN_BUFFER_SUPPORTED */ - - -/* - * Initialize main buffer controller. - */ - -GLOBAL void -jinit_c_main_controller (j_compress_ptr cinfo, boolean need_full_buffer) -{ - // bk001204 - don't use main - my_main_ptr jmain; - int ci; - jpeg_component_info *compptr; - - jmain = (my_main_ptr) - (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, - SIZEOF(my_main_controller)); - cinfo->main = (struct jpeg_c_main_controller *) jmain; - jmain->pub.start_pass = start_pass_main; - - /* We don't need to create a buffer in raw-data mode. */ - if (cinfo->raw_data_in) - return; - - /* Create the buffer. It holds downsampled data, so each component - * may be of a different size. - */ - if (need_full_buffer) { -#ifdef FULL_MAIN_BUFFER_SUPPORTED - /* Allocate a full-image virtual array for each component */ - /* Note we pad the bottom to a multiple of the iMCU height */ - for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; - ci++, compptr++) { - jmain->whole_image[ci] = (*cinfo->mem->request_virt_sarray) - ((j_common_ptr) cinfo, JPOOL_IMAGE, FALSE, - compptr->width_in_blocks * DCTSIZE, - (JDIMENSION) jround_up((long) compptr->height_in_blocks, - (long) compptr->v_samp_factor) * DCTSIZE, - (JDIMENSION) (compptr->v_samp_factor * DCTSIZE)); - } -#else - ERREXIT(cinfo, JERR_BAD_BUFFER_MODE); -#endif - } else { -#ifdef FULL_MAIN_BUFFER_SUPPORTED - jmain->whole_image[0] = NULL; /* flag for no virtual arrays */ -#endif - /* Allocate a strip buffer for each component */ - for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; - ci++, compptr++) { - jmain->buffer[ci] = (*cinfo->mem->alloc_sarray) - ((j_common_ptr) cinfo, JPOOL_IMAGE, - compptr->width_in_blocks * DCTSIZE, - (JDIMENSION) (compptr->v_samp_factor * DCTSIZE)); - } - } -} diff --git a/engine/jpeg-6/jcmarker.c b/engine/jpeg-6/jcmarker.c deleted file mode 100644 index f4d290b..0000000 --- a/engine/jpeg-6/jcmarker.c +++ /dev/null @@ -1,639 +0,0 @@ -/* - * jcmarker.c - * - * Copyright (C) 1991-1995, Thomas G. Lane. - * This file is part of the Independent JPEG Group's software. - * For conditions of distribution and use, see the accompanying README file. - * - * This file contains routines to write JPEG datastream markers. - */ - -#define JPEG_INTERNALS -#include "jinclude.h" -#include "jpeglib.h" - - -typedef enum { /* JPEG marker codes */ - M_SOF0 = 0xc0, - M_SOF1 = 0xc1, - M_SOF2 = 0xc2, - M_SOF3 = 0xc3, - - M_SOF5 = 0xc5, - M_SOF6 = 0xc6, - M_SOF7 = 0xc7, - - M_JPG = 0xc8, - M_SOF9 = 0xc9, - M_SOF10 = 0xca, - M_SOF11 = 0xcb, - - M_SOF13 = 0xcd, - M_SOF14 = 0xce, - M_SOF15 = 0xcf, - - M_DHT = 0xc4, - - M_DAC = 0xcc, - - M_RST0 = 0xd0, - M_RST1 = 0xd1, - M_RST2 = 0xd2, - M_RST3 = 0xd3, - M_RST4 = 0xd4, - M_RST5 = 0xd5, - M_RST6 = 0xd6, - M_RST7 = 0xd7, - - M_SOI = 0xd8, - M_EOI = 0xd9, - M_SOS = 0xda, - M_DQT = 0xdb, - M_DNL = 0xdc, - M_DRI = 0xdd, - M_DHP = 0xde, - M_EXP = 0xdf, - - M_APP0 = 0xe0, - M_APP1 = 0xe1, - M_APP2 = 0xe2, - M_APP3 = 0xe3, - M_APP4 = 0xe4, - M_APP5 = 0xe5, - M_APP6 = 0xe6, - M_APP7 = 0xe7, - M_APP8 = 0xe8, - M_APP9 = 0xe9, - M_APP10 = 0xea, - M_APP11 = 0xeb, - M_APP12 = 0xec, - M_APP13 = 0xed, - M_APP14 = 0xee, - M_APP15 = 0xef, - - M_JPG0 = 0xf0, - M_JPG13 = 0xfd, - M_COM = 0xfe, - - M_TEM = 0x01, - - M_ERROR = 0x100 -} JPEG_MARKER; - - -/* - * Basic output routines. - * - * Note that we do not support suspension while writing a marker. - * Therefore, an application using suspension must ensure that there is - * enough buffer space for the initial markers (typ. 600-700 bytes) before - * calling jpeg_start_compress, and enough space to write the trailing EOI - * (a few bytes) before calling jpeg_finish_compress. Multipass compression - * modes are not supported at all with suspension, so those two are the only - * points where markers will be written. - */ - -LOCAL void -emit_byte (j_compress_ptr cinfo, int val) -/* Emit a byte */ -{ - struct jpeg_destination_mgr * dest = cinfo->dest; - - *(dest->next_output_byte)++ = (JOCTET) val; - if (--dest->free_in_buffer == 0) { - if (! (*dest->empty_output_buffer) (cinfo)) - ERREXIT(cinfo, JERR_CANT_SUSPEND); - } -} - - -LOCAL void -emit_marker (j_compress_ptr cinfo, JPEG_MARKER mark) -/* Emit a marker code */ -{ - emit_byte(cinfo, 0xFF); - emit_byte(cinfo, (int) mark); -} - - -LOCAL void -emit_2bytes (j_compress_ptr cinfo, int value) -/* Emit a 2-byte integer; these are always MSB first in JPEG files */ -{ - emit_byte(cinfo, (value >> 8) & 0xFF); - emit_byte(cinfo, value & 0xFF); -} - - -/* - * Routines to write specific marker types. - */ - -LOCAL int -emit_dqt (j_compress_ptr cinfo, int index) -/* Emit a DQT marker */ -/* Returns the precision used (0 = 8bits, 1 = 16bits) for baseline checking */ -{ - JQUANT_TBL * qtbl = cinfo->quant_tbl_ptrs[index]; - int prec; - int i; - - if (qtbl == NULL) - ERREXIT1(cinfo, JERR_NO_QUANT_TABLE, index); - - prec = 0; - for (i = 0; i < DCTSIZE2; i++) { - if (qtbl->quantval[i] > 255) - prec = 1; - } - - if (! qtbl->sent_table) { - emit_marker(cinfo, M_DQT); - - emit_2bytes(cinfo, prec ? DCTSIZE2*2 + 1 + 2 : DCTSIZE2 + 1 + 2); - - emit_byte(cinfo, index + (prec<<4)); - - for (i = 0; i < DCTSIZE2; i++) { - if (prec) - emit_byte(cinfo, qtbl->quantval[i] >> 8); - emit_byte(cinfo, qtbl->quantval[i] & 0xFF); - } - - qtbl->sent_table = TRUE; - } - - return prec; -} - - -LOCAL void -emit_dht (j_compress_ptr cinfo, int index, boolean is_ac) -/* Emit a DHT marker */ -{ - JHUFF_TBL * htbl; - int length, i; - - if (is_ac) { - htbl = cinfo->ac_huff_tbl_ptrs[index]; - index += 0x10; /* output index has AC bit set */ - } else { - htbl = cinfo->dc_huff_tbl_ptrs[index]; - } - - if (htbl == NULL) - ERREXIT1(cinfo, JERR_NO_HUFF_TABLE, index); - - if (! htbl->sent_table) { - emit_marker(cinfo, M_DHT); - - length = 0; - for (i = 1; i <= 16; i++) - length += htbl->bits[i]; - - emit_2bytes(cinfo, length + 2 + 1 + 16); - emit_byte(cinfo, index); - - for (i = 1; i <= 16; i++) - emit_byte(cinfo, htbl->bits[i]); - - for (i = 0; i < length; i++) - emit_byte(cinfo, htbl->huffval[i]); - - htbl->sent_table = TRUE; - } -} - - -LOCAL void -emit_dac (j_compress_ptr cinfo) -/* Emit a DAC marker */ -/* Since the useful info is so small, we want to emit all the tables in */ -/* one DAC marker. Therefore this routine does its own scan of the table. */ -{ -#ifdef C_ARITH_CODING_SUPPORTED - char dc_in_use[NUM_ARITH_TBLS]; - char ac_in_use[NUM_ARITH_TBLS]; - int length, i; - jpeg_component_info *compptr; - - for (i = 0; i < NUM_ARITH_TBLS; i++) - dc_in_use[i] = ac_in_use[i] = 0; - - for (i = 0; i < cinfo->comps_in_scan; i++) { - compptr = cinfo->cur_comp_info[i]; - dc_in_use[compptr->dc_tbl_no] = 1; - ac_in_use[compptr->ac_tbl_no] = 1; - } - - length = 0; - for (i = 0; i < NUM_ARITH_TBLS; i++) - length += dc_in_use[i] + ac_in_use[i]; - - emit_marker(cinfo, M_DAC); - - emit_2bytes(cinfo, length*2 + 2); - - for (i = 0; i < NUM_ARITH_TBLS; i++) { - if (dc_in_use[i]) { - emit_byte(cinfo, i); - emit_byte(cinfo, cinfo->arith_dc_L[i] + (cinfo->arith_dc_U[i]<<4)); - } - if (ac_in_use[i]) { - emit_byte(cinfo, i + 0x10); - emit_byte(cinfo, cinfo->arith_ac_K[i]); - } - } -#endif /* C_ARITH_CODING_SUPPORTED */ -} - - -LOCAL void -emit_dri (j_compress_ptr cinfo) -/* Emit a DRI marker */ -{ - emit_marker(cinfo, M_DRI); - - emit_2bytes(cinfo, 4); /* fixed length */ - - emit_2bytes(cinfo, (int) cinfo->restart_interval); -} - - -LOCAL void -emit_sof (j_compress_ptr cinfo, JPEG_MARKER code) -/* Emit a SOF marker */ -{ - int ci; - jpeg_component_info *compptr; - - emit_marker(cinfo, code); - - emit_2bytes(cinfo, 3 * cinfo->num_components + 2 + 5 + 1); /* length */ - - /* Make sure image isn't bigger than SOF field can handle */ - if ((long) cinfo->image_height > 65535L || - (long) cinfo->image_width > 65535L) - ERREXIT1(cinfo, JERR_IMAGE_TOO_BIG, (unsigned int) 65535); - - emit_byte(cinfo, cinfo->data_precision); - emit_2bytes(cinfo, (int) cinfo->image_height); - emit_2bytes(cinfo, (int) cinfo->image_width); - - emit_byte(cinfo, cinfo->num_components); - - for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; - ci++, compptr++) { - emit_byte(cinfo, compptr->component_id); - emit_byte(cinfo, (compptr->h_samp_factor << 4) + compptr->v_samp_factor); - emit_byte(cinfo, compptr->quant_tbl_no); - } -} - - -LOCAL void -emit_sos (j_compress_ptr cinfo) -/* Emit a SOS marker */ -{ - int i, td, ta; - jpeg_component_info *compptr; - - emit_marker(cinfo, M_SOS); - - emit_2bytes(cinfo, 2 * cinfo->comps_in_scan + 2 + 1 + 3); /* length */ - - emit_byte(cinfo, cinfo->comps_in_scan); - - for (i = 0; i < cinfo->comps_in_scan; i++) { - compptr = cinfo->cur_comp_info[i]; - emit_byte(cinfo, compptr->component_id); - td = compptr->dc_tbl_no; - ta = compptr->ac_tbl_no; - if (cinfo->progressive_mode) { - /* Progressive mode: only DC or only AC tables are used in one scan; - * furthermore, Huffman coding of DC refinement uses no table at all. - * We emit 0 for unused field(s); this is recommended by the P&M text - * but does not seem to be specified in the standard. - */ - if (cinfo->Ss == 0) { - ta = 0; /* DC scan */ - if (cinfo->Ah != 0 && !cinfo->arith_code) - td = 0; /* no DC table either */ - } else { - td = 0; /* AC scan */ - } - } - emit_byte(cinfo, (td << 4) + ta); - } - - emit_byte(cinfo, cinfo->Ss); - emit_byte(cinfo, cinfo->Se); - emit_byte(cinfo, (cinfo->Ah << 4) + cinfo->Al); -} - - -LOCAL void -emit_jfif_app0 (j_compress_ptr cinfo) -/* Emit a JFIF-compliant APP0 marker */ -{ - /* - * Length of APP0 block (2 bytes) - * Block ID (4 bytes - ASCII "JFIF") - * Zero byte (1 byte to terminate the ID string) - * Version Major, Minor (2 bytes - 0x01, 0x01) - * Units (1 byte - 0x00 = none, 0x01 = inch, 0x02 = cm) - * Xdpu (2 bytes - dots per unit horizontal) - * Ydpu (2 bytes - dots per unit vertical) - * Thumbnail X size (1 byte) - * Thumbnail Y size (1 byte) - */ - - emit_marker(cinfo, M_APP0); - - emit_2bytes(cinfo, 2 + 4 + 1 + 2 + 1 + 2 + 2 + 1 + 1); /* length */ - - emit_byte(cinfo, 0x4A); /* Identifier: ASCII "JFIF" */ - emit_byte(cinfo, 0x46); - emit_byte(cinfo, 0x49); - emit_byte(cinfo, 0x46); - emit_byte(cinfo, 0); - /* We currently emit version code 1.01 since we use no 1.02 features. - * This may avoid complaints from some older decoders. - */ - emit_byte(cinfo, 1); /* Major version */ - emit_byte(cinfo, 1); /* Minor version */ - emit_byte(cinfo, cinfo->density_unit); /* Pixel size information */ - emit_2bytes(cinfo, (int) cinfo->X_density); - emit_2bytes(cinfo, (int) cinfo->Y_density); - emit_byte(cinfo, 0); /* No thumbnail image */ - emit_byte(cinfo, 0); -} - - -LOCAL void -emit_adobe_app14 (j_compress_ptr cinfo) -/* Emit an Adobe APP14 marker */ -{ - /* - * Length of APP14 block (2 bytes) - * Block ID (5 bytes - ASCII "Adobe") - * Version Number (2 bytes - currently 100) - * Flags0 (2 bytes - currently 0) - * Flags1 (2 bytes - currently 0) - * Color transform (1 byte) - * - * Although Adobe TN 5116 mentions Version = 101, all the Adobe files - * now in circulation seem to use Version = 100, so that's what we write. - * - * We write the color transform byte as 1 if the JPEG color space is - * YCbCr, 2 if it's YCCK, 0 otherwise. Adobe's definition has to do with - * whether the encoder performed a transformation, which is pretty useless. - */ - - emit_marker(cinfo, M_APP14); - - emit_2bytes(cinfo, 2 + 5 + 2 + 2 + 2 + 1); /* length */ - - emit_byte(cinfo, 0x41); /* Identifier: ASCII "Adobe" */ - emit_byte(cinfo, 0x64); - emit_byte(cinfo, 0x6F); - emit_byte(cinfo, 0x62); - emit_byte(cinfo, 0x65); - emit_2bytes(cinfo, 100); /* Version */ - emit_2bytes(cinfo, 0); /* Flags0 */ - emit_2bytes(cinfo, 0); /* Flags1 */ - switch (cinfo->jpeg_color_space) { - case JCS_YCbCr: - emit_byte(cinfo, 1); /* Color transform = 1 */ - break; - case JCS_YCCK: - emit_byte(cinfo, 2); /* Color transform = 2 */ - break; - default: - emit_byte(cinfo, 0); /* Color transform = 0 */ - break; - } -} - - -/* - * This routine is exported for possible use by applications. - * The intended use is to emit COM or APPn markers after calling - * jpeg_start_compress() and before the first jpeg_write_scanlines() call - * (hence, after write_file_header but before write_frame_header). - * Other uses are not guaranteed to produce desirable results. - */ - -METHODDEF void -write_any_marker (j_compress_ptr cinfo, int marker, - const JOCTET *dataptr, unsigned int datalen) -/* Emit an arbitrary marker with parameters */ -{ - if (datalen <= (unsigned int) 65533) { /* safety check */ - emit_marker(cinfo, (JPEG_MARKER) marker); - - emit_2bytes(cinfo, (int) (datalen + 2)); /* total length */ - - while (datalen--) { - emit_byte(cinfo, *dataptr); - dataptr++; - } - } -} - - -/* - * Write datastream header. - * This consists of an SOI and optional APPn markers. - * We recommend use of the JFIF marker, but not the Adobe marker, - * when using YCbCr or grayscale data. The JFIF marker should NOT - * be used for any other JPEG colorspace. The Adobe marker is helpful - * to distinguish RGB, CMYK, and YCCK colorspaces. - * Note that an application can write additional header markers after - * jpeg_start_compress returns. - */ - -METHODDEF void -write_file_header (j_compress_ptr cinfo) -{ - emit_marker(cinfo, M_SOI); /* first the SOI */ - - if (cinfo->write_JFIF_header) /* next an optional JFIF APP0 */ - emit_jfif_app0(cinfo); - if (cinfo->write_Adobe_marker) /* next an optional Adobe APP14 */ - emit_adobe_app14(cinfo); -} - - -/* - * Write frame header. - * This consists of DQT and SOFn markers. - * Note that we do not emit the SOF until we have emitted the DQT(s). - * This avoids compatibility problems with incorrect implementations that - * try to error-check the quant table numbers as soon as they see the SOF. - */ - -METHODDEF void -write_frame_header (j_compress_ptr cinfo) -{ - int ci, prec; - boolean is_baseline; - jpeg_component_info *compptr; - - /* Emit DQT for each quantization table. - * Note that emit_dqt() suppresses any duplicate tables. - */ - prec = 0; - for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; - ci++, compptr++) { - prec += emit_dqt(cinfo, compptr->quant_tbl_no); - } - /* now prec is nonzero iff there are any 16-bit quant tables. */ - - /* Check for a non-baseline specification. - * Note we assume that Huffman table numbers won't be changed later. - */ - if (cinfo->arith_code || cinfo->progressive_mode || - cinfo->data_precision != 8) { - is_baseline = FALSE; - } else { - is_baseline = TRUE; - for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; - ci++, compptr++) { - if (compptr->dc_tbl_no > 1 || compptr->ac_tbl_no > 1) - is_baseline = FALSE; - } - if (prec && is_baseline) { - is_baseline = FALSE; - /* If it's baseline except for quantizer size, warn the user */ - TRACEMS(cinfo, 0, JTRC_16BIT_TABLES); - } - } - - /* Emit the proper SOF marker */ - if (cinfo->arith_code) { - emit_sof(cinfo, M_SOF9); /* SOF code for arithmetic coding */ - } else { - if (cinfo->progressive_mode) - emit_sof(cinfo, M_SOF2); /* SOF code for progressive Huffman */ - else if (is_baseline) - emit_sof(cinfo, M_SOF0); /* SOF code for baseline implementation */ - else - emit_sof(cinfo, M_SOF1); /* SOF code for non-baseline Huffman file */ - } -} - - -/* - * Write scan header. - * This consists of DHT or DAC markers, optional DRI, and SOS. - * Compressed data will be written following the SOS. - */ - -METHODDEF void -write_scan_header (j_compress_ptr cinfo) -{ - int i; - jpeg_component_info *compptr; - - if (cinfo->arith_code) { - /* Emit arith conditioning info. We may have some duplication - * if the file has multiple scans, but it's so small it's hardly - * worth worrying about. - */ - emit_dac(cinfo); - } else { - /* Emit Huffman tables. - * Note that emit_dht() suppresses any duplicate tables. - */ - for (i = 0; i < cinfo->comps_in_scan; i++) { - compptr = cinfo->cur_comp_info[i]; - if (cinfo->progressive_mode) { - /* Progressive mode: only DC or only AC tables are used in one scan */ - if (cinfo->Ss == 0) { - if (cinfo->Ah == 0) /* DC needs no table for refinement scan */ - emit_dht(cinfo, compptr->dc_tbl_no, FALSE); - } else { - emit_dht(cinfo, compptr->ac_tbl_no, TRUE); - } - } else { - /* Sequential mode: need both DC and AC tables */ - emit_dht(cinfo, compptr->dc_tbl_no, FALSE); - emit_dht(cinfo, compptr->ac_tbl_no, TRUE); - } - } - } - - /* Emit DRI if required --- note that DRI value could change for each scan. - * If it doesn't, a tiny amount of space is wasted in multiple-scan files. - * We assume DRI will never be nonzero for one scan and zero for a later one. - */ - if (cinfo->restart_interval) - emit_dri(cinfo); - - emit_sos(cinfo); -} - - -/* - * Write datastream trailer. - */ - -METHODDEF void -write_file_trailer (j_compress_ptr cinfo) -{ - emit_marker(cinfo, M_EOI); -} - - -/* - * Write an abbreviated table-specification datastream. - * This consists of SOI, DQT and DHT tables, and EOI. - * Any table that is defined and not marked sent_table = TRUE will be - * emitted. Note that all tables will be marked sent_table = TRUE at exit. - */ - -METHODDEF void -write_tables_only (j_compress_ptr cinfo) -{ - int i; - - emit_marker(cinfo, M_SOI); - - for (i = 0; i < NUM_QUANT_TBLS; i++) { - if (cinfo->quant_tbl_ptrs[i] != NULL) - (void) emit_dqt(cinfo, i); - } - - if (! cinfo->arith_code) { - for (i = 0; i < NUM_HUFF_TBLS; i++) { - if (cinfo->dc_huff_tbl_ptrs[i] != NULL) - emit_dht(cinfo, i, FALSE); - if (cinfo->ac_huff_tbl_ptrs[i] != NULL) - emit_dht(cinfo, i, TRUE); - } - } - - emit_marker(cinfo, M_EOI); -} - - -/* - * Initialize the marker writer module. - */ - -GLOBAL void -jinit_marker_writer (j_compress_ptr cinfo) -{ - /* Create the subobject */ - cinfo->marker = (struct jpeg_marker_writer *) - (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, - SIZEOF(struct jpeg_marker_writer)); - /* Initialize method pointers */ - cinfo->marker->write_any_marker = write_any_marker; - cinfo->marker->write_file_header = write_file_header; - cinfo->marker->write_frame_header = write_frame_header; - cinfo->marker->write_scan_header = write_scan_header; - cinfo->marker->write_file_trailer = write_file_trailer; - cinfo->marker->write_tables_only = write_tables_only; -} diff --git a/engine/jpeg-6/jcmaster.c b/engine/jpeg-6/jcmaster.c deleted file mode 100644 index 84494e6..0000000 --- a/engine/jpeg-6/jcmaster.c +++ /dev/null @@ -1,578 +0,0 @@ -/* - * jcmaster.c - * - * Copyright (C) 1991-1995, Thomas G. Lane. - * This file is part of the Independent JPEG Group's software. - * For conditions of distribution and use, see the accompanying README file. - * - * This file contains master control logic for the JPEG compressor. - * These routines are concerned with parameter validation, initial setup, - * and inter-pass control (determining the number of passes and the work - * to be done in each pass). - */ - -#define JPEG_INTERNALS -#include "jinclude.h" -#include "jpeglib.h" - - -/* Private state */ - -typedef enum { - main_pass, /* input data, also do first output step */ - huff_opt_pass, /* Huffman code optimization pass */ - output_pass /* data output pass */ -} c_pass_type; - -typedef struct { - struct jpeg_comp_master pub; /* public fields */ - - c_pass_type pass_type; /* the type of the current pass */ - - int pass_number; /* # of passes completed */ - int total_passes; /* total # of passes needed */ - - int scan_number; /* current index in scan_info[] */ -} my_comp_master; - -typedef my_comp_master * my_master_ptr; - - -/* - * Support routines that do various essential calculations. - */ - -LOCAL void -initial_setup (j_compress_ptr cinfo) -/* Do computations that are needed before master selection phase */ -{ - int ci; - jpeg_component_info *compptr; - long samplesperrow; - JDIMENSION jd_samplesperrow; - - /* Sanity check on image dimensions */ - if (cinfo->image_height <= 0 || cinfo->image_width <= 0 - || cinfo->num_components <= 0 || cinfo->input_components <= 0) - ERREXIT(cinfo, JERR_EMPTY_IMAGE); - - /* Make sure image isn't bigger than I can handle */ - if ((long) cinfo->image_height > (long) JPEG_MAX_DIMENSION || - (long) cinfo->image_width > (long) JPEG_MAX_DIMENSION) - ERREXIT1(cinfo, JERR_IMAGE_TOO_BIG, (unsigned int) JPEG_MAX_DIMENSION); - - /* Width of an input scanline must be representable as JDIMENSION. */ - samplesperrow = (long) cinfo->image_width * (long) cinfo->input_components; - jd_samplesperrow = (JDIMENSION) samplesperrow; - if ((long) jd_samplesperrow != samplesperrow) - ERREXIT(cinfo, JERR_WIDTH_OVERFLOW); - - /* For now, precision must match compiled-in value... */ - if (cinfo->data_precision != BITS_IN_JSAMPLE) - ERREXIT1(cinfo, JERR_BAD_PRECISION, cinfo->data_precision); - - /* Check that number of components won't exceed internal array sizes */ - if (cinfo->num_components > MAX_COMPONENTS) - ERREXIT2(cinfo, JERR_COMPONENT_COUNT, cinfo->num_components, - MAX_COMPONENTS); - - /* Compute maximum sampling factors; check factor validity */ - cinfo->max_h_samp_factor = 1; - cinfo->max_v_samp_factor = 1; - for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; - ci++, compptr++) { - if (compptr->h_samp_factor<=0 || compptr->h_samp_factor>MAX_SAMP_FACTOR || - compptr->v_samp_factor<=0 || compptr->v_samp_factor>MAX_SAMP_FACTOR) - ERREXIT(cinfo, JERR_BAD_SAMPLING); - cinfo->max_h_samp_factor = MAX(cinfo->max_h_samp_factor, - compptr->h_samp_factor); - cinfo->max_v_samp_factor = MAX(cinfo->max_v_samp_factor, - compptr->v_samp_factor); - } - - /* Compute dimensions of components */ - for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; - ci++, compptr++) { - /* Fill in the correct component_index value; don't rely on application */ - compptr->component_index = ci; - /* For compression, we never do DCT scaling. */ - compptr->DCT_scaled_size = DCTSIZE; - /* Size in DCT blocks */ - compptr->width_in_blocks = (JDIMENSION) - jdiv_round_up((long) cinfo->image_width * (long) compptr->h_samp_factor, - (long) (cinfo->max_h_samp_factor * DCTSIZE)); - compptr->height_in_blocks = (JDIMENSION) - jdiv_round_up((long) cinfo->image_height * (long) compptr->v_samp_factor, - (long) (cinfo->max_v_samp_factor * DCTSIZE)); - /* Size in samples */ - compptr->downsampled_width = (JDIMENSION) - jdiv_round_up((long) cinfo->image_width * (long) compptr->h_samp_factor, - (long) cinfo->max_h_samp_factor); - compptr->downsampled_height = (JDIMENSION) - jdiv_round_up((long) cinfo->image_height * (long) compptr->v_samp_factor, - (long) cinfo->max_v_samp_factor); - /* Mark component needed (this flag isn't actually used for compression) */ - compptr->component_needed = TRUE; - } - - /* Compute number of fully interleaved MCU rows (number of times that - * main controller will call coefficient controller). - */ - cinfo->total_iMCU_rows = (JDIMENSION) - jdiv_round_up((long) cinfo->image_height, - (long) (cinfo->max_v_samp_factor*DCTSIZE)); -} - - -#ifdef C_MULTISCAN_FILES_SUPPORTED - -LOCAL void -validate_script (j_compress_ptr cinfo) -/* Verify that the scan script in cinfo->scan_info[] is valid; also - * determine whether it uses progressive JPEG, and set cinfo->progressive_mode. - */ -{ - const jpeg_scan_info * scanptr; - int scanno, ncomps, ci, coefi, thisi; - int Ss, Se, Ah, Al; - boolean component_sent[MAX_COMPONENTS]; -#ifdef C_PROGRESSIVE_SUPPORTED - int * last_bitpos_ptr; - int last_bitpos[MAX_COMPONENTS][DCTSIZE2]; - /* -1 until that coefficient has been seen; then last Al for it */ -#endif - - if (cinfo->num_scans <= 0) - ERREXIT1(cinfo, JERR_BAD_SCAN_SCRIPT, 0); - - /* For sequential JPEG, all scans must have Ss=0, Se=DCTSIZE2-1; - * for progressive JPEG, no scan can have this. - */ - scanptr = cinfo->scan_info; - if (scanptr->Ss != 0 || scanptr->Se != DCTSIZE2-1) { -#ifdef C_PROGRESSIVE_SUPPORTED - cinfo->progressive_mode = TRUE; - last_bitpos_ptr = & last_bitpos[0][0]; - for (ci = 0; ci < cinfo->num_components; ci++) - for (coefi = 0; coefi < DCTSIZE2; coefi++) - *last_bitpos_ptr++ = -1; -#else - ERREXIT(cinfo, JERR_NOT_COMPILED); -#endif - } else { - cinfo->progressive_mode = FALSE; - for (ci = 0; ci < cinfo->num_components; ci++) - component_sent[ci] = FALSE; - } - - for (scanno = 1; scanno <= cinfo->num_scans; scanptr++, scanno++) { - /* Validate component indexes */ - ncomps = scanptr->comps_in_scan; - if (ncomps <= 0 || ncomps > MAX_COMPS_IN_SCAN) - ERREXIT2(cinfo, JERR_COMPONENT_COUNT, ncomps, MAX_COMPS_IN_SCAN); - for (ci = 0; ci < ncomps; ci++) { - thisi = scanptr->component_index[ci]; - if (thisi < 0 || thisi >= cinfo->num_components) - ERREXIT1(cinfo, JERR_BAD_SCAN_SCRIPT, scanno); - /* Components must appear in SOF order within each scan */ - if (ci > 0 && thisi <= scanptr->component_index[ci-1]) - ERREXIT1(cinfo, JERR_BAD_SCAN_SCRIPT, scanno); - } - /* Validate progression parameters */ - Ss = scanptr->Ss; - Se = scanptr->Se; - Ah = scanptr->Ah; - Al = scanptr->Al; - if (cinfo->progressive_mode) { -#ifdef C_PROGRESSIVE_SUPPORTED - if (Ss < 0 || Ss >= DCTSIZE2 || Se < Ss || Se >= DCTSIZE2 || - Ah < 0 || Ah > 13 || Al < 0 || Al > 13) - ERREXIT1(cinfo, JERR_BAD_PROG_SCRIPT, scanno); - if (Ss == 0) { - if (Se != 0) /* DC and AC together not OK */ - ERREXIT1(cinfo, JERR_BAD_PROG_SCRIPT, scanno); - } else { - if (ncomps != 1) /* AC scans must be for only one component */ - ERREXIT1(cinfo, JERR_BAD_PROG_SCRIPT, scanno); - } - for (ci = 0; ci < ncomps; ci++) { - last_bitpos_ptr = & last_bitpos[scanptr->component_index[ci]][0]; - if (Ss != 0 && last_bitpos_ptr[0] < 0) /* AC without prior DC scan */ - ERREXIT1(cinfo, JERR_BAD_PROG_SCRIPT, scanno); - for (coefi = Ss; coefi <= Se; coefi++) { - if (last_bitpos_ptr[coefi] < 0) { - /* first scan of this coefficient */ - if (Ah != 0) - ERREXIT1(cinfo, JERR_BAD_PROG_SCRIPT, scanno); - } else { - /* not first scan */ - if (Ah != last_bitpos_ptr[coefi] || Al != Ah-1) - ERREXIT1(cinfo, JERR_BAD_PROG_SCRIPT, scanno); - } - last_bitpos_ptr[coefi] = Al; - } - } -#endif - } else { - /* For sequential JPEG, all progression parameters must be these: */ - if (Ss != 0 || Se != DCTSIZE2-1 || Ah != 0 || Al != 0) - ERREXIT1(cinfo, JERR_BAD_PROG_SCRIPT, scanno); - /* Make sure components are not sent twice */ - for (ci = 0; ci < ncomps; ci++) { - thisi = scanptr->component_index[ci]; - if (component_sent[thisi]) - ERREXIT1(cinfo, JERR_BAD_SCAN_SCRIPT, scanno); - component_sent[thisi] = TRUE; - } - } - } - - /* Now verify that everything got sent. */ - if (cinfo->progressive_mode) { -#ifdef C_PROGRESSIVE_SUPPORTED - /* For progressive mode, we only check that at least some DC data - * got sent for each component; the spec does not require that all bits - * of all coefficients be transmitted. Would it be wiser to enforce - * transmission of all coefficient bits?? - */ - for (ci = 0; ci < cinfo->num_components; ci++) { - if (last_bitpos[ci][0] < 0) - ERREXIT(cinfo, JERR_MISSING_DATA); - } -#endif - } else { - for (ci = 0; ci < cinfo->num_components; ci++) { - if (! component_sent[ci]) - ERREXIT(cinfo, JERR_MISSING_DATA); - } - } -} - -#endif /* C_MULTISCAN_FILES_SUPPORTED */ - - -LOCAL void -select_scan_parameters (j_compress_ptr cinfo) -/* Set up the scan parameters for the current scan */ -{ - int ci; - -#ifdef C_MULTISCAN_FILES_SUPPORTED - if (cinfo->scan_info != NULL) { - /* Prepare for current scan --- the script is already validated */ - my_master_ptr master = (my_master_ptr) cinfo->master; - const jpeg_scan_info * scanptr = cinfo->scan_info + master->scan_number; - - cinfo->comps_in_scan = scanptr->comps_in_scan; - for (ci = 0; ci < scanptr->comps_in_scan; ci++) { - cinfo->cur_comp_info[ci] = - &cinfo->comp_info[scanptr->component_index[ci]]; - } - cinfo->Ss = scanptr->Ss; - cinfo->Se = scanptr->Se; - cinfo->Ah = scanptr->Ah; - cinfo->Al = scanptr->Al; - } - else -#endif - { - /* Prepare for single sequential-JPEG scan containing all components */ - if (cinfo->num_components > MAX_COMPS_IN_SCAN) - ERREXIT2(cinfo, JERR_COMPONENT_COUNT, cinfo->num_components, - MAX_COMPS_IN_SCAN); - cinfo->comps_in_scan = cinfo->num_components; - for (ci = 0; ci < cinfo->num_components; ci++) { - cinfo->cur_comp_info[ci] = &cinfo->comp_info[ci]; - } - cinfo->Ss = 0; - cinfo->Se = DCTSIZE2-1; - cinfo->Ah = 0; - cinfo->Al = 0; - } -} - - -LOCAL void -per_scan_setup (j_compress_ptr cinfo) -/* Do computations that are needed before processing a JPEG scan */ -/* cinfo->comps_in_scan and cinfo->cur_comp_info[] are already set */ -{ - int ci, mcublks, tmp; - jpeg_component_info *compptr; - - if (cinfo->comps_in_scan == 1) { - - /* Noninterleaved (single-component) scan */ - compptr = cinfo->cur_comp_info[0]; - - /* Overall image size in MCUs */ - cinfo->MCUs_per_row = compptr->width_in_blocks; - cinfo->MCU_rows_in_scan = compptr->height_in_blocks; - - /* For noninterleaved scan, always one block per MCU */ - compptr->MCU_width = 1; - compptr->MCU_height = 1; - compptr->MCU_blocks = 1; - compptr->MCU_sample_width = DCTSIZE; - compptr->last_col_width = 1; - /* For noninterleaved scans, it is convenient to define last_row_height - * as the number of block rows present in the last iMCU row. - */ - tmp = (int) (compptr->height_in_blocks % compptr->v_samp_factor); - if (tmp == 0) tmp = compptr->v_samp_factor; - compptr->last_row_height = tmp; - - /* Prepare array describing MCU composition */ - cinfo->blocks_in_MCU = 1; - cinfo->MCU_membership[0] = 0; - - } else { - - /* Interleaved (multi-component) scan */ - if (cinfo->comps_in_scan <= 0 || cinfo->comps_in_scan > MAX_COMPS_IN_SCAN) - ERREXIT2(cinfo, JERR_COMPONENT_COUNT, cinfo->comps_in_scan, - MAX_COMPS_IN_SCAN); - - /* Overall image size in MCUs */ - cinfo->MCUs_per_row = (JDIMENSION) - jdiv_round_up((long) cinfo->image_width, - (long) (cinfo->max_h_samp_factor*DCTSIZE)); - cinfo->MCU_rows_in_scan = (JDIMENSION) - jdiv_round_up((long) cinfo->image_height, - (long) (cinfo->max_v_samp_factor*DCTSIZE)); - - cinfo->blocks_in_MCU = 0; - - for (ci = 0; ci < cinfo->comps_in_scan; ci++) { - compptr = cinfo->cur_comp_info[ci]; - /* Sampling factors give # of blocks of component in each MCU */ - compptr->MCU_width = compptr->h_samp_factor; - compptr->MCU_height = compptr->v_samp_factor; - compptr->MCU_blocks = compptr->MCU_width * compptr->MCU_height; - compptr->MCU_sample_width = compptr->MCU_width * DCTSIZE; - /* Figure number of non-dummy blocks in last MCU column & row */ - tmp = (int) (compptr->width_in_blocks % compptr->MCU_width); - if (tmp == 0) tmp = compptr->MCU_width; - compptr->last_col_width = tmp; - tmp = (int) (compptr->height_in_blocks % compptr->MCU_height); - if (tmp == 0) tmp = compptr->MCU_height; - compptr->last_row_height = tmp; - /* Prepare array describing MCU composition */ - mcublks = compptr->MCU_blocks; - if (cinfo->blocks_in_MCU + mcublks > C_MAX_BLOCKS_IN_MCU) - ERREXIT(cinfo, JERR_BAD_MCU_SIZE); - while (mcublks-- > 0) { - cinfo->MCU_membership[cinfo->blocks_in_MCU++] = ci; - } - } - - } - - /* Convert restart specified in rows to actual MCU count. */ - /* Note that count must fit in 16 bits, so we provide limiting. */ - if (cinfo->restart_in_rows > 0) { - long nominal = (long) cinfo->restart_in_rows * (long) cinfo->MCUs_per_row; - cinfo->restart_interval = (unsigned int) MIN(nominal, 65535L); - } -} - - -/* - * Per-pass setup. - * This is called at the beginning of each pass. We determine which modules - * will be active during this pass and give them appropriate start_pass calls. - * We also set is_last_pass to indicate whether any more passes will be - * required. - */ - -METHODDEF void -prepare_for_pass (j_compress_ptr cinfo) -{ - my_master_ptr master = (my_master_ptr) cinfo->master; - - switch (master->pass_type) { - case main_pass: - /* Initial pass: will collect input data, and do either Huffman - * optimization or data output for the first scan. - */ - select_scan_parameters(cinfo); - per_scan_setup(cinfo); - if (! cinfo->raw_data_in) { - (*cinfo->cconvert->start_pass) (cinfo); - (*cinfo->downsample->start_pass) (cinfo); - (*cinfo->prep->start_pass) (cinfo, JBUF_PASS_THRU); - } - (*cinfo->fdct->start_pass) (cinfo); - (*cinfo->entropy->start_pass) (cinfo, cinfo->optimize_coding); - (*cinfo->coef->start_pass) (cinfo, - (master->total_passes > 1 ? - JBUF_SAVE_AND_PASS : JBUF_PASS_THRU)); - (*cinfo->main->start_pass) (cinfo, JBUF_PASS_THRU); - if (cinfo->optimize_coding) { - /* No immediate data output; postpone writing frame/scan headers */ - master->pub.call_pass_startup = FALSE; - } else { - /* Will write frame/scan headers at first jpeg_write_scanlines call */ - master->pub.call_pass_startup = TRUE; - } - break; -#ifdef ENTROPY_OPT_SUPPORTED - case huff_opt_pass: - /* Do Huffman optimization for a scan after the first one. */ - select_scan_parameters(cinfo); - per_scan_setup(cinfo); - if (cinfo->Ss != 0 || cinfo->Ah == 0 || cinfo->arith_code) { - (*cinfo->entropy->start_pass) (cinfo, TRUE); - (*cinfo->coef->start_pass) (cinfo, JBUF_CRANK_DEST); - master->pub.call_pass_startup = FALSE; - break; - } - /* Special case: Huffman DC refinement scans need no Huffman table - * and therefore we can skip the optimization pass for them. - */ - master->pass_type = output_pass; - master->pass_number++; - /*FALLTHROUGH*/ -#endif - case output_pass: - /* Do a data-output pass. */ - /* We need not repeat per-scan setup if prior optimization pass did it. */ - if (! cinfo->optimize_coding) { - select_scan_parameters(cinfo); - per_scan_setup(cinfo); - } - (*cinfo->entropy->start_pass) (cinfo, FALSE); - (*cinfo->coef->start_pass) (cinfo, JBUF_CRANK_DEST); - /* We emit frame/scan headers now */ - if (master->scan_number == 0) - (*cinfo->marker->write_frame_header) (cinfo); - (*cinfo->marker->write_scan_header) (cinfo); - master->pub.call_pass_startup = FALSE; - break; - default: - ERREXIT(cinfo, JERR_NOT_COMPILED); - } - - master->pub.is_last_pass = (master->pass_number == master->total_passes-1); - - /* Set up progress monitor's pass info if present */ - if (cinfo->progress != NULL) { - cinfo->progress->completed_passes = master->pass_number; - cinfo->progress->total_passes = master->total_passes; - } -} - - -/* - * Special start-of-pass hook. - * This is called by jpeg_write_scanlines if call_pass_startup is TRUE. - * In single-pass processing, we need this hook because we don't want to - * write frame/scan headers during jpeg_start_compress; we want to let the - * application write COM markers etc. between jpeg_start_compress and the - * jpeg_write_scanlines loop. - * In multi-pass processing, this routine is not used. - */ - -METHODDEF void -pass_startup (j_compress_ptr cinfo) -{ - cinfo->master->call_pass_startup = FALSE; /* reset flag so call only once */ - - (*cinfo->marker->write_frame_header) (cinfo); - (*cinfo->marker->write_scan_header) (cinfo); -} - - -/* - * Finish up at end of pass. - */ - -METHODDEF void -finish_pass_master (j_compress_ptr cinfo) -{ - my_master_ptr master = (my_master_ptr) cinfo->master; - - /* The entropy coder always needs an end-of-pass call, - * either to analyze statistics or to flush its output buffer. - */ - (*cinfo->entropy->finish_pass) (cinfo); - - /* Update state for next pass */ - switch (master->pass_type) { - case main_pass: - /* next pass is either output of scan 0 (after optimization) - * or output of scan 1 (if no optimization). - */ - master->pass_type = output_pass; - if (! cinfo->optimize_coding) - master->scan_number++; - break; - case huff_opt_pass: - /* next pass is always output of current scan */ - master->pass_type = output_pass; - break; - case output_pass: - /* next pass is either optimization or output of next scan */ - if (cinfo->optimize_coding) - master->pass_type = huff_opt_pass; - master->scan_number++; - break; - } - - master->pass_number++; -} - - -/* - * Initialize master compression control. - */ - -GLOBAL void -jinit_c_master_control (j_compress_ptr cinfo, boolean transcode_only) -{ - my_master_ptr master; - - master = (my_master_ptr) - (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, - SIZEOF(my_comp_master)); - cinfo->master = (struct jpeg_comp_master *) master; - master->pub.prepare_for_pass = prepare_for_pass; - master->pub.pass_startup = pass_startup; - master->pub.finish_pass = finish_pass_master; - master->pub.is_last_pass = FALSE; - - /* Validate parameters, determine derived values */ - initial_setup(cinfo); - - if (cinfo->scan_info != NULL) { -#ifdef C_MULTISCAN_FILES_SUPPORTED - validate_script(cinfo); -#else - ERREXIT(cinfo, JERR_NOT_COMPILED); -#endif - } else { - cinfo->progressive_mode = FALSE; - cinfo->num_scans = 1; - } - - if (cinfo->progressive_mode) /* TEMPORARY HACK ??? */ - cinfo->optimize_coding = TRUE; /* assume default tables no good for progressive mode */ - - /* Initialize my private state */ - if (transcode_only) { - /* no main pass in transcoding */ - if (cinfo->optimize_coding) - master->pass_type = huff_opt_pass; - else - master->pass_type = output_pass; - } else { - /* for normal compression, first pass is always this type: */ - master->pass_type = main_pass; - } - master->scan_number = 0; - master->pass_number = 0; - if (cinfo->optimize_coding) - master->total_passes = cinfo->num_scans * 2; - else - master->total_passes = cinfo->num_scans; -} diff --git a/engine/jpeg-6/jcomapi.c b/engine/jpeg-6/jcomapi.c deleted file mode 100644 index c10903f..0000000 --- a/engine/jpeg-6/jcomapi.c +++ /dev/null @@ -1,94 +0,0 @@ -/* - * jcomapi.c - * - * Copyright (C) 1994, Thomas G. Lane. - * This file is part of the Independent JPEG Group's software. - * For conditions of distribution and use, see the accompanying README file. - * - * This file contains application interface routines that are used for both - * compression and decompression. - */ - -#define JPEG_INTERNALS -#include "jinclude.h" -#include "jpeglib.h" - - -/* - * Abort processing of a JPEG compression or decompression operation, - * but don't destroy the object itself. - * - * For this, we merely clean up all the nonpermanent memory pools. - * Note that temp files (virtual arrays) are not allowed to belong to - * the permanent pool, so we will be able to close all temp files here. - * Closing a data source or destination, if necessary, is the application's - * responsibility. - */ - -GLOBAL void -jpeg_abort (j_common_ptr cinfo) -{ - int pool; - - /* Releasing pools in reverse order might help avoid fragmentation - * with some (brain-damaged) malloc libraries. - */ - for (pool = JPOOL_NUMPOOLS-1; pool > JPOOL_PERMANENT; pool--) { - (*cinfo->mem->free_pool) (cinfo, pool); - } - - /* Reset overall state for possible reuse of object */ - cinfo->global_state = (cinfo->is_decompressor ? DSTATE_START : CSTATE_START); -} - - -/* - * Destruction of a JPEG object. - * - * Everything gets deallocated except the master jpeg_compress_struct itself - * and the error manager struct. Both of these are supplied by the application - * and must be freed, if necessary, by the application. (Often they are on - * the stack and so don't need to be freed anyway.) - * Closing a data source or destination, if necessary, is the application's - * responsibility. - */ - -GLOBAL void -jpeg_destroy (j_common_ptr cinfo) -{ - /* We need only tell the memory manager to release everything. */ - /* NB: mem pointer is NULL if memory mgr failed to initialize. */ - if (cinfo->mem != NULL) - (*cinfo->mem->self_destruct) (cinfo); - cinfo->mem = NULL; /* be safe if jpeg_destroy is called twice */ - cinfo->global_state = 0; /* mark it destroyed */ -} - - -/* - * Convenience routines for allocating quantization and Huffman tables. - * (Would jutils.c be a more reasonable place to put these?) - */ - -GLOBAL JQUANT_TBL * -jpeg_alloc_quant_table (j_common_ptr cinfo) -{ - JQUANT_TBL *tbl; - - tbl = (JQUANT_TBL *) - (*cinfo->mem->alloc_small) (cinfo, JPOOL_PERMANENT, SIZEOF(JQUANT_TBL)); - tbl->sent_table = FALSE; /* make sure this is false in any new table */ - return tbl; -} - - -GLOBAL JHUFF_TBL * -jpeg_alloc_huff_table (j_common_ptr cinfo) -{ - JHUFF_TBL *tbl; - - tbl = (JHUFF_TBL *) - (*cinfo->mem->alloc_small) (cinfo, JPOOL_PERMANENT, SIZEOF(JHUFF_TBL)); - tbl->sent_table = FALSE; /* make sure this is false in any new table */ - return tbl; -} diff --git a/engine/jpeg-6/jconfig.h b/engine/jpeg-6/jconfig.h deleted file mode 100644 index 7d2f733..0000000 --- a/engine/jpeg-6/jconfig.h +++ /dev/null @@ -1,41 +0,0 @@ -/* jconfig.wat --- jconfig.h for Watcom C/C++ on MS-DOS or OS/2. */ -/* see jconfig.doc for explanations */ - -#define HAVE_PROTOTYPES -#define HAVE_UNSIGNED_CHAR -#define HAVE_UNSIGNED_SHORT -/* #define void char */ -/* #define const */ -#define CHAR_IS_UNSIGNED -#define HAVE_STDDEF_H -#define HAVE_STDLIB_H -#undef NEED_BSD_STRINGS -#undef NEED_SYS_TYPES_H -#undef NEED_FAR_POINTERS /* Watcom uses flat 32-bit addressing */ -#undef NEED_SHORT_EXTERNAL_NAMES -#undef INCOMPLETE_TYPES_BROKEN - -#define JDCT_DEFAULT JDCT_FLOAT -#define JDCT_FASTEST JDCT_FLOAT - -#ifdef JPEG_INTERNALS - -#undef RIGHT_SHIFT_IS_UNSIGNED - -#endif /* JPEG_INTERNALS */ - -#ifdef JPEG_CJPEG_DJPEG - -#define BMP_SUPPORTED /* BMP image file format */ -#define GIF_SUPPORTED /* GIF image file format */ -#define PPM_SUPPORTED /* PBMPLUS PPM/PGM image file format */ -#undef RLE_SUPPORTED /* Utah RLE image file format */ -#define TARGA_SUPPORTED /* Targa image file format */ - -#undef TWO_FILE_COMMANDLINE /* optional */ -#define USE_SETMODE /* Needed to make one-file style work in Watcom */ -#undef NEED_SIGNAL_CATCHER /* Define this if you use jmemname.c */ -#undef DONT_USE_B_MODE -#undef PROGRESS_REPORT /* optional */ - -#endif /* JPEG_CJPEG_DJPEG */ diff --git a/engine/jpeg-6/jcparam.c b/engine/jpeg-6/jcparam.c deleted file mode 100644 index 29862d3..0000000 --- a/engine/jpeg-6/jcparam.c +++ /dev/null @@ -1,575 +0,0 @@ -/* - * jcparam.c - * - * Copyright (C) 1991-1995, Thomas G. Lane. - * This file is part of the Independent JPEG Group's software. - * For conditions of distribution and use, see the accompanying README file. - * - * This file contains optional default-setting code for the JPEG compressor. - * Applications do not have to use this file, but those that don't use it - * must know a lot more about the innards of the JPEG code. - */ - -#define JPEG_INTERNALS -#include "jinclude.h" -#include "jpeglib.h" - - -/* - * Quantization table setup routines - */ - -GLOBAL void -jpeg_add_quant_table (j_compress_ptr cinfo, int which_tbl, - const unsigned int *basic_table, - int scale_factor, boolean force_baseline) -/* Define a quantization table equal to the basic_table times - * a scale factor (given as a percentage). - * If force_baseline is TRUE, the computed quantization table entries - * are limited to 1..255 for JPEG baseline compatibility. - */ -{ - JQUANT_TBL ** qtblptr = & cinfo->quant_tbl_ptrs[which_tbl]; - int i; - long temp; - - /* Safety check to ensure start_compress not called yet. */ - if (cinfo->global_state != CSTATE_START) - ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); - - if (*qtblptr == NULL) - *qtblptr = jpeg_alloc_quant_table((j_common_ptr) cinfo); - - for (i = 0; i < DCTSIZE2; i++) { - temp = ((long) basic_table[i] * scale_factor + 50L) / 100L; - /* limit the values to the valid range */ - if (temp <= 0L) temp = 1L; - if (temp > 32767L) temp = 32767L; /* max quantizer needed for 12 bits */ - if (force_baseline && temp > 255L) - temp = 255L; /* limit to baseline range if requested */ - (*qtblptr)->quantval[i] = (UINT16) temp; - } - - /* Initialize sent_table FALSE so table will be written to JPEG file. */ - (*qtblptr)->sent_table = FALSE; -} - - -GLOBAL void -jpeg_set_linear_quality (j_compress_ptr cinfo, int scale_factor, - boolean force_baseline) -/* Set or change the 'quality' (quantization) setting, using default tables - * and a straight percentage-scaling quality scale. In most cases it's better - * to use jpeg_set_quality (below); this entry point is provided for - * applications that insist on a linear percentage scaling. - */ -{ - /* This is the sample quantization table given in the JPEG spec section K.1, - * but expressed in zigzag order (as are all of our quant. tables). - * The spec says that the values given produce "good" quality, and - * when divided by 2, "very good" quality. - */ - static const unsigned int std_luminance_quant_tbl[DCTSIZE2] = { - 16, 11, 12, 14, 12, 10, 16, 14, - 13, 14, 18, 17, 16, 19, 24, 40, - 26, 24, 22, 22, 24, 49, 35, 37, - 29, 40, 58, 51, 61, 60, 57, 51, - 56, 55, 64, 72, 92, 78, 64, 68, - 87, 69, 55, 56, 80, 109, 81, 87, - 95, 98, 103, 104, 103, 62, 77, 113, - 121, 112, 100, 120, 92, 101, 103, 99 - }; - static const unsigned int std_chrominance_quant_tbl[DCTSIZE2] = { - 17, 18, 18, 24, 21, 24, 47, 26, - 26, 47, 99, 66, 56, 66, 99, 99, - 99, 99, 99, 99, 99, 99, 99, 99, - 99, 99, 99, 99, 99, 99, 99, 99, - 99, 99, 99, 99, 99, 99, 99, 99, - 99, 99, 99, 99, 99, 99, 99, 99, - 99, 99, 99, 99, 99, 99, 99, 99, - 99, 99, 99, 99, 99, 99, 99, 99 - }; - - /* Set up two quantization tables using the specified scaling */ - jpeg_add_quant_table(cinfo, 0, std_luminance_quant_tbl, - scale_factor, force_baseline); - jpeg_add_quant_table(cinfo, 1, std_chrominance_quant_tbl, - scale_factor, force_baseline); -} - - -GLOBAL int -jpeg_quality_scaling (int quality) -/* Convert a user-specified quality rating to a percentage scaling factor - * for an underlying quantization table, using our recommended scaling curve. - * The input 'quality' factor should be 0 (terrible) to 100 (very good). - */ -{ - /* Safety limit on quality factor. Convert 0 to 1 to avoid zero divide. */ - if (quality <= 0) quality = 1; - if (quality > 100) quality = 100; - - /* The basic table is used as-is (scaling 100) for a quality of 50. - * Qualities 50..100 are converted to scaling percentage 200 - 2*Q; - * note that at Q=100 the scaling is 0, which will cause j_add_quant_table - * to make all the table entries 1 (hence, no quantization loss). - * Qualities 1..50 are converted to scaling percentage 5000/Q. - */ - if (quality < 50) - quality = 5000 / quality; - else - quality = 200 - quality*2; - - return quality; -} - - -GLOBAL void -jpeg_set_quality (j_compress_ptr cinfo, int quality, boolean force_baseline) -/* Set or change the 'quality' (quantization) setting, using default tables. - * This is the standard quality-adjusting entry point for typical user - * interfaces; only those who want detailed control over quantization tables - * would use the preceding three routines directly. - */ -{ - /* Convert user 0-100 rating to percentage scaling */ - quality = jpeg_quality_scaling(quality); - - /* Set up standard quality tables */ - jpeg_set_linear_quality(cinfo, quality, force_baseline); -} - - -/* - * Huffman table setup routines - */ - -LOCAL void -add_huff_table (j_compress_ptr cinfo, - JHUFF_TBL **htblptr, const UINT8 *bits, const UINT8 *val) -/* Define a Huffman table */ -{ - if (*htblptr == NULL) - *htblptr = jpeg_alloc_huff_table((j_common_ptr) cinfo); - - MEMCOPY((*htblptr)->bits, bits, SIZEOF((*htblptr)->bits)); - MEMCOPY((*htblptr)->huffval, val, SIZEOF((*htblptr)->huffval)); - - /* Initialize sent_table FALSE so table will be written to JPEG file. */ - (*htblptr)->sent_table = FALSE; -} - - -LOCAL void -std_huff_tables (j_compress_ptr cinfo) -/* Set up the standard Huffman tables (cf. JPEG standard section K.3) */ -/* IMPORTANT: these are only valid for 8-bit data precision! */ -{ - static const UINT8 bits_dc_luminance[17] = - { /* 0-base */ 0, 0, 1, 5, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0 }; - static const UINT8 val_dc_luminance[] = - { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 }; - - static const UINT8 bits_dc_chrominance[17] = - { /* 0-base */ 0, 0, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0 }; - static const UINT8 val_dc_chrominance[] = - { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 }; - - static const UINT8 bits_ac_luminance[17] = - { /* 0-base */ 0, 0, 2, 1, 3, 3, 2, 4, 3, 5, 5, 4, 4, 0, 0, 1, 0x7d }; - static const UINT8 val_ac_luminance[] = - { 0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12, - 0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07, - 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08, - 0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0, - 0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16, - 0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28, - 0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, - 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, - 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, - 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, - 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, - 0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, - 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, - 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, - 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, - 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5, - 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4, - 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2, - 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, - 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, - 0xf9, 0xfa }; - - static const UINT8 bits_ac_chrominance[17] = - { /* 0-base */ 0, 0, 2, 1, 2, 4, 4, 3, 4, 7, 5, 4, 4, 0, 1, 2, 0x77 }; - static const UINT8 val_ac_chrominance[] = - { 0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21, - 0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71, - 0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91, - 0xa1, 0xb1, 0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0, - 0x15, 0x62, 0x72, 0xd1, 0x0a, 0x16, 0x24, 0x34, - 0xe1, 0x25, 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26, - 0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38, - 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, - 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, - 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, - 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, - 0x79, 0x7a, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, - 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, - 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, - 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, - 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, - 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, - 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, - 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, - 0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, - 0xf9, 0xfa }; - - add_huff_table(cinfo, &cinfo->dc_huff_tbl_ptrs[0], - bits_dc_luminance, val_dc_luminance); - add_huff_table(cinfo, &cinfo->ac_huff_tbl_ptrs[0], - bits_ac_luminance, val_ac_luminance); - add_huff_table(cinfo, &cinfo->dc_huff_tbl_ptrs[1], - bits_dc_chrominance, val_dc_chrominance); - add_huff_table(cinfo, &cinfo->ac_huff_tbl_ptrs[1], - bits_ac_chrominance, val_ac_chrominance); -} - - -/* - * Default parameter setup for compression. - * - * Applications that don't choose to use this routine must do their - * own setup of all these parameters. Alternately, you can call this - * to establish defaults and then alter parameters selectively. This - * is the recommended approach since, if we add any new parameters, - * your code will still work (they'll be set to reasonable defaults). - */ - -GLOBAL void -jpeg_set_defaults (j_compress_ptr cinfo) -{ - int i; - - /* Safety check to ensure start_compress not called yet. */ - if (cinfo->global_state != CSTATE_START) - ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); - - /* Allocate comp_info array large enough for maximum component count. - * Array is made permanent in case application wants to compress - * multiple images at same param settings. - */ - if (cinfo->comp_info == NULL) - cinfo->comp_info = (jpeg_component_info *) - (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT, - MAX_COMPONENTS * SIZEOF(jpeg_component_info)); - - /* Initialize everything not dependent on the color space */ - - cinfo->data_precision = BITS_IN_JSAMPLE; - /* Set up two quantization tables using default quality of 75 */ - jpeg_set_quality(cinfo, 75, TRUE); - /* Set up two Huffman tables */ - std_huff_tables(cinfo); - - /* Initialize default arithmetic coding conditioning */ - for (i = 0; i < NUM_ARITH_TBLS; i++) { - cinfo->arith_dc_L[i] = 0; - cinfo->arith_dc_U[i] = 1; - cinfo->arith_ac_K[i] = 5; - } - - /* Default is no multiple-scan output */ - cinfo->scan_info = NULL; - cinfo->num_scans = 0; - - /* Expect normal source image, not raw downsampled data */ - cinfo->raw_data_in = FALSE; - - /* Use Huffman coding, not arithmetic coding, by default */ - cinfo->arith_code = FALSE; - - /* By default, don't do extra passes to optimize entropy coding */ - cinfo->optimize_coding = FALSE; - /* The standard Huffman tables are only valid for 8-bit data precision. - * If the precision is higher, force optimization on so that usable - * tables will be computed. This test can be removed if default tables - * are supplied that are valid for the desired precision. - */ - if (cinfo->data_precision > 8) - cinfo->optimize_coding = TRUE; - - /* By default, use the simpler non-cosited sampling alignment */ - cinfo->CCIR601_sampling = FALSE; - - /* No input smoothing */ - cinfo->smoothing_factor = 0; - - /* DCT algorithm preference */ - cinfo->dct_method = JDCT_DEFAULT; - - /* No restart markers */ - cinfo->restart_interval = 0; - cinfo->restart_in_rows = 0; - - /* Fill in default JFIF marker parameters. Note that whether the marker - * will actually be written is determined by jpeg_set_colorspace. - */ - cinfo->density_unit = 0; /* Pixel size is unknown by default */ - cinfo->X_density = 1; /* Pixel aspect ratio is square by default */ - cinfo->Y_density = 1; - - /* Choose JPEG colorspace based on input space, set defaults accordingly */ - - jpeg_default_colorspace(cinfo); -} - - -/* - * Select an appropriate JPEG colorspace for in_color_space. - */ - -GLOBAL void -jpeg_default_colorspace (j_compress_ptr cinfo) -{ - switch (cinfo->in_color_space) { - case JCS_GRAYSCALE: - jpeg_set_colorspace(cinfo, JCS_GRAYSCALE); - break; - case JCS_RGB: - jpeg_set_colorspace(cinfo, JCS_YCbCr); - break; - case JCS_YCbCr: - jpeg_set_colorspace(cinfo, JCS_YCbCr); - break; - case JCS_CMYK: - jpeg_set_colorspace(cinfo, JCS_CMYK); /* By default, no translation */ - break; - case JCS_YCCK: - jpeg_set_colorspace(cinfo, JCS_YCCK); - break; - case JCS_UNKNOWN: - jpeg_set_colorspace(cinfo, JCS_UNKNOWN); - break; - default: - ERREXIT(cinfo, JERR_BAD_IN_COLORSPACE); - } -} - - -/* - * Set the JPEG colorspace, and choose colorspace-dependent default values. - */ - -GLOBAL void -jpeg_set_colorspace (j_compress_ptr cinfo, J_COLOR_SPACE colorspace) -{ - jpeg_component_info * compptr; - int ci; - -#define SET_COMP(index,id,hsamp,vsamp,quant,dctbl,actbl) \ - (compptr = &cinfo->comp_info[index], \ - compptr->component_id = (id), \ - compptr->h_samp_factor = (hsamp), \ - compptr->v_samp_factor = (vsamp), \ - compptr->quant_tbl_no = (quant), \ - compptr->dc_tbl_no = (dctbl), \ - compptr->ac_tbl_no = (actbl) ) - - /* Safety check to ensure start_compress not called yet. */ - if (cinfo->global_state != CSTATE_START) - ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); - - /* For all colorspaces, we use Q and Huff tables 0 for luminance components, - * tables 1 for chrominance components. - */ - - cinfo->jpeg_color_space = colorspace; - - cinfo->write_JFIF_header = FALSE; /* No marker for non-JFIF colorspaces */ - cinfo->write_Adobe_marker = FALSE; /* write no Adobe marker by default */ - - switch (colorspace) { - case JCS_GRAYSCALE: - cinfo->write_JFIF_header = TRUE; /* Write a JFIF marker */ - cinfo->num_components = 1; - /* JFIF specifies component ID 1 */ - SET_COMP(0, 1, 1,1, 0, 0,0); - break; - case JCS_RGB: - cinfo->write_Adobe_marker = TRUE; /* write Adobe marker to flag RGB */ - cinfo->num_components = 3; - SET_COMP(0, 0x52 /* 'R' */, 1,1, 0, 0,0); - SET_COMP(1, 0x47 /* 'G' */, 1,1, 0, 0,0); - SET_COMP(2, 0x42 /* 'B' */, 1,1, 0, 0,0); - break; - case JCS_YCbCr: - cinfo->write_JFIF_header = TRUE; /* Write a JFIF marker */ - cinfo->num_components = 3; - /* JFIF specifies component IDs 1,2,3 */ - /* We default to 2x2 subsamples of chrominance */ - SET_COMP(0, 1, 2,2, 0, 0,0); - SET_COMP(1, 2, 1,1, 1, 1,1); - SET_COMP(2, 3, 1,1, 1, 1,1); - break; - case JCS_CMYK: - cinfo->write_Adobe_marker = TRUE; /* write Adobe marker to flag CMYK */ - cinfo->num_components = 4; - SET_COMP(0, 0x43 /* 'C' */, 1,1, 0, 0,0); - SET_COMP(1, 0x4D /* 'M' */, 1,1, 0, 0,0); - SET_COMP(2, 0x59 /* 'Y' */, 1,1, 0, 0,0); - SET_COMP(3, 0x4B /* 'K' */, 1,1, 0, 0,0); - break; - case JCS_YCCK: - cinfo->write_Adobe_marker = TRUE; /* write Adobe marker to flag YCCK */ - cinfo->num_components = 4; - SET_COMP(0, 1, 2,2, 0, 0,0); - SET_COMP(1, 2, 1,1, 1, 1,1); - SET_COMP(2, 3, 1,1, 1, 1,1); - SET_COMP(3, 4, 2,2, 0, 0,0); - break; - case JCS_UNKNOWN: - cinfo->num_components = cinfo->input_components; - if (cinfo->num_components < 1 || cinfo->num_components > MAX_COMPONENTS) - ERREXIT2(cinfo, JERR_COMPONENT_COUNT, cinfo->num_components, - MAX_COMPONENTS); - for (ci = 0; ci < cinfo->num_components; ci++) { - SET_COMP(ci, ci, 1,1, 0, 0,0); - } - break; - default: - ERREXIT(cinfo, JERR_BAD_J_COLORSPACE); - } -} - - -#ifdef C_PROGRESSIVE_SUPPORTED - -LOCAL jpeg_scan_info * -fill_a_scan (jpeg_scan_info * scanptr, int ci, - int Ss, int Se, int Ah, int Al) -/* Support routine: generate one scan for specified component */ -{ - scanptr->comps_in_scan = 1; - scanptr->component_index[0] = ci; - scanptr->Ss = Ss; - scanptr->Se = Se; - scanptr->Ah = Ah; - scanptr->Al = Al; - scanptr++; - return scanptr; -} - -LOCAL jpeg_scan_info * -fill_scans (jpeg_scan_info * scanptr, int ncomps, - int Ss, int Se, int Ah, int Al) -/* Support routine: generate one scan for each component */ -{ - int ci; - - for (ci = 0; ci < ncomps; ci++) { - scanptr->comps_in_scan = 1; - scanptr->component_index[0] = ci; - scanptr->Ss = Ss; - scanptr->Se = Se; - scanptr->Ah = Ah; - scanptr->Al = Al; - scanptr++; - } - return scanptr; -} - -LOCAL jpeg_scan_info * -fill_dc_scans (jpeg_scan_info * scanptr, int ncomps, int Ah, int Al) -/* Support routine: generate interleaved DC scan if possible, else N scans */ -{ - int ci; - - if (ncomps <= MAX_COMPS_IN_SCAN) { - /* Single interleaved DC scan */ - scanptr->comps_in_scan = ncomps; - for (ci = 0; ci < ncomps; ci++) - scanptr->component_index[ci] = ci; - scanptr->Ss = scanptr->Se = 0; - scanptr->Ah = Ah; - scanptr->Al = Al; - scanptr++; - } else { - /* Noninterleaved DC scan for each component */ - scanptr = fill_scans(scanptr, ncomps, 0, 0, Ah, Al); - } - return scanptr; -} - - -/* - * Create a recommended progressive-JPEG script. - * cinfo->num_components and cinfo->jpeg_color_space must be correct. - */ - -GLOBAL void -jpeg_simple_progression (j_compress_ptr cinfo) -{ - int ncomps = cinfo->num_components; - int nscans; - jpeg_scan_info * scanptr; - - /* Safety check to ensure start_compress not called yet. */ - if (cinfo->global_state != CSTATE_START) - ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); - - /* Figure space needed for script. Calculation must match code below! */ - if (ncomps == 3 && cinfo->jpeg_color_space == JCS_YCbCr) { - /* Custom script for YCbCr color images. */ - nscans = 10; - } else { - /* All-purpose script for other color spaces. */ - if (ncomps > MAX_COMPS_IN_SCAN) - nscans = 6 * ncomps; /* 2 DC + 4 AC scans per component */ - else - nscans = 2 + 4 * ncomps; /* 2 DC scans; 4 AC scans per component */ - } - - /* Allocate space for script. */ - /* We use permanent pool just in case application re-uses script. */ - scanptr = (jpeg_scan_info *) - (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT, - nscans * SIZEOF(jpeg_scan_info)); - cinfo->scan_info = scanptr; - cinfo->num_scans = nscans; - - if (ncomps == 3 && cinfo->jpeg_color_space == JCS_YCbCr) { - /* Custom script for YCbCr color images. */ - /* Initial DC scan */ - scanptr = fill_dc_scans(scanptr, ncomps, 0, 1); - /* Initial AC scan: get some luma data out in a hurry */ - scanptr = fill_a_scan(scanptr, 0, 1, 5, 0, 2); - /* Chroma data is too small to be worth expending many scans on */ - scanptr = fill_a_scan(scanptr, 2, 1, 63, 0, 1); - scanptr = fill_a_scan(scanptr, 1, 1, 63, 0, 1); - /* Complete spectral selection for luma AC */ - scanptr = fill_a_scan(scanptr, 0, 6, 63, 0, 2); - /* Refine next bit of luma AC */ - scanptr = fill_a_scan(scanptr, 0, 1, 63, 2, 1); - /* Finish DC successive approximation */ - scanptr = fill_dc_scans(scanptr, ncomps, 1, 0); - /* Finish AC successive approximation */ - scanptr = fill_a_scan(scanptr, 2, 1, 63, 1, 0); - scanptr = fill_a_scan(scanptr, 1, 1, 63, 1, 0); - /* Luma bottom bit comes last since it's usually largest scan */ - scanptr = fill_a_scan(scanptr, 0, 1, 63, 1, 0); - } else { - /* All-purpose script for other color spaces. */ - /* Successive approximation first pass */ - scanptr = fill_dc_scans(scanptr, ncomps, 0, 1); - scanptr = fill_scans(scanptr, ncomps, 1, 5, 0, 2); - scanptr = fill_scans(scanptr, ncomps, 6, 63, 0, 2); - /* Successive approximation second pass */ - scanptr = fill_scans(scanptr, ncomps, 1, 63, 2, 1); - /* Successive approximation final pass */ - scanptr = fill_dc_scans(scanptr, ncomps, 1, 0); - scanptr = fill_scans(scanptr, ncomps, 1, 63, 1, 0); - } -} - -#endif /* C_PROGRESSIVE_SUPPORTED */ diff --git a/engine/jpeg-6/jcphuff.c b/engine/jpeg-6/jcphuff.c deleted file mode 100644 index 922c17c..0000000 --- a/engine/jpeg-6/jcphuff.c +++ /dev/null @@ -1,829 +0,0 @@ -/* - * jcphuff.c - * - * Copyright (C) 1995, Thomas G. Lane. - * This file is part of the Independent JPEG Group's software. - * For conditions of distribution and use, see the accompanying README file. - * - * This file contains Huffman entropy encoding routines for progressive JPEG. - * - * We do not support output suspension in this module, since the library - * currently does not allow multiple-scan files to be written with output - * suspension. - */ - -#define JPEG_INTERNALS -#include "jinclude.h" -#include "jpeglib.h" -#include "jchuff.h" /* Declarations shared with jchuff.c */ - -#ifdef C_PROGRESSIVE_SUPPORTED - -/* Expanded entropy encoder object for progressive Huffman encoding. */ - -typedef struct { - struct jpeg_entropy_encoder pub; /* public fields */ - - /* Mode flag: TRUE for optimization, FALSE for actual data output */ - boolean gather_statistics; - - /* Bit-level coding status. - * next_output_byte/free_in_buffer are local copies of cinfo->dest fields. - */ - JOCTET * next_output_byte; /* => next byte to write in buffer */ - size_t free_in_buffer; /* # of byte spaces remaining in buffer */ - INT32 put_buffer; /* current bit-accumulation buffer */ - int put_bits; /* # of bits now in it */ - j_compress_ptr cinfo; /* link to cinfo (needed for dump_buffer) */ - - /* Coding status for DC components */ - int last_dc_val[MAX_COMPS_IN_SCAN]; /* last DC coef for each component */ - - /* Coding status for AC components */ - int ac_tbl_no; /* the table number of the single component */ - unsigned int EOBRUN; /* run length of EOBs */ - unsigned int BE; /* # of buffered correction bits before MCU */ - char * bit_buffer; /* buffer for correction bits (1 per char) */ - /* packing correction bits tightly would save some space but cost time... */ - - unsigned int restarts_to_go; /* MCUs left in this restart interval */ - int next_restart_num; /* next restart number to write (0-7) */ - - /* Pointers to derived tables (these workspaces have image lifespan). - * Since any one scan codes only DC or only AC, we only need one set - * of tables, not one for DC and one for AC. - */ - c_derived_tbl * derived_tbls[NUM_HUFF_TBLS]; - - /* Statistics tables for optimization; again, one set is enough */ - long * count_ptrs[NUM_HUFF_TBLS]; -} phuff_entropy_encoder; - -typedef phuff_entropy_encoder * phuff_entropy_ptr; - -/* MAX_CORR_BITS is the number of bits the AC refinement correction-bit - * buffer can hold. Larger sizes may slightly improve compression, but - * 1000 is already well into the realm of overkill. - * The minimum safe size is 64 bits. - */ - -#define MAX_CORR_BITS 1000 /* Max # of correction bits I can buffer */ - -/* IRIGHT_SHIFT is like RIGHT_SHIFT, but works on int rather than INT32. - * We assume that int right shift is unsigned if INT32 right shift is, - * which should be safe. - */ - -#ifdef RIGHT_SHIFT_IS_UNSIGNED -#define ISHIFT_TEMPS int ishift_temp; -#define IRIGHT_SHIFT(x,shft) \ - ((ishift_temp = (x)) < 0 ? \ - (ishift_temp >> (shft)) | ((~0) << (16-(shft))) : \ - (ishift_temp >> (shft))) -#else -#define ISHIFT_TEMPS -#define IRIGHT_SHIFT(x,shft) ((x) >> (shft)) -#endif - -/* Forward declarations */ -METHODDEF boolean encode_mcu_DC_first JPP((j_compress_ptr cinfo, - JBLOCKROW *MCU_data)); -METHODDEF boolean encode_mcu_AC_first JPP((j_compress_ptr cinfo, - JBLOCKROW *MCU_data)); -METHODDEF boolean encode_mcu_DC_refine JPP((j_compress_ptr cinfo, - JBLOCKROW *MCU_data)); -METHODDEF boolean encode_mcu_AC_refine JPP((j_compress_ptr cinfo, - JBLOCKROW *MCU_data)); -METHODDEF void finish_pass_phuff JPP((j_compress_ptr cinfo)); -METHODDEF void finish_pass_gather_phuff JPP((j_compress_ptr cinfo)); - - -/* - * Initialize for a Huffman-compressed scan using progressive JPEG. - */ - -METHODDEF void -start_pass_phuff (j_compress_ptr cinfo, boolean gather_statistics) -{ - phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy; - boolean is_DC_band; - int ci, tbl; - jpeg_component_info * compptr; - - entropy->cinfo = cinfo; - entropy->gather_statistics = gather_statistics; - - is_DC_band = (cinfo->Ss == 0); - - /* We assume jcmaster.c already validated the scan parameters. */ - - /* Select execution routines */ - if (cinfo->Ah == 0) { - if (is_DC_band) - entropy->pub.encode_mcu = encode_mcu_DC_first; - else - entropy->pub.encode_mcu = encode_mcu_AC_first; - } else { - if (is_DC_band) - entropy->pub.encode_mcu = encode_mcu_DC_refine; - else { - entropy->pub.encode_mcu = encode_mcu_AC_refine; - /* AC refinement needs a correction bit buffer */ - if (entropy->bit_buffer == NULL) - entropy->bit_buffer = (char *) - (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, - MAX_CORR_BITS * SIZEOF(char)); - } - } - if (gather_statistics) - entropy->pub.finish_pass = finish_pass_gather_phuff; - else - entropy->pub.finish_pass = finish_pass_phuff; - - /* Only DC coefficients may be interleaved, so cinfo->comps_in_scan = 1 - * for AC coefficients. - */ - for (ci = 0; ci < cinfo->comps_in_scan; ci++) { - compptr = cinfo->cur_comp_info[ci]; - /* Initialize DC predictions to 0 */ - entropy->last_dc_val[ci] = 0; - /* Make sure requested tables are present */ - /* (In gather mode, tables need not be allocated yet) */ - if (is_DC_band) { - if (cinfo->Ah != 0) /* DC refinement needs no table */ - continue; - tbl = compptr->dc_tbl_no; - if (tbl < 0 || tbl >= NUM_HUFF_TBLS || - (cinfo->dc_huff_tbl_ptrs[tbl] == NULL && !gather_statistics)) - ERREXIT1(cinfo,JERR_NO_HUFF_TABLE, tbl); - } else { - entropy->ac_tbl_no = tbl = compptr->ac_tbl_no; - if (tbl < 0 || tbl >= NUM_HUFF_TBLS || - (cinfo->ac_huff_tbl_ptrs[tbl] == NULL && !gather_statistics)) - ERREXIT1(cinfo,JERR_NO_HUFF_TABLE, tbl); - } - if (gather_statistics) { - /* Allocate and zero the statistics tables */ - /* Note that jpeg_gen_optimal_table expects 257 entries in each table! */ - if (entropy->count_ptrs[tbl] == NULL) - entropy->count_ptrs[tbl] = (long *) - (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, - 257 * SIZEOF(long)); - MEMZERO(entropy->count_ptrs[tbl], 257 * SIZEOF(long)); - } else { - /* Compute derived values for Huffman tables */ - /* We may do this more than once for a table, but it's not expensive */ - if (is_DC_band) - jpeg_make_c_derived_tbl(cinfo, cinfo->dc_huff_tbl_ptrs[tbl], - & entropy->derived_tbls[tbl]); - else - jpeg_make_c_derived_tbl(cinfo, cinfo->ac_huff_tbl_ptrs[tbl], - & entropy->derived_tbls[tbl]); - } - } - - /* Initialize AC stuff */ - entropy->EOBRUN = 0; - entropy->BE = 0; - - /* Initialize bit buffer to empty */ - entropy->put_buffer = 0; - entropy->put_bits = 0; - - /* Initialize restart stuff */ - entropy->restarts_to_go = cinfo->restart_interval; - entropy->next_restart_num = 0; -} - - -/* Outputting bytes to the file. - * NB: these must be called only when actually outputting, - * that is, entropy->gather_statistics == FALSE. - */ - -/* Emit a byte */ -#define emit_byte(entropy,val) \ - { *(entropy)->next_output_byte++ = (JOCTET) (val); \ - if (--(entropy)->free_in_buffer == 0) \ - dump_buffer(entropy); } - - -LOCAL void -dump_buffer (phuff_entropy_ptr entropy) -/* Empty the output buffer; we do not support suspension in this module. */ -{ - struct jpeg_destination_mgr * dest = entropy->cinfo->dest; - - if (! (*dest->empty_output_buffer) (entropy->cinfo)) - ERREXIT(entropy->cinfo, JERR_CANT_SUSPEND); - /* After a successful buffer dump, must reset buffer pointers */ - entropy->next_output_byte = dest->next_output_byte; - entropy->free_in_buffer = dest->free_in_buffer; -} - - -/* Outputting bits to the file */ - -/* Only the right 24 bits of put_buffer are used; the valid bits are - * left-justified in this part. At most 16 bits can be passed to emit_bits - * in one call, and we never retain more than 7 bits in put_buffer - * between calls, so 24 bits are sufficient. - */ - -INLINE -LOCAL void -emit_bits (phuff_entropy_ptr entropy, unsigned int code, int size) -/* Emit some bits, unless we are in gather mode */ -{ - /* This routine is heavily used, so it's worth coding tightly. */ - register INT32 put_buffer = (INT32) code; - register int put_bits = entropy->put_bits; - - /* if size is 0, caller used an invalid Huffman table entry */ - if (size == 0) - ERREXIT(entropy->cinfo, JERR_HUFF_MISSING_CODE); - - if (entropy->gather_statistics) - return; /* do nothing if we're only getting stats */ - - put_buffer &= (((INT32) 1)<put_buffer; /* and merge with old buffer contents */ - - while (put_bits >= 8) { - int c = (int) ((put_buffer >> 16) & 0xFF); - - emit_byte(entropy, c); - if (c == 0xFF) { /* need to stuff a zero byte? */ - emit_byte(entropy, 0); - } - put_buffer <<= 8; - put_bits -= 8; - } - - entropy->put_buffer = put_buffer; /* update variables */ - entropy->put_bits = put_bits; -} - - -LOCAL void -flush_bits (phuff_entropy_ptr entropy) -{ - emit_bits(entropy, 0x7F, 7); /* fill any partial byte with ones */ - entropy->put_buffer = 0; /* and reset bit-buffer to empty */ - entropy->put_bits = 0; -} - - -/* - * Emit (or just count) a Huffman symbol. - */ - -INLINE -LOCAL void -emit_symbol (phuff_entropy_ptr entropy, int tbl_no, int symbol) -{ - if (entropy->gather_statistics) - entropy->count_ptrs[tbl_no][symbol]++; - else { - c_derived_tbl * tbl = entropy->derived_tbls[tbl_no]; - emit_bits(entropy, tbl->ehufco[symbol], tbl->ehufsi[symbol]); - } -} - - -/* - * Emit bits from a correction bit buffer. - */ - -LOCAL void -emit_buffered_bits (phuff_entropy_ptr entropy, char * bufstart, - unsigned int nbits) -{ - if (entropy->gather_statistics) - return; /* no real work */ - - while (nbits > 0) { - emit_bits(entropy, (unsigned int) (*bufstart), 1); - bufstart++; - nbits--; - } -} - - -/* - * Emit any pending EOBRUN symbol. - */ - -LOCAL void -emit_eobrun (phuff_entropy_ptr entropy) -{ - register int temp, nbits; - - if (entropy->EOBRUN > 0) { /* if there is any pending EOBRUN */ - temp = entropy->EOBRUN; - nbits = 0; - while ((temp >>= 1)) - nbits++; - - emit_symbol(entropy, entropy->ac_tbl_no, nbits << 4); - if (nbits) - emit_bits(entropy, entropy->EOBRUN, nbits); - - entropy->EOBRUN = 0; - - /* Emit any buffered correction bits */ - emit_buffered_bits(entropy, entropy->bit_buffer, entropy->BE); - entropy->BE = 0; - } -} - - -/* - * Emit a restart marker & resynchronize predictions. - */ - -LOCAL void -emit_restart (phuff_entropy_ptr entropy, int restart_num) -{ - int ci; - - emit_eobrun(entropy); - - if (! entropy->gather_statistics) { - flush_bits(entropy); - emit_byte(entropy, 0xFF); - emit_byte(entropy, JPEG_RST0 + restart_num); - } - - if (entropy->cinfo->Ss == 0) { - /* Re-initialize DC predictions to 0 */ - for (ci = 0; ci < entropy->cinfo->comps_in_scan; ci++) - entropy->last_dc_val[ci] = 0; - } else { - /* Re-initialize all AC-related fields to 0 */ - entropy->EOBRUN = 0; - entropy->BE = 0; - } -} - - -/* - * MCU encoding for DC initial scan (either spectral selection, - * or first pass of successive approximation). - */ - -METHODDEF boolean -encode_mcu_DC_first (j_compress_ptr cinfo, JBLOCKROW *MCU_data) -{ - phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy; - register int temp, temp2; - register int nbits; - int blkn, ci; - int Al = cinfo->Al; - JBLOCKROW block; - jpeg_component_info * compptr; - ISHIFT_TEMPS - - entropy->next_output_byte = cinfo->dest->next_output_byte; - entropy->free_in_buffer = cinfo->dest->free_in_buffer; - - /* Emit restart marker if needed */ - if (cinfo->restart_interval) - if (entropy->restarts_to_go == 0) - emit_restart(entropy, entropy->next_restart_num); - - /* Encode the MCU data blocks */ - for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) { - block = MCU_data[blkn]; - ci = cinfo->MCU_membership[blkn]; - compptr = cinfo->cur_comp_info[ci]; - - /* Compute the DC value after the required point transform by Al. - * This is simply an arithmetic right shift. - */ - temp2 = IRIGHT_SHIFT((int) ((*block)[0]), Al); - - /* DC differences are figured on the point-transformed values. */ - temp = temp2 - entropy->last_dc_val[ci]; - entropy->last_dc_val[ci] = temp2; - - /* Encode the DC coefficient difference per section G.1.2.1 */ - temp2 = temp; - if (temp < 0) { - temp = -temp; /* temp is abs value of input */ - /* For a negative input, want temp2 = bitwise complement of abs(input) */ - /* This code assumes we are on a two's complement machine */ - temp2--; - } - - /* Find the number of bits needed for the magnitude of the coefficient */ - nbits = 0; - while (temp) { - nbits++; - temp >>= 1; - } - - /* Count/emit the Huffman-coded symbol for the number of bits */ - emit_symbol(entropy, compptr->dc_tbl_no, nbits); - - /* Emit that number of bits of the value, if positive, */ - /* or the complement of its magnitude, if negative. */ - if (nbits) /* emit_bits rejects calls with size 0 */ - emit_bits(entropy, (unsigned int) temp2, nbits); - } - - cinfo->dest->next_output_byte = entropy->next_output_byte; - cinfo->dest->free_in_buffer = entropy->free_in_buffer; - - /* Update restart-interval state too */ - if (cinfo->restart_interval) { - if (entropy->restarts_to_go == 0) { - entropy->restarts_to_go = cinfo->restart_interval; - entropy->next_restart_num++; - entropy->next_restart_num &= 7; - } - entropy->restarts_to_go--; - } - - return TRUE; -} - - -/* - * MCU encoding for AC initial scan (either spectral selection, - * or first pass of successive approximation). - */ - -METHODDEF boolean -encode_mcu_AC_first (j_compress_ptr cinfo, JBLOCKROW *MCU_data) -{ - phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy; - register int temp, temp2; - register int nbits; - register int r, k; - int Se = cinfo->Se; - int Al = cinfo->Al; - JBLOCKROW block; - - entropy->next_output_byte = cinfo->dest->next_output_byte; - entropy->free_in_buffer = cinfo->dest->free_in_buffer; - - /* Emit restart marker if needed */ - if (cinfo->restart_interval) - if (entropy->restarts_to_go == 0) - emit_restart(entropy, entropy->next_restart_num); - - /* Encode the MCU data block */ - block = MCU_data[0]; - - /* Encode the AC coefficients per section G.1.2.2, fig. G.3 */ - - r = 0; /* r = run length of zeros */ - - for (k = cinfo->Ss; k <= Se; k++) { - if ((temp = (*block)[jpeg_natural_order[k]]) == 0) { - r++; - continue; - } - /* We must apply the point transform by Al. For AC coefficients this - * is an integer division with rounding towards 0. To do this portably - * in C, we shift after obtaining the absolute value; so the code is - * interwoven with finding the abs value (temp) and output bits (temp2). - */ - if (temp < 0) { - temp = -temp; /* temp is abs value of input */ - temp >>= Al; /* apply the point transform */ - /* For a negative coef, want temp2 = bitwise complement of abs(coef) */ - temp2 = ~temp; - } else { - temp >>= Al; /* apply the point transform */ - temp2 = temp; - } - /* Watch out for case that nonzero coef is zero after point transform */ - if (temp == 0) { - r++; - continue; - } - - /* Emit any pending EOBRUN */ - if (entropy->EOBRUN > 0) - emit_eobrun(entropy); - /* if run length > 15, must emit special run-length-16 codes (0xF0) */ - while (r > 15) { - emit_symbol(entropy, entropy->ac_tbl_no, 0xF0); - r -= 16; - } - - /* Find the number of bits needed for the magnitude of the coefficient */ - nbits = 1; /* there must be at least one 1 bit */ - while ((temp >>= 1)) - nbits++; - - /* Count/emit Huffman symbol for run length / number of bits */ - emit_symbol(entropy, entropy->ac_tbl_no, (r << 4) + nbits); - - /* Emit that number of bits of the value, if positive, */ - /* or the complement of its magnitude, if negative. */ - emit_bits(entropy, (unsigned int) temp2, nbits); - - r = 0; /* reset zero run length */ - } - - if (r > 0) { /* If there are trailing zeroes, */ - entropy->EOBRUN++; /* count an EOB */ - if (entropy->EOBRUN == 0x7FFF) - emit_eobrun(entropy); /* force it out to avoid overflow */ - } - - cinfo->dest->next_output_byte = entropy->next_output_byte; - cinfo->dest->free_in_buffer = entropy->free_in_buffer; - - /* Update restart-interval state too */ - if (cinfo->restart_interval) { - if (entropy->restarts_to_go == 0) { - entropy->restarts_to_go = cinfo->restart_interval; - entropy->next_restart_num++; - entropy->next_restart_num &= 7; - } - entropy->restarts_to_go--; - } - - return TRUE; -} - - -/* - * MCU encoding for DC successive approximation refinement scan. - * Note: we assume such scans can be multi-component, although the spec - * is not very clear on the point. - */ - -METHODDEF boolean -encode_mcu_DC_refine (j_compress_ptr cinfo, JBLOCKROW *MCU_data) -{ - phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy; - register int temp; - int blkn; - int Al = cinfo->Al; - JBLOCKROW block; - - entropy->next_output_byte = cinfo->dest->next_output_byte; - entropy->free_in_buffer = cinfo->dest->free_in_buffer; - - /* Emit restart marker if needed */ - if (cinfo->restart_interval) - if (entropy->restarts_to_go == 0) - emit_restart(entropy, entropy->next_restart_num); - - /* Encode the MCU data blocks */ - for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) { - block = MCU_data[blkn]; - - /* We simply emit the Al'th bit of the DC coefficient value. */ - temp = (*block)[0]; - emit_bits(entropy, (unsigned int) (temp >> Al), 1); - } - - cinfo->dest->next_output_byte = entropy->next_output_byte; - cinfo->dest->free_in_buffer = entropy->free_in_buffer; - - /* Update restart-interval state too */ - if (cinfo->restart_interval) { - if (entropy->restarts_to_go == 0) { - entropy->restarts_to_go = cinfo->restart_interval; - entropy->next_restart_num++; - entropy->next_restart_num &= 7; - } - entropy->restarts_to_go--; - } - - return TRUE; -} - - -/* - * MCU encoding for AC successive approximation refinement scan. - */ - -METHODDEF boolean -encode_mcu_AC_refine (j_compress_ptr cinfo, JBLOCKROW *MCU_data) -{ - phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy; - register int temp; - register int r, k; - int EOB; - char *BR_buffer; - unsigned int BR; - int Se = cinfo->Se; - int Al = cinfo->Al; - JBLOCKROW block; - int absvalues[DCTSIZE2]; - - entropy->next_output_byte = cinfo->dest->next_output_byte; - entropy->free_in_buffer = cinfo->dest->free_in_buffer; - - /* Emit restart marker if needed */ - if (cinfo->restart_interval) - if (entropy->restarts_to_go == 0) - emit_restart(entropy, entropy->next_restart_num); - - /* Encode the MCU data block */ - block = MCU_data[0]; - - /* It is convenient to make a pre-pass to determine the transformed - * coefficients' absolute values and the EOB position. - */ - EOB = 0; - for (k = cinfo->Ss; k <= Se; k++) { - temp = (*block)[jpeg_natural_order[k]]; - /* We must apply the point transform by Al. For AC coefficients this - * is an integer division with rounding towards 0. To do this portably - * in C, we shift after obtaining the absolute value. - */ - if (temp < 0) - temp = -temp; /* temp is abs value of input */ - temp >>= Al; /* apply the point transform */ - absvalues[k] = temp; /* save abs value for main pass */ - if (temp == 1) - EOB = k; /* EOB = index of last newly-nonzero coef */ - } - - /* Encode the AC coefficients per section G.1.2.3, fig. G.7 */ - - r = 0; /* r = run length of zeros */ - BR = 0; /* BR = count of buffered bits added now */ - BR_buffer = entropy->bit_buffer + entropy->BE; /* Append bits to buffer */ - - for (k = cinfo->Ss; k <= Se; k++) { - if ((temp = absvalues[k]) == 0) { - r++; - continue; - } - - /* Emit any required ZRLs, but not if they can be folded into EOB */ - while (r > 15 && k <= EOB) { - /* emit any pending EOBRUN and the BE correction bits */ - emit_eobrun(entropy); - /* Emit ZRL */ - emit_symbol(entropy, entropy->ac_tbl_no, 0xF0); - r -= 16; - /* Emit buffered correction bits that must be associated with ZRL */ - emit_buffered_bits(entropy, BR_buffer, BR); - BR_buffer = entropy->bit_buffer; /* BE bits are gone now */ - BR = 0; - } - - /* If the coef was previously nonzero, it only needs a correction bit. - * NOTE: a straight translation of the spec's figure G.7 would suggest - * that we also need to test r > 15. But if r > 15, we can only get here - * if k > EOB, which implies that this coefficient is not 1. - */ - if (temp > 1) { - /* The correction bit is the next bit of the absolute value. */ - BR_buffer[BR++] = (char) (temp & 1); - continue; - } - - /* Emit any pending EOBRUN and the BE correction bits */ - emit_eobrun(entropy); - - /* Count/emit Huffman symbol for run length / number of bits */ - emit_symbol(entropy, entropy->ac_tbl_no, (r << 4) + 1); - - /* Emit output bit for newly-nonzero coef */ - temp = ((*block)[jpeg_natural_order[k]] < 0) ? 0 : 1; - emit_bits(entropy, (unsigned int) temp, 1); - - /* Emit buffered correction bits that must be associated with this code */ - emit_buffered_bits(entropy, BR_buffer, BR); - BR_buffer = entropy->bit_buffer; /* BE bits are gone now */ - BR = 0; - r = 0; /* reset zero run length */ - } - - if (r > 0 || BR > 0) { /* If there are trailing zeroes, */ - entropy->EOBRUN++; /* count an EOB */ - entropy->BE += BR; /* concat my correction bits to older ones */ - /* We force out the EOB if we risk either: - * 1. overflow of the EOB counter; - * 2. overflow of the correction bit buffer during the next MCU. - */ - if (entropy->EOBRUN == 0x7FFF || entropy->BE > (MAX_CORR_BITS-DCTSIZE2+1)) - emit_eobrun(entropy); - } - - cinfo->dest->next_output_byte = entropy->next_output_byte; - cinfo->dest->free_in_buffer = entropy->free_in_buffer; - - /* Update restart-interval state too */ - if (cinfo->restart_interval) { - if (entropy->restarts_to_go == 0) { - entropy->restarts_to_go = cinfo->restart_interval; - entropy->next_restart_num++; - entropy->next_restart_num &= 7; - } - entropy->restarts_to_go--; - } - - return TRUE; -} - - -/* - * Finish up at the end of a Huffman-compressed progressive scan. - */ - -METHODDEF void -finish_pass_phuff (j_compress_ptr cinfo) -{ - phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy; - - entropy->next_output_byte = cinfo->dest->next_output_byte; - entropy->free_in_buffer = cinfo->dest->free_in_buffer; - - /* Flush out any buffered data */ - emit_eobrun(entropy); - flush_bits(entropy); - - cinfo->dest->next_output_byte = entropy->next_output_byte; - cinfo->dest->free_in_buffer = entropy->free_in_buffer; -} - - -/* - * Finish up a statistics-gathering pass and create the new Huffman tables. - */ - -METHODDEF void -finish_pass_gather_phuff (j_compress_ptr cinfo) -{ - phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy; - boolean is_DC_band; - int ci, tbl; - jpeg_component_info * compptr; - JHUFF_TBL **htblptr; - boolean did[NUM_HUFF_TBLS]; - - /* Flush out buffered data (all we care about is counting the EOB symbol) */ - emit_eobrun(entropy); - - is_DC_band = (cinfo->Ss == 0); - - /* It's important not to apply jpeg_gen_optimal_table more than once - * per table, because it clobbers the input frequency counts! - */ - MEMZERO(did, SIZEOF(did)); - - for (ci = 0; ci < cinfo->comps_in_scan; ci++) { - compptr = cinfo->cur_comp_info[ci]; - if (is_DC_band) { - if (cinfo->Ah != 0) /* DC refinement needs no table */ - continue; - tbl = compptr->dc_tbl_no; - } else { - tbl = compptr->ac_tbl_no; - } - if (! did[tbl]) { - if (is_DC_band) - htblptr = & cinfo->dc_huff_tbl_ptrs[tbl]; - else - htblptr = & cinfo->ac_huff_tbl_ptrs[tbl]; - if (*htblptr == NULL) - *htblptr = jpeg_alloc_huff_table((j_common_ptr) cinfo); - jpeg_gen_optimal_table(cinfo, *htblptr, entropy->count_ptrs[tbl]); - did[tbl] = TRUE; - } - } -} - - -/* - * Module initialization routine for progressive Huffman entropy encoding. - */ - -GLOBAL void -jinit_phuff_encoder (j_compress_ptr cinfo) -{ - phuff_entropy_ptr entropy; - int i; - - entropy = (phuff_entropy_ptr) - (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, - SIZEOF(phuff_entropy_encoder)); - cinfo->entropy = (struct jpeg_entropy_encoder *) entropy; - entropy->pub.start_pass = start_pass_phuff; - - /* Mark tables unallocated */ - for (i = 0; i < NUM_HUFF_TBLS; i++) { - entropy->derived_tbls[i] = NULL; - entropy->count_ptrs[i] = NULL; - } - entropy->bit_buffer = NULL; /* needed only in AC refinement scan */ -} - -#endif /* C_PROGRESSIVE_SUPPORTED */ diff --git a/engine/jpeg-6/jcprepct.c b/engine/jpeg-6/jcprepct.c deleted file mode 100644 index 7e60946..0000000 --- a/engine/jpeg-6/jcprepct.c +++ /dev/null @@ -1,371 +0,0 @@ -/* - * jcprepct.c - * - * Copyright (C) 1994, Thomas G. Lane. - * This file is part of the Independent JPEG Group's software. - * For conditions of distribution and use, see the accompanying README file. - * - * This file contains the compression preprocessing controller. - * This controller manages the color conversion, downsampling, - * and edge expansion steps. - * - * Most of the complexity here is associated with buffering input rows - * as required by the downsampler. See the comments at the head of - * jcsample.c for the downsampler's needs. - */ - -#define JPEG_INTERNALS -#include "jinclude.h" -#include "jpeglib.h" - - -/* At present, jcsample.c can request context rows only for smoothing. - * In the future, we might also need context rows for CCIR601 sampling - * or other more-complex downsampling procedures. The code to support - * context rows should be compiled only if needed. - */ -#ifdef INPUT_SMOOTHING_SUPPORTED -#define CONTEXT_ROWS_SUPPORTED -#endif - - -/* - * For the simple (no-context-row) case, we just need to buffer one - * row group's worth of pixels for the downsampling step. At the bottom of - * the image, we pad to a full row group by replicating the last pixel row. - * The downsampler's last output row is then replicated if needed to pad - * out to a full iMCU row. - * - * When providing context rows, we must buffer three row groups' worth of - * pixels. Three row groups are physically allocated, but the row pointer - * arrays are made five row groups high, with the extra pointers above and - * below "wrapping around" to point to the last and first real row groups. - * This allows the downsampler to access the proper context rows. - * At the top and bottom of the image, we create dummy context rows by - * copying the first or last real pixel row. This copying could be avoided - * by pointer hacking as is done in jdmainct.c, but it doesn't seem worth the - * trouble on the compression side. - */ - - -/* Private buffer controller object */ - -typedef struct { - struct jpeg_c_prep_controller pub; /* public fields */ - - /* Downsampling input buffer. This buffer holds color-converted data - * until we have enough to do a downsample step. - */ - JSAMPARRAY color_buf[MAX_COMPONENTS]; - - JDIMENSION rows_to_go; /* counts rows remaining in source image */ - int next_buf_row; /* index of next row to store in color_buf */ - -#ifdef CONTEXT_ROWS_SUPPORTED /* only needed for context case */ - int this_row_group; /* starting row index of group to process */ - int next_buf_stop; /* downsample when we reach this index */ -#endif -} my_prep_controller; - -typedef my_prep_controller * my_prep_ptr; - - -/* - * Initialize for a processing pass. - */ - -METHODDEF void -start_pass_prep (j_compress_ptr cinfo, J_BUF_MODE pass_mode) -{ - my_prep_ptr prep = (my_prep_ptr) cinfo->prep; - - if (pass_mode != JBUF_PASS_THRU) - ERREXIT(cinfo, JERR_BAD_BUFFER_MODE); - - /* Initialize total-height counter for detecting bottom of image */ - prep->rows_to_go = cinfo->image_height; - /* Mark the conversion buffer empty */ - prep->next_buf_row = 0; -#ifdef CONTEXT_ROWS_SUPPORTED - /* Preset additional state variables for context mode. - * These aren't used in non-context mode, so we needn't test which mode. - */ - prep->this_row_group = 0; - /* Set next_buf_stop to stop after two row groups have been read in. */ - prep->next_buf_stop = 2 * cinfo->max_v_samp_factor; -#endif -} - - -/* - * Expand an image vertically from height input_rows to height output_rows, - * by duplicating the bottom row. - */ - -LOCAL void -expand_bottom_edge (JSAMPARRAY image_data, JDIMENSION num_cols, - int input_rows, int output_rows) -{ - register int row; - - for (row = input_rows; row < output_rows; row++) { - jcopy_sample_rows(image_data, input_rows-1, image_data, row, - 1, num_cols); - } -} - - -/* - * Process some data in the simple no-context case. - * - * Preprocessor output data is counted in "row groups". A row group - * is defined to be v_samp_factor sample rows of each component. - * Downsampling will produce this much data from each max_v_samp_factor - * input rows. - */ - -METHODDEF void -pre_process_data (j_compress_ptr cinfo, - JSAMPARRAY input_buf, JDIMENSION *in_row_ctr, - JDIMENSION in_rows_avail, - JSAMPIMAGE output_buf, JDIMENSION *out_row_group_ctr, - JDIMENSION out_row_groups_avail) -{ - my_prep_ptr prep = (my_prep_ptr) cinfo->prep; - int numrows, ci; - JDIMENSION inrows; - jpeg_component_info * compptr; - - while (*in_row_ctr < in_rows_avail && - *out_row_group_ctr < out_row_groups_avail) { - /* Do color conversion to fill the conversion buffer. */ - inrows = in_rows_avail - *in_row_ctr; - numrows = cinfo->max_v_samp_factor - prep->next_buf_row; - numrows = (int) MIN((JDIMENSION) numrows, inrows); - (*cinfo->cconvert->color_convert) (cinfo, input_buf + *in_row_ctr, - prep->color_buf, - (JDIMENSION) prep->next_buf_row, - numrows); - *in_row_ctr += numrows; - prep->next_buf_row += numrows; - prep->rows_to_go -= numrows; - /* If at bottom of image, pad to fill the conversion buffer. */ - if (prep->rows_to_go == 0 && - prep->next_buf_row < cinfo->max_v_samp_factor) { - for (ci = 0; ci < cinfo->num_components; ci++) { - expand_bottom_edge(prep->color_buf[ci], cinfo->image_width, - prep->next_buf_row, cinfo->max_v_samp_factor); - } - prep->next_buf_row = cinfo->max_v_samp_factor; - } - /* If we've filled the conversion buffer, empty it. */ - if (prep->next_buf_row == cinfo->max_v_samp_factor) { - (*cinfo->downsample->downsample) (cinfo, - prep->color_buf, (JDIMENSION) 0, - output_buf, *out_row_group_ctr); - prep->next_buf_row = 0; - (*out_row_group_ctr)++; - } - /* If at bottom of image, pad the output to a full iMCU height. - * Note we assume the caller is providing a one-iMCU-height output buffer! - */ - if (prep->rows_to_go == 0 && - *out_row_group_ctr < out_row_groups_avail) { - for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; - ci++, compptr++) { - expand_bottom_edge(output_buf[ci], - compptr->width_in_blocks * DCTSIZE, - (int) (*out_row_group_ctr * compptr->v_samp_factor), - (int) (out_row_groups_avail * compptr->v_samp_factor)); - } - *out_row_group_ctr = out_row_groups_avail; - break; /* can exit outer loop without test */ - } - } -} - - -#ifdef CONTEXT_ROWS_SUPPORTED - -/* - * Process some data in the context case. - */ - -METHODDEF void -pre_process_context (j_compress_ptr cinfo, - JSAMPARRAY input_buf, JDIMENSION *in_row_ctr, - JDIMENSION in_rows_avail, - JSAMPIMAGE output_buf, JDIMENSION *out_row_group_ctr, - JDIMENSION out_row_groups_avail) -{ - my_prep_ptr prep = (my_prep_ptr) cinfo->prep; - int numrows, ci; - int buf_height = cinfo->max_v_samp_factor * 3; - JDIMENSION inrows; - jpeg_component_info * compptr; - - while (*out_row_group_ctr < out_row_groups_avail) { - if (*in_row_ctr < in_rows_avail) { - /* Do color conversion to fill the conversion buffer. */ - inrows = in_rows_avail - *in_row_ctr; - numrows = prep->next_buf_stop - prep->next_buf_row; - numrows = (int) MIN((JDIMENSION) numrows, inrows); - (*cinfo->cconvert->color_convert) (cinfo, input_buf + *in_row_ctr, - prep->color_buf, - (JDIMENSION) prep->next_buf_row, - numrows); - /* Pad at top of image, if first time through */ - if (prep->rows_to_go == cinfo->image_height) { - for (ci = 0; ci < cinfo->num_components; ci++) { - int row; - for (row = 1; row <= cinfo->max_v_samp_factor; row++) { - jcopy_sample_rows(prep->color_buf[ci], 0, - prep->color_buf[ci], -row, - 1, cinfo->image_width); - } - } - } - *in_row_ctr += numrows; - prep->next_buf_row += numrows; - prep->rows_to_go -= numrows; - } else { - /* Return for more data, unless we are at the bottom of the image. */ - if (prep->rows_to_go != 0) - break; - } - /* If at bottom of image, pad to fill the conversion buffer. */ - if (prep->rows_to_go == 0 && - prep->next_buf_row < prep->next_buf_stop) { - for (ci = 0; ci < cinfo->num_components; ci++) { - expand_bottom_edge(prep->color_buf[ci], cinfo->image_width, - prep->next_buf_row, prep->next_buf_stop); - } - prep->next_buf_row = prep->next_buf_stop; - } - /* If we've gotten enough data, downsample a row group. */ - if (prep->next_buf_row == prep->next_buf_stop) { - (*cinfo->downsample->downsample) (cinfo, - prep->color_buf, - (JDIMENSION) prep->this_row_group, - output_buf, *out_row_group_ctr); - (*out_row_group_ctr)++; - /* Advance pointers with wraparound as necessary. */ - prep->this_row_group += cinfo->max_v_samp_factor; - if (prep->this_row_group >= buf_height) - prep->this_row_group = 0; - if (prep->next_buf_row >= buf_height) - prep->next_buf_row = 0; - prep->next_buf_stop = prep->next_buf_row + cinfo->max_v_samp_factor; - } - /* If at bottom of image, pad the output to a full iMCU height. - * Note we assume the caller is providing a one-iMCU-height output buffer! - */ - if (prep->rows_to_go == 0 && - *out_row_group_ctr < out_row_groups_avail) { - for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; - ci++, compptr++) { - expand_bottom_edge(output_buf[ci], - compptr->width_in_blocks * DCTSIZE, - (int) (*out_row_group_ctr * compptr->v_samp_factor), - (int) (out_row_groups_avail * compptr->v_samp_factor)); - } - *out_row_group_ctr = out_row_groups_avail; - break; /* can exit outer loop without test */ - } - } -} - - -/* - * Create the wrapped-around downsampling input buffer needed for context mode. - */ - -LOCAL void -create_context_buffer (j_compress_ptr cinfo) -{ - my_prep_ptr prep = (my_prep_ptr) cinfo->prep; - int rgroup_height = cinfo->max_v_samp_factor; - int ci, i; - jpeg_component_info * compptr; - JSAMPARRAY true_buffer, fake_buffer; - - /* Grab enough space for fake row pointers for all the components; - * we need five row groups' worth of pointers for each component. - */ - fake_buffer = (JSAMPARRAY) - (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, - (cinfo->num_components * 5 * rgroup_height) * - SIZEOF(JSAMPROW)); - - for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; - ci++, compptr++) { - /* Allocate the actual buffer space (3 row groups) for this component. - * We make the buffer wide enough to allow the downsampler to edge-expand - * horizontally within the buffer, if it so chooses. - */ - true_buffer = (*cinfo->mem->alloc_sarray) - ((j_common_ptr) cinfo, JPOOL_IMAGE, - (JDIMENSION) (((long) compptr->width_in_blocks * DCTSIZE * - cinfo->max_h_samp_factor) / compptr->h_samp_factor), - (JDIMENSION) (3 * rgroup_height)); - /* Copy true buffer row pointers into the middle of the fake row array */ - MEMCOPY(fake_buffer + rgroup_height, true_buffer, - 3 * rgroup_height * SIZEOF(JSAMPROW)); - /* Fill in the above and below wraparound pointers */ - for (i = 0; i < rgroup_height; i++) { - fake_buffer[i] = true_buffer[2 * rgroup_height + i]; - fake_buffer[4 * rgroup_height + i] = true_buffer[i]; - } - prep->color_buf[ci] = fake_buffer + rgroup_height; - fake_buffer += 5 * rgroup_height; /* point to space for next component */ - } -} - -#endif /* CONTEXT_ROWS_SUPPORTED */ - - -/* - * Initialize preprocessing controller. - */ - -GLOBAL void -jinit_c_prep_controller (j_compress_ptr cinfo, boolean need_full_buffer) -{ - my_prep_ptr prep; - int ci; - jpeg_component_info * compptr; - - if (need_full_buffer) /* safety check */ - ERREXIT(cinfo, JERR_BAD_BUFFER_MODE); - - prep = (my_prep_ptr) - (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, - SIZEOF(my_prep_controller)); - cinfo->prep = (struct jpeg_c_prep_controller *) prep; - prep->pub.start_pass = start_pass_prep; - - /* Allocate the color conversion buffer. - * We make the buffer wide enough to allow the downsampler to edge-expand - * horizontally within the buffer, if it so chooses. - */ - if (cinfo->downsample->need_context_rows) { - /* Set up to provide context rows */ -#ifdef CONTEXT_ROWS_SUPPORTED - prep->pub.pre_process_data = pre_process_context; - create_context_buffer(cinfo); -#else - ERREXIT(cinfo, JERR_NOT_COMPILED); -#endif - } else { - /* No context, just make it tall enough for one row group */ - prep->pub.pre_process_data = pre_process_data; - for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; - ci++, compptr++) { - prep->color_buf[ci] = (*cinfo->mem->alloc_sarray) - ((j_common_ptr) cinfo, JPOOL_IMAGE, - (JDIMENSION) (((long) compptr->width_in_blocks * DCTSIZE * - cinfo->max_h_samp_factor) / compptr->h_samp_factor), - (JDIMENSION) cinfo->max_v_samp_factor); - } - } -} diff --git a/engine/jpeg-6/jcsample.c b/engine/jpeg-6/jcsample.c deleted file mode 100644 index bf0fb46..0000000 --- a/engine/jpeg-6/jcsample.c +++ /dev/null @@ -1,519 +0,0 @@ -/* - * jcsample.c - * - * Copyright (C) 1991-1994, Thomas G. Lane. - * This file is part of the Independent JPEG Group's software. - * For conditions of distribution and use, see the accompanying README file. - * - * This file contains downsampling routines. - * - * Downsampling input data is counted in "row groups". A row group - * is defined to be max_v_samp_factor pixel rows of each component, - * from which the downsampler produces v_samp_factor sample rows. - * A single row group is processed in each call to the downsampler module. - * - * The downsampler is responsible for edge-expansion of its output data - * to fill an integral number of DCT blocks horizontally. The source buffer - * may be modified if it is helpful for this purpose (the source buffer is - * allocated wide enough to correspond to the desired output width). - * The caller (the prep controller) is responsible for vertical padding. - * - * The downsampler may request "context rows" by setting need_context_rows - * during startup. In this case, the input arrays will contain at least - * one row group's worth of pixels above and below the passed-in data; - * the caller will create dummy rows at image top and bottom by replicating - * the first or last real pixel row. - * - * An excellent reference for image resampling is - * Digital Image Warping, George Wolberg, 1990. - * Pub. by IEEE Computer Society Press, Los Alamitos, CA. ISBN 0-8186-8944-7. - * - * The downsampling algorithm used here is a simple average of the source - * pixels covered by the output pixel. The hi-falutin sampling literature - * refers to this as a "box filter". In general the characteristics of a box - * filter are not very good, but for the specific cases we normally use (1:1 - * and 2:1 ratios) the box is equivalent to a "triangle filter" which is not - * nearly so bad. If you intend to use other sampling ratios, you'd be well - * advised to improve this code. - * - * A simple input-smoothing capability is provided. This is mainly intended - * for cleaning up color-dithered GIF input files (if you find it inadequate, - * we suggest using an external filtering program such as pnmconvol). When - * enabled, each input pixel P is replaced by a weighted sum of itself and its - * eight neighbors. P's weight is 1-8*SF and each neighbor's weight is SF, - * where SF = (smoothing_factor / 1024). - * Currently, smoothing is only supported for 2h2v sampling factors. - */ - -#define JPEG_INTERNALS -#include "jinclude.h" -#include "jpeglib.h" - - -/* Pointer to routine to downsample a single component */ -typedef JMETHOD(void, downsample1_ptr, - (j_compress_ptr cinfo, jpeg_component_info * compptr, - JSAMPARRAY input_data, JSAMPARRAY output_data)); - -/* Private subobject */ - -typedef struct { - struct jpeg_downsampler pub; /* public fields */ - - /* Downsampling method pointers, one per component */ - downsample1_ptr methods[MAX_COMPONENTS]; -} my_downsampler; - -typedef my_downsampler * my_downsample_ptr; - - -/* - * Initialize for a downsampling pass. - */ - -METHODDEF void -start_pass_downsample (j_compress_ptr cinfo) -{ - /* no work for now */ -} - - -/* - * Expand a component horizontally from width input_cols to width output_cols, - * by duplicating the rightmost samples. - */ - -LOCAL void -expand_right_edge (JSAMPARRAY image_data, int num_rows, - JDIMENSION input_cols, JDIMENSION output_cols) -{ - register JSAMPROW ptr; - register JSAMPLE pixval; - register int count; - int row; - int numcols = (int) (output_cols - input_cols); - - if (numcols > 0) { - for (row = 0; row < num_rows; row++) { - ptr = image_data[row] + input_cols; - pixval = ptr[-1]; /* don't need GETJSAMPLE() here */ - for (count = numcols; count > 0; count--) - *ptr++ = pixval; - } - } -} - - -/* - * Do downsampling for a whole row group (all components). - * - * In this version we simply downsample each component independently. - */ - -METHODDEF void -sep_downsample (j_compress_ptr cinfo, - JSAMPIMAGE input_buf, JDIMENSION in_row_index, - JSAMPIMAGE output_buf, JDIMENSION out_row_group_index) -{ - my_downsample_ptr downsample = (my_downsample_ptr) cinfo->downsample; - int ci; - jpeg_component_info * compptr; - JSAMPARRAY in_ptr, out_ptr; - - for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; - ci++, compptr++) { - in_ptr = input_buf[ci] + in_row_index; - out_ptr = output_buf[ci] + (out_row_group_index * compptr->v_samp_factor); - (*downsample->methods[ci]) (cinfo, compptr, in_ptr, out_ptr); - } -} - - -/* - * Downsample pixel values of a single component. - * One row group is processed per call. - * This version handles arbitrary integral sampling ratios, without smoothing. - * Note that this version is not actually used for customary sampling ratios. - */ - -METHODDEF void -int_downsample (j_compress_ptr cinfo, jpeg_component_info * compptr, - JSAMPARRAY input_data, JSAMPARRAY output_data) -{ - int inrow, outrow, h_expand, v_expand, numpix, numpix2, h, v; - JDIMENSION outcol, outcol_h; /* outcol_h == outcol*h_expand */ - JDIMENSION output_cols = compptr->width_in_blocks * DCTSIZE; - JSAMPROW inptr, outptr; - INT32 outvalue; - - h_expand = cinfo->max_h_samp_factor / compptr->h_samp_factor; - v_expand = cinfo->max_v_samp_factor / compptr->v_samp_factor; - numpix = h_expand * v_expand; - numpix2 = numpix/2; - - /* Expand input data enough to let all the output samples be generated - * by the standard loop. Special-casing padded output would be more - * efficient. - */ - expand_right_edge(input_data, cinfo->max_v_samp_factor, - cinfo->image_width, output_cols * h_expand); - - inrow = 0; - for (outrow = 0; outrow < compptr->v_samp_factor; outrow++) { - outptr = output_data[outrow]; - for (outcol = 0, outcol_h = 0; outcol < output_cols; - outcol++, outcol_h += h_expand) { - outvalue = 0; - for (v = 0; v < v_expand; v++) { - inptr = input_data[inrow+v] + outcol_h; - for (h = 0; h < h_expand; h++) { - outvalue += (INT32) GETJSAMPLE(*inptr++); - } - } - *outptr++ = (JSAMPLE) ((outvalue + numpix2) / numpix); - } - inrow += v_expand; - } -} - - -/* - * Downsample pixel values of a single component. - * This version handles the special case of a full-size component, - * without smoothing. - */ - -METHODDEF void -fullsize_downsample (j_compress_ptr cinfo, jpeg_component_info * compptr, - JSAMPARRAY input_data, JSAMPARRAY output_data) -{ - /* Copy the data */ - jcopy_sample_rows(input_data, 0, output_data, 0, - cinfo->max_v_samp_factor, cinfo->image_width); - /* Edge-expand */ - expand_right_edge(output_data, cinfo->max_v_samp_factor, - cinfo->image_width, compptr->width_in_blocks * DCTSIZE); -} - - -/* - * Downsample pixel values of a single component. - * This version handles the common case of 2:1 horizontal and 1:1 vertical, - * without smoothing. - * - * A note about the "bias" calculations: when rounding fractional values to - * integer, we do not want to always round 0.5 up to the next integer. - * If we did that, we'd introduce a noticeable bias towards larger values. - * Instead, this code is arranged so that 0.5 will be rounded up or down at - * alternate pixel locations (a simple ordered dither pattern). - */ - -METHODDEF void -h2v1_downsample (j_compress_ptr cinfo, jpeg_component_info * compptr, - JSAMPARRAY input_data, JSAMPARRAY output_data) -{ - int outrow; - JDIMENSION outcol; - JDIMENSION output_cols = compptr->width_in_blocks * DCTSIZE; - register JSAMPROW inptr, outptr; - register int bias; - - /* Expand input data enough to let all the output samples be generated - * by the standard loop. Special-casing padded output would be more - * efficient. - */ - expand_right_edge(input_data, cinfo->max_v_samp_factor, - cinfo->image_width, output_cols * 2); - - for (outrow = 0; outrow < compptr->v_samp_factor; outrow++) { - outptr = output_data[outrow]; - inptr = input_data[outrow]; - bias = 0; /* bias = 0,1,0,1,... for successive samples */ - for (outcol = 0; outcol < output_cols; outcol++) { - *outptr++ = (JSAMPLE) ((GETJSAMPLE(*inptr) + GETJSAMPLE(inptr[1]) - + bias) >> 1); - bias ^= 1; /* 0=>1, 1=>0 */ - inptr += 2; - } - } -} - - -/* - * Downsample pixel values of a single component. - * This version handles the standard case of 2:1 horizontal and 2:1 vertical, - * without smoothing. - */ - -METHODDEF void -h2v2_downsample (j_compress_ptr cinfo, jpeg_component_info * compptr, - JSAMPARRAY input_data, JSAMPARRAY output_data) -{ - int inrow, outrow; - JDIMENSION outcol; - JDIMENSION output_cols = compptr->width_in_blocks * DCTSIZE; - register JSAMPROW inptr0, inptr1, outptr; - register int bias; - - /* Expand input data enough to let all the output samples be generated - * by the standard loop. Special-casing padded output would be more - * efficient. - */ - expand_right_edge(input_data, cinfo->max_v_samp_factor, - cinfo->image_width, output_cols * 2); - - inrow = 0; - for (outrow = 0; outrow < compptr->v_samp_factor; outrow++) { - outptr = output_data[outrow]; - inptr0 = input_data[inrow]; - inptr1 = input_data[inrow+1]; - bias = 1; /* bias = 1,2,1,2,... for successive samples */ - for (outcol = 0; outcol < output_cols; outcol++) { - *outptr++ = (JSAMPLE) ((GETJSAMPLE(*inptr0) + GETJSAMPLE(inptr0[1]) + - GETJSAMPLE(*inptr1) + GETJSAMPLE(inptr1[1]) - + bias) >> 2); - bias ^= 3; /* 1=>2, 2=>1 */ - inptr0 += 2; inptr1 += 2; - } - inrow += 2; - } -} - - -#ifdef INPUT_SMOOTHING_SUPPORTED - -/* - * Downsample pixel values of a single component. - * This version handles the standard case of 2:1 horizontal and 2:1 vertical, - * with smoothing. One row of context is required. - */ - -METHODDEF void -h2v2_smooth_downsample (j_compress_ptr cinfo, jpeg_component_info * compptr, - JSAMPARRAY input_data, JSAMPARRAY output_data) -{ - int inrow, outrow; - JDIMENSION colctr; - JDIMENSION output_cols = compptr->width_in_blocks * DCTSIZE; - register JSAMPROW inptr0, inptr1, above_ptr, below_ptr, outptr; - INT32 membersum, neighsum, memberscale, neighscale; - - /* Expand input data enough to let all the output samples be generated - * by the standard loop. Special-casing padded output would be more - * efficient. - */ - expand_right_edge(input_data - 1, cinfo->max_v_samp_factor + 2, - cinfo->image_width, output_cols * 2); - - /* We don't bother to form the individual "smoothed" input pixel values; - * we can directly compute the output which is the average of the four - * smoothed values. Each of the four member pixels contributes a fraction - * (1-8*SF) to its own smoothed image and a fraction SF to each of the three - * other smoothed pixels, therefore a total fraction (1-5*SF)/4 to the final - * output. The four corner-adjacent neighbor pixels contribute a fraction - * SF to just one smoothed pixel, or SF/4 to the final output; while the - * eight edge-adjacent neighbors contribute SF to each of two smoothed - * pixels, or SF/2 overall. In order to use integer arithmetic, these - * factors are scaled by 2^16 = 65536. - * Also recall that SF = smoothing_factor / 1024. - */ - - memberscale = 16384 - cinfo->smoothing_factor * 80; /* scaled (1-5*SF)/4 */ - neighscale = cinfo->smoothing_factor * 16; /* scaled SF/4 */ - - inrow = 0; - for (outrow = 0; outrow < compptr->v_samp_factor; outrow++) { - outptr = output_data[outrow]; - inptr0 = input_data[inrow]; - inptr1 = input_data[inrow+1]; - above_ptr = input_data[inrow-1]; - below_ptr = input_data[inrow+2]; - - /* Special case for first column: pretend column -1 is same as column 0 */ - membersum = GETJSAMPLE(*inptr0) + GETJSAMPLE(inptr0[1]) + - GETJSAMPLE(*inptr1) + GETJSAMPLE(inptr1[1]); - neighsum = GETJSAMPLE(*above_ptr) + GETJSAMPLE(above_ptr[1]) + - GETJSAMPLE(*below_ptr) + GETJSAMPLE(below_ptr[1]) + - GETJSAMPLE(*inptr0) + GETJSAMPLE(inptr0[2]) + - GETJSAMPLE(*inptr1) + GETJSAMPLE(inptr1[2]); - neighsum += neighsum; - neighsum += GETJSAMPLE(*above_ptr) + GETJSAMPLE(above_ptr[2]) + - GETJSAMPLE(*below_ptr) + GETJSAMPLE(below_ptr[2]); - membersum = membersum * memberscale + neighsum * neighscale; - *outptr++ = (JSAMPLE) ((membersum + 32768) >> 16); - inptr0 += 2; inptr1 += 2; above_ptr += 2; below_ptr += 2; - - for (colctr = output_cols - 2; colctr > 0; colctr--) { - /* sum of pixels directly mapped to this output element */ - membersum = GETJSAMPLE(*inptr0) + GETJSAMPLE(inptr0[1]) + - GETJSAMPLE(*inptr1) + GETJSAMPLE(inptr1[1]); - /* sum of edge-neighbor pixels */ - neighsum = GETJSAMPLE(*above_ptr) + GETJSAMPLE(above_ptr[1]) + - GETJSAMPLE(*below_ptr) + GETJSAMPLE(below_ptr[1]) + - GETJSAMPLE(inptr0[-1]) + GETJSAMPLE(inptr0[2]) + - GETJSAMPLE(inptr1[-1]) + GETJSAMPLE(inptr1[2]); - /* The edge-neighbors count twice as much as corner-neighbors */ - neighsum += neighsum; - /* Add in the corner-neighbors */ - neighsum += GETJSAMPLE(above_ptr[-1]) + GETJSAMPLE(above_ptr[2]) + - GETJSAMPLE(below_ptr[-1]) + GETJSAMPLE(below_ptr[2]); - /* form final output scaled up by 2^16 */ - membersum = membersum * memberscale + neighsum * neighscale; - /* round, descale and output it */ - *outptr++ = (JSAMPLE) ((membersum + 32768) >> 16); - inptr0 += 2; inptr1 += 2; above_ptr += 2; below_ptr += 2; - } - - /* Special case for last column */ - membersum = GETJSAMPLE(*inptr0) + GETJSAMPLE(inptr0[1]) + - GETJSAMPLE(*inptr1) + GETJSAMPLE(inptr1[1]); - neighsum = GETJSAMPLE(*above_ptr) + GETJSAMPLE(above_ptr[1]) + - GETJSAMPLE(*below_ptr) + GETJSAMPLE(below_ptr[1]) + - GETJSAMPLE(inptr0[-1]) + GETJSAMPLE(inptr0[1]) + - GETJSAMPLE(inptr1[-1]) + GETJSAMPLE(inptr1[1]); - neighsum += neighsum; - neighsum += GETJSAMPLE(above_ptr[-1]) + GETJSAMPLE(above_ptr[1]) + - GETJSAMPLE(below_ptr[-1]) + GETJSAMPLE(below_ptr[1]); - membersum = membersum * memberscale + neighsum * neighscale; - *outptr = (JSAMPLE) ((membersum + 32768) >> 16); - - inrow += 2; - } -} - - -/* - * Downsample pixel values of a single component. - * This version handles the special case of a full-size component, - * with smoothing. One row of context is required. - */ - -METHODDEF void -fullsize_smooth_downsample (j_compress_ptr cinfo, jpeg_component_info *compptr, - JSAMPARRAY input_data, JSAMPARRAY output_data) -{ - int outrow; - JDIMENSION colctr; - JDIMENSION output_cols = compptr->width_in_blocks * DCTSIZE; - register JSAMPROW inptr, above_ptr, below_ptr, outptr; - INT32 membersum, neighsum, memberscale, neighscale; - int colsum, lastcolsum, nextcolsum; - - /* Expand input data enough to let all the output samples be generated - * by the standard loop. Special-casing padded output would be more - * efficient. - */ - expand_right_edge(input_data - 1, cinfo->max_v_samp_factor + 2, - cinfo->image_width, output_cols); - - /* Each of the eight neighbor pixels contributes a fraction SF to the - * smoothed pixel, while the main pixel contributes (1-8*SF). In order - * to use integer arithmetic, these factors are multiplied by 2^16 = 65536. - * Also recall that SF = smoothing_factor / 1024. - */ - - memberscale = 65536L - cinfo->smoothing_factor * 512L; /* scaled 1-8*SF */ - neighscale = cinfo->smoothing_factor * 64; /* scaled SF */ - - for (outrow = 0; outrow < compptr->v_samp_factor; outrow++) { - outptr = output_data[outrow]; - inptr = input_data[outrow]; - above_ptr = input_data[outrow-1]; - below_ptr = input_data[outrow+1]; - - /* Special case for first column */ - colsum = GETJSAMPLE(*above_ptr++) + GETJSAMPLE(*below_ptr++) + - GETJSAMPLE(*inptr); - membersum = GETJSAMPLE(*inptr++); - nextcolsum = GETJSAMPLE(*above_ptr) + GETJSAMPLE(*below_ptr) + - GETJSAMPLE(*inptr); - neighsum = colsum + (colsum - membersum) + nextcolsum; - membersum = membersum * memberscale + neighsum * neighscale; - *outptr++ = (JSAMPLE) ((membersum + 32768) >> 16); - lastcolsum = colsum; colsum = nextcolsum; - - for (colctr = output_cols - 2; colctr > 0; colctr--) { - membersum = GETJSAMPLE(*inptr++); - above_ptr++; below_ptr++; - nextcolsum = GETJSAMPLE(*above_ptr) + GETJSAMPLE(*below_ptr) + - GETJSAMPLE(*inptr); - neighsum = lastcolsum + (colsum - membersum) + nextcolsum; - membersum = membersum * memberscale + neighsum * neighscale; - *outptr++ = (JSAMPLE) ((membersum + 32768) >> 16); - lastcolsum = colsum; colsum = nextcolsum; - } - - /* Special case for last column */ - membersum = GETJSAMPLE(*inptr); - neighsum = lastcolsum + (colsum - membersum) + colsum; - membersum = membersum * memberscale + neighsum * neighscale; - *outptr = (JSAMPLE) ((membersum + 32768) >> 16); - - } -} - -#endif /* INPUT_SMOOTHING_SUPPORTED */ - - -/* - * Module initialization routine for downsampling. - * Note that we must select a routine for each component. - */ - -GLOBAL void -jinit_downsampler (j_compress_ptr cinfo) -{ - my_downsample_ptr downsample; - int ci; - jpeg_component_info * compptr; - boolean smoothok = TRUE; - - downsample = (my_downsample_ptr) - (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, - SIZEOF(my_downsampler)); - cinfo->downsample = (struct jpeg_downsampler *) downsample; - downsample->pub.start_pass = start_pass_downsample; - downsample->pub.downsample = sep_downsample; - downsample->pub.need_context_rows = FALSE; - - if (cinfo->CCIR601_sampling) - ERREXIT(cinfo, JERR_CCIR601_NOTIMPL); - - /* Verify we can handle the sampling factors, and set up method pointers */ - for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; - ci++, compptr++) { - if (compptr->h_samp_factor == cinfo->max_h_samp_factor && - compptr->v_samp_factor == cinfo->max_v_samp_factor) { -#ifdef INPUT_SMOOTHING_SUPPORTED - if (cinfo->smoothing_factor) { - downsample->methods[ci] = fullsize_smooth_downsample; - downsample->pub.need_context_rows = TRUE; - } else -#endif - downsample->methods[ci] = fullsize_downsample; - } else if (compptr->h_samp_factor * 2 == cinfo->max_h_samp_factor && - compptr->v_samp_factor == cinfo->max_v_samp_factor) { - smoothok = FALSE; - downsample->methods[ci] = h2v1_downsample; - } else if (compptr->h_samp_factor * 2 == cinfo->max_h_samp_factor && - compptr->v_samp_factor * 2 == cinfo->max_v_samp_factor) { -#ifdef INPUT_SMOOTHING_SUPPORTED - if (cinfo->smoothing_factor) { - downsample->methods[ci] = h2v2_smooth_downsample; - downsample->pub.need_context_rows = TRUE; - } else -#endif - downsample->methods[ci] = h2v2_downsample; - } else if ((cinfo->max_h_samp_factor % compptr->h_samp_factor) == 0 && - (cinfo->max_v_samp_factor % compptr->v_samp_factor) == 0) { - smoothok = FALSE; - downsample->methods[ci] = int_downsample; - } else - ERREXIT(cinfo, JERR_FRACT_SAMPLE_NOTIMPL); - } - -#ifdef INPUT_SMOOTHING_SUPPORTED - if (cinfo->smoothing_factor && !smoothok) - TRACEMS(cinfo, 0, JTRC_SMOOTH_NOTIMPL); -#endif -} diff --git a/engine/jpeg-6/jctrans.c b/engine/jpeg-6/jctrans.c deleted file mode 100644 index 8fc53b1..0000000 --- a/engine/jpeg-6/jctrans.c +++ /dev/null @@ -1,371 +0,0 @@ -/* - * jctrans.c - * - * Copyright (C) 1995, Thomas G. Lane. - * This file is part of the Independent JPEG Group's software. - * For conditions of distribution and use, see the accompanying README file. - * - * This file contains library routines for transcoding compression, - * that is, writing raw DCT coefficient arrays to an output JPEG file. - * The routines in jcapimin.c will also be needed by a transcoder. - */ - -#define JPEG_INTERNALS -#include "jinclude.h" -#include "jpeglib.h" - - -/* Forward declarations */ -LOCAL void transencode_master_selection - JPP((j_compress_ptr cinfo, jvirt_barray_ptr * coef_arrays)); -LOCAL void transencode_coef_controller - JPP((j_compress_ptr cinfo, jvirt_barray_ptr * coef_arrays)); - - -/* - * Compression initialization for writing raw-coefficient data. - * Before calling this, all parameters and a data destination must be set up. - * Call jpeg_finish_compress() to actually write the data. - * - * The number of passed virtual arrays must match cinfo->num_components. - * Note that the virtual arrays need not be filled or even realized at - * the time write_coefficients is called; indeed, if the virtual arrays - * were requested from this compression object's memory manager, they - * typically will be realized during this routine and filled afterwards. - */ - -GLOBAL void -jpeg_write_coefficients (j_compress_ptr cinfo, jvirt_barray_ptr * coef_arrays) -{ - if (cinfo->global_state != CSTATE_START) - ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); - /* Mark all tables to be written */ - jpeg_suppress_tables(cinfo, FALSE); - /* (Re)initialize error mgr and destination modules */ - (*cinfo->err->reset_error_mgr) ((j_common_ptr) cinfo); - (*cinfo->dest->init_destination) (cinfo); - /* Perform master selection of active modules */ - transencode_master_selection(cinfo, coef_arrays); - /* Wait for jpeg_finish_compress() call */ - cinfo->next_scanline = 0; /* so jpeg_write_marker works */ - cinfo->global_state = CSTATE_WRCOEFS; -} - - -/* - * Initialize the compression object with default parameters, - * then copy from the source object all parameters needed for lossless - * transcoding. Parameters that can be varied without loss (such as - * scan script and Huffman optimization) are left in their default states. - */ - -GLOBAL void -jpeg_copy_critical_parameters (j_decompress_ptr srcinfo, - j_compress_ptr dstinfo) -{ - JQUANT_TBL ** qtblptr; - jpeg_component_info *incomp, *outcomp; - JQUANT_TBL *c_quant, *slot_quant; - int tblno, ci, coefi; - - /* Safety check to ensure start_compress not called yet. */ - if (dstinfo->global_state != CSTATE_START) - ERREXIT1(dstinfo, JERR_BAD_STATE, dstinfo->global_state); - /* Copy fundamental image dimensions */ - dstinfo->image_width = srcinfo->image_width; - dstinfo->image_height = srcinfo->image_height; - dstinfo->input_components = srcinfo->num_components; - dstinfo->in_color_space = srcinfo->jpeg_color_space; - /* Initialize all parameters to default values */ - jpeg_set_defaults(dstinfo); - /* jpeg_set_defaults may choose wrong colorspace, eg YCbCr if input is RGB. - * Fix it to get the right header markers for the image colorspace. - */ - jpeg_set_colorspace(dstinfo, srcinfo->jpeg_color_space); - dstinfo->data_precision = srcinfo->data_precision; - dstinfo->CCIR601_sampling = srcinfo->CCIR601_sampling; - /* Copy the source's quantization tables. */ - for (tblno = 0; tblno < NUM_QUANT_TBLS; tblno++) { - if (srcinfo->quant_tbl_ptrs[tblno] != NULL) { - qtblptr = & dstinfo->quant_tbl_ptrs[tblno]; - if (*qtblptr == NULL) - *qtblptr = jpeg_alloc_quant_table((j_common_ptr) dstinfo); - MEMCOPY((*qtblptr)->quantval, - srcinfo->quant_tbl_ptrs[tblno]->quantval, - SIZEOF((*qtblptr)->quantval)); - (*qtblptr)->sent_table = FALSE; - } - } - /* Copy the source's per-component info. - * Note we assume jpeg_set_defaults has allocated the dest comp_info array. - */ - dstinfo->num_components = srcinfo->num_components; - if (dstinfo->num_components < 1 || dstinfo->num_components > MAX_COMPONENTS) - ERREXIT2(dstinfo, JERR_COMPONENT_COUNT, dstinfo->num_components, - MAX_COMPONENTS); - for (ci = 0, incomp = srcinfo->comp_info, outcomp = dstinfo->comp_info; - ci < dstinfo->num_components; ci++, incomp++, outcomp++) { - outcomp->component_id = incomp->component_id; - outcomp->h_samp_factor = incomp->h_samp_factor; - outcomp->v_samp_factor = incomp->v_samp_factor; - outcomp->quant_tbl_no = incomp->quant_tbl_no; - /* Make sure saved quantization table for component matches the qtable - * slot. If not, the input file re-used this qtable slot. - * IJG encoder currently cannot duplicate this. - */ - tblno = outcomp->quant_tbl_no; - if (tblno < 0 || tblno >= NUM_QUANT_TBLS || - srcinfo->quant_tbl_ptrs[tblno] == NULL) - ERREXIT1(dstinfo, JERR_NO_QUANT_TABLE, tblno); - slot_quant = srcinfo->quant_tbl_ptrs[tblno]; - c_quant = incomp->quant_table; - if (c_quant != NULL) { - for (coefi = 0; coefi < DCTSIZE2; coefi++) { - if (c_quant->quantval[coefi] != slot_quant->quantval[coefi]) - ERREXIT1(dstinfo, JERR_MISMATCHED_QUANT_TABLE, tblno); - } - } - /* Note: we do not copy the source's Huffman table assignments; - * instead we rely on jpeg_set_colorspace to have made a suitable choice. - */ - } -} - - -/* - * Master selection of compression modules for transcoding. - * This substitutes for jcinit.c's initialization of the full compressor. - */ - -LOCAL void -transencode_master_selection (j_compress_ptr cinfo, - jvirt_barray_ptr * coef_arrays) -{ - /* Although we don't actually use input_components for transcoding, - * jcmaster.c's initial_setup will complain if input_components is 0. - */ - cinfo->input_components = 1; - /* Initialize master control (includes parameter checking/processing) */ - jinit_c_master_control(cinfo, TRUE /* transcode only */); - - /* Entropy encoding: either Huffman or arithmetic coding. */ - if (cinfo->arith_code) { - ERREXIT(cinfo, JERR_ARITH_NOTIMPL); - } else { - if (cinfo->progressive_mode) { -#ifdef C_PROGRESSIVE_SUPPORTED - jinit_phuff_encoder(cinfo); -#else - ERREXIT(cinfo, JERR_NOT_COMPILED); -#endif - } else - jinit_huff_encoder(cinfo); - } - - /* We need a special coefficient buffer controller. */ - transencode_coef_controller(cinfo, coef_arrays); - - jinit_marker_writer(cinfo); - - /* We can now tell the memory manager to allocate virtual arrays. */ - (*cinfo->mem->realize_virt_arrays) ((j_common_ptr) cinfo); - - /* Write the datastream header (SOI) immediately. - * Frame and scan headers are postponed till later. - * This lets application insert special markers after the SOI. - */ - (*cinfo->marker->write_file_header) (cinfo); -} - - -/* - * The rest of this file is a special implementation of the coefficient - * buffer controller. This is similar to jccoefct.c, but it handles only - * output from presupplied virtual arrays. Furthermore, we generate any - * dummy padding blocks on-the-fly rather than expecting them to be present - * in the arrays. - */ - -/* Private buffer controller object */ - -typedef struct { - struct jpeg_c_coef_controller pub; /* public fields */ - - JDIMENSION iMCU_row_num; /* iMCU row # within image */ - JDIMENSION mcu_ctr; /* counts MCUs processed in current row */ - int MCU_vert_offset; /* counts MCU rows within iMCU row */ - int MCU_rows_per_iMCU_row; /* number of such rows needed */ - - /* Virtual block array for each component. */ - jvirt_barray_ptr * whole_image; - - /* Workspace for constructing dummy blocks at right/bottom edges. */ - JBLOCKROW dummy_buffer[C_MAX_BLOCKS_IN_MCU]; -} my_coef_controller; - -typedef my_coef_controller * my_coef_ptr; - - -LOCAL void -start_iMCU_row (j_compress_ptr cinfo) -/* Reset within-iMCU-row counters for a new row */ -{ - my_coef_ptr coef = (my_coef_ptr) cinfo->coef; - - /* In an interleaved scan, an MCU row is the same as an iMCU row. - * In a noninterleaved scan, an iMCU row has v_samp_factor MCU rows. - * But at the bottom of the image, process only what's left. - */ - if (cinfo->comps_in_scan > 1) { - coef->MCU_rows_per_iMCU_row = 1; - } else { - if (coef->iMCU_row_num < (cinfo->total_iMCU_rows-1)) - coef->MCU_rows_per_iMCU_row = cinfo->cur_comp_info[0]->v_samp_factor; - else - coef->MCU_rows_per_iMCU_row = cinfo->cur_comp_info[0]->last_row_height; - } - - coef->mcu_ctr = 0; - coef->MCU_vert_offset = 0; -} - - -/* - * Initialize for a processing pass. - */ - -METHODDEF void -start_pass_coef (j_compress_ptr cinfo, J_BUF_MODE pass_mode) -{ - my_coef_ptr coef = (my_coef_ptr) cinfo->coef; - - if (pass_mode != JBUF_CRANK_DEST) - ERREXIT(cinfo, JERR_BAD_BUFFER_MODE); - - coef->iMCU_row_num = 0; - start_iMCU_row(cinfo); -} - - -/* - * Process some data. - * We process the equivalent of one fully interleaved MCU row ("iMCU" row) - * per call, ie, v_samp_factor block rows for each component in the scan. - * The data is obtained from the virtual arrays and fed to the entropy coder. - * Returns TRUE if the iMCU row is completed, FALSE if suspended. - * - * NB: input_buf is ignored; it is likely to be a NULL pointer. - */ - -METHODDEF boolean -compress_output (j_compress_ptr cinfo, JSAMPIMAGE input_buf) -{ - my_coef_ptr coef = (my_coef_ptr) cinfo->coef; - JDIMENSION MCU_col_num; /* index of current MCU within row */ - JDIMENSION last_MCU_col = cinfo->MCUs_per_row - 1; - JDIMENSION last_iMCU_row = cinfo->total_iMCU_rows - 1; - int blkn, ci, xindex, yindex, yoffset, blockcnt; - JDIMENSION start_col; - JBLOCKARRAY buffer[MAX_COMPS_IN_SCAN]; - JBLOCKROW MCU_buffer[C_MAX_BLOCKS_IN_MCU]; - JBLOCKROW buffer_ptr; - jpeg_component_info *compptr; - - /* Align the virtual buffers for the components used in this scan. */ - for (ci = 0; ci < cinfo->comps_in_scan; ci++) { - compptr = cinfo->cur_comp_info[ci]; - buffer[ci] = (*cinfo->mem->access_virt_barray) - ((j_common_ptr) cinfo, coef->whole_image[compptr->component_index], - coef->iMCU_row_num * compptr->v_samp_factor, - (JDIMENSION) compptr->v_samp_factor, FALSE); - } - - /* Loop to process one whole iMCU row */ - for (yoffset = coef->MCU_vert_offset; yoffset < coef->MCU_rows_per_iMCU_row; - yoffset++) { - for (MCU_col_num = coef->mcu_ctr; MCU_col_num < cinfo->MCUs_per_row; - MCU_col_num++) { - /* Construct list of pointers to DCT blocks belonging to this MCU */ - blkn = 0; /* index of current DCT block within MCU */ - for (ci = 0; ci < cinfo->comps_in_scan; ci++) { - compptr = cinfo->cur_comp_info[ci]; - start_col = MCU_col_num * compptr->MCU_width; - blockcnt = (MCU_col_num < last_MCU_col) ? compptr->MCU_width - : compptr->last_col_width; - for (yindex = 0; yindex < compptr->MCU_height; yindex++) { - if (coef->iMCU_row_num < last_iMCU_row || - yindex+yoffset < compptr->last_row_height) { - /* Fill in pointers to real blocks in this row */ - buffer_ptr = buffer[ci][yindex+yoffset] + start_col; - for (xindex = 0; xindex < blockcnt; xindex++) - MCU_buffer[blkn++] = buffer_ptr++; - } else { - /* At bottom of image, need a whole row of dummy blocks */ - xindex = 0; - } - /* Fill in any dummy blocks needed in this row. - * Dummy blocks are filled in the same way as in jccoefct.c: - * all zeroes in the AC entries, DC entries equal to previous - * block's DC value. The init routine has already zeroed the - * AC entries, so we need only set the DC entries correctly. - */ - for (; xindex < compptr->MCU_width; xindex++) { - MCU_buffer[blkn] = coef->dummy_buffer[blkn]; - MCU_buffer[blkn][0][0] = MCU_buffer[blkn-1][0][0]; - blkn++; - } - } - } - /* Try to write the MCU. */ - if (! (*cinfo->entropy->encode_mcu) (cinfo, MCU_buffer)) { - /* Suspension forced; update state counters and exit */ - coef->MCU_vert_offset = yoffset; - coef->mcu_ctr = MCU_col_num; - return FALSE; - } - } - /* Completed an MCU row, but perhaps not an iMCU row */ - coef->mcu_ctr = 0; - } - /* Completed the iMCU row, advance counters for next one */ - coef->iMCU_row_num++; - start_iMCU_row(cinfo); - return TRUE; -} - - -/* - * Initialize coefficient buffer controller. - * - * Each passed coefficient array must be the right size for that - * coefficient: width_in_blocks wide and height_in_blocks high, - * with unitheight at least v_samp_factor. - */ - -LOCAL void -transencode_coef_controller (j_compress_ptr cinfo, - jvirt_barray_ptr * coef_arrays) -{ - my_coef_ptr coef; - JBLOCKROW buffer; - int i; - - coef = (my_coef_ptr) - (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, - SIZEOF(my_coef_controller)); - cinfo->coef = (struct jpeg_c_coef_controller *) coef; - coef->pub.start_pass = start_pass_coef; - coef->pub.compress_data = compress_output; - - /* Save pointer to virtual arrays */ - coef->whole_image = coef_arrays; - - /* Allocate and pre-zero space for dummy DCT blocks. */ - buffer = (JBLOCKROW) - (*cinfo->mem->alloc_large) ((j_common_ptr) cinfo, JPOOL_IMAGE, - C_MAX_BLOCKS_IN_MCU * SIZEOF(JBLOCK)); - jzero_far((void FAR *) buffer, C_MAX_BLOCKS_IN_MCU * SIZEOF(JBLOCK)); - for (i = 0; i < C_MAX_BLOCKS_IN_MCU; i++) { - coef->dummy_buffer[i] = buffer + i; - } -} diff --git a/engine/jpeg-6/jdapimin.c b/engine/jpeg-6/jdapimin.c deleted file mode 100644 index d568187..0000000 --- a/engine/jpeg-6/jdapimin.c +++ /dev/null @@ -1,398 +0,0 @@ -/* - * jdapimin.c - * - * Copyright (C) 1994-1995, Thomas G. Lane. - * This file is part of the Independent JPEG Group's software. - * For conditions of distribution and use, see the accompanying README file. - * - * This file contains application interface code for the decompression half - * of the JPEG library. These are the "minimum" API routines that may be - * needed in either the normal full-decompression case or the - * transcoding-only case. - * - * Most of the routines intended to be called directly by an application - * are in this file or in jdapistd.c. But also see jcomapi.c for routines - * shared by compression and decompression, and jdtrans.c for the transcoding - * case. - */ - -#define JPEG_INTERNALS -#include "jinclude.h" -#include "jpeglib.h" - - -/* - * Initialization of a JPEG decompression object. - * The error manager must already be set up (in case memory manager fails). - */ - -GLOBAL void -jpeg_create_decompress (j_decompress_ptr cinfo) -{ - int i; - - /* For debugging purposes, zero the whole master structure. - * But error manager pointer is already there, so save and restore it. - */ - { - struct jpeg_error_mgr * err = cinfo->err; - MEMZERO(cinfo, SIZEOF(struct jpeg_decompress_struct)); - cinfo->err = err; - } - cinfo->is_decompressor = TRUE; - - /* Initialize a memory manager instance for this object */ - jinit_memory_mgr((j_common_ptr) cinfo); - - /* Zero out pointers to permanent structures. */ - cinfo->progress = NULL; - cinfo->src = NULL; - - for (i = 0; i < NUM_QUANT_TBLS; i++) - cinfo->quant_tbl_ptrs[i] = NULL; - - for (i = 0; i < NUM_HUFF_TBLS; i++) { - cinfo->dc_huff_tbl_ptrs[i] = NULL; - cinfo->ac_huff_tbl_ptrs[i] = NULL; - } - - /* Initialize marker processor so application can override methods - * for COM, APPn markers before calling jpeg_read_header. - */ - jinit_marker_reader(cinfo); - - /* And initialize the overall input controller. */ - jinit_input_controller(cinfo); - - /* OK, I'm ready */ - cinfo->global_state = DSTATE_START; -} - - -/* - * Destruction of a JPEG decompression object - */ - -GLOBAL void -jpeg_destroy_decompress (j_decompress_ptr cinfo) -{ - jpeg_destroy((j_common_ptr) cinfo); /* use common routine */ -} - - -/* - * Abort processing of a JPEG decompression operation, - * but don't destroy the object itself. - */ - -GLOBAL void -jpeg_abort_decompress (j_decompress_ptr cinfo) -{ - jpeg_abort((j_common_ptr) cinfo); /* use common routine */ -} - - -/* - * Install a special processing method for COM or APPn markers. - */ - -GLOBAL void -jpeg_set_marker_processor (j_decompress_ptr cinfo, int marker_code, - jpeg_marker_parser_method routine) -{ - if (marker_code == JPEG_COM) - cinfo->marker->process_COM = routine; - else if (marker_code >= JPEG_APP0 && marker_code <= JPEG_APP0+15) - cinfo->marker->process_APPn[marker_code-JPEG_APP0] = routine; - else - ERREXIT1(cinfo, JERR_UNKNOWN_MARKER, marker_code); -} - - -/* - * Set default decompression parameters. - */ - -LOCAL void -default_decompress_parms (j_decompress_ptr cinfo) -{ - /* Guess the input colorspace, and set output colorspace accordingly. */ - /* (Wish JPEG committee had provided a real way to specify this...) */ - /* Note application may override our guesses. */ - switch (cinfo->num_components) { - case 1: - cinfo->jpeg_color_space = JCS_GRAYSCALE; - cinfo->out_color_space = JCS_GRAYSCALE; - break; - - case 3: - if (cinfo->saw_JFIF_marker) { - cinfo->jpeg_color_space = JCS_YCbCr; /* JFIF implies YCbCr */ - } else if (cinfo->saw_Adobe_marker) { - switch (cinfo->Adobe_transform) { - case 0: - cinfo->jpeg_color_space = JCS_RGB; - break; - case 1: - cinfo->jpeg_color_space = JCS_YCbCr; - break; - default: - WARNMS1(cinfo, JWRN_ADOBE_XFORM, cinfo->Adobe_transform); - cinfo->jpeg_color_space = JCS_YCbCr; /* assume it's YCbCr */ - break; - } - } else { - /* Saw no special markers, try to guess from the component IDs */ - int cid0 = cinfo->comp_info[0].component_id; - int cid1 = cinfo->comp_info[1].component_id; - int cid2 = cinfo->comp_info[2].component_id; - - if (cid0 == 1 && cid1 == 2 && cid2 == 3) - cinfo->jpeg_color_space = JCS_YCbCr; /* assume JFIF w/out marker */ - else if (cid0 == 82 && cid1 == 71 && cid2 == 66) - cinfo->jpeg_color_space = JCS_RGB; /* ASCII 'R', 'G', 'B' */ - else { - TRACEMS3(cinfo, 1, JTRC_UNKNOWN_IDS, cid0, cid1, cid2); - cinfo->jpeg_color_space = JCS_YCbCr; /* assume it's YCbCr */ - } - } - /* Always guess RGB is proper output colorspace. */ - cinfo->out_color_space = JCS_RGB; - break; - - case 4: - if (cinfo->saw_Adobe_marker) { - switch (cinfo->Adobe_transform) { - case 0: - cinfo->jpeg_color_space = JCS_CMYK; - break; - case 2: - cinfo->jpeg_color_space = JCS_YCCK; - break; - default: - WARNMS1(cinfo, JWRN_ADOBE_XFORM, cinfo->Adobe_transform); - cinfo->jpeg_color_space = JCS_YCCK; /* assume it's YCCK */ - break; - } - } else { - /* No special markers, assume straight CMYK. */ - cinfo->jpeg_color_space = JCS_CMYK; - } - cinfo->out_color_space = JCS_CMYK; - break; - - default: - cinfo->jpeg_color_space = JCS_UNKNOWN; - cinfo->out_color_space = JCS_UNKNOWN; - break; - } - - /* Set defaults for other decompression parameters. */ - cinfo->scale_num = 1; /* 1:1 scaling */ - cinfo->scale_denom = 1; - cinfo->output_gamma = 1.0; - cinfo->buffered_image = FALSE; - cinfo->raw_data_out = FALSE; - cinfo->dct_method = JDCT_DEFAULT; - cinfo->do_fancy_upsampling = TRUE; - cinfo->do_block_smoothing = TRUE; - cinfo->quantize_colors = FALSE; - /* We set these in case application only sets quantize_colors. */ - cinfo->dither_mode = JDITHER_FS; -#ifdef QUANT_2PASS_SUPPORTED - cinfo->two_pass_quantize = TRUE; -#else - cinfo->two_pass_quantize = FALSE; -#endif - cinfo->desired_number_of_colors = 256; - cinfo->colormap = NULL; - /* Initialize for no mode change in buffered-image mode. */ - cinfo->enable_1pass_quant = FALSE; - cinfo->enable_external_quant = FALSE; - cinfo->enable_2pass_quant = FALSE; -} - - -/* - * Decompression startup: read start of JPEG datastream to see what's there. - * Need only initialize JPEG object and supply a data source before calling. - * - * This routine will read as far as the first SOS marker (ie, actual start of - * compressed data), and will save all tables and parameters in the JPEG - * object. It will also initialize the decompression parameters to default - * values, and finally return JPEG_HEADER_OK. On return, the application may - * adjust the decompression parameters and then call jpeg_start_decompress. - * (Or, if the application only wanted to determine the image parameters, - * the data need not be decompressed. In that case, call jpeg_abort or - * jpeg_destroy to release any temporary space.) - * If an abbreviated (tables only) datastream is presented, the routine will - * return JPEG_HEADER_TABLES_ONLY upon reaching EOI. The application may then - * re-use the JPEG object to read the abbreviated image datastream(s). - * It is unnecessary (but OK) to call jpeg_abort in this case. - * The JPEG_SUSPENDED return code only occurs if the data source module - * requests suspension of the decompressor. In this case the application - * should load more source data and then re-call jpeg_read_header to resume - * processing. - * If a non-suspending data source is used and require_image is TRUE, then the - * return code need not be inspected since only JPEG_HEADER_OK is possible. - * - * This routine is now just a front end to jpeg_consume_input, with some - * extra error checking. - */ - -GLOBAL int -jpeg_read_header (j_decompress_ptr cinfo, boolean require_image) -{ - int retcode; - - if (cinfo->global_state != DSTATE_START && - cinfo->global_state != DSTATE_INHEADER) - ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); - - retcode = jpeg_consume_input(cinfo); - - switch (retcode) { - case JPEG_REACHED_SOS: - retcode = JPEG_HEADER_OK; - break; - case JPEG_REACHED_EOI: - if (require_image) /* Complain if application wanted an image */ - ERREXIT(cinfo, JERR_NO_IMAGE); - /* Reset to start state; it would be safer to require the application to - * call jpeg_abort, but we can't change it now for compatibility reasons. - * A side effect is to free any temporary memory (there shouldn't be any). - */ - jpeg_abort((j_common_ptr) cinfo); /* sets state = DSTATE_START */ - retcode = JPEG_HEADER_TABLES_ONLY; - break; - case JPEG_SUSPENDED: - /* no work */ - break; - } - - return retcode; -} - - -/* - * Consume data in advance of what the decompressor requires. - * This can be called at any time once the decompressor object has - * been created and a data source has been set up. - * - * This routine is essentially a state machine that handles a couple - * of critical state-transition actions, namely initial setup and - * transition from header scanning to ready-for-start_decompress. - * All the actual input is done via the input controller's consume_input - * method. - */ - -GLOBAL int -jpeg_consume_input (j_decompress_ptr cinfo) -{ - int retcode = JPEG_SUSPENDED; - - /* NB: every possible DSTATE value should be listed in this switch */ - switch (cinfo->global_state) { - case DSTATE_START: - /* Start-of-datastream actions: reset appropriate modules */ - (*cinfo->inputctl->reset_input_controller) (cinfo); - /* Initialize application's data source module */ - (*cinfo->src->init_source) (cinfo); - cinfo->global_state = DSTATE_INHEADER; - /*FALLTHROUGH*/ - case DSTATE_INHEADER: - retcode = (*cinfo->inputctl->consume_input) (cinfo); - if (retcode == JPEG_REACHED_SOS) { /* Found SOS, prepare to decompress */ - /* Set up default parameters based on header data */ - default_decompress_parms(cinfo); - /* Set global state: ready for start_decompress */ - cinfo->global_state = DSTATE_READY; - } - break; - case DSTATE_READY: - /* Can't advance past first SOS until start_decompress is called */ - retcode = JPEG_REACHED_SOS; - break; - case DSTATE_PRELOAD: - case DSTATE_PRESCAN: - case DSTATE_SCANNING: - case DSTATE_RAW_OK: - case DSTATE_BUFIMAGE: - case DSTATE_BUFPOST: - case DSTATE_STOPPING: - retcode = (*cinfo->inputctl->consume_input) (cinfo); - break; - default: - ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); - } - return retcode; -} - - -/* - * Have we finished reading the input file? - */ - -GLOBAL boolean -jpeg_input_complete (j_decompress_ptr cinfo) -{ - /* Check for valid jpeg object */ - if (cinfo->global_state < DSTATE_START || - cinfo->global_state > DSTATE_STOPPING) - ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); - return cinfo->inputctl->eoi_reached; -} - - -/* - * Is there more than one scan? - */ - -GLOBAL boolean -jpeg_has_multiple_scans (j_decompress_ptr cinfo) -{ - /* Only valid after jpeg_read_header completes */ - if (cinfo->global_state < DSTATE_READY || - cinfo->global_state > DSTATE_STOPPING) - ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); - return cinfo->inputctl->has_multiple_scans; -} - - -/* - * Finish JPEG decompression. - * - * This will normally just verify the file trailer and release temp storage. - * - * Returns FALSE if suspended. The return value need be inspected only if - * a suspending data source is used. - */ - -GLOBAL boolean -jpeg_finish_decompress (j_decompress_ptr cinfo) -{ - if ((cinfo->global_state == DSTATE_SCANNING || - cinfo->global_state == DSTATE_RAW_OK) && ! cinfo->buffered_image) { - /* Terminate final pass of non-buffered mode */ - if (cinfo->output_scanline < cinfo->output_height) - ERREXIT(cinfo, JERR_TOO_LITTLE_DATA); - (*cinfo->master->finish_output_pass) (cinfo); - cinfo->global_state = DSTATE_STOPPING; - } else if (cinfo->global_state == DSTATE_BUFIMAGE) { - /* Finishing after a buffered-image operation */ - cinfo->global_state = DSTATE_STOPPING; - } else if (cinfo->global_state != DSTATE_STOPPING) { - /* STOPPING = repeat call after a suspension, anything else is error */ - ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); - } - /* Read until EOI */ - while (! cinfo->inputctl->eoi_reached) { - if ((*cinfo->inputctl->consume_input) (cinfo) == JPEG_SUSPENDED) - return FALSE; /* Suspend, come back later */ - } - /* Do final cleanup */ - (*cinfo->src->term_source) (cinfo); - /* We can use jpeg_abort to release memory and reset global_state */ - jpeg_abort((j_common_ptr) cinfo); - return TRUE; -} diff --git a/engine/jpeg-6/jdapistd.c b/engine/jpeg-6/jdapistd.c deleted file mode 100644 index e36f25c..0000000 --- a/engine/jpeg-6/jdapistd.c +++ /dev/null @@ -1,275 +0,0 @@ -/* - * jdapistd.c - * - * Copyright (C) 1994-1995, Thomas G. Lane. - * This file is part of the Independent JPEG Group's software. - * For conditions of distribution and use, see the accompanying README file. - * - * This file contains application interface code for the decompression half - * of the JPEG library. These are the "standard" API routines that are - * used in the normal full-decompression case. They are not used by a - * transcoding-only application. Note that if an application links in - * jpeg_start_decompress, it will end up linking in the entire decompressor. - * We thus must separate this file from jdapimin.c to avoid linking the - * whole decompression library into a transcoder. - */ - -#define JPEG_INTERNALS -#include "jinclude.h" -#include "jpeglib.h" - - -/* Forward declarations */ -LOCAL boolean output_pass_setup JPP((j_decompress_ptr cinfo)); - - -/* - * Decompression initialization. - * jpeg_read_header must be completed before calling this. - * - * If a multipass operating mode was selected, this will do all but the - * last pass, and thus may take a great deal of time. - * - * Returns FALSE if suspended. The return value need be inspected only if - * a suspending data source is used. - */ - -GLOBAL boolean -jpeg_start_decompress (j_decompress_ptr cinfo) -{ - if (cinfo->global_state == DSTATE_READY) { - /* First call: initialize master control, select active modules */ - jinit_master_decompress(cinfo); - if (cinfo->buffered_image) { - /* No more work here; expecting jpeg_start_output next */ - cinfo->global_state = DSTATE_BUFIMAGE; - return TRUE; - } - cinfo->global_state = DSTATE_PRELOAD; - } - if (cinfo->global_state == DSTATE_PRELOAD) { - /* If file has multiple scans, absorb them all into the coef buffer */ - if (cinfo->inputctl->has_multiple_scans) { -#ifdef D_MULTISCAN_FILES_SUPPORTED - for (;;) { - int retcode; - /* Call progress monitor hook if present */ - if (cinfo->progress != NULL) - (*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo); - /* Absorb some more input */ - retcode = (*cinfo->inputctl->consume_input) (cinfo); - if (retcode == JPEG_SUSPENDED) - return FALSE; - if (retcode == JPEG_REACHED_EOI) - break; - /* Advance progress counter if appropriate */ - if (cinfo->progress != NULL && - (retcode == JPEG_ROW_COMPLETED || retcode == JPEG_REACHED_SOS)) { - if (++cinfo->progress->pass_counter >= cinfo->progress->pass_limit) { - /* jdmaster underestimated number of scans; ratchet up one scan */ - cinfo->progress->pass_limit += (long) cinfo->total_iMCU_rows; - } - } - } -#else - ERREXIT(cinfo, JERR_NOT_COMPILED); -#endif /* D_MULTISCAN_FILES_SUPPORTED */ - } - cinfo->output_scan_number = cinfo->input_scan_number; - } else if (cinfo->global_state != DSTATE_PRESCAN) - ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); - /* Perform any dummy output passes, and set up for the final pass */ - return output_pass_setup(cinfo); -} - - -/* - * Set up for an output pass, and perform any dummy pass(es) needed. - * Common subroutine for jpeg_start_decompress and jpeg_start_output. - * Entry: global_state = DSTATE_PRESCAN only if previously suspended. - * Exit: If done, returns TRUE and sets global_state for proper output mode. - * If suspended, returns FALSE and sets global_state = DSTATE_PRESCAN. - */ - -LOCAL boolean -output_pass_setup (j_decompress_ptr cinfo) -{ - if (cinfo->global_state != DSTATE_PRESCAN) { - /* First call: do pass setup */ - (*cinfo->master->prepare_for_output_pass) (cinfo); - cinfo->output_scanline = 0; - cinfo->global_state = DSTATE_PRESCAN; - } - /* Loop over any required dummy passes */ - while (cinfo->master->is_dummy_pass) { -#ifdef QUANT_2PASS_SUPPORTED - /* Crank through the dummy pass */ - while (cinfo->output_scanline < cinfo->output_height) { - JDIMENSION last_scanline; - /* Call progress monitor hook if present */ - if (cinfo->progress != NULL) { - cinfo->progress->pass_counter = (long) cinfo->output_scanline; - cinfo->progress->pass_limit = (long) cinfo->output_height; - (*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo); - } - /* Process some data */ - last_scanline = cinfo->output_scanline; - (*cinfo->main->process_data) (cinfo, (JSAMPARRAY) NULL, - &cinfo->output_scanline, (JDIMENSION) 0); - if (cinfo->output_scanline == last_scanline) - return FALSE; /* No progress made, must suspend */ - } - /* Finish up dummy pass, and set up for another one */ - (*cinfo->master->finish_output_pass) (cinfo); - (*cinfo->master->prepare_for_output_pass) (cinfo); - cinfo->output_scanline = 0; -#else - ERREXIT(cinfo, JERR_NOT_COMPILED); -#endif /* QUANT_2PASS_SUPPORTED */ - } - /* Ready for application to drive output pass through - * jpeg_read_scanlines or jpeg_read_raw_data. - */ - cinfo->global_state = cinfo->raw_data_out ? DSTATE_RAW_OK : DSTATE_SCANNING; - return TRUE; -} - - -/* - * Read some scanlines of data from the JPEG decompressor. - * - * The return value will be the number of lines actually read. - * This may be less than the number requested in several cases, - * including bottom of image, data source suspension, and operating - * modes that emit multiple scanlines at a time. - * - * Note: we warn about excess calls to jpeg_read_scanlines() since - * this likely signals an application programmer error. However, - * an oversize buffer (max_lines > scanlines remaining) is not an error. - */ - -GLOBAL JDIMENSION -jpeg_read_scanlines (j_decompress_ptr cinfo, JSAMPARRAY scanlines, - JDIMENSION max_lines) -{ - JDIMENSION row_ctr; - - if (cinfo->global_state != DSTATE_SCANNING) - ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); - if (cinfo->output_scanline >= cinfo->output_height) { - WARNMS(cinfo, JWRN_TOO_MUCH_DATA); - return 0; - } - - /* Call progress monitor hook if present */ - if (cinfo->progress != NULL) { - cinfo->progress->pass_counter = (long) cinfo->output_scanline; - cinfo->progress->pass_limit = (long) cinfo->output_height; - (*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo); - } - - /* Process some data */ - row_ctr = 0; - (*cinfo->main->process_data) (cinfo, scanlines, &row_ctr, max_lines); - cinfo->output_scanline += row_ctr; - return row_ctr; -} - - -/* - * Alternate entry point to read raw data. - * Processes exactly one iMCU row per call, unless suspended. - */ - -GLOBAL JDIMENSION -jpeg_read_raw_data (j_decompress_ptr cinfo, JSAMPIMAGE data, - JDIMENSION max_lines) -{ - JDIMENSION lines_per_iMCU_row; - - if (cinfo->global_state != DSTATE_RAW_OK) - ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); - if (cinfo->output_scanline >= cinfo->output_height) { - WARNMS(cinfo, JWRN_TOO_MUCH_DATA); - return 0; - } - - /* Call progress monitor hook if present */ - if (cinfo->progress != NULL) { - cinfo->progress->pass_counter = (long) cinfo->output_scanline; - cinfo->progress->pass_limit = (long) cinfo->output_height; - (*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo); - } - - /* Verify that at least one iMCU row can be returned. */ - lines_per_iMCU_row = cinfo->max_v_samp_factor * cinfo->min_DCT_scaled_size; - if (max_lines < lines_per_iMCU_row) - ERREXIT(cinfo, JERR_BUFFER_SIZE); - - /* Decompress directly into user's buffer. */ - if (! (*cinfo->coef->decompress_data) (cinfo, data)) - return 0; /* suspension forced, can do nothing more */ - - /* OK, we processed one iMCU row. */ - cinfo->output_scanline += lines_per_iMCU_row; - return lines_per_iMCU_row; -} - - -/* Additional entry points for buffered-image mode. */ - -#ifdef D_MULTISCAN_FILES_SUPPORTED - -/* - * Initialize for an output pass in buffered-image mode. - */ - -GLOBAL boolean -jpeg_start_output (j_decompress_ptr cinfo, int scan_number) -{ - if (cinfo->global_state != DSTATE_BUFIMAGE && - cinfo->global_state != DSTATE_PRESCAN) - ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); - /* Limit scan number to valid range */ - if (scan_number <= 0) - scan_number = 1; - if (cinfo->inputctl->eoi_reached && - scan_number > cinfo->input_scan_number) - scan_number = cinfo->input_scan_number; - cinfo->output_scan_number = scan_number; - /* Perform any dummy output passes, and set up for the real pass */ - return output_pass_setup(cinfo); -} - - -/* - * Finish up after an output pass in buffered-image mode. - * - * Returns FALSE if suspended. The return value need be inspected only if - * a suspending data source is used. - */ - -GLOBAL boolean -jpeg_finish_output (j_decompress_ptr cinfo) -{ - if ((cinfo->global_state == DSTATE_SCANNING || - cinfo->global_state == DSTATE_RAW_OK) && cinfo->buffered_image) { - /* Terminate this pass. */ - /* We do not require the whole pass to have been completed. */ - (*cinfo->master->finish_output_pass) (cinfo); - cinfo->global_state = DSTATE_BUFPOST; - } else if (cinfo->global_state != DSTATE_BUFPOST) { - /* BUFPOST = repeat call after a suspension, anything else is error */ - ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); - } - /* Read markers looking for SOS or EOI */ - while (cinfo->input_scan_number <= cinfo->output_scan_number && - ! cinfo->inputctl->eoi_reached) { - if ((*cinfo->inputctl->consume_input) (cinfo) == JPEG_SUSPENDED) - return FALSE; /* Suspend, come back later */ - } - cinfo->global_state = DSTATE_BUFIMAGE; - return TRUE; -} - -#endif /* D_MULTISCAN_FILES_SUPPORTED */ diff --git a/engine/jpeg-6/jdatadst.c b/engine/jpeg-6/jdatadst.c deleted file mode 100644 index 08c4daf..0000000 --- a/engine/jpeg-6/jdatadst.c +++ /dev/null @@ -1,151 +0,0 @@ -/* - * jdatadst.c - * - * Copyright (C) 1994, Thomas G. Lane. - * This file is part of the Independent JPEG Group's software. - * For conditions of distribution and use, see the accompanying README file. - * - * This file contains compression data destination routines for the case of - * emitting JPEG data to a file (or any stdio stream). While these routines - * are sufficient for most applications, some will want to use a different - * destination manager. - * IMPORTANT: we assume that fwrite() will correctly transcribe an array of - * JOCTETs into 8-bit-wide elements on external storage. If char is wider - * than 8 bits on your machine, you may need to do some tweaking. - */ - -/* this is not a core library module, so it doesn't define JPEG_INTERNALS */ -#include "jinclude.h" -#include "jpeglib.h" -#include "jerror.h" - - -/* Expanded data destination object for stdio output */ - -typedef struct { - struct jpeg_destination_mgr pub; /* public fields */ - - FILE * outfile; /* target stream */ - JOCTET * buffer; /* start of buffer */ -} my_destination_mgr; - -typedef my_destination_mgr * my_dest_ptr; - -#define OUTPUT_BUF_SIZE 4096 /* choose an efficiently fwrite'able size */ - - -/* - * Initialize destination --- called by jpeg_start_compress - * before any data is actually written. - */ - -METHODDEF void -init_destination (j_compress_ptr cinfo) -{ - my_dest_ptr dest = (my_dest_ptr) cinfo->dest; - - /* Allocate the output buffer --- it will be released when done with image */ - dest->buffer = (JOCTET *) - (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, - OUTPUT_BUF_SIZE * SIZEOF(JOCTET)); - - dest->pub.next_output_byte = dest->buffer; - dest->pub.free_in_buffer = OUTPUT_BUF_SIZE; -} - - -/* - * Empty the output buffer --- called whenever buffer fills up. - * - * In typical applications, this should write the entire output buffer - * (ignoring the current state of next_output_byte & free_in_buffer), - * reset the pointer & count to the start of the buffer, and return TRUE - * indicating that the buffer has been dumped. - * - * In applications that need to be able to suspend compression due to output - * overrun, a FALSE return indicates that the buffer cannot be emptied now. - * In this situation, the compressor will return to its caller (possibly with - * an indication that it has not accepted all the supplied scanlines). The - * application should resume compression after it has made more room in the - * output buffer. Note that there are substantial restrictions on the use of - * suspension --- see the documentation. - * - * When suspending, the compressor will back up to a convenient restart point - * (typically the start of the current MCU). next_output_byte & free_in_buffer - * indicate where the restart point will be if the current call returns FALSE. - * Data beyond this point will be regenerated after resumption, so do not - * write it out when emptying the buffer externally. - */ - -METHODDEF boolean -empty_output_buffer (j_compress_ptr cinfo) -{ - my_dest_ptr dest = (my_dest_ptr) cinfo->dest; - - if (JFWRITE(dest->outfile, dest->buffer, OUTPUT_BUF_SIZE) != - (size_t) OUTPUT_BUF_SIZE) - ERREXIT(cinfo, JERR_FILE_WRITE); - - dest->pub.next_output_byte = dest->buffer; - dest->pub.free_in_buffer = OUTPUT_BUF_SIZE; - - return TRUE; -} - - -/* - * Terminate destination --- called by jpeg_finish_compress - * after all data has been written. Usually needs to flush buffer. - * - * NB: *not* called by jpeg_abort or jpeg_destroy; surrounding - * application must deal with any cleanup that should happen even - * for error exit. - */ - -METHODDEF void -term_destination (j_compress_ptr cinfo) -{ - my_dest_ptr dest = (my_dest_ptr) cinfo->dest; - size_t datacount = OUTPUT_BUF_SIZE - dest->pub.free_in_buffer; - - /* Write any data remaining in the buffer */ - if (datacount > 0) { - if (JFWRITE(dest->outfile, dest->buffer, datacount) != datacount) - ERREXIT(cinfo, JERR_FILE_WRITE); - } - fflush(dest->outfile); - /* Make sure we wrote the output file OK */ - if (ferror(dest->outfile)) - ERREXIT(cinfo, JERR_FILE_WRITE); -} - - -/* - * Prepare for output to a stdio stream. - * The caller must have already opened the stream, and is responsible - * for closing it after finishing compression. - */ - -GLOBAL void -jpeg_stdio_dest (j_compress_ptr cinfo, FILE * outfile) -{ - my_dest_ptr dest; - - /* The destination object is made permanent so that multiple JPEG images - * can be written to the same file without re-executing jpeg_stdio_dest. - * This makes it dangerous to use this manager and a different destination - * manager serially with the same JPEG object, because their private object - * sizes may be different. Caveat programmer. - */ - if (cinfo->dest == NULL) { /* first time for this JPEG object? */ - cinfo->dest = (struct jpeg_destination_mgr *) - (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT, - SIZEOF(my_destination_mgr)); - } - - dest = (my_dest_ptr) cinfo->dest; - dest->pub.init_destination = init_destination; - dest->pub.empty_output_buffer = empty_output_buffer; - dest->pub.term_destination = term_destination; - dest->outfile = outfile; -} diff --git a/engine/jpeg-6/jdatasrc.c b/engine/jpeg-6/jdatasrc.c deleted file mode 100644 index 0bf7866..0000000 --- a/engine/jpeg-6/jdatasrc.c +++ /dev/null @@ -1,204 +0,0 @@ -/* - * jdatasrc.c - * - * Copyright (C) 1994, Thomas G. Lane. - * This file is part of the Independent JPEG Group's software. - * For conditions of distribution and use, see the accompanying README file. - * - * This file contains decompression data source routines for the case of - * reading JPEG data from a file (or any stdio stream). While these routines - * are sufficient for most applications, some will want to use a different - * source manager. - * IMPORTANT: we assume that fread() will correctly transcribe an array of - * JOCTETs from 8-bit-wide elements on external storage. If char is wider - * than 8 bits on your machine, you may need to do some tweaking. - */ - - -/* this is not a core library module, so it doesn't define JPEG_INTERNALS */ -#include "jinclude.h" -#include "jpeglib.h" -#include "jerror.h" - - -/* Expanded data source object for stdio input */ - -typedef struct { - struct jpeg_source_mgr pub; /* public fields */ - - unsigned char *infile; /* source stream */ - JOCTET * buffer; /* start of buffer */ - boolean start_of_file; /* have we gotten any data yet? */ -} my_source_mgr; - -typedef my_source_mgr * my_src_ptr; - -#define INPUT_BUF_SIZE 4096 /* choose an efficiently fread'able size */ - - -/* - * Initialize source --- called by jpeg_read_header - * before any data is actually read. - */ - -METHODDEF void -init_source (j_decompress_ptr cinfo) -{ - my_src_ptr src = (my_src_ptr) cinfo->src; - - /* We reset the empty-input-file flag for each image, - * but we don't clear the input buffer. - * This is correct behavior for reading a series of images from one source. - */ - src->start_of_file = TRUE; -} - - -/* - * Fill the input buffer --- called whenever buffer is emptied. - * - * In typical applications, this should read fresh data into the buffer - * (ignoring the current state of next_input_byte & bytes_in_buffer), - * reset the pointer & count to the start of the buffer, and return TRUE - * indicating that the buffer has been reloaded. It is not necessary to - * fill the buffer entirely, only to obtain at least one more byte. - * - * There is no such thing as an EOF return. If the end of the file has been - * reached, the routine has a choice of ERREXIT() or inserting fake data into - * the buffer. In most cases, generating a warning message and inserting a - * fake EOI marker is the best course of action --- this will allow the - * decompressor to output however much of the image is there. However, - * the resulting error message is misleading if the real problem is an empty - * input file, so we handle that case specially. - * - * In applications that need to be able to suspend compression due to input - * not being available yet, a FALSE return indicates that no more data can be - * obtained right now, but more may be forthcoming later. In this situation, - * the decompressor will return to its caller (with an indication of the - * number of scanlines it has read, if any). The application should resume - * decompression after it has loaded more data into the input buffer. Note - * that there are substantial restrictions on the use of suspension --- see - * the documentation. - * - * When suspending, the decompressor will back up to a convenient restart point - * (typically the start of the current MCU). next_input_byte & bytes_in_buffer - * indicate where the restart point will be if the current call returns FALSE. - * Data beyond this point must be rescanned after resumption, so move it to - * the front of the buffer rather than discarding it. - */ - -METHODDEF boolean -fill_input_buffer (j_decompress_ptr cinfo) -{ - my_src_ptr src = (my_src_ptr) cinfo->src; - - memcpy( src->buffer, src->infile, INPUT_BUF_SIZE ); - - src->infile += INPUT_BUF_SIZE; - - src->pub.next_input_byte = src->buffer; - src->pub.bytes_in_buffer = INPUT_BUF_SIZE; - src->start_of_file = FALSE; - - return TRUE; -} - - -/* - * Skip data --- used to skip over a potentially large amount of - * uninteresting data (such as an APPn marker). - * - * Writers of suspendable-input applications must note that skip_input_data - * is not granted the right to give a suspension return. If the skip extends - * beyond the data currently in the buffer, the buffer can be marked empty so - * that the next read will cause a fill_input_buffer call that can suspend. - * Arranging for additional bytes to be discarded before reloading the input - * buffer is the application writer's problem. - */ - -METHODDEF void -skip_input_data (j_decompress_ptr cinfo, long num_bytes) -{ - my_src_ptr src = (my_src_ptr) cinfo->src; - - /* Just a dumb implementation for now. Could use fseek() except - * it doesn't work on pipes. Not clear that being smart is worth - * any trouble anyway --- large skips are infrequent. - */ - if (num_bytes > 0) { - while (num_bytes > (long) src->pub.bytes_in_buffer) { - num_bytes -= (long) src->pub.bytes_in_buffer; - (void) fill_input_buffer(cinfo); - /* note we assume that fill_input_buffer will never return FALSE, - * so suspension need not be handled. - */ - } - src->pub.next_input_byte += (size_t) num_bytes; - src->pub.bytes_in_buffer -= (size_t) num_bytes; - } -} - - -/* - * An additional method that can be provided by data source modules is the - * resync_to_restart method for error recovery in the presence of RST markers. - * For the moment, this source module just uses the default resync method - * provided by the JPEG library. That method assumes that no backtracking - * is possible. - */ - - -/* - * Terminate source --- called by jpeg_finish_decompress - * after all data has been read. Often a no-op. - * - * NB: *not* called by jpeg_abort or jpeg_destroy; surrounding - * application must deal with any cleanup that should happen even - * for error exit. - */ - -METHODDEF void -term_source (j_decompress_ptr cinfo) -{ - /* no work necessary here */ -} - - -/* - * Prepare for input from a stdio stream. - * The caller must have already opened the stream, and is responsible - * for closing it after finishing decompression. - */ - -GLOBAL void -jpeg_stdio_src (j_decompress_ptr cinfo, unsigned char *infile) -{ - my_src_ptr src; - - /* The source object and input buffer are made permanent so that a series - * of JPEG images can be read from the same file by calling jpeg_stdio_src - * only before the first one. (If we discarded the buffer at the end of - * one image, we'd likely lose the start of the next one.) - * This makes it unsafe to use this manager and a different source - * manager serially with the same JPEG object. Caveat programmer. - */ - if (cinfo->src == NULL) { /* first time for this JPEG object? */ - cinfo->src = (struct jpeg_source_mgr *) - (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT, - SIZEOF(my_source_mgr)); - src = (my_src_ptr) cinfo->src; - src->buffer = (JOCTET *) - (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT, - INPUT_BUF_SIZE * SIZEOF(JOCTET)); - } - - src = (my_src_ptr) cinfo->src; - src->pub.init_source = init_source; - src->pub.fill_input_buffer = fill_input_buffer; - src->pub.skip_input_data = skip_input_data; - src->pub.resync_to_restart = jpeg_resync_to_restart; /* use default method */ - src->pub.term_source = term_source; - src->infile = infile; - src->pub.bytes_in_buffer = 0; /* forces fill_input_buffer on first read */ - src->pub.next_input_byte = NULL; /* until buffer loaded */ -} diff --git a/engine/jpeg-6/jdcoefct.c b/engine/jpeg-6/jdcoefct.c deleted file mode 100644 index ba153f5..0000000 --- a/engine/jpeg-6/jdcoefct.c +++ /dev/null @@ -1,725 +0,0 @@ -/* - * jdcoefct.c - * - * Copyright (C) 1994-1995, Thomas G. Lane. - * This file is part of the Independent JPEG Group's software. - * For conditions of distribution and use, see the accompanying README file. - * - * This file contains the coefficient buffer controller for decompression. - * This controller is the top level of the JPEG decompressor proper. - * The coefficient buffer lies between entropy decoding and inverse-DCT steps. - * - * In buffered-image mode, this controller is the interface between - * input-oriented processing and output-oriented processing. - * Also, the input side (only) is used when reading a file for transcoding. - */ - -#define JPEG_INTERNALS -#include "jinclude.h" -#include "jpeglib.h" - -/* Block smoothing is only applicable for progressive JPEG, so: */ -#ifndef D_PROGRESSIVE_SUPPORTED -#undef BLOCK_SMOOTHING_SUPPORTED -#endif - -/* Private buffer controller object */ - -typedef struct { - struct jpeg_d_coef_controller pub; /* public fields */ - - /* These variables keep track of the current location of the input side. */ - /* cinfo->input_iMCU_row is also used for this. */ - JDIMENSION MCU_ctr; /* counts MCUs processed in current row */ - int MCU_vert_offset; /* counts MCU rows within iMCU row */ - int MCU_rows_per_iMCU_row; /* number of such rows needed */ - - /* The output side's location is represented by cinfo->output_iMCU_row. */ - - /* In single-pass modes, it's sufficient to buffer just one MCU. - * We allocate a workspace of D_MAX_BLOCKS_IN_MCU coefficient blocks, - * and let the entropy decoder write into that workspace each time. - * (On 80x86, the workspace is FAR even though it's not really very big; - * this is to keep the module interfaces unchanged when a large coefficient - * buffer is necessary.) - * In multi-pass modes, this array points to the current MCU's blocks - * within the virtual arrays; it is used only by the input side. - */ - JBLOCKROW MCU_buffer[D_MAX_BLOCKS_IN_MCU]; - -#ifdef D_MULTISCAN_FILES_SUPPORTED - /* In multi-pass modes, we need a virtual block array for each component. */ - jvirt_barray_ptr whole_image[MAX_COMPONENTS]; -#endif - -#ifdef BLOCK_SMOOTHING_SUPPORTED - /* When doing block smoothing, we latch coefficient Al values here */ - int * coef_bits_latch; -#define SAVED_COEFS 6 /* we save coef_bits[0..5] */ -#endif -} my_coef_controller; - -typedef my_coef_controller * my_coef_ptr; - -/* Forward declarations */ -METHODDEF int decompress_onepass - JPP((j_decompress_ptr cinfo, JSAMPIMAGE output_buf)); -#ifdef D_MULTISCAN_FILES_SUPPORTED -METHODDEF int decompress_data - JPP((j_decompress_ptr cinfo, JSAMPIMAGE output_buf)); -#endif -#ifdef BLOCK_SMOOTHING_SUPPORTED -LOCAL boolean smoothing_ok JPP((j_decompress_ptr cinfo)); -METHODDEF int decompress_smooth_data - JPP((j_decompress_ptr cinfo, JSAMPIMAGE output_buf)); -#endif - - -LOCAL void -start_iMCU_row (j_decompress_ptr cinfo) -/* Reset within-iMCU-row counters for a new row (input side) */ -{ - my_coef_ptr coef = (my_coef_ptr) cinfo->coef; - - /* In an interleaved scan, an MCU row is the same as an iMCU row. - * In a noninterleaved scan, an iMCU row has v_samp_factor MCU rows. - * But at the bottom of the image, process only what's left. - */ - if (cinfo->comps_in_scan > 1) { - coef->MCU_rows_per_iMCU_row = 1; - } else { - if (cinfo->input_iMCU_row < (cinfo->total_iMCU_rows-1)) - coef->MCU_rows_per_iMCU_row = cinfo->cur_comp_info[0]->v_samp_factor; - else - coef->MCU_rows_per_iMCU_row = cinfo->cur_comp_info[0]->last_row_height; - } - - coef->MCU_ctr = 0; - coef->MCU_vert_offset = 0; -} - - -/* - * Initialize for an input processing pass. - */ - -METHODDEF void -start_input_pass (j_decompress_ptr cinfo) -{ - cinfo->input_iMCU_row = 0; - start_iMCU_row(cinfo); -} - - -/* - * Initialize for an output processing pass. - */ - -METHODDEF void -start_output_pass (j_decompress_ptr cinfo) -{ -#ifdef BLOCK_SMOOTHING_SUPPORTED - my_coef_ptr coef = (my_coef_ptr) cinfo->coef; - - /* If multipass, check to see whether to use block smoothing on this pass */ - if (coef->pub.coef_arrays != NULL) { - if (cinfo->do_block_smoothing && smoothing_ok(cinfo)) - coef->pub.decompress_data = decompress_smooth_data; - else - coef->pub.decompress_data = decompress_data; - } -#endif - cinfo->output_iMCU_row = 0; -} - - -/* - * Decompress and return some data in the single-pass case. - * Always attempts to emit one fully interleaved MCU row ("iMCU" row). - * Input and output must run in lockstep since we have only a one-MCU buffer. - * Return value is JPEG_ROW_COMPLETED, JPEG_SCAN_COMPLETED, or JPEG_SUSPENDED. - * - * NB: output_buf contains a plane for each component in image. - * For single pass, this is the same as the components in the scan. - */ - -METHODDEF int -decompress_onepass (j_decompress_ptr cinfo, JSAMPIMAGE output_buf) -{ - my_coef_ptr coef = (my_coef_ptr) cinfo->coef; - JDIMENSION MCU_col_num; /* index of current MCU within row */ - JDIMENSION last_MCU_col = cinfo->MCUs_per_row - 1; - JDIMENSION last_iMCU_row = cinfo->total_iMCU_rows - 1; - int blkn, ci, xindex, yindex, yoffset, useful_width; - JSAMPARRAY output_ptr; - JDIMENSION start_col, output_col; - jpeg_component_info *compptr; - inverse_DCT_method_ptr inverse_DCT; - - /* Loop to process as much as one whole iMCU row */ - for (yoffset = coef->MCU_vert_offset; yoffset < coef->MCU_rows_per_iMCU_row; - yoffset++) { - for (MCU_col_num = coef->MCU_ctr; MCU_col_num <= last_MCU_col; - MCU_col_num++) { - /* Try to fetch an MCU. Entropy decoder expects buffer to be zeroed. */ - jzero_far((void FAR *) coef->MCU_buffer[0], - (size_t) (cinfo->blocks_in_MCU * SIZEOF(JBLOCK))); - if (! (*cinfo->entropy->decode_mcu) (cinfo, coef->MCU_buffer)) { - /* Suspension forced; update state counters and exit */ - coef->MCU_vert_offset = yoffset; - coef->MCU_ctr = MCU_col_num; - return JPEG_SUSPENDED; - } - /* Determine where data should go in output_buf and do the IDCT thing. - * We skip dummy blocks at the right and bottom edges (but blkn gets - * incremented past them!). Note the inner loop relies on having - * allocated the MCU_buffer[] blocks sequentially. - */ - blkn = 0; /* index of current DCT block within MCU */ - for (ci = 0; ci < cinfo->comps_in_scan; ci++) { - compptr = cinfo->cur_comp_info[ci]; - /* Don't bother to IDCT an uninteresting component. */ - if (! compptr->component_needed) { - blkn += compptr->MCU_blocks; - continue; - } - inverse_DCT = cinfo->idct->inverse_DCT[compptr->component_index]; - useful_width = (MCU_col_num < last_MCU_col) ? compptr->MCU_width - : compptr->last_col_width; - output_ptr = output_buf[ci] + yoffset * compptr->DCT_scaled_size; - start_col = MCU_col_num * compptr->MCU_sample_width; - for (yindex = 0; yindex < compptr->MCU_height; yindex++) { - if (cinfo->input_iMCU_row < last_iMCU_row || - yoffset+yindex < compptr->last_row_height) { - output_col = start_col; - for (xindex = 0; xindex < useful_width; xindex++) { - (*inverse_DCT) (cinfo, compptr, - (JCOEFPTR) coef->MCU_buffer[blkn+xindex], - output_ptr, output_col); - output_col += compptr->DCT_scaled_size; - } - } - blkn += compptr->MCU_width; - output_ptr += compptr->DCT_scaled_size; - } - } - } - /* Completed an MCU row, but perhaps not an iMCU row */ - coef->MCU_ctr = 0; - } - /* Completed the iMCU row, advance counters for next one */ - cinfo->output_iMCU_row++; - if (++(cinfo->input_iMCU_row) < cinfo->total_iMCU_rows) { - start_iMCU_row(cinfo); - return JPEG_ROW_COMPLETED; - } - /* Completed the scan */ - (*cinfo->inputctl->finish_input_pass) (cinfo); - return JPEG_SCAN_COMPLETED; -} - - -/* - * Dummy consume-input routine for single-pass operation. - */ - -METHODDEF int -dummy_consume_data (j_decompress_ptr cinfo) -{ - return JPEG_SUSPENDED; /* Always indicate nothing was done */ -} - - -#ifdef D_MULTISCAN_FILES_SUPPORTED - -/* - * Consume input data and store it in the full-image coefficient buffer. - * We read as much as one fully interleaved MCU row ("iMCU" row) per call, - * ie, v_samp_factor block rows for each component in the scan. - * Return value is JPEG_ROW_COMPLETED, JPEG_SCAN_COMPLETED, or JPEG_SUSPENDED. - */ - -METHODDEF int -consume_data (j_decompress_ptr cinfo) -{ - my_coef_ptr coef = (my_coef_ptr) cinfo->coef; - JDIMENSION MCU_col_num; /* index of current MCU within row */ - int blkn, ci, xindex, yindex, yoffset; - JDIMENSION start_col; - JBLOCKARRAY buffer[MAX_COMPS_IN_SCAN]; - JBLOCKROW buffer_ptr; - jpeg_component_info *compptr; - - /* Align the virtual buffers for the components used in this scan. */ - for (ci = 0; ci < cinfo->comps_in_scan; ci++) { - compptr = cinfo->cur_comp_info[ci]; - buffer[ci] = (*cinfo->mem->access_virt_barray) - ((j_common_ptr) cinfo, coef->whole_image[compptr->component_index], - cinfo->input_iMCU_row * compptr->v_samp_factor, - (JDIMENSION) compptr->v_samp_factor, TRUE); - /* Note: entropy decoder expects buffer to be zeroed, - * but this is handled automatically by the memory manager - * because we requested a pre-zeroed array. - */ - } - - /* Loop to process one whole iMCU row */ - for (yoffset = coef->MCU_vert_offset; yoffset < coef->MCU_rows_per_iMCU_row; - yoffset++) { - for (MCU_col_num = coef->MCU_ctr; MCU_col_num < cinfo->MCUs_per_row; - MCU_col_num++) { - /* Construct list of pointers to DCT blocks belonging to this MCU */ - blkn = 0; /* index of current DCT block within MCU */ - for (ci = 0; ci < cinfo->comps_in_scan; ci++) { - compptr = cinfo->cur_comp_info[ci]; - start_col = MCU_col_num * compptr->MCU_width; - for (yindex = 0; yindex < compptr->MCU_height; yindex++) { - buffer_ptr = buffer[ci][yindex+yoffset] + start_col; - for (xindex = 0; xindex < compptr->MCU_width; xindex++) { - coef->MCU_buffer[blkn++] = buffer_ptr++; - } - } - } - /* Try to fetch the MCU. */ - if (! (*cinfo->entropy->decode_mcu) (cinfo, coef->MCU_buffer)) { - /* Suspension forced; update state counters and exit */ - coef->MCU_vert_offset = yoffset; - coef->MCU_ctr = MCU_col_num; - return JPEG_SUSPENDED; - } - } - /* Completed an MCU row, but perhaps not an iMCU row */ - coef->MCU_ctr = 0; - } - /* Completed the iMCU row, advance counters for next one */ - if (++(cinfo->input_iMCU_row) < cinfo->total_iMCU_rows) { - start_iMCU_row(cinfo); - return JPEG_ROW_COMPLETED; - } - /* Completed the scan */ - (*cinfo->inputctl->finish_input_pass) (cinfo); - return JPEG_SCAN_COMPLETED; -} - - -/* - * Decompress and return some data in the multi-pass case. - * Always attempts to emit one fully interleaved MCU row ("iMCU" row). - * Return value is JPEG_ROW_COMPLETED, JPEG_SCAN_COMPLETED, or JPEG_SUSPENDED. - * - * NB: output_buf contains a plane for each component in image. - */ - -METHODDEF int -decompress_data (j_decompress_ptr cinfo, JSAMPIMAGE output_buf) -{ - my_coef_ptr coef = (my_coef_ptr) cinfo->coef; - JDIMENSION last_iMCU_row = cinfo->total_iMCU_rows - 1; - JDIMENSION block_num; - int ci, block_row, block_rows; - JBLOCKARRAY buffer; - JBLOCKROW buffer_ptr; - JSAMPARRAY output_ptr; - JDIMENSION output_col; - jpeg_component_info *compptr; - inverse_DCT_method_ptr inverse_DCT; - - /* Force some input to be done if we are getting ahead of the input. */ - while (cinfo->input_scan_number < cinfo->output_scan_number || - (cinfo->input_scan_number == cinfo->output_scan_number && - cinfo->input_iMCU_row <= cinfo->output_iMCU_row)) { - if ((*cinfo->inputctl->consume_input)(cinfo) == JPEG_SUSPENDED) - return JPEG_SUSPENDED; - } - - /* OK, output from the virtual arrays. */ - for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; - ci++, compptr++) { - /* Don't bother to IDCT an uninteresting component. */ - if (! compptr->component_needed) - continue; - /* Align the virtual buffer for this component. */ - buffer = (*cinfo->mem->access_virt_barray) - ((j_common_ptr) cinfo, coef->whole_image[ci], - cinfo->output_iMCU_row * compptr->v_samp_factor, - (JDIMENSION) compptr->v_samp_factor, FALSE); - /* Count non-dummy DCT block rows in this iMCU row. */ - if (cinfo->output_iMCU_row < last_iMCU_row) - block_rows = compptr->v_samp_factor; - else { - /* NB: can't use last_row_height here; it is input-side-dependent! */ - block_rows = (int) (compptr->height_in_blocks % compptr->v_samp_factor); - if (block_rows == 0) block_rows = compptr->v_samp_factor; - } - inverse_DCT = cinfo->idct->inverse_DCT[ci]; - output_ptr = output_buf[ci]; - /* Loop over all DCT blocks to be processed. */ - for (block_row = 0; block_row < block_rows; block_row++) { - buffer_ptr = buffer[block_row]; - output_col = 0; - for (block_num = 0; block_num < compptr->width_in_blocks; block_num++) { - (*inverse_DCT) (cinfo, compptr, (JCOEFPTR) buffer_ptr, - output_ptr, output_col); - buffer_ptr++; - output_col += compptr->DCT_scaled_size; - } - output_ptr += compptr->DCT_scaled_size; - } - } - - if (++(cinfo->output_iMCU_row) < cinfo->total_iMCU_rows) - return JPEG_ROW_COMPLETED; - return JPEG_SCAN_COMPLETED; -} - -#endif /* D_MULTISCAN_FILES_SUPPORTED */ - - -#ifdef BLOCK_SMOOTHING_SUPPORTED - -/* - * This code applies interblock smoothing as described by section K.8 - * of the JPEG standard: the first 5 AC coefficients are estimated from - * the DC values of a DCT block and its 8 neighboring blocks. - * We apply smoothing only for progressive JPEG decoding, and only if - * the coefficients it can estimate are not yet known to full precision. - */ - -/* - * Determine whether block smoothing is applicable and safe. - * We also latch the current states of the coef_bits[] entries for the - * AC coefficients; otherwise, if the input side of the decompressor - * advances into a new scan, we might think the coefficients are known - * more accurately than they really are. - */ - -LOCAL boolean -smoothing_ok (j_decompress_ptr cinfo) -{ - my_coef_ptr coef = (my_coef_ptr) cinfo->coef; - boolean smoothing_useful = FALSE; - int ci, coefi; - jpeg_component_info *compptr; - JQUANT_TBL * qtable; - int * coef_bits; - int * coef_bits_latch; - - if (! cinfo->progressive_mode || cinfo->coef_bits == NULL) - return FALSE; - - /* Allocate latch area if not already done */ - if (coef->coef_bits_latch == NULL) - coef->coef_bits_latch = (int *) - (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, - cinfo->num_components * - (SAVED_COEFS * SIZEOF(int))); - coef_bits_latch = coef->coef_bits_latch; - - for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; - ci++, compptr++) { - /* All components' quantization values must already be latched. */ - if ((qtable = compptr->quant_table) == NULL) - return FALSE; - /* Verify DC & first 5 AC quantizers are nonzero to avoid zero-divide. */ - for (coefi = 0; coefi <= 5; coefi++) { - if (qtable->quantval[coefi] == 0) - return FALSE; - } - /* DC values must be at least partly known for all components. */ - coef_bits = cinfo->coef_bits[ci]; - if (coef_bits[0] < 0) - return FALSE; - /* Block smoothing is helpful if some AC coefficients remain inaccurate. */ - for (coefi = 1; coefi <= 5; coefi++) { - coef_bits_latch[coefi] = coef_bits[coefi]; - if (coef_bits[coefi] != 0) - smoothing_useful = TRUE; - } - coef_bits_latch += SAVED_COEFS; - } - - return smoothing_useful; -} - - -/* - * Variant of decompress_data for use when doing block smoothing. - */ - -METHODDEF int -decompress_smooth_data (j_decompress_ptr cinfo, JSAMPIMAGE output_buf) -{ - my_coef_ptr coef = (my_coef_ptr) cinfo->coef; - JDIMENSION last_iMCU_row = cinfo->total_iMCU_rows - 1; - JDIMENSION block_num, last_block_column; - int ci, block_row, block_rows, access_rows; - JBLOCKARRAY buffer; - JBLOCKROW buffer_ptr, prev_block_row, next_block_row; - JSAMPARRAY output_ptr; - JDIMENSION output_col; - jpeg_component_info *compptr; - inverse_DCT_method_ptr inverse_DCT; - boolean first_row, last_row; - JBLOCK workspace; - int *coef_bits; - JQUANT_TBL *quanttbl; - INT32 Q00,Q01,Q02,Q10,Q11,Q20, num; - int DC1,DC2,DC3,DC4,DC5,DC6,DC7,DC8,DC9; - int Al, pred; - - /* Force some input to be done if we are getting ahead of the input. */ - while (cinfo->input_scan_number <= cinfo->output_scan_number && - ! cinfo->inputctl->eoi_reached) { - if (cinfo->input_scan_number == cinfo->output_scan_number) { - /* If input is working on current scan, we ordinarily want it to - * have completed the current row. But if input scan is DC, - * we want it to keep one row ahead so that next block row's DC - * values are up to date. - */ - JDIMENSION delta = (cinfo->Ss == 0) ? 1 : 0; - if (cinfo->input_iMCU_row > cinfo->output_iMCU_row+delta) - break; - } - if ((*cinfo->inputctl->consume_input)(cinfo) == JPEG_SUSPENDED) - return JPEG_SUSPENDED; - } - - /* OK, output from the virtual arrays. */ - for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; - ci++, compptr++) { - /* Don't bother to IDCT an uninteresting component. */ - if (! compptr->component_needed) - continue; - /* Count non-dummy DCT block rows in this iMCU row. */ - if (cinfo->output_iMCU_row < last_iMCU_row) { - block_rows = compptr->v_samp_factor; - access_rows = block_rows * 2; /* this and next iMCU row */ - last_row = FALSE; - } else { - /* NB: can't use last_row_height here; it is input-side-dependent! */ - block_rows = (int) (compptr->height_in_blocks % compptr->v_samp_factor); - if (block_rows == 0) block_rows = compptr->v_samp_factor; - access_rows = block_rows; /* this iMCU row only */ - last_row = TRUE; - } - /* Align the virtual buffer for this component. */ - if (cinfo->output_iMCU_row > 0) { - access_rows += compptr->v_samp_factor; /* prior iMCU row too */ - buffer = (*cinfo->mem->access_virt_barray) - ((j_common_ptr) cinfo, coef->whole_image[ci], - (cinfo->output_iMCU_row - 1) * compptr->v_samp_factor, - (JDIMENSION) access_rows, FALSE); - buffer += compptr->v_samp_factor; /* point to current iMCU row */ - first_row = FALSE; - } else { - buffer = (*cinfo->mem->access_virt_barray) - ((j_common_ptr) cinfo, coef->whole_image[ci], - (JDIMENSION) 0, (JDIMENSION) access_rows, FALSE); - first_row = TRUE; - } - /* Fetch component-dependent info */ - coef_bits = coef->coef_bits_latch + (ci * SAVED_COEFS); - quanttbl = compptr->quant_table; - Q00 = quanttbl->quantval[0]; - Q01 = quanttbl->quantval[1]; - Q10 = quanttbl->quantval[2]; - Q20 = quanttbl->quantval[3]; - Q11 = quanttbl->quantval[4]; - Q02 = quanttbl->quantval[5]; - inverse_DCT = cinfo->idct->inverse_DCT[ci]; - output_ptr = output_buf[ci]; - /* Loop over all DCT blocks to be processed. */ - for (block_row = 0; block_row < block_rows; block_row++) { - buffer_ptr = buffer[block_row]; - if (first_row && block_row == 0) - prev_block_row = buffer_ptr; - else - prev_block_row = buffer[block_row-1]; - if (last_row && block_row == block_rows-1) - next_block_row = buffer_ptr; - else - next_block_row = buffer[block_row+1]; - /* We fetch the surrounding DC values using a sliding-register approach. - * Initialize all nine here so as to do the right thing on narrow pics. - */ - DC1 = DC2 = DC3 = (int) prev_block_row[0][0]; - DC4 = DC5 = DC6 = (int) buffer_ptr[0][0]; - DC7 = DC8 = DC9 = (int) next_block_row[0][0]; - output_col = 0; - last_block_column = compptr->width_in_blocks - 1; - for (block_num = 0; block_num <= last_block_column; block_num++) { - /* Fetch current DCT block into workspace so we can modify it. */ - jcopy_block_row(buffer_ptr, (JBLOCKROW) workspace, (JDIMENSION) 1); - /* Update DC values */ - if (block_num < last_block_column) { - DC3 = (int) prev_block_row[1][0]; - DC6 = (int) buffer_ptr[1][0]; - DC9 = (int) next_block_row[1][0]; - } - /* Compute coefficient estimates per K.8. - * An estimate is applied only if coefficient is still zero, - * and is not known to be fully accurate. - */ - /* AC01 */ - if ((Al=coef_bits[1]) != 0 && workspace[1] == 0) { - num = 36 * Q00 * (DC4 - DC6); - if (num >= 0) { - pred = (int) (((Q01<<7) + num) / (Q01<<8)); - if (Al > 0 && pred >= (1< 0 && pred >= (1<= 0) { - pred = (int) (((Q10<<7) + num) / (Q10<<8)); - if (Al > 0 && pred >= (1< 0 && pred >= (1<= 0) { - pred = (int) (((Q20<<7) + num) / (Q20<<8)); - if (Al > 0 && pred >= (1< 0 && pred >= (1<= 0) { - pred = (int) (((Q11<<7) + num) / (Q11<<8)); - if (Al > 0 && pred >= (1< 0 && pred >= (1<= 0) { - pred = (int) (((Q02<<7) + num) / (Q02<<8)); - if (Al > 0 && pred >= (1< 0 && pred >= (1<DCT_scaled_size; - } - output_ptr += compptr->DCT_scaled_size; - } - } - - if (++(cinfo->output_iMCU_row) < cinfo->total_iMCU_rows) - return JPEG_ROW_COMPLETED; - return JPEG_SCAN_COMPLETED; -} - -#endif /* BLOCK_SMOOTHING_SUPPORTED */ - - -/* - * Initialize coefficient buffer controller. - */ - -GLOBAL void -jinit_d_coef_controller (j_decompress_ptr cinfo, boolean need_full_buffer) -{ - my_coef_ptr coef; - - coef = (my_coef_ptr) - (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, - SIZEOF(my_coef_controller)); - cinfo->coef = (struct jpeg_d_coef_controller *) coef; - coef->pub.start_input_pass = start_input_pass; - coef->pub.start_output_pass = start_output_pass; -#ifdef BLOCK_SMOOTHING_SUPPORTED - coef->coef_bits_latch = NULL; -#endif - - /* Create the coefficient buffer. */ - if (need_full_buffer) { -#ifdef D_MULTISCAN_FILES_SUPPORTED - /* Allocate a full-image virtual array for each component, */ - /* padded to a multiple of samp_factor DCT blocks in each direction. */ - /* Note we ask for a pre-zeroed array. */ - int ci, access_rows; - jpeg_component_info *compptr; - - for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; - ci++, compptr++) { - access_rows = compptr->v_samp_factor; -#ifdef BLOCK_SMOOTHING_SUPPORTED - /* If block smoothing could be used, need a bigger window */ - if (cinfo->progressive_mode) - access_rows *= 3; -#endif - coef->whole_image[ci] = (*cinfo->mem->request_virt_barray) - ((j_common_ptr) cinfo, JPOOL_IMAGE, TRUE, - (JDIMENSION) jround_up((long) compptr->width_in_blocks, - (long) compptr->h_samp_factor), - (JDIMENSION) jround_up((long) compptr->height_in_blocks, - (long) compptr->v_samp_factor), - (JDIMENSION) access_rows); - } - coef->pub.consume_data = consume_data; - coef->pub.decompress_data = decompress_data; - coef->pub.coef_arrays = coef->whole_image; /* link to virtual arrays */ -#else - ERREXIT(cinfo, JERR_NOT_COMPILED); -#endif - } else { - /* We only need a single-MCU buffer. */ - JBLOCKROW buffer; - int i; - - buffer = (JBLOCKROW) - (*cinfo->mem->alloc_large) ((j_common_ptr) cinfo, JPOOL_IMAGE, - D_MAX_BLOCKS_IN_MCU * SIZEOF(JBLOCK)); - for (i = 0; i < D_MAX_BLOCKS_IN_MCU; i++) { - coef->MCU_buffer[i] = buffer + i; - } - coef->pub.consume_data = dummy_consume_data; - coef->pub.decompress_data = decompress_onepass; - coef->pub.coef_arrays = NULL; /* flag for no virtual arrays */ - } -} diff --git a/engine/jpeg-6/jdcolor.c b/engine/jpeg-6/jdcolor.c deleted file mode 100644 index b2bdf6e..0000000 --- a/engine/jpeg-6/jdcolor.c +++ /dev/null @@ -1,367 +0,0 @@ -/* - * jdcolor.c - * - * Copyright (C) 1991-1995, Thomas G. Lane. - * This file is part of the Independent JPEG Group's software. - * For conditions of distribution and use, see the accompanying README file. - * - * This file contains output colorspace conversion routines. - */ - -#define JPEG_INTERNALS -#include "jinclude.h" -#include "jpeglib.h" - - -/* Private subobject */ - -typedef struct { - struct jpeg_color_deconverter pub; /* public fields */ - - /* Private state for YCC->RGB conversion */ - int * Cr_r_tab; /* => table for Cr to R conversion */ - int * Cb_b_tab; /* => table for Cb to B conversion */ - INT32 * Cr_g_tab; /* => table for Cr to G conversion */ - INT32 * Cb_g_tab; /* => table for Cb to G conversion */ -} my_color_deconverter; - -typedef my_color_deconverter * my_cconvert_ptr; - - -/**************** YCbCr -> RGB conversion: most common case **************/ - -/* - * YCbCr is defined per CCIR 601-1, except that Cb and Cr are - * normalized to the range 0..MAXJSAMPLE rather than -0.5 .. 0.5. - * The conversion equations to be implemented are therefore - * R = Y + 1.40200 * Cr - * G = Y - 0.34414 * Cb - 0.71414 * Cr - * B = Y + 1.77200 * Cb - * where Cb and Cr represent the incoming values less CENTERJSAMPLE. - * (These numbers are derived from TIFF 6.0 section 21, dated 3-June-92.) - * - * To avoid floating-point arithmetic, we represent the fractional constants - * as integers scaled up by 2^16 (about 4 digits precision); we have to divide - * the products by 2^16, with appropriate rounding, to get the correct answer. - * Notice that Y, being an integral input, does not contribute any fraction - * so it need not participate in the rounding. - * - * For even more speed, we avoid doing any multiplications in the inner loop - * by precalculating the constants times Cb and Cr for all possible values. - * For 8-bit JSAMPLEs this is very reasonable (only 256 entries per table); - * for 12-bit samples it is still acceptable. It's not very reasonable for - * 16-bit samples, but if you want lossless storage you shouldn't be changing - * colorspace anyway. - * The Cr=>R and Cb=>B values can be rounded to integers in advance; the - * values for the G calculation are left scaled up, since we must add them - * together before rounding. - */ - -#define SCALEBITS 16 /* speediest right-shift on some machines */ -#define ONE_HALF ((INT32) 1 << (SCALEBITS-1)) -#define FIX(x) ((INT32) ((x) * (1L<RGB colorspace conversion. - */ - -LOCAL void -build_ycc_rgb_table (j_decompress_ptr cinfo) -{ - my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert; - int i; - INT32 x; - SHIFT_TEMPS - - cconvert->Cr_r_tab = (int *) - (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, - (MAXJSAMPLE+1) * SIZEOF(int)); - cconvert->Cb_b_tab = (int *) - (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, - (MAXJSAMPLE+1) * SIZEOF(int)); - cconvert->Cr_g_tab = (INT32 *) - (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, - (MAXJSAMPLE+1) * SIZEOF(INT32)); - cconvert->Cb_g_tab = (INT32 *) - (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, - (MAXJSAMPLE+1) * SIZEOF(INT32)); - - for (i = 0, x = -CENTERJSAMPLE; i <= MAXJSAMPLE; i++, x++) { - /* i is the actual input pixel value, in the range 0..MAXJSAMPLE */ - /* The Cb or Cr value we are thinking of is x = i - CENTERJSAMPLE */ - /* Cr=>R value is nearest int to 1.40200 * x */ - cconvert->Cr_r_tab[i] = (int) - RIGHT_SHIFT(FIX(1.40200) * x + ONE_HALF, SCALEBITS); - /* Cb=>B value is nearest int to 1.77200 * x */ - cconvert->Cb_b_tab[i] = (int) - RIGHT_SHIFT(FIX(1.77200) * x + ONE_HALF, SCALEBITS); - /* Cr=>G value is scaled-up -0.71414 * x */ - cconvert->Cr_g_tab[i] = (- FIX(0.71414)) * x; - /* Cb=>G value is scaled-up -0.34414 * x */ - /* We also add in ONE_HALF so that need not do it in inner loop */ - cconvert->Cb_g_tab[i] = (- FIX(0.34414)) * x + ONE_HALF; - } -} - - -/* - * Convert some rows of samples to the output colorspace. - * - * Note that we change from noninterleaved, one-plane-per-component format - * to interleaved-pixel format. The output buffer is therefore three times - * as wide as the input buffer. - * A starting row offset is provided only for the input buffer. The caller - * can easily adjust the passed output_buf value to accommodate any row - * offset required on that side. - */ - -METHODDEF void -ycc_rgb_convert (j_decompress_ptr cinfo, - JSAMPIMAGE input_buf, JDIMENSION input_row, - JSAMPARRAY output_buf, int num_rows) -{ - my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert; - register int y, cb, cr; - register JSAMPROW outptr; - register JSAMPROW inptr0, inptr1, inptr2; - register JDIMENSION col; - JDIMENSION num_cols = cinfo->output_width; - /* copy these pointers into registers if possible */ - register JSAMPLE * range_limit = cinfo->sample_range_limit; - register int * Crrtab = cconvert->Cr_r_tab; - register int * Cbbtab = cconvert->Cb_b_tab; - register INT32 * Crgtab = cconvert->Cr_g_tab; - register INT32 * Cbgtab = cconvert->Cb_g_tab; - SHIFT_TEMPS - - while (--num_rows >= 0) { - inptr0 = input_buf[0][input_row]; - inptr1 = input_buf[1][input_row]; - inptr2 = input_buf[2][input_row]; - input_row++; - outptr = *output_buf++; - for (col = 0; col < num_cols; col++) { - y = GETJSAMPLE(inptr0[col]); - cb = GETJSAMPLE(inptr1[col]); - cr = GETJSAMPLE(inptr2[col]); - /* Range-limiting is essential due to noise introduced by DCT losses. */ - outptr[RGB_RED] = range_limit[y + Crrtab[cr]]; - outptr[RGB_GREEN] = range_limit[y + - ((int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], - SCALEBITS))]; - outptr[RGB_BLUE] = range_limit[y + Cbbtab[cb]]; - outptr += RGB_PIXELSIZE; - } - } -} - - -/**************** Cases other than YCbCr -> RGB **************/ - - -/* - * Color conversion for no colorspace change: just copy the data, - * converting from separate-planes to interleaved representation. - */ - -METHODDEF void -null_convert (j_decompress_ptr cinfo, - JSAMPIMAGE input_buf, JDIMENSION input_row, - JSAMPARRAY output_buf, int num_rows) -{ - register JSAMPROW inptr, outptr; - register JDIMENSION count; - register int num_components = cinfo->num_components; - JDIMENSION num_cols = cinfo->output_width; - int ci; - - while (--num_rows >= 0) { - for (ci = 0; ci < num_components; ci++) { - inptr = input_buf[ci][input_row]; - outptr = output_buf[0] + ci; - for (count = num_cols; count > 0; count--) { - *outptr = *inptr++; /* needn't bother with GETJSAMPLE() here */ - outptr += num_components; - } - } - input_row++; - output_buf++; - } -} - - -/* - * Color conversion for grayscale: just copy the data. - * This also works for YCbCr -> grayscale conversion, in which - * we just copy the Y (luminance) component and ignore chrominance. - */ - -METHODDEF void -grayscale_convert (j_decompress_ptr cinfo, - JSAMPIMAGE input_buf, JDIMENSION input_row, - JSAMPARRAY output_buf, int num_rows) -{ - jcopy_sample_rows(input_buf[0], (int) input_row, output_buf, 0, - num_rows, cinfo->output_width); -} - - -/* - * Adobe-style YCCK->CMYK conversion. - * We convert YCbCr to R=1-C, G=1-M, and B=1-Y using the same - * conversion as above, while passing K (black) unchanged. - * We assume build_ycc_rgb_table has been called. - */ - -METHODDEF void -ycck_cmyk_convert (j_decompress_ptr cinfo, - JSAMPIMAGE input_buf, JDIMENSION input_row, - JSAMPARRAY output_buf, int num_rows) -{ - my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert; - register int y, cb, cr; - register JSAMPROW outptr; - register JSAMPROW inptr0, inptr1, inptr2, inptr3; - register JDIMENSION col; - JDIMENSION num_cols = cinfo->output_width; - /* copy these pointers into registers if possible */ - register JSAMPLE * range_limit = cinfo->sample_range_limit; - register int * Crrtab = cconvert->Cr_r_tab; - register int * Cbbtab = cconvert->Cb_b_tab; - register INT32 * Crgtab = cconvert->Cr_g_tab; - register INT32 * Cbgtab = cconvert->Cb_g_tab; - SHIFT_TEMPS - - while (--num_rows >= 0) { - inptr0 = input_buf[0][input_row]; - inptr1 = input_buf[1][input_row]; - inptr2 = input_buf[2][input_row]; - inptr3 = input_buf[3][input_row]; - input_row++; - outptr = *output_buf++; - for (col = 0; col < num_cols; col++) { - y = GETJSAMPLE(inptr0[col]); - cb = GETJSAMPLE(inptr1[col]); - cr = GETJSAMPLE(inptr2[col]); - /* Range-limiting is essential due to noise introduced by DCT losses. */ - outptr[0] = range_limit[MAXJSAMPLE - (y + Crrtab[cr])]; /* red */ - outptr[1] = range_limit[MAXJSAMPLE - (y + /* green */ - ((int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], - SCALEBITS)))]; - outptr[2] = range_limit[MAXJSAMPLE - (y + Cbbtab[cb])]; /* blue */ - /* K passes through unchanged */ - outptr[3] = inptr3[col]; /* don't need GETJSAMPLE here */ - outptr += 4; - } - } -} - - -/* - * Empty method for start_pass. - */ - -METHODDEF void -start_pass_dcolor (j_decompress_ptr cinfo) -{ - /* no work needed */ -} - - -/* - * Module initialization routine for output colorspace conversion. - */ - -GLOBAL void -jinit_color_deconverter (j_decompress_ptr cinfo) -{ - my_cconvert_ptr cconvert; - int ci; - - cconvert = (my_cconvert_ptr) - (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, - SIZEOF(my_color_deconverter)); - cinfo->cconvert = (struct jpeg_color_deconverter *) cconvert; - cconvert->pub.start_pass = start_pass_dcolor; - - /* Make sure num_components agrees with jpeg_color_space */ - switch (cinfo->jpeg_color_space) { - case JCS_GRAYSCALE: - if (cinfo->num_components != 1) - ERREXIT(cinfo, JERR_BAD_J_COLORSPACE); - break; - - case JCS_RGB: - case JCS_YCbCr: - if (cinfo->num_components != 3) - ERREXIT(cinfo, JERR_BAD_J_COLORSPACE); - break; - - case JCS_CMYK: - case JCS_YCCK: - if (cinfo->num_components != 4) - ERREXIT(cinfo, JERR_BAD_J_COLORSPACE); - break; - - default: /* JCS_UNKNOWN can be anything */ - if (cinfo->num_components < 1) - ERREXIT(cinfo, JERR_BAD_J_COLORSPACE); - break; - } - - /* Set out_color_components and conversion method based on requested space. - * Also clear the component_needed flags for any unused components, - * so that earlier pipeline stages can avoid useless computation. - */ - - switch (cinfo->out_color_space) { - case JCS_GRAYSCALE: - cinfo->out_color_components = 1; - if (cinfo->jpeg_color_space == JCS_GRAYSCALE || - cinfo->jpeg_color_space == JCS_YCbCr) { - cconvert->pub.color_convert = grayscale_convert; - /* For color->grayscale conversion, only the Y (0) component is needed */ - for (ci = 1; ci < cinfo->num_components; ci++) - cinfo->comp_info[ci].component_needed = FALSE; - } else - ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL); - break; - - case JCS_RGB: - cinfo->out_color_components = RGB_PIXELSIZE; - if (cinfo->jpeg_color_space == JCS_YCbCr) { - cconvert->pub.color_convert = ycc_rgb_convert; - build_ycc_rgb_table(cinfo); - } else if (cinfo->jpeg_color_space == JCS_RGB && RGB_PIXELSIZE == 3) { - cconvert->pub.color_convert = null_convert; - } else - ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL); - break; - - case JCS_CMYK: - cinfo->out_color_components = 4; - if (cinfo->jpeg_color_space == JCS_YCCK) { - cconvert->pub.color_convert = ycck_cmyk_convert; - build_ycc_rgb_table(cinfo); - } else if (cinfo->jpeg_color_space == JCS_CMYK) { - cconvert->pub.color_convert = null_convert; - } else - ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL); - break; - - default: - /* Permit null conversion to same output space */ - if (cinfo->out_color_space == cinfo->jpeg_color_space) { - cinfo->out_color_components = cinfo->num_components; - cconvert->pub.color_convert = null_convert; - } else /* unsupported non-null conversion */ - ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL); - break; - } - - if (cinfo->quantize_colors) - cinfo->output_components = 1; /* single colormapped output component */ - else - cinfo->output_components = cinfo->out_color_components; -} diff --git a/engine/jpeg-6/jdct.h b/engine/jpeg-6/jdct.h deleted file mode 100644 index 3ce790b..0000000 --- a/engine/jpeg-6/jdct.h +++ /dev/null @@ -1,176 +0,0 @@ -/* - * jdct.h - * - * Copyright (C) 1994, Thomas G. Lane. - * This file is part of the Independent JPEG Group's software. - * For conditions of distribution and use, see the accompanying README file. - * - * This include file contains common declarations for the forward and - * inverse DCT modules. These declarations are private to the DCT managers - * (jcdctmgr.c, jddctmgr.c) and the individual DCT algorithms. - * The individual DCT algorithms are kept in separate files to ease - * machine-dependent tuning (e.g., assembly coding). - */ - - -/* - * A forward DCT routine is given a pointer to a work area of type DCTELEM[]; - * the DCT is to be performed in-place in that buffer. Type DCTELEM is int - * for 8-bit samples, INT32 for 12-bit samples. (NOTE: Floating-point DCT - * implementations use an array of type FAST_FLOAT, instead.) - * The DCT inputs are expected to be signed (range +-CENTERJSAMPLE). - * The DCT outputs are returned scaled up by a factor of 8; they therefore - * have a range of +-8K for 8-bit data, +-128K for 12-bit data. This - * convention improves accuracy in integer implementations and saves some - * work in floating-point ones. - * Quantization of the output coefficients is done by jcdctmgr.c. - */ - -#if BITS_IN_JSAMPLE == 8 -typedef int DCTELEM; /* 16 or 32 bits is fine */ -#else -typedef INT32 DCTELEM; /* must have 32 bits */ -#endif - -typedef JMETHOD(void, forward_DCT_method_ptr, (DCTELEM * data)); -typedef JMETHOD(void, float_DCT_method_ptr, (FAST_FLOAT * data)); - - -/* - * An inverse DCT routine is given a pointer to the input JBLOCK and a pointer - * to an output sample array. The routine must dequantize the input data as - * well as perform the IDCT; for dequantization, it uses the multiplier table - * pointed to by compptr->dct_table. The output data is to be placed into the - * sample array starting at a specified column. (Any row offset needed will - * be applied to the array pointer before it is passed to the IDCT code.) - * Note that the number of samples emitted by the IDCT routine is - * DCT_scaled_size * DCT_scaled_size. - */ - -/* typedef inverse_DCT_method_ptr is declared in jpegint.h */ - -/* - * Each IDCT routine has its own ideas about the best dct_table element type. - */ - -typedef MULTIPLIER ISLOW_MULT_TYPE; /* short or int, whichever is faster */ -#if BITS_IN_JSAMPLE == 8 -typedef MULTIPLIER IFAST_MULT_TYPE; /* 16 bits is OK, use short if faster */ -#define IFAST_SCALE_BITS 2 /* fractional bits in scale factors */ -#else -typedef INT32 IFAST_MULT_TYPE; /* need 32 bits for scaled quantizers */ -#define IFAST_SCALE_BITS 13 /* fractional bits in scale factors */ -#endif -typedef FAST_FLOAT FLOAT_MULT_TYPE; /* preferred floating type */ - - -/* - * Each IDCT routine is responsible for range-limiting its results and - * converting them to unsigned form (0..MAXJSAMPLE). The raw outputs could - * be quite far out of range if the input data is corrupt, so a bulletproof - * range-limiting step is required. We use a mask-and-table-lookup method - * to do the combined operations quickly. See the comments with - * prepare_range_limit_table (in jdmaster.c) for more info. - */ - -#define IDCT_range_limit(cinfo) ((cinfo)->sample_range_limit + CENTERJSAMPLE) - -#define RANGE_MASK (MAXJSAMPLE * 4 + 3) /* 2 bits wider than legal samples */ - - -/* Short forms of external names for systems with brain-damaged linkers. */ - -#ifdef NEED_SHORT_EXTERNAL_NAMES -#define jpeg_fdct_islow jFDislow -#define jpeg_fdct_ifast jFDifast -#define jpeg_fdct_float jFDfloat -#define jpeg_idct_islow jRDislow -#define jpeg_idct_ifast jRDifast -#define jpeg_idct_float jRDfloat -#define jpeg_idct_4x4 jRD4x4 -#define jpeg_idct_2x2 jRD2x2 -#define jpeg_idct_1x1 jRD1x1 -#endif /* NEED_SHORT_EXTERNAL_NAMES */ - -/* Extern declarations for the forward and inverse DCT routines. */ - -EXTERN void jpeg_fdct_islow JPP((DCTELEM * data)); -EXTERN void jpeg_fdct_ifast JPP((DCTELEM * data)); -EXTERN void jpeg_fdct_float JPP((FAST_FLOAT * data)); - -EXTERN void jpeg_idct_islow - JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr, - JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col)); -EXTERN void jpeg_idct_ifast - JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr, - JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col)); -EXTERN void jpeg_idct_float - JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr, - JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col)); -EXTERN void jpeg_idct_4x4 - JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr, - JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col)); -EXTERN void jpeg_idct_2x2 - JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr, - JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col)); -EXTERN void jpeg_idct_1x1 - JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr, - JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col)); - - -/* - * Macros for handling fixed-point arithmetic; these are used by many - * but not all of the DCT/IDCT modules. - * - * All values are expected to be of type INT32. - * Fractional constants are scaled left by CONST_BITS bits. - * CONST_BITS is defined within each module using these macros, - * and may differ from one module to the next. - */ - -#define ONE ((INT32) 1) -#define CONST_SCALE (ONE << CONST_BITS) - -/* Convert a positive real constant to an integer scaled by CONST_SCALE. - * Caution: some C compilers fail to reduce "FIX(constant)" at compile time, - * thus causing a lot of useless floating-point operations at run time. - */ - -#define FIX(x) ((INT32) ((x) * CONST_SCALE + 0.5)) - -/* Descale and correctly round an INT32 value that's scaled by N bits. - * We assume RIGHT_SHIFT rounds towards minus infinity, so adding - * the fudge factor is correct for either sign of X. - */ - -#define DESCALE(x,n) RIGHT_SHIFT((x) + (ONE << ((n)-1)), n) - -/* Multiply an INT32 variable by an INT32 constant to yield an INT32 result. - * This macro is used only when the two inputs will actually be no more than - * 16 bits wide, so that a 16x16->32 bit multiply can be used instead of a - * full 32x32 multiply. This provides a useful speedup on many machines. - * Unfortunately there is no way to specify a 16x16->32 multiply portably - * in C, but some C compilers will do the right thing if you provide the - * correct combination of casts. - */ - -#ifdef SHORTxSHORT_32 /* may work if 'int' is 32 bits */ -#define MULTIPLY16C16(var,const) (((INT16) (var)) * ((INT16) (const))) -#endif -#ifdef SHORTxLCONST_32 /* known to work with Microsoft C 6.0 */ -#define MULTIPLY16C16(var,const) (((INT16) (var)) * ((INT32) (const))) -#endif - -#ifndef MULTIPLY16C16 /* default definition */ -#define MULTIPLY16C16(var,const) ((var) * (const)) -#endif - -/* Same except both inputs are variables. */ - -#ifdef SHORTxSHORT_32 /* may work if 'int' is 32 bits */ -#define MULTIPLY16V16(var1,var2) (((INT16) (var1)) * ((INT16) (var2))) -#endif - -#ifndef MULTIPLY16V16 /* default definition */ -#define MULTIPLY16V16(var1,var2) ((var1) * (var2)) -#endif diff --git a/engine/jpeg-6/jddctmgr.c b/engine/jpeg-6/jddctmgr.c deleted file mode 100644 index 71215f1..0000000 --- a/engine/jpeg-6/jddctmgr.c +++ /dev/null @@ -1,270 +0,0 @@ -/* - * jddctmgr.c - * - * Copyright (C) 1994-1995, Thomas G. Lane. - * This file is part of the Independent JPEG Group's software. - * For conditions of distribution and use, see the accompanying README file. - * - * This file contains the inverse-DCT management logic. - * This code selects a particular IDCT implementation to be used, - * and it performs related housekeeping chores. No code in this file - * is executed per IDCT step, only during output pass setup. - * - * Note that the IDCT routines are responsible for performing coefficient - * dequantization as well as the IDCT proper. This module sets up the - * dequantization multiplier table needed by the IDCT routine. - */ - -#define JPEG_INTERNALS -#include "jinclude.h" -#include "jpeglib.h" -#include "jdct.h" /* Private declarations for DCT subsystem */ - - -/* - * The decompressor input side (jdinput.c) saves away the appropriate - * quantization table for each component at the start of the first scan - * involving that component. (This is necessary in order to correctly - * decode files that reuse Q-table slots.) - * When we are ready to make an output pass, the saved Q-table is converted - * to a multiplier table that will actually be used by the IDCT routine. - * The multiplier table contents are IDCT-method-dependent. To support - * application changes in IDCT method between scans, we can remake the - * multiplier tables if necessary. - * In buffered-image mode, the first output pass may occur before any data - * has been seen for some components, and thus before their Q-tables have - * been saved away. To handle this case, multiplier tables are preset - * to zeroes; the result of the IDCT will be a neutral gray level. - */ - - -/* Private subobject for this module */ - -typedef struct { - struct jpeg_inverse_dct pub; /* public fields */ - - /* This array contains the IDCT method code that each multiplier table - * is currently set up for, or -1 if it's not yet set up. - * The actual multiplier tables are pointed to by dct_table in the - * per-component comp_info structures. - */ - int cur_method[MAX_COMPONENTS]; -} my_idct_controller; - -typedef my_idct_controller * my_idct_ptr; - - -/* Allocated multiplier tables: big enough for any supported variant */ - -typedef union { - ISLOW_MULT_TYPE islow_array[DCTSIZE2]; -#ifdef DCT_IFAST_SUPPORTED - IFAST_MULT_TYPE ifast_array[DCTSIZE2]; -#endif -#ifdef DCT_FLOAT_SUPPORTED - FLOAT_MULT_TYPE float_array[DCTSIZE2]; -#endif -} multiplier_table; - - -/* The current scaled-IDCT routines require ISLOW-style multiplier tables, - * so be sure to compile that code if either ISLOW or SCALING is requested. - */ -#ifdef DCT_ISLOW_SUPPORTED -#define PROVIDE_ISLOW_TABLES -#else -#ifdef IDCT_SCALING_SUPPORTED -#define PROVIDE_ISLOW_TABLES -#endif -#endif - - -/* - * Prepare for an output pass. - * Here we select the proper IDCT routine for each component and build - * a matching multiplier table. - */ - -METHODDEF void -start_pass (j_decompress_ptr cinfo) -{ - my_idct_ptr idct = (my_idct_ptr) cinfo->idct; - int ci, i; - jpeg_component_info *compptr; - int method = 0; - inverse_DCT_method_ptr method_ptr = NULL; - JQUANT_TBL * qtbl; - - for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; - ci++, compptr++) { - /* Select the proper IDCT routine for this component's scaling */ - switch (compptr->DCT_scaled_size) { -#ifdef IDCT_SCALING_SUPPORTED - case 1: - method_ptr = jpeg_idct_1x1; - method = JDCT_ISLOW; /* jidctred uses islow-style table */ - break; - case 2: - method_ptr = jpeg_idct_2x2; - method = JDCT_ISLOW; /* jidctred uses islow-style table */ - break; - case 4: - method_ptr = jpeg_idct_4x4; - method = JDCT_ISLOW; /* jidctred uses islow-style table */ - break; -#endif - case DCTSIZE: - switch (cinfo->dct_method) { -#ifdef DCT_ISLOW_SUPPORTED - case JDCT_ISLOW: - method_ptr = jpeg_idct_islow; - method = JDCT_ISLOW; - break; -#endif -#ifdef DCT_IFAST_SUPPORTED - case JDCT_IFAST: - method_ptr = jpeg_idct_ifast; - method = JDCT_IFAST; - break; -#endif -#ifdef DCT_FLOAT_SUPPORTED - case JDCT_FLOAT: - method_ptr = jpeg_idct_float; - method = JDCT_FLOAT; - break; -#endif - default: - ERREXIT(cinfo, JERR_NOT_COMPILED); - break; - } - break; - default: - ERREXIT1(cinfo, JERR_BAD_DCTSIZE, compptr->DCT_scaled_size); - break; - } - idct->pub.inverse_DCT[ci] = method_ptr; - /* Create multiplier table from quant table. - * However, we can skip this if the component is uninteresting - * or if we already built the table. Also, if no quant table - * has yet been saved for the component, we leave the - * multiplier table all-zero; we'll be reading zeroes from the - * coefficient controller's buffer anyway. - */ - if (! compptr->component_needed || idct->cur_method[ci] == method) - continue; - qtbl = compptr->quant_table; - if (qtbl == NULL) /* happens if no data yet for component */ - continue; - idct->cur_method[ci] = method; - switch (method) { -#ifdef PROVIDE_ISLOW_TABLES - case JDCT_ISLOW: - { - /* For LL&M IDCT method, multipliers are equal to raw quantization - * coefficients, but are stored in natural order as ints. - */ - ISLOW_MULT_TYPE * ismtbl = (ISLOW_MULT_TYPE *) compptr->dct_table; - for (i = 0; i < DCTSIZE2; i++) { - ismtbl[i] = (ISLOW_MULT_TYPE) qtbl->quantval[jpeg_zigzag_order[i]]; - } - } - break; -#endif -#ifdef DCT_IFAST_SUPPORTED - case JDCT_IFAST: - { - /* For AA&N IDCT method, multipliers are equal to quantization - * coefficients scaled by scalefactor[row]*scalefactor[col], where - * scalefactor[0] = 1 - * scalefactor[k] = cos(k*PI/16) * sqrt(2) for k=1..7 - * For integer operation, the multiplier table is to be scaled by - * IFAST_SCALE_BITS. The multipliers are stored in natural order. - */ - IFAST_MULT_TYPE * ifmtbl = (IFAST_MULT_TYPE *) compptr->dct_table; -#define CONST_BITS 14 - static const INT16 aanscales[DCTSIZE2] = { - /* precomputed values scaled up by 14 bits */ - 16384, 22725, 21407, 19266, 16384, 12873, 8867, 4520, - 22725, 31521, 29692, 26722, 22725, 17855, 12299, 6270, - 21407, 29692, 27969, 25172, 21407, 16819, 11585, 5906, - 19266, 26722, 25172, 22654, 19266, 15137, 10426, 5315, - 16384, 22725, 21407, 19266, 16384, 12873, 8867, 4520, - 12873, 17855, 16819, 15137, 12873, 10114, 6967, 3552, - 8867, 12299, 11585, 10426, 8867, 6967, 4799, 2446, - 4520, 6270, 5906, 5315, 4520, 3552, 2446, 1247 - }; - SHIFT_TEMPS - - for (i = 0; i < DCTSIZE2; i++) { - ifmtbl[i] = (IFAST_MULT_TYPE) - DESCALE(MULTIPLY16V16((INT32) qtbl->quantval[jpeg_zigzag_order[i]], - (INT32) aanscales[i]), - CONST_BITS-IFAST_SCALE_BITS); - } - } - break; -#endif -#ifdef DCT_FLOAT_SUPPORTED - case JDCT_FLOAT: - { - /* For float AA&N IDCT method, multipliers are equal to quantization - * coefficients scaled by scalefactor[row]*scalefactor[col], where - * scalefactor[0] = 1 - * scalefactor[k] = cos(k*PI/16) * sqrt(2) for k=1..7 - * The multipliers are stored in natural order. - */ - FLOAT_MULT_TYPE * fmtbl = (FLOAT_MULT_TYPE *) compptr->dct_table; - int row, col; - static const double aanscalefactor[DCTSIZE] = { - 1.0, 1.387039845, 1.306562965, 1.175875602, - 1.0, 0.785694958, 0.541196100, 0.275899379 - }; - - i = 0; - for (row = 0; row < DCTSIZE; row++) { - for (col = 0; col < DCTSIZE; col++) { - fmtbl[i] = (FLOAT_MULT_TYPE) - ((double) qtbl->quantval[jpeg_zigzag_order[i]] * - aanscalefactor[row] * aanscalefactor[col]); - i++; - } - } - } - break; -#endif - default: - ERREXIT(cinfo, JERR_NOT_COMPILED); - break; - } - } -} - - -/* - * Initialize IDCT manager. - */ - -GLOBAL void -jinit_inverse_dct (j_decompress_ptr cinfo) -{ - my_idct_ptr idct; - int ci; - jpeg_component_info *compptr; - - idct = (my_idct_ptr) - (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, - SIZEOF(my_idct_controller)); - cinfo->idct = (struct jpeg_inverse_dct *) idct; - idct->pub.start_pass = start_pass; - - for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; - ci++, compptr++) { - /* Allocate and pre-zero a multiplier table for each component */ - compptr->dct_table = - (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, - SIZEOF(multiplier_table)); - MEMZERO(compptr->dct_table, SIZEOF(multiplier_table)); - /* Mark multiplier table not yet set up for any method */ - idct->cur_method[ci] = -1; - } -} diff --git a/engine/jpeg-6/jdhuff.c b/engine/jpeg-6/jdhuff.c deleted file mode 100644 index 95174b1..0000000 --- a/engine/jpeg-6/jdhuff.c +++ /dev/null @@ -1,574 +0,0 @@ -/* - * jdhuff.c - * - * Copyright (C) 1991-1995, Thomas G. Lane. - * This file is part of the Independent JPEG Group's software. - * For conditions of distribution and use, see the accompanying README file. - * - * This file contains Huffman entropy decoding routines. - * - * Much of the complexity here has to do with supporting input suspension. - * If the data source module demands suspension, we want to be able to back - * up to the start of the current MCU. To do this, we copy state variables - * into local working storage, and update them back to the permanent - * storage only upon successful completion of an MCU. - */ - -#define JPEG_INTERNALS -#include "jinclude.h" -#include "jpeglib.h" -#include "jdhuff.h" /* Declarations shared with jdphuff.c */ - - -/* - * Expanded entropy decoder object for Huffman decoding. - * - * The savable_state subrecord contains fields that change within an MCU, - * but must not be updated permanently until we complete the MCU. - */ - -typedef struct { - int last_dc_val[MAX_COMPS_IN_SCAN]; /* last DC coef for each component */ -} savable_state; - -/* This macro is to work around compilers with missing or broken - * structure assignment. You'll need to fix this code if you have - * such a compiler and you change MAX_COMPS_IN_SCAN. - */ - -#ifndef NO_STRUCT_ASSIGN -#define ASSIGN_STATE(dest,src) ((dest) = (src)) -#else -#if MAX_COMPS_IN_SCAN == 4 -#define ASSIGN_STATE(dest,src) \ - ((dest).last_dc_val[0] = (src).last_dc_val[0], \ - (dest).last_dc_val[1] = (src).last_dc_val[1], \ - (dest).last_dc_val[2] = (src).last_dc_val[2], \ - (dest).last_dc_val[3] = (src).last_dc_val[3]) -#endif -#endif - - -typedef struct { - struct jpeg_entropy_decoder pub; /* public fields */ - - /* These fields are loaded into local variables at start of each MCU. - * In case of suspension, we exit WITHOUT updating them. - */ - bitread_perm_state bitstate; /* Bit buffer at start of MCU */ - savable_state saved; /* Other state at start of MCU */ - - /* These fields are NOT loaded into local working state. */ - unsigned int restarts_to_go; /* MCUs left in this restart interval */ - - /* Pointers to derived tables (these workspaces have image lifespan) */ - d_derived_tbl * dc_derived_tbls[NUM_HUFF_TBLS]; - d_derived_tbl * ac_derived_tbls[NUM_HUFF_TBLS]; -} huff_entropy_decoder; - -typedef huff_entropy_decoder * huff_entropy_ptr; - - -/* - * Initialize for a Huffman-compressed scan. - */ - -METHODDEF void -start_pass_huff_decoder (j_decompress_ptr cinfo) -{ - huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy; - int ci, dctbl, actbl; - jpeg_component_info * compptr; - - /* Check that the scan parameters Ss, Se, Ah/Al are OK for sequential JPEG. - * This ought to be an error condition, but we make it a warning because - * there are some baseline files out there with all zeroes in these bytes. - */ - if (cinfo->Ss != 0 || cinfo->Se != DCTSIZE2-1 || - cinfo->Ah != 0 || cinfo->Al != 0) - WARNMS(cinfo, JWRN_NOT_SEQUENTIAL); - - for (ci = 0; ci < cinfo->comps_in_scan; ci++) { - compptr = cinfo->cur_comp_info[ci]; - dctbl = compptr->dc_tbl_no; - actbl = compptr->ac_tbl_no; - /* Make sure requested tables are present */ - if (dctbl < 0 || dctbl >= NUM_HUFF_TBLS || - cinfo->dc_huff_tbl_ptrs[dctbl] == NULL) - ERREXIT1(cinfo, JERR_NO_HUFF_TABLE, dctbl); - if (actbl < 0 || actbl >= NUM_HUFF_TBLS || - cinfo->ac_huff_tbl_ptrs[actbl] == NULL) - ERREXIT1(cinfo, JERR_NO_HUFF_TABLE, actbl); - /* Compute derived values for Huffman tables */ - /* We may do this more than once for a table, but it's not expensive */ - jpeg_make_d_derived_tbl(cinfo, cinfo->dc_huff_tbl_ptrs[dctbl], - & entropy->dc_derived_tbls[dctbl]); - jpeg_make_d_derived_tbl(cinfo, cinfo->ac_huff_tbl_ptrs[actbl], - & entropy->ac_derived_tbls[actbl]); - /* Initialize DC predictions to 0 */ - entropy->saved.last_dc_val[ci] = 0; - } - - /* Initialize bitread state variables */ - entropy->bitstate.bits_left = 0; - entropy->bitstate.get_buffer = 0; /* unnecessary, but keeps Purify quiet */ - entropy->bitstate.printed_eod = FALSE; - - /* Initialize restart counter */ - entropy->restarts_to_go = cinfo->restart_interval; -} - - -/* - * Compute the derived values for a Huffman table. - * Note this is also used by jdphuff.c. - */ - -GLOBAL void -jpeg_make_d_derived_tbl (j_decompress_ptr cinfo, JHUFF_TBL * htbl, - d_derived_tbl ** pdtbl) -{ - d_derived_tbl *dtbl; - int p, i, l, si; - int lookbits, ctr; - char huffsize[257]; - unsigned int huffcode[257]; - unsigned int code; - - /* Allocate a workspace if we haven't already done so. */ - if (*pdtbl == NULL) - *pdtbl = (d_derived_tbl *) - (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, - SIZEOF(d_derived_tbl)); - dtbl = *pdtbl; - dtbl->pub = htbl; /* fill in back link */ - - /* Figure C.1: make table of Huffman code length for each symbol */ - /* Note that this is in code-length order. */ - - p = 0; - for (l = 1; l <= 16; l++) { - for (i = 1; i <= (int) htbl->bits[l]; i++) - huffsize[p++] = (char) l; - } - huffsize[p] = 0; - - /* Figure C.2: generate the codes themselves */ - /* Note that this is in code-length order. */ - - code = 0; - si = huffsize[0]; - p = 0; - while (huffsize[p]) { - while (((int) huffsize[p]) == si) { - huffcode[p++] = code; - code++; - } - code <<= 1; - si++; - } - - /* Figure F.15: generate decoding tables for bit-sequential decoding */ - - p = 0; - for (l = 1; l <= 16; l++) { - if (htbl->bits[l]) { - dtbl->valptr[l] = p; /* huffval[] index of 1st symbol of code length l */ - dtbl->mincode[l] = huffcode[p]; /* minimum code of length l */ - p += htbl->bits[l]; - dtbl->maxcode[l] = huffcode[p-1]; /* maximum code of length l */ - } else { - dtbl->maxcode[l] = -1; /* -1 if no codes of this length */ - } - } - dtbl->maxcode[17] = 0xFFFFFL; /* ensures jpeg_huff_decode terminates */ - - /* Compute lookahead tables to speed up decoding. - * First we set all the table entries to 0, indicating "too long"; - * then we iterate through the Huffman codes that are short enough and - * fill in all the entries that correspond to bit sequences starting - * with that code. - */ - - MEMZERO(dtbl->look_nbits, SIZEOF(dtbl->look_nbits)); - - p = 0; - for (l = 1; l <= HUFF_LOOKAHEAD; l++) { - for (i = 1; i <= (int) htbl->bits[l]; i++, p++) { - /* l = current code's length, p = its index in huffcode[] & huffval[]. */ - /* Generate left-justified code followed by all possible bit sequences */ - lookbits = huffcode[p] << (HUFF_LOOKAHEAD-l); - for (ctr = 1 << (HUFF_LOOKAHEAD-l); ctr > 0; ctr--) { - dtbl->look_nbits[lookbits] = l; - dtbl->look_sym[lookbits] = htbl->huffval[p]; - lookbits++; - } - } - } -} - - -/* - * Out-of-line code for bit fetching (shared with jdphuff.c). - * See jdhuff.h for info about usage. - * Note: current values of get_buffer and bits_left are passed as parameters, - * but are returned in the corresponding fields of the state struct. - * - * On most machines MIN_GET_BITS should be 25 to allow the full 32-bit width - * of get_buffer to be used. (On machines with wider words, an even larger - * buffer could be used.) However, on some machines 32-bit shifts are - * quite slow and take time proportional to the number of places shifted. - * (This is true with most PC compilers, for instance.) In this case it may - * be a win to set MIN_GET_BITS to the minimum value of 15. This reduces the - * average shift distance at the cost of more calls to jpeg_fill_bit_buffer. - */ - -#ifdef SLOW_SHIFT_32 -#define MIN_GET_BITS 15 /* minimum allowable value */ -#else -#define MIN_GET_BITS (BIT_BUF_SIZE-7) -#endif - - -GLOBAL boolean -jpeg_fill_bit_buffer (bitread_working_state * state, - register bit_buf_type get_buffer, register int bits_left, - int nbits) -/* Load up the bit buffer to a depth of at least nbits */ -{ - /* Copy heavily used state fields into locals (hopefully registers) */ - register const JOCTET * next_input_byte = state->next_input_byte; - register size_t bytes_in_buffer = state->bytes_in_buffer; - register int c; - - /* Attempt to load at least MIN_GET_BITS bits into get_buffer. */ - /* (It is assumed that no request will be for more than that many bits.) */ - - while (bits_left < MIN_GET_BITS) { - /* Attempt to read a byte */ - if (state->unread_marker != 0) - goto no_more_data; /* can't advance past a marker */ - - if (bytes_in_buffer == 0) { - if (! (*state->cinfo->src->fill_input_buffer) (state->cinfo)) - return FALSE; - next_input_byte = state->cinfo->src->next_input_byte; - bytes_in_buffer = state->cinfo->src->bytes_in_buffer; - } - bytes_in_buffer--; - c = GETJOCTET(*next_input_byte++); - - /* If it's 0xFF, check and discard stuffed zero byte */ - if (c == 0xFF) { - do { - if (bytes_in_buffer == 0) { - if (! (*state->cinfo->src->fill_input_buffer) (state->cinfo)) - return FALSE; - next_input_byte = state->cinfo->src->next_input_byte; - bytes_in_buffer = state->cinfo->src->bytes_in_buffer; - } - bytes_in_buffer--; - c = GETJOCTET(*next_input_byte++); - } while (c == 0xFF); - - if (c == 0) { - /* Found FF/00, which represents an FF data byte */ - c = 0xFF; - } else { - /* Oops, it's actually a marker indicating end of compressed data. */ - /* Better put it back for use later */ - state->unread_marker = c; - - no_more_data: - /* There should be enough bits still left in the data segment; */ - /* if so, just break out of the outer while loop. */ - if (bits_left >= nbits) - break; - /* Uh-oh. Report corrupted data to user and stuff zeroes into - * the data stream, so that we can produce some kind of image. - * Note that this code will be repeated for each byte demanded - * for the rest of the segment. We use a nonvolatile flag to ensure - * that only one warning message appears. - */ - if (! *(state->printed_eod_ptr)) { - WARNMS(state->cinfo, JWRN_HIT_MARKER); - *(state->printed_eod_ptr) = TRUE; - } - c = 0; /* insert a zero byte into bit buffer */ - } - } - - /* OK, load c into get_buffer */ - get_buffer = (get_buffer << 8) | c; - bits_left += 8; - } - - /* Unload the local registers */ - state->next_input_byte = next_input_byte; - state->bytes_in_buffer = bytes_in_buffer; - state->get_buffer = get_buffer; - state->bits_left = bits_left; - - return TRUE; -} - - -/* - * Out-of-line code for Huffman code decoding. - * See jdhuff.h for info about usage. - */ - -GLOBAL int -jpeg_huff_decode (bitread_working_state * state, - register bit_buf_type get_buffer, register int bits_left, - d_derived_tbl * htbl, int min_bits) -{ - register int l = min_bits; - register INT32 code; - - /* HUFF_DECODE has determined that the code is at least min_bits */ - /* bits long, so fetch that many bits in one swoop. */ - - CHECK_BIT_BUFFER(*state, l, return -1); - code = GET_BITS(l); - - /* Collect the rest of the Huffman code one bit at a time. */ - /* This is per Figure F.16 in the JPEG spec. */ - - while (code > htbl->maxcode[l]) { - code <<= 1; - CHECK_BIT_BUFFER(*state, 1, return -1); - code |= GET_BITS(1); - l++; - } - - /* Unload the local registers */ - state->get_buffer = get_buffer; - state->bits_left = bits_left; - - /* With garbage input we may reach the sentinel value l = 17. */ - - if (l > 16) { - WARNMS(state->cinfo, JWRN_HUFF_BAD_CODE); - return 0; /* fake a zero as the safest result */ - } - - return htbl->pub->huffval[ htbl->valptr[l] + - ((int) (code - htbl->mincode[l])) ]; -} - - -/* - * Figure F.12: extend sign bit. - * On some machines, a shift and add will be faster than a table lookup. - */ - -#ifdef AVOID_TABLES - -#define HUFF_EXTEND(x,s) ((x) < (1<<((s)-1)) ? (x) + (((-1)<<(s)) + 1) : (x)) - -#else - -#define HUFF_EXTEND(x,s) ((x) < extend_test[s] ? (x) + extend_offset[s] : (x)) - -static const int extend_test[16] = /* entry n is 2**(n-1) */ - { 0, 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080, - 0x0100, 0x0200, 0x0400, 0x0800, 0x1000, 0x2000, 0x4000 }; - -static const int extend_offset[16] = /* entry n is (-1 << n) + 1 */ - { 0, ((-1)<<1) + 1, ((-1)<<2) + 1, ((-1)<<3) + 1, ((-1)<<4) + 1, - ((-1)<<5) + 1, ((-1)<<6) + 1, ((-1)<<7) + 1, ((-1)<<8) + 1, - ((-1)<<9) + 1, ((-1)<<10) + 1, ((-1)<<11) + 1, ((-1)<<12) + 1, - ((-1)<<13) + 1, ((-1)<<14) + 1, ((-1)<<15) + 1 }; - -#endif /* AVOID_TABLES */ - - -/* - * Check for a restart marker & resynchronize decoder. - * Returns FALSE if must suspend. - */ - -LOCAL boolean -process_restart (j_decompress_ptr cinfo) -{ - huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy; - int ci; - - /* Throw away any unused bits remaining in bit buffer; */ - /* include any full bytes in next_marker's count of discarded bytes */ - cinfo->marker->discarded_bytes += entropy->bitstate.bits_left / 8; - entropy->bitstate.bits_left = 0; - - /* Advance past the RSTn marker */ - if (! (*cinfo->marker->read_restart_marker) (cinfo)) - return FALSE; - - /* Re-initialize DC predictions to 0 */ - for (ci = 0; ci < cinfo->comps_in_scan; ci++) - entropy->saved.last_dc_val[ci] = 0; - - /* Reset restart counter */ - entropy->restarts_to_go = cinfo->restart_interval; - - /* Next segment can get another out-of-data warning */ - entropy->bitstate.printed_eod = FALSE; - - return TRUE; -} - - -/* - * Decode and return one MCU's worth of Huffman-compressed coefficients. - * The coefficients are reordered from zigzag order into natural array order, - * but are not dequantized. - * - * The i'th block of the MCU is stored into the block pointed to by - * MCU_data[i]. WE ASSUME THIS AREA HAS BEEN ZEROED BY THE CALLER. - * (Wholesale zeroing is usually a little faster than retail...) - * - * Returns FALSE if data source requested suspension. In that case no - * changes have been made to permanent state. (Exception: some output - * coefficients may already have been assigned. This is harmless for - * this module, since we'll just re-assign them on the next call.) - */ - -METHODDEF boolean -decode_mcu (j_decompress_ptr cinfo, JBLOCKROW *MCU_data) -{ - huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy; - register int s, k, r; - int blkn, ci; - JBLOCKROW block; - BITREAD_STATE_VARS; - savable_state state; - d_derived_tbl * dctbl; - d_derived_tbl * actbl; - jpeg_component_info * compptr; - - /* Process restart marker if needed; may have to suspend */ - if (cinfo->restart_interval) { - if (entropy->restarts_to_go == 0) - if (! process_restart(cinfo)) - return FALSE; - } - - /* Load up working state */ - BITREAD_LOAD_STATE(cinfo,entropy->bitstate); - ASSIGN_STATE(state, entropy->saved); - - /* Outer loop handles each block in the MCU */ - - for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) { - block = MCU_data[blkn]; - ci = cinfo->MCU_membership[blkn]; - compptr = cinfo->cur_comp_info[ci]; - dctbl = entropy->dc_derived_tbls[compptr->dc_tbl_no]; - actbl = entropy->ac_derived_tbls[compptr->ac_tbl_no]; - - /* Decode a single block's worth of coefficients */ - - /* Section F.2.2.1: decode the DC coefficient difference */ - HUFF_DECODE(s, br_state, dctbl, return FALSE, label1); - if (s) { - CHECK_BIT_BUFFER(br_state, s, return FALSE); - r = GET_BITS(s); - s = HUFF_EXTEND(r, s); - } - - /* Shortcut if component's values are not interesting */ - if (! compptr->component_needed) - goto skip_ACs; - - /* Convert DC difference to actual value, update last_dc_val */ - s += state.last_dc_val[ci]; - state.last_dc_val[ci] = s; - /* Output the DC coefficient (assumes jpeg_natural_order[0] = 0) */ - (*block)[0] = (JCOEF) s; - - /* Do we need to decode the AC coefficients for this component? */ - if (compptr->DCT_scaled_size > 1) { - - /* Section F.2.2.2: decode the AC coefficients */ - /* Since zeroes are skipped, output area must be cleared beforehand */ - for (k = 1; k < DCTSIZE2; k++) { - HUFF_DECODE(s, br_state, actbl, return FALSE, label2); - - r = s >> 4; - s &= 15; - - if (s) { - k += r; - CHECK_BIT_BUFFER(br_state, s, return FALSE); - r = GET_BITS(s); - s = HUFF_EXTEND(r, s); - /* Output coefficient in natural (dezigzagged) order. - * Note: the extra entries in jpeg_natural_order[] will save us - * if k >= DCTSIZE2, which could happen if the data is corrupted. - */ - (*block)[jpeg_natural_order[k]] = (JCOEF) s; - } else { - if (r != 15) - break; - k += 15; - } - } - - } else { -skip_ACs: - - /* Section F.2.2.2: decode the AC coefficients */ - /* In this path we just discard the values */ - for (k = 1; k < DCTSIZE2; k++) { - HUFF_DECODE(s, br_state, actbl, return FALSE, label3); - - r = s >> 4; - s &= 15; - - if (s) { - k += r; - CHECK_BIT_BUFFER(br_state, s, return FALSE); - DROP_BITS(s); - } else { - if (r != 15) - break; - k += 15; - } - } - - } - } - - /* Completed MCU, so update state */ - BITREAD_SAVE_STATE(cinfo,entropy->bitstate); - ASSIGN_STATE(entropy->saved, state); - - /* Account for restart interval (no-op if not using restarts) */ - entropy->restarts_to_go--; - - return TRUE; -} - - -/* - * Module initialization routine for Huffman entropy decoding. - */ - -GLOBAL void -jinit_huff_decoder (j_decompress_ptr cinfo) -{ - huff_entropy_ptr entropy; - int i; - - entropy = (huff_entropy_ptr) - (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, - SIZEOF(huff_entropy_decoder)); - cinfo->entropy = (struct jpeg_entropy_decoder *) entropy; - entropy->pub.start_pass = start_pass_huff_decoder; - entropy->pub.decode_mcu = decode_mcu; - - /* Mark tables unallocated */ - for (i = 0; i < NUM_HUFF_TBLS; i++) { - entropy->dc_derived_tbls[i] = entropy->ac_derived_tbls[i] = NULL; - } -} diff --git a/engine/jpeg-6/jdhuff.h b/engine/jpeg-6/jdhuff.h deleted file mode 100644 index d375c78..0000000 --- a/engine/jpeg-6/jdhuff.h +++ /dev/null @@ -1,202 +0,0 @@ -/* - * jdhuff.h - * - * Copyright (C) 1991-1995, Thomas G. Lane. - * This file is part of the Independent JPEG Group's software. - * For conditions of distribution and use, see the accompanying README file. - * - * This file contains declarations for Huffman entropy decoding routines - * that are shared between the sequential decoder (jdhuff.c) and the - * progressive decoder (jdphuff.c). No other modules need to see these. - */ - -/* Short forms of external names for systems with brain-damaged linkers. */ - -#ifdef NEED_SHORT_EXTERNAL_NAMES -#define jpeg_make_d_derived_tbl jMkDDerived -#define jpeg_fill_bit_buffer jFilBitBuf -#define jpeg_huff_decode jHufDecode -#endif /* NEED_SHORT_EXTERNAL_NAMES */ - - -/* Derived data constructed for each Huffman table */ - -#define HUFF_LOOKAHEAD 8 /* # of bits of lookahead */ - -typedef struct { - /* Basic tables: (element [0] of each array is unused) */ - INT32 mincode[17]; /* smallest code of length k */ - INT32 maxcode[18]; /* largest code of length k (-1 if none) */ - /* (maxcode[17] is a sentinel to ensure jpeg_huff_decode terminates) */ - int valptr[17]; /* huffval[] index of 1st symbol of length k */ - - /* Link to public Huffman table (needed only in jpeg_huff_decode) */ - JHUFF_TBL *pub; - - /* Lookahead tables: indexed by the next HUFF_LOOKAHEAD bits of - * the input data stream. If the next Huffman code is no more - * than HUFF_LOOKAHEAD bits long, we can obtain its length and - * the corresponding symbol directly from these tables. - */ - int look_nbits[1< 32 bits on your machine, and shifting/masking longs is - * reasonably fast, making bit_buf_type be long and setting BIT_BUF_SIZE - * appropriately should be a win. Unfortunately we can't do this with - * something like #define BIT_BUF_SIZE (sizeof(bit_buf_type)*8) - * because not all machines measure sizeof in 8-bit bytes. - */ - -typedef struct { /* Bitreading state saved across MCUs */ - bit_buf_type get_buffer; /* current bit-extraction buffer */ - int bits_left; /* # of unused bits in it */ - boolean printed_eod; /* flag to suppress multiple warning msgs */ -} bitread_perm_state; - -typedef struct { /* Bitreading working state within an MCU */ - /* current data source state */ - const JOCTET * next_input_byte; /* => next byte to read from source */ - size_t bytes_in_buffer; /* # of bytes remaining in source buffer */ - int unread_marker; /* nonzero if we have hit a marker */ - /* bit input buffer --- note these values are kept in register variables, - * not in this struct, inside the inner loops. - */ - bit_buf_type get_buffer; /* current bit-extraction buffer */ - int bits_left; /* # of unused bits in it */ - /* pointers needed by jpeg_fill_bit_buffer */ - j_decompress_ptr cinfo; /* back link to decompress master record */ - boolean * printed_eod_ptr; /* => flag in permanent state */ -} bitread_working_state; - -/* Macros to declare and load/save bitread local variables. */ -#define BITREAD_STATE_VARS \ - register bit_buf_type get_buffer; \ - register int bits_left; \ - bitread_working_state br_state - -#define BITREAD_LOAD_STATE(cinfop,permstate) \ - br_state.cinfo = cinfop; \ - br_state.next_input_byte = cinfop->src->next_input_byte; \ - br_state.bytes_in_buffer = cinfop->src->bytes_in_buffer; \ - br_state.unread_marker = cinfop->unread_marker; \ - get_buffer = permstate.get_buffer; \ - bits_left = permstate.bits_left; \ - br_state.printed_eod_ptr = & permstate.printed_eod - -#define BITREAD_SAVE_STATE(cinfop,permstate) \ - cinfop->src->next_input_byte = br_state.next_input_byte; \ - cinfop->src->bytes_in_buffer = br_state.bytes_in_buffer; \ - cinfop->unread_marker = br_state.unread_marker; \ - permstate.get_buffer = get_buffer; \ - permstate.bits_left = bits_left - -/* - * These macros provide the in-line portion of bit fetching. - * Use CHECK_BIT_BUFFER to ensure there are N bits in get_buffer - * before using GET_BITS, PEEK_BITS, or DROP_BITS. - * The variables get_buffer and bits_left are assumed to be locals, - * but the state struct might not be (jpeg_huff_decode needs this). - * CHECK_BIT_BUFFER(state,n,action); - * Ensure there are N bits in get_buffer; if suspend, take action. - * val = GET_BITS(n); - * Fetch next N bits. - * val = PEEK_BITS(n); - * Fetch next N bits without removing them from the buffer. - * DROP_BITS(n); - * Discard next N bits. - * The value N should be a simple variable, not an expression, because it - * is evaluated multiple times. - */ - -#define CHECK_BIT_BUFFER(state,nbits,action) \ - { if (bits_left < (nbits)) { \ - if (! jpeg_fill_bit_buffer(&(state),get_buffer,bits_left,nbits)) \ - { action; } \ - get_buffer = (state).get_buffer; bits_left = (state).bits_left; } } - -#define GET_BITS(nbits) \ - (((int) (get_buffer >> (bits_left -= (nbits)))) & ((1<<(nbits))-1)) - -#define PEEK_BITS(nbits) \ - (((int) (get_buffer >> (bits_left - (nbits)))) & ((1<<(nbits))-1)) - -#define DROP_BITS(nbits) \ - (bits_left -= (nbits)) - -/* Load up the bit buffer to a depth of at least nbits */ -EXTERN boolean jpeg_fill_bit_buffer JPP((bitread_working_state * state, - register bit_buf_type get_buffer, register int bits_left, - int nbits)); - - -/* - * Code for extracting next Huffman-coded symbol from input bit stream. - * Again, this is time-critical and we make the main paths be macros. - * - * We use a lookahead table to process codes of up to HUFF_LOOKAHEAD bits - * without looping. Usually, more than 95% of the Huffman codes will be 8 - * or fewer bits long. The few overlength codes are handled with a loop, - * which need not be inline code. - * - * Notes about the HUFF_DECODE macro: - * 1. Near the end of the data segment, we may fail to get enough bits - * for a lookahead. In that case, we do it the hard way. - * 2. If the lookahead table contains no entry, the next code must be - * more than HUFF_LOOKAHEAD bits long. - * 3. jpeg_huff_decode returns -1 if forced to suspend. - */ - -#define HUFF_DECODE(result,state,htbl,failaction,slowlabel) \ -{ register int nb, look; \ - if (bits_left < HUFF_LOOKAHEAD) { \ - if (! jpeg_fill_bit_buffer(&state,get_buffer,bits_left, 0)) {failaction;} \ - get_buffer = state.get_buffer; bits_left = state.bits_left; \ - if (bits_left < HUFF_LOOKAHEAD) { \ - nb = 1; goto slowlabel; \ - } \ - } \ - look = PEEK_BITS(HUFF_LOOKAHEAD); \ - if ((nb = htbl->look_nbits[look]) != 0) { \ - DROP_BITS(nb); \ - result = htbl->look_sym[look]; \ - } else { \ - nb = HUFF_LOOKAHEAD+1; \ -slowlabel: \ - if ((result=jpeg_huff_decode(&state,get_buffer,bits_left,htbl,nb)) < 0) \ - { failaction; } \ - get_buffer = state.get_buffer; bits_left = state.bits_left; \ - } \ -} - -/* Out-of-line case for Huffman code fetching */ -EXTERN int jpeg_huff_decode JPP((bitread_working_state * state, - register bit_buf_type get_buffer, register int bits_left, - d_derived_tbl * htbl, int min_bits)); diff --git a/engine/jpeg-6/jdinput.c b/engine/jpeg-6/jdinput.c deleted file mode 100644 index 3061a17..0000000 --- a/engine/jpeg-6/jdinput.c +++ /dev/null @@ -1,381 +0,0 @@ -/* - * jdinput.c - * - * Copyright (C) 1991-1995, Thomas G. Lane. - * This file is part of the Independent JPEG Group's software. - * For conditions of distribution and use, see the accompanying README file. - * - * This file contains input control logic for the JPEG decompressor. - * These routines are concerned with controlling the decompressor's input - * processing (marker reading and coefficient decoding). The actual input - * reading is done in jdmarker.c, jdhuff.c, and jdphuff.c. - */ - -#define JPEG_INTERNALS -#include "jinclude.h" -#include "jpeglib.h" - - -/* Private state */ - -typedef struct { - struct jpeg_input_controller pub; /* public fields */ - - boolean inheaders; /* TRUE until first SOS is reached */ -} my_input_controller; - -typedef my_input_controller * my_inputctl_ptr; - - -/* Forward declarations */ -METHODDEF int consume_markers JPP((j_decompress_ptr cinfo)); - - -/* - * Routines to calculate various quantities related to the size of the image. - */ - -LOCAL void -initial_setup (j_decompress_ptr cinfo) -/* Called once, when first SOS marker is reached */ -{ - int ci; - jpeg_component_info *compptr; - - /* Make sure image isn't bigger than I can handle */ - if ((long) cinfo->image_height > (long) JPEG_MAX_DIMENSION || - (long) cinfo->image_width > (long) JPEG_MAX_DIMENSION) - ERREXIT1(cinfo, JERR_IMAGE_TOO_BIG, (unsigned int) JPEG_MAX_DIMENSION); - - /* For now, precision must match compiled-in value... */ - if (cinfo->data_precision != BITS_IN_JSAMPLE) - ERREXIT1(cinfo, JERR_BAD_PRECISION, cinfo->data_precision); - - /* Check that number of components won't exceed internal array sizes */ - if (cinfo->num_components > MAX_COMPONENTS) - ERREXIT2(cinfo, JERR_COMPONENT_COUNT, cinfo->num_components, - MAX_COMPONENTS); - - /* Compute maximum sampling factors; check factor validity */ - cinfo->max_h_samp_factor = 1; - cinfo->max_v_samp_factor = 1; - for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; - ci++, compptr++) { - if (compptr->h_samp_factor<=0 || compptr->h_samp_factor>MAX_SAMP_FACTOR || - compptr->v_samp_factor<=0 || compptr->v_samp_factor>MAX_SAMP_FACTOR) - ERREXIT(cinfo, JERR_BAD_SAMPLING); - cinfo->max_h_samp_factor = MAX(cinfo->max_h_samp_factor, - compptr->h_samp_factor); - cinfo->max_v_samp_factor = MAX(cinfo->max_v_samp_factor, - compptr->v_samp_factor); - } - - /* We initialize DCT_scaled_size and min_DCT_scaled_size to DCTSIZE. - * In the full decompressor, this will be overridden by jdmaster.c; - * but in the transcoder, jdmaster.c is not used, so we must do it here. - */ - cinfo->min_DCT_scaled_size = DCTSIZE; - - /* Compute dimensions of components */ - for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; - ci++, compptr++) { - compptr->DCT_scaled_size = DCTSIZE; - /* Size in DCT blocks */ - compptr->width_in_blocks = (JDIMENSION) - jdiv_round_up((long) cinfo->image_width * (long) compptr->h_samp_factor, - (long) (cinfo->max_h_samp_factor * DCTSIZE)); - compptr->height_in_blocks = (JDIMENSION) - jdiv_round_up((long) cinfo->image_height * (long) compptr->v_samp_factor, - (long) (cinfo->max_v_samp_factor * DCTSIZE)); - /* downsampled_width and downsampled_height will also be overridden by - * jdmaster.c if we are doing full decompression. The transcoder library - * doesn't use these values, but the calling application might. - */ - /* Size in samples */ - compptr->downsampled_width = (JDIMENSION) - jdiv_round_up((long) cinfo->image_width * (long) compptr->h_samp_factor, - (long) cinfo->max_h_samp_factor); - compptr->downsampled_height = (JDIMENSION) - jdiv_round_up((long) cinfo->image_height * (long) compptr->v_samp_factor, - (long) cinfo->max_v_samp_factor); - /* Mark component needed, until color conversion says otherwise */ - compptr->component_needed = TRUE; - /* Mark no quantization table yet saved for component */ - compptr->quant_table = NULL; - } - - /* Compute number of fully interleaved MCU rows. */ - cinfo->total_iMCU_rows = (JDIMENSION) - jdiv_round_up((long) cinfo->image_height, - (long) (cinfo->max_v_samp_factor*DCTSIZE)); - - /* Decide whether file contains multiple scans */ - if (cinfo->comps_in_scan < cinfo->num_components || cinfo->progressive_mode) - cinfo->inputctl->has_multiple_scans = TRUE; - else - cinfo->inputctl->has_multiple_scans = FALSE; -} - - -LOCAL void -per_scan_setup (j_decompress_ptr cinfo) -/* Do computations that are needed before processing a JPEG scan */ -/* cinfo->comps_in_scan and cinfo->cur_comp_info[] were set from SOS marker */ -{ - int ci, mcublks, tmp; - jpeg_component_info *compptr; - - if (cinfo->comps_in_scan == 1) { - - /* Noninterleaved (single-component) scan */ - compptr = cinfo->cur_comp_info[0]; - - /* Overall image size in MCUs */ - cinfo->MCUs_per_row = compptr->width_in_blocks; - cinfo->MCU_rows_in_scan = compptr->height_in_blocks; - - /* For noninterleaved scan, always one block per MCU */ - compptr->MCU_width = 1; - compptr->MCU_height = 1; - compptr->MCU_blocks = 1; - compptr->MCU_sample_width = compptr->DCT_scaled_size; - compptr->last_col_width = 1; - /* For noninterleaved scans, it is convenient to define last_row_height - * as the number of block rows present in the last iMCU row. - */ - tmp = (int) (compptr->height_in_blocks % compptr->v_samp_factor); - if (tmp == 0) tmp = compptr->v_samp_factor; - compptr->last_row_height = tmp; - - /* Prepare array describing MCU composition */ - cinfo->blocks_in_MCU = 1; - cinfo->MCU_membership[0] = 0; - - } else { - - /* Interleaved (multi-component) scan */ - if (cinfo->comps_in_scan <= 0 || cinfo->comps_in_scan > MAX_COMPS_IN_SCAN) - ERREXIT2(cinfo, JERR_COMPONENT_COUNT, cinfo->comps_in_scan, - MAX_COMPS_IN_SCAN); - - /* Overall image size in MCUs */ - cinfo->MCUs_per_row = (JDIMENSION) - jdiv_round_up((long) cinfo->image_width, - (long) (cinfo->max_h_samp_factor*DCTSIZE)); - cinfo->MCU_rows_in_scan = (JDIMENSION) - jdiv_round_up((long) cinfo->image_height, - (long) (cinfo->max_v_samp_factor*DCTSIZE)); - - cinfo->blocks_in_MCU = 0; - - for (ci = 0; ci < cinfo->comps_in_scan; ci++) { - compptr = cinfo->cur_comp_info[ci]; - /* Sampling factors give # of blocks of component in each MCU */ - compptr->MCU_width = compptr->h_samp_factor; - compptr->MCU_height = compptr->v_samp_factor; - compptr->MCU_blocks = compptr->MCU_width * compptr->MCU_height; - compptr->MCU_sample_width = compptr->MCU_width * compptr->DCT_scaled_size; - /* Figure number of non-dummy blocks in last MCU column & row */ - tmp = (int) (compptr->width_in_blocks % compptr->MCU_width); - if (tmp == 0) tmp = compptr->MCU_width; - compptr->last_col_width = tmp; - tmp = (int) (compptr->height_in_blocks % compptr->MCU_height); - if (tmp == 0) tmp = compptr->MCU_height; - compptr->last_row_height = tmp; - /* Prepare array describing MCU composition */ - mcublks = compptr->MCU_blocks; - if (cinfo->blocks_in_MCU + mcublks > D_MAX_BLOCKS_IN_MCU) - ERREXIT(cinfo, JERR_BAD_MCU_SIZE); - while (mcublks-- > 0) { - cinfo->MCU_membership[cinfo->blocks_in_MCU++] = ci; - } - } - - } -} - - -/* - * Save away a copy of the Q-table referenced by each component present - * in the current scan, unless already saved during a prior scan. - * - * In a multiple-scan JPEG file, the encoder could assign different components - * the same Q-table slot number, but change table definitions between scans - * so that each component uses a different Q-table. (The IJG encoder is not - * currently capable of doing this, but other encoders might.) Since we want - * to be able to dequantize all the components at the end of the file, this - * means that we have to save away the table actually used for each component. - * We do this by copying the table at the start of the first scan containing - * the component. - * The JPEG spec prohibits the encoder from changing the contents of a Q-table - * slot between scans of a component using that slot. If the encoder does so - * anyway, this decoder will simply use the Q-table values that were current - * at the start of the first scan for the component. - * - * The decompressor output side looks only at the saved quant tables, - * not at the current Q-table slots. - */ - -LOCAL void -latch_quant_tables (j_decompress_ptr cinfo) -{ - int ci, qtblno; - jpeg_component_info *compptr; - JQUANT_TBL * qtbl; - - for (ci = 0; ci < cinfo->comps_in_scan; ci++) { - compptr = cinfo->cur_comp_info[ci]; - /* No work if we already saved Q-table for this component */ - if (compptr->quant_table != NULL) - continue; - /* Make sure specified quantization table is present */ - qtblno = compptr->quant_tbl_no; - if (qtblno < 0 || qtblno >= NUM_QUANT_TBLS || - cinfo->quant_tbl_ptrs[qtblno] == NULL) - ERREXIT1(cinfo, JERR_NO_QUANT_TABLE, qtblno); - /* OK, save away the quantization table */ - qtbl = (JQUANT_TBL *) - (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, - SIZEOF(JQUANT_TBL)); - MEMCOPY(qtbl, cinfo->quant_tbl_ptrs[qtblno], SIZEOF(JQUANT_TBL)); - compptr->quant_table = qtbl; - } -} - - -/* - * Initialize the input modules to read a scan of compressed data. - * The first call to this is done by jdmaster.c after initializing - * the entire decompressor (during jpeg_start_decompress). - * Subsequent calls come from consume_markers, below. - */ - -METHODDEF void -start_input_pass (j_decompress_ptr cinfo) -{ - per_scan_setup(cinfo); - latch_quant_tables(cinfo); - (*cinfo->entropy->start_pass) (cinfo); - (*cinfo->coef->start_input_pass) (cinfo); - cinfo->inputctl->consume_input = cinfo->coef->consume_data; -} - - -/* - * Finish up after inputting a compressed-data scan. - * This is called by the coefficient controller after it's read all - * the expected data of the scan. - */ - -METHODDEF void -finish_input_pass (j_decompress_ptr cinfo) -{ - cinfo->inputctl->consume_input = consume_markers; -} - - -/* - * Read JPEG markers before, between, or after compressed-data scans. - * Change state as necessary when a new scan is reached. - * Return value is JPEG_SUSPENDED, JPEG_REACHED_SOS, or JPEG_REACHED_EOI. - * - * The consume_input method pointer points either here or to the - * coefficient controller's consume_data routine, depending on whether - * we are reading a compressed data segment or inter-segment markers. - */ - -METHODDEF int -consume_markers (j_decompress_ptr cinfo) -{ - my_inputctl_ptr inputctl = (my_inputctl_ptr) cinfo->inputctl; - int val; - - if (inputctl->pub.eoi_reached) /* After hitting EOI, read no further */ - return JPEG_REACHED_EOI; - - val = (*cinfo->marker->read_markers) (cinfo); - - switch (val) { - case JPEG_REACHED_SOS: /* Found SOS */ - if (inputctl->inheaders) { /* 1st SOS */ - initial_setup(cinfo); - inputctl->inheaders = FALSE; - /* Note: start_input_pass must be called by jdmaster.c - * before any more input can be consumed. jdapi.c is - * responsible for enforcing this sequencing. - */ - } else { /* 2nd or later SOS marker */ - if (! inputctl->pub.has_multiple_scans) - ERREXIT(cinfo, JERR_EOI_EXPECTED); /* Oops, I wasn't expecting this! */ - start_input_pass(cinfo); - } - break; - case JPEG_REACHED_EOI: /* Found EOI */ - inputctl->pub.eoi_reached = TRUE; - if (inputctl->inheaders) { /* Tables-only datastream, apparently */ - if (cinfo->marker->saw_SOF) - ERREXIT(cinfo, JERR_SOF_NO_SOS); - } else { - /* Prevent infinite loop in coef ctlr's decompress_data routine - * if user set output_scan_number larger than number of scans. - */ - if (cinfo->output_scan_number > cinfo->input_scan_number) - cinfo->output_scan_number = cinfo->input_scan_number; - } - break; - case JPEG_SUSPENDED: - break; - } - - return val; -} - - -/* - * Reset state to begin a fresh datastream. - */ - -METHODDEF void -reset_input_controller (j_decompress_ptr cinfo) -{ - my_inputctl_ptr inputctl = (my_inputctl_ptr) cinfo->inputctl; - - inputctl->pub.consume_input = consume_markers; - inputctl->pub.has_multiple_scans = FALSE; /* "unknown" would be better */ - inputctl->pub.eoi_reached = FALSE; - inputctl->inheaders = TRUE; - /* Reset other modules */ - (*cinfo->err->reset_error_mgr) ((j_common_ptr) cinfo); - (*cinfo->marker->reset_marker_reader) (cinfo); - /* Reset progression state -- would be cleaner if entropy decoder did this */ - cinfo->coef_bits = NULL; -} - - -/* - * Initialize the input controller module. - * This is called only once, when the decompression object is created. - */ - -GLOBAL void -jinit_input_controller (j_decompress_ptr cinfo) -{ - my_inputctl_ptr inputctl; - - /* Create subobject in permanent pool */ - inputctl = (my_inputctl_ptr) - (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT, - SIZEOF(my_input_controller)); - cinfo->inputctl = (struct jpeg_input_controller *) inputctl; - /* Initialize method pointers */ - inputctl->pub.consume_input = consume_markers; - inputctl->pub.reset_input_controller = reset_input_controller; - inputctl->pub.start_input_pass = start_input_pass; - inputctl->pub.finish_input_pass = finish_input_pass; - /* Initialize state: can't use reset_input_controller since we don't - * want to try to reset other modules yet. - */ - inputctl->pub.has_multiple_scans = FALSE; /* "unknown" would be better */ - inputctl->pub.eoi_reached = FALSE; - inputctl->inheaders = TRUE; -} diff --git a/engine/jpeg-6/jdmainct.c b/engine/jpeg-6/jdmainct.c deleted file mode 100644 index 6cb0b7a..0000000 --- a/engine/jpeg-6/jdmainct.c +++ /dev/null @@ -1,520 +0,0 @@ -/* - * jdmainct.c - * - * Copyright (C) 1994-1995, Thomas G. Lane. - * This file is part of the Independent JPEG Group's software. - * For conditions of distribution and use, see the accompanying README file. - * - * This file contains the main buffer controller for decompression. - * The main buffer lies between the JPEG decompressor proper and the - * post-processor; it holds downsampled data in the JPEG colorspace. - * - * Note that this code is bypassed in raw-data mode, since the application - * supplies the equivalent of the main buffer in that case. - */ - -#define JPEG_INTERNALS -#include "jinclude.h" -#include "jpeglib.h" - - -/* - * In the current system design, the main buffer need never be a full-image - * buffer; any full-height buffers will be found inside the coefficient or - * postprocessing controllers. Nonetheless, the main controller is not - * trivial. Its responsibility is to provide context rows for upsampling/ - * rescaling, and doing this in an efficient fashion is a bit tricky. - * - * Postprocessor input data is counted in "row groups". A row group - * is defined to be (v_samp_factor * DCT_scaled_size / min_DCT_scaled_size) - * sample rows of each component. (We require DCT_scaled_size values to be - * chosen such that these numbers are integers. In practice DCT_scaled_size - * values will likely be powers of two, so we actually have the stronger - * condition that DCT_scaled_size / min_DCT_scaled_size is an integer.) - * Upsampling will typically produce max_v_samp_factor pixel rows from each - * row group (times any additional scale factor that the upsampler is - * applying). - * - * The coefficient controller will deliver data to us one iMCU row at a time; - * each iMCU row contains v_samp_factor * DCT_scaled_size sample rows, or - * exactly min_DCT_scaled_size row groups. (This amount of data corresponds - * to one row of MCUs when the image is fully interleaved.) Note that the - * number of sample rows varies across components, but the number of row - * groups does not. Some garbage sample rows may be included in the last iMCU - * row at the bottom of the image. - * - * Depending on the vertical scaling algorithm used, the upsampler may need - * access to the sample row(s) above and below its current input row group. - * The upsampler is required to set need_context_rows TRUE at global selection - * time if so. When need_context_rows is FALSE, this controller can simply - * obtain one iMCU row at a time from the coefficient controller and dole it - * out as row groups to the postprocessor. - * - * When need_context_rows is TRUE, this controller guarantees that the buffer - * passed to postprocessing contains at least one row group's worth of samples - * above and below the row group(s) being processed. Note that the context - * rows "above" the first passed row group appear at negative row offsets in - * the passed buffer. At the top and bottom of the image, the required - * context rows are manufactured by duplicating the first or last real sample - * row; this avoids having special cases in the upsampling inner loops. - * - * The amount of context is fixed at one row group just because that's a - * convenient number for this controller to work with. The existing - * upsamplers really only need one sample row of context. An upsampler - * supporting arbitrary output rescaling might wish for more than one row - * group of context when shrinking the image; tough, we don't handle that. - * (This is justified by the assumption that downsizing will be handled mostly - * by adjusting the DCT_scaled_size values, so that the actual scale factor at - * the upsample step needn't be much less than one.) - * - * To provide the desired context, we have to retain the last two row groups - * of one iMCU row while reading in the next iMCU row. (The last row group - * can't be processed until we have another row group for its below-context, - * and so we have to save the next-to-last group too for its above-context.) - * We could do this most simply by copying data around in our buffer, but - * that'd be very slow. We can avoid copying any data by creating a rather - * strange pointer structure. Here's how it works. We allocate a workspace - * consisting of M+2 row groups (where M = min_DCT_scaled_size is the number - * of row groups per iMCU row). We create two sets of redundant pointers to - * the workspace. Labeling the physical row groups 0 to M+1, the synthesized - * pointer lists look like this: - * M+1 M-1 - * master pointer --> 0 master pointer --> 0 - * 1 1 - * ... ... - * M-3 M-3 - * M-2 M - * M-1 M+1 - * M M-2 - * M+1 M-1 - * 0 0 - * We read alternate iMCU rows using each master pointer; thus the last two - * row groups of the previous iMCU row remain un-overwritten in the workspace. - * The pointer lists are set up so that the required context rows appear to - * be adjacent to the proper places when we pass the pointer lists to the - * upsampler. - * - * The above pictures describe the normal state of the pointer lists. - * At top and bottom of the image, we diddle the pointer lists to duplicate - * the first or last sample row as necessary (this is cheaper than copying - * sample rows around). - * - * This scheme breaks down if M < 2, ie, min_DCT_scaled_size is 1. In that - * situation each iMCU row provides only one row group so the buffering logic - * must be different (eg, we must read two iMCU rows before we can emit the - * first row group). For now, we simply do not support providing context - * rows when min_DCT_scaled_size is 1. That combination seems unlikely to - * be worth providing --- if someone wants a 1/8th-size preview, they probably - * want it quick and dirty, so a context-free upsampler is sufficient. - */ - - -/* Private buffer controller object */ - -typedef struct { - struct jpeg_d_main_controller pub; /* public fields */ - - /* Pointer to allocated workspace (M or M+2 row groups). */ - JSAMPARRAY buffer[MAX_COMPONENTS]; - - boolean buffer_full; /* Have we gotten an iMCU row from decoder? */ - JDIMENSION rowgroup_ctr; /* counts row groups output to postprocessor */ - - /* Remaining fields are only used in the context case. */ - - /* These are the master pointers to the funny-order pointer lists. */ - JSAMPIMAGE xbuffer[2]; /* pointers to weird pointer lists */ - - int whichptr; /* indicates which pointer set is now in use */ - int context_state; /* process_data state machine status */ - JDIMENSION rowgroups_avail; /* row groups available to postprocessor */ - JDIMENSION iMCU_row_ctr; /* counts iMCU rows to detect image top/bot */ -} my_main_controller; - -typedef my_main_controller * my_main_ptr; - -/* context_state values: */ -#define CTX_PREPARE_FOR_IMCU 0 /* need to prepare for MCU row */ -#define CTX_PROCESS_IMCU 1 /* feeding iMCU to postprocessor */ -#define CTX_POSTPONED_ROW 2 /* feeding postponed row group */ - - -/* Forward declarations */ -METHODDEF void process_data_simple_main - JPP((j_decompress_ptr cinfo, JSAMPARRAY output_buf, - JDIMENSION *out_row_ctr, JDIMENSION out_rows_avail)); -METHODDEF void process_data_context_main - JPP((j_decompress_ptr cinfo, JSAMPARRAY output_buf, - JDIMENSION *out_row_ctr, JDIMENSION out_rows_avail)); -#ifdef QUANT_2PASS_SUPPORTED -METHODDEF void process_data_crank_post - JPP((j_decompress_ptr cinfo, JSAMPARRAY output_buf, - JDIMENSION *out_row_ctr, JDIMENSION out_rows_avail)); -#endif - - -LOCAL void -alloc_funny_pointers (j_decompress_ptr cinfo) -/* Allocate space for the funny pointer lists. - * This is done only once, not once per pass. - */ -{ - // bk001204 - no use main - my_main_ptr jmain = (my_main_ptr) cinfo->main; - int ci, rgroup; - int M = cinfo->min_DCT_scaled_size; - jpeg_component_info *compptr; - JSAMPARRAY xbuf; - - /* Get top-level space for component array pointers. - * We alloc both arrays with one call to save a few cycles. - */ - jmain->xbuffer[0] = (JSAMPIMAGE) - (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, - cinfo->num_components * 2 * SIZEOF(JSAMPARRAY)); - jmain->xbuffer[1] = jmain->xbuffer[0] + cinfo->num_components; - - for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; - ci++, compptr++) { - rgroup = (compptr->v_samp_factor * compptr->DCT_scaled_size) / - cinfo->min_DCT_scaled_size; /* height of a row group of component */ - /* Get space for pointer lists --- M+4 row groups in each list. - * We alloc both pointer lists with one call to save a few cycles. - */ - xbuf = (JSAMPARRAY) - (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, - 2 * (rgroup * (M + 4)) * SIZEOF(JSAMPROW)); - xbuf += rgroup; /* want one row group at negative offsets */ - jmain->xbuffer[0][ci] = xbuf; - xbuf += rgroup * (M + 4); - jmain->xbuffer[1][ci] = xbuf; - } -} - - -LOCAL void -make_funny_pointers (j_decompress_ptr cinfo) -/* Create the funny pointer lists discussed in the comments above. - * The actual workspace is already allocated (in main->buffer), - * and the space for the pointer lists is allocated too. - * This routine just fills in the curiously ordered lists. - * This will be repeated at the beginning of each pass. - */ -{ - // bk001204 - no use main - my_main_ptr jmain = (my_main_ptr) cinfo->main; - int ci, i, rgroup; - int M = cinfo->min_DCT_scaled_size; - jpeg_component_info *compptr; - JSAMPARRAY buf, xbuf0, xbuf1; - - for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; - ci++, compptr++) { - rgroup = (compptr->v_samp_factor * compptr->DCT_scaled_size) / - cinfo->min_DCT_scaled_size; /* height of a row group of component */ - xbuf0 = jmain->xbuffer[0][ci]; - xbuf1 = jmain->xbuffer[1][ci]; - /* First copy the workspace pointers as-is */ - buf = jmain->buffer[ci]; - for (i = 0; i < rgroup * (M + 2); i++) { - xbuf0[i] = xbuf1[i] = buf[i]; - } - /* In the second list, put the last four row groups in swapped order */ - for (i = 0; i < rgroup * 2; i++) { - xbuf1[rgroup*(M-2) + i] = buf[rgroup*M + i]; - xbuf1[rgroup*M + i] = buf[rgroup*(M-2) + i]; - } - /* The wraparound pointers at top and bottom will be filled later - * (see set_wraparound_pointers, below). Initially we want the "above" - * pointers to duplicate the first actual data line. This only needs - * to happen in xbuffer[0]. - */ - for (i = 0; i < rgroup; i++) { - xbuf0[i - rgroup] = xbuf0[0]; - } - } -} - - -LOCAL void -set_wraparound_pointers (j_decompress_ptr cinfo) -/* Set up the "wraparound" pointers at top and bottom of the pointer lists. - * This changes the pointer list state from top-of-image to the normal state. - */ -{ - // bk001204 - no use main - my_main_ptr jmain = (my_main_ptr) cinfo->main; - int ci, i, rgroup; - int M = cinfo->min_DCT_scaled_size; - jpeg_component_info *compptr; - JSAMPARRAY xbuf0, xbuf1; - - for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; - ci++, compptr++) { - rgroup = (compptr->v_samp_factor * compptr->DCT_scaled_size) / - cinfo->min_DCT_scaled_size; /* height of a row group of component */ - xbuf0 = jmain->xbuffer[0][ci]; - xbuf1 = jmain->xbuffer[1][ci]; - for (i = 0; i < rgroup; i++) { - xbuf0[i - rgroup] = xbuf0[rgroup*(M+1) + i]; - xbuf1[i - rgroup] = xbuf1[rgroup*(M+1) + i]; - xbuf0[rgroup*(M+2) + i] = xbuf0[i]; - xbuf1[rgroup*(M+2) + i] = xbuf1[i]; - } - } -} - - -LOCAL void -set_bottom_pointers (j_decompress_ptr cinfo) -/* Change the pointer lists to duplicate the last sample row at the bottom - * of the image. whichptr indicates which xbuffer holds the final iMCU row. - * Also sets rowgroups_avail to indicate number of nondummy row groups in row. - */ -{ - // bk001204 - no use main - my_main_ptr jmain = (my_main_ptr) cinfo->main; - int ci, i, rgroup, iMCUheight, rows_left; - jpeg_component_info *compptr; - JSAMPARRAY xbuf; - - for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; - ci++, compptr++) { - /* Count sample rows in one iMCU row and in one row group */ - iMCUheight = compptr->v_samp_factor * compptr->DCT_scaled_size; - rgroup = iMCUheight / cinfo->min_DCT_scaled_size; - /* Count nondummy sample rows remaining for this component */ - rows_left = (int) (compptr->downsampled_height % (JDIMENSION) iMCUheight); - if (rows_left == 0) rows_left = iMCUheight; - /* Count nondummy row groups. Should get same answer for each component, - * so we need only do it once. - */ - if (ci == 0) { - jmain->rowgroups_avail = (JDIMENSION) ((rows_left-1) / rgroup + 1); - } - /* Duplicate the last real sample row rgroup*2 times; this pads out the - * last partial rowgroup and ensures at least one full rowgroup of context. - */ - xbuf = jmain->xbuffer[jmain->whichptr][ci]; - for (i = 0; i < rgroup * 2; i++) { - xbuf[rows_left + i] = xbuf[rows_left-1]; - } - } -} - - -/* - * Initialize for a processing pass. - */ - -METHODDEF void -start_pass_main (j_decompress_ptr cinfo, J_BUF_MODE pass_mode) -{ - // bk001204 - no use main - my_main_ptr jmain = (my_main_ptr) cinfo->main; - - switch (pass_mode) { - case JBUF_PASS_THRU: - if (cinfo->upsample->need_context_rows) { - jmain->pub.process_data = process_data_context_main; - make_funny_pointers(cinfo); /* Create the xbuffer[] lists */ - jmain->whichptr = 0; /* Read first iMCU row into xbuffer[0] */ - jmain->context_state = CTX_PREPARE_FOR_IMCU; - jmain->iMCU_row_ctr = 0; - } else { - /* Simple case with no context needed */ - jmain->pub.process_data = process_data_simple_main; - } - jmain->buffer_full = FALSE; /* Mark buffer empty */ - jmain->rowgroup_ctr = 0; - break; -#ifdef QUANT_2PASS_SUPPORTED - case JBUF_CRANK_DEST: - /* For last pass of 2-pass quantization, just crank the postprocessor */ - jmain->pub.process_data = process_data_crank_post; - break; -#endif - default: - ERREXIT(cinfo, JERR_BAD_BUFFER_MODE); - break; - } -} - - -/* - * Process some data. - * This handles the simple case where no context is required. - */ - -METHODDEF void -process_data_simple_main (j_decompress_ptr cinfo, - JSAMPARRAY output_buf, JDIMENSION *out_row_ctr, - JDIMENSION out_rows_avail) -{ - // bk001204 - no use main - my_main_ptr jmain = (my_main_ptr) cinfo->main; - JDIMENSION rowgroups_avail; - - /* Read input data if we haven't filled the main buffer yet */ - if (! jmain->buffer_full) { - if (! (*cinfo->coef->decompress_data) (cinfo, jmain->buffer)) - return; /* suspension forced, can do nothing more */ - jmain->buffer_full = TRUE; /* OK, we have an iMCU row to work with */ - } - - /* There are always min_DCT_scaled_size row groups in an iMCU row. */ - rowgroups_avail = (JDIMENSION) cinfo->min_DCT_scaled_size; - /* Note: at the bottom of the image, we may pass extra garbage row groups - * to the postprocessor. The postprocessor has to check for bottom - * of image anyway (at row resolution), so no point in us doing it too. - */ - - /* Feed the postprocessor */ - (*cinfo->post->post_process_data) (cinfo, jmain->buffer, - &jmain->rowgroup_ctr, rowgroups_avail, - output_buf, out_row_ctr, out_rows_avail); - - /* Has postprocessor consumed all the data yet? If so, mark buffer empty */ - if (jmain->rowgroup_ctr >= rowgroups_avail) { - jmain->buffer_full = FALSE; - jmain->rowgroup_ctr = 0; - } -} - - -/* - * Process some data. - * This handles the case where context rows must be provided. - */ - -METHODDEF void -process_data_context_main (j_decompress_ptr cinfo, - JSAMPARRAY output_buf, JDIMENSION *out_row_ctr, - JDIMENSION out_rows_avail) -{ - // bk001204 - no use main - my_main_ptr jmain = (my_main_ptr) cinfo->main; - - /* Read input data if we haven't filled the main buffer yet */ - if (! jmain->buffer_full) { - if (! (*cinfo->coef->decompress_data) (cinfo, - jmain->xbuffer[jmain->whichptr])) - return; /* suspension forced, can do nothing more */ - jmain->buffer_full = TRUE; /* OK, we have an iMCU row to work with */ - jmain->iMCU_row_ctr++; /* count rows received */ - } - - /* Postprocessor typically will not swallow all the input data it is handed - * in one call (due to filling the output buffer first). Must be prepared - * to exit and restart. This switch lets us keep track of how far we got. - * Note that each case falls through to the next on successful completion. - */ - switch (jmain->context_state) { - case CTX_POSTPONED_ROW: - /* Call postprocessor using previously set pointers for postponed row */ - (*cinfo->post->post_process_data) (cinfo, jmain->xbuffer[jmain->whichptr], - &jmain->rowgroup_ctr, jmain->rowgroups_avail, - output_buf, out_row_ctr, out_rows_avail); - if (jmain->rowgroup_ctr < jmain->rowgroups_avail) - return; /* Need to suspend */ - jmain->context_state = CTX_PREPARE_FOR_IMCU; - if (*out_row_ctr >= out_rows_avail) - return; /* Postprocessor exactly filled output buf */ - /*FALLTHROUGH*/ - case CTX_PREPARE_FOR_IMCU: - /* Prepare to process first M-1 row groups of this iMCU row */ - jmain->rowgroup_ctr = 0; - jmain->rowgroups_avail = (JDIMENSION) (cinfo->min_DCT_scaled_size - 1); - /* Check for bottom of image: if so, tweak pointers to "duplicate" - * the last sample row, and adjust rowgroups_avail to ignore padding rows. - */ - if (jmain->iMCU_row_ctr == cinfo->total_iMCU_rows) - set_bottom_pointers(cinfo); - jmain->context_state = CTX_PROCESS_IMCU; - /*FALLTHROUGH*/ - case CTX_PROCESS_IMCU: - /* Call postprocessor using previously set pointers */ - (*cinfo->post->post_process_data) (cinfo, jmain->xbuffer[jmain->whichptr], - &jmain->rowgroup_ctr, jmain->rowgroups_avail, - output_buf, out_row_ctr, out_rows_avail); - if (jmain->rowgroup_ctr < jmain->rowgroups_avail) - return; /* Need to suspend */ - /* After the first iMCU, change wraparound pointers to normal state */ - if (jmain->iMCU_row_ctr == 1) - set_wraparound_pointers(cinfo); - /* Prepare to load new iMCU row using other xbuffer list */ - jmain->whichptr ^= 1; /* 0=>1 or 1=>0 */ - jmain->buffer_full = FALSE; - /* Still need to process last row group of this iMCU row, */ - /* which is saved at index M+1 of the other xbuffer */ - jmain->rowgroup_ctr = (JDIMENSION) (cinfo->min_DCT_scaled_size + 1); - jmain->rowgroups_avail = (JDIMENSION) (cinfo->min_DCT_scaled_size + 2); - jmain->context_state = CTX_POSTPONED_ROW; - } -} - - -/* - * Process some data. - * Final pass of two-pass quantization: just call the postprocessor. - * Source data will be the postprocessor controller's internal buffer. - */ - -#ifdef QUANT_2PASS_SUPPORTED - -METHODDEF void -process_data_crank_post (j_decompress_ptr cinfo, - JSAMPARRAY output_buf, JDIMENSION *out_row_ctr, - JDIMENSION out_rows_avail) -{ - (*cinfo->post->post_process_data) (cinfo, (JSAMPIMAGE) NULL, - (JDIMENSION *) NULL, (JDIMENSION) 0, - output_buf, out_row_ctr, out_rows_avail); -} - -#endif /* QUANT_2PASS_SUPPORTED */ - - -/* - * Initialize main buffer controller. - */ - -GLOBAL void -jinit_d_main_controller (j_decompress_ptr cinfo, boolean need_full_buffer) -{ - // bk001204 - no use main - my_main_ptr jmain; - int ci, rgroup, ngroups; - jpeg_component_info *compptr; - - jmain = (my_main_ptr) - (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, - SIZEOF(my_main_controller)); - cinfo->main = (struct jpeg_d_main_controller *) jmain; - jmain->pub.start_pass = start_pass_main; - - if (need_full_buffer) /* shouldn't happen */ - ERREXIT(cinfo, JERR_BAD_BUFFER_MODE); - - /* Allocate the workspace. - * ngroups is the number of row groups we need. - */ - if (cinfo->upsample->need_context_rows) { - if (cinfo->min_DCT_scaled_size < 2) /* unsupported, see comments above */ - ERREXIT(cinfo, JERR_NOTIMPL); - alloc_funny_pointers(cinfo); /* Alloc space for xbuffer[] lists */ - ngroups = cinfo->min_DCT_scaled_size + 2; - } else { - ngroups = cinfo->min_DCT_scaled_size; - } - - for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; - ci++, compptr++) { - rgroup = (compptr->v_samp_factor * compptr->DCT_scaled_size) / - cinfo->min_DCT_scaled_size; /* height of a row group of component */ - jmain->buffer[ci] = (*cinfo->mem->alloc_sarray) - ((j_common_ptr) cinfo, JPOOL_IMAGE, - compptr->width_in_blocks * compptr->DCT_scaled_size, - (JDIMENSION) (rgroup * ngroups)); - } -} diff --git a/engine/jpeg-6/jdmarker.c b/engine/jpeg-6/jdmarker.c deleted file mode 100644 index 80e5f78..0000000 --- a/engine/jpeg-6/jdmarker.c +++ /dev/null @@ -1,1052 +0,0 @@ -/* - * jdmarker.c - * - * Copyright (C) 1991-1995, Thomas G. Lane. - * This file is part of the Independent JPEG Group's software. - * For conditions of distribution and use, see the accompanying README file. - * - * This file contains routines to decode JPEG datastream markers. - * Most of the complexity arises from our desire to support input - * suspension: if not all of the data for a marker is available, - * we must exit back to the application. On resumption, we reprocess - * the marker. - */ - -#define JPEG_INTERNALS -#include "jinclude.h" -#include "jpeglib.h" - - -typedef enum { /* JPEG marker codes */ - M_SOF0 = 0xc0, - M_SOF1 = 0xc1, - M_SOF2 = 0xc2, - M_SOF3 = 0xc3, - - M_SOF5 = 0xc5, - M_SOF6 = 0xc6, - M_SOF7 = 0xc7, - - M_JPG = 0xc8, - M_SOF9 = 0xc9, - M_SOF10 = 0xca, - M_SOF11 = 0xcb, - - M_SOF13 = 0xcd, - M_SOF14 = 0xce, - M_SOF15 = 0xcf, - - M_DHT = 0xc4, - - M_DAC = 0xcc, - - M_RST0 = 0xd0, - M_RST1 = 0xd1, - M_RST2 = 0xd2, - M_RST3 = 0xd3, - M_RST4 = 0xd4, - M_RST5 = 0xd5, - M_RST6 = 0xd6, - M_RST7 = 0xd7, - - M_SOI = 0xd8, - M_EOI = 0xd9, - M_SOS = 0xda, - M_DQT = 0xdb, - M_DNL = 0xdc, - M_DRI = 0xdd, - M_DHP = 0xde, - M_EXP = 0xdf, - - M_APP0 = 0xe0, - M_APP1 = 0xe1, - M_APP2 = 0xe2, - M_APP3 = 0xe3, - M_APP4 = 0xe4, - M_APP5 = 0xe5, - M_APP6 = 0xe6, - M_APP7 = 0xe7, - M_APP8 = 0xe8, - M_APP9 = 0xe9, - M_APP10 = 0xea, - M_APP11 = 0xeb, - M_APP12 = 0xec, - M_APP13 = 0xed, - M_APP14 = 0xee, - M_APP15 = 0xef, - - M_JPG0 = 0xf0, - M_JPG13 = 0xfd, - M_COM = 0xfe, - - M_TEM = 0x01, - - M_ERROR = 0x100 -} JPEG_MARKER; - - -/* - * Macros for fetching data from the data source module. - * - * At all times, cinfo->src->next_input_byte and ->bytes_in_buffer reflect - * the current restart point; we update them only when we have reached a - * suitable place to restart if a suspension occurs. - */ - -/* Declare and initialize local copies of input pointer/count */ -#define INPUT_VARS(cinfo) \ - struct jpeg_source_mgr * datasrc = (cinfo)->src; \ - const JOCTET * next_input_byte = datasrc->next_input_byte; \ - size_t bytes_in_buffer = datasrc->bytes_in_buffer - -/* Unload the local copies --- do this only at a restart boundary */ -#define INPUT_SYNC(cinfo) \ - ( datasrc->next_input_byte = next_input_byte, \ - datasrc->bytes_in_buffer = bytes_in_buffer ) - -/* Reload the local copies --- seldom used except in MAKE_BYTE_AVAIL */ -#define INPUT_RELOAD(cinfo) \ - ( next_input_byte = datasrc->next_input_byte, \ - bytes_in_buffer = datasrc->bytes_in_buffer ) - -/* Internal macro for INPUT_BYTE and INPUT_2BYTES: make a byte available. - * Note we do *not* do INPUT_SYNC before calling fill_input_buffer, - * but we must reload the local copies after a successful fill. - */ -#define MAKE_BYTE_AVAIL(cinfo,action) \ - if (bytes_in_buffer == 0) { \ - if (! (*datasrc->fill_input_buffer) (cinfo)) \ - { action; } \ - INPUT_RELOAD(cinfo); \ - } \ - bytes_in_buffer-- - -/* Read a byte into variable V. - * If must suspend, take the specified action (typically "return FALSE"). - */ -#define INPUT_BYTE(cinfo,V,action) \ - MAKESTMT( MAKE_BYTE_AVAIL(cinfo,action); \ - V = GETJOCTET(*next_input_byte++); ) - -/* As above, but read two bytes interpreted as an unsigned 16-bit integer. - * V should be declared unsigned int or perhaps INT32. - */ -#define INPUT_2BYTES(cinfo,V,action) \ - MAKESTMT( MAKE_BYTE_AVAIL(cinfo,action); \ - V = ((unsigned int) GETJOCTET(*next_input_byte++)) << 8; \ - MAKE_BYTE_AVAIL(cinfo,action); \ - V += GETJOCTET(*next_input_byte++); ) - - -/* - * Routines to process JPEG markers. - * - * Entry condition: JPEG marker itself has been read and its code saved - * in cinfo->unread_marker; input restart point is just after the marker. - * - * Exit: if return TRUE, have read and processed any parameters, and have - * updated the restart point to point after the parameters. - * If return FALSE, was forced to suspend before reaching end of - * marker parameters; restart point has not been moved. Same routine - * will be called again after application supplies more input data. - * - * This approach to suspension assumes that all of a marker's parameters can - * fit into a single input bufferload. This should hold for "normal" - * markers. Some COM/APPn markers might have large parameter segments, - * but we use skip_input_data to get past those, and thereby put the problem - * on the source manager's shoulders. - * - * Note that we don't bother to avoid duplicate trace messages if a - * suspension occurs within marker parameters. Other side effects - * require more care. - */ - - -LOCAL boolean -get_soi (j_decompress_ptr cinfo) -/* Process an SOI marker */ -{ - int i; - - TRACEMS(cinfo, 1, JTRC_SOI); - - if (cinfo->marker->saw_SOI) - ERREXIT(cinfo, JERR_SOI_DUPLICATE); - - /* Reset all parameters that are defined to be reset by SOI */ - - for (i = 0; i < NUM_ARITH_TBLS; i++) { - cinfo->arith_dc_L[i] = 0; - cinfo->arith_dc_U[i] = 1; - cinfo->arith_ac_K[i] = 5; - } - cinfo->restart_interval = 0; - - /* Set initial assumptions for colorspace etc */ - - cinfo->jpeg_color_space = JCS_UNKNOWN; - cinfo->CCIR601_sampling = FALSE; /* Assume non-CCIR sampling??? */ - - cinfo->saw_JFIF_marker = FALSE; - cinfo->density_unit = 0; /* set default JFIF APP0 values */ - cinfo->X_density = 1; - cinfo->Y_density = 1; - cinfo->saw_Adobe_marker = FALSE; - cinfo->Adobe_transform = 0; - - cinfo->marker->saw_SOI = TRUE; - - return TRUE; -} - - -LOCAL boolean -get_sof (j_decompress_ptr cinfo, boolean is_prog, boolean is_arith) -/* Process a SOFn marker */ -{ - INT32 length; - int c, ci; - jpeg_component_info * compptr; - INPUT_VARS(cinfo); - - cinfo->progressive_mode = is_prog; - cinfo->arith_code = is_arith; - - INPUT_2BYTES(cinfo, length, return FALSE); - - INPUT_BYTE(cinfo, cinfo->data_precision, return FALSE); - INPUT_2BYTES(cinfo, cinfo->image_height, return FALSE); - INPUT_2BYTES(cinfo, cinfo->image_width, return FALSE); - INPUT_BYTE(cinfo, cinfo->num_components, return FALSE); - - length -= 8; - - TRACEMS4(cinfo, 1, JTRC_SOF, cinfo->unread_marker, - (int) cinfo->image_width, (int) cinfo->image_height, - cinfo->num_components); - - if (cinfo->marker->saw_SOF) - ERREXIT(cinfo, JERR_SOF_DUPLICATE); - - /* We don't support files in which the image height is initially specified */ - /* as 0 and is later redefined by DNL. As long as we have to check that, */ - /* might as well have a general sanity check. */ - if (cinfo->image_height <= 0 || cinfo->image_width <= 0 - || cinfo->num_components <= 0) - ERREXIT(cinfo, JERR_EMPTY_IMAGE); - - if (length != (cinfo->num_components * 3)) - ERREXIT(cinfo, JERR_BAD_LENGTH); - - if (cinfo->comp_info == NULL) /* do only once, even if suspend */ - cinfo->comp_info = (jpeg_component_info *) (*cinfo->mem->alloc_small) - ((j_common_ptr) cinfo, JPOOL_IMAGE, - cinfo->num_components * SIZEOF(jpeg_component_info)); - - for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; - ci++, compptr++) { - compptr->component_index = ci; - INPUT_BYTE(cinfo, compptr->component_id, return FALSE); - INPUT_BYTE(cinfo, c, return FALSE); - compptr->h_samp_factor = (c >> 4) & 15; - compptr->v_samp_factor = (c ) & 15; - INPUT_BYTE(cinfo, compptr->quant_tbl_no, return FALSE); - - TRACEMS4(cinfo, 1, JTRC_SOF_COMPONENT, - compptr->component_id, compptr->h_samp_factor, - compptr->v_samp_factor, compptr->quant_tbl_no); - } - - cinfo->marker->saw_SOF = TRUE; - - INPUT_SYNC(cinfo); - return TRUE; -} - - -LOCAL boolean -get_sos (j_decompress_ptr cinfo) -/* Process a SOS marker */ -{ - INT32 length; - int i, ci, n, c, cc; - jpeg_component_info * compptr; - INPUT_VARS(cinfo); - - if (! cinfo->marker->saw_SOF) - ERREXIT(cinfo, JERR_SOS_NO_SOF); - - INPUT_2BYTES(cinfo, length, return FALSE); - - INPUT_BYTE(cinfo, n, return FALSE); /* Number of components */ - - if (length != (n * 2 + 6) || n < 1 || n > MAX_COMPS_IN_SCAN) - ERREXIT(cinfo, JERR_BAD_LENGTH); - - TRACEMS1(cinfo, 1, JTRC_SOS, n); - - cinfo->comps_in_scan = n; - - /* Collect the component-spec parameters */ - - for (i = 0; i < n; i++) { - INPUT_BYTE(cinfo, cc, return FALSE); - INPUT_BYTE(cinfo, c, return FALSE); - - for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; - ci++, compptr++) { - if (cc == compptr->component_id) - goto id_found; - } - - ERREXIT1(cinfo, JERR_BAD_COMPONENT_ID, cc); - - id_found: - - cinfo->cur_comp_info[i] = compptr; - compptr->dc_tbl_no = (c >> 4) & 15; - compptr->ac_tbl_no = (c ) & 15; - - TRACEMS3(cinfo, 1, JTRC_SOS_COMPONENT, cc, - compptr->dc_tbl_no, compptr->ac_tbl_no); - } - - /* Collect the additional scan parameters Ss, Se, Ah/Al. */ - INPUT_BYTE(cinfo, c, return FALSE); - cinfo->Ss = c; - INPUT_BYTE(cinfo, c, return FALSE); - cinfo->Se = c; - INPUT_BYTE(cinfo, c, return FALSE); - cinfo->Ah = (c >> 4) & 15; - cinfo->Al = (c ) & 15; - - TRACEMS4(cinfo, 1, JTRC_SOS_PARAMS, cinfo->Ss, cinfo->Se, - cinfo->Ah, cinfo->Al); - - /* Prepare to scan data & restart markers */ - cinfo->marker->next_restart_num = 0; - - /* Count another SOS marker */ - cinfo->input_scan_number++; - - INPUT_SYNC(cinfo); - return TRUE; -} - - -METHODDEF boolean -get_app0 (j_decompress_ptr cinfo) -/* Process an APP0 marker */ -{ -#define JFIF_LEN 14 - INT32 length; - UINT8 b[JFIF_LEN]; - int buffp; - INPUT_VARS(cinfo); - - INPUT_2BYTES(cinfo, length, return FALSE); - length -= 2; - - /* See if a JFIF APP0 marker is present */ - - if (length >= JFIF_LEN) { - for (buffp = 0; buffp < JFIF_LEN; buffp++) - INPUT_BYTE(cinfo, b[buffp], return FALSE); - length -= JFIF_LEN; - - if (b[0]==0x4A && b[1]==0x46 && b[2]==0x49 && b[3]==0x46 && b[4]==0) { - /* Found JFIF APP0 marker: check version */ - /* Major version must be 1, anything else signals an incompatible change. - * We used to treat this as an error, but now it's a nonfatal warning, - * because some bozo at Hijaak couldn't read the spec. - * Minor version should be 0..2, but process anyway if newer. - */ - if (b[5] != 1) - WARNMS2(cinfo, JWRN_JFIF_MAJOR, b[5], b[6]); - else if (b[6] > 2) - TRACEMS2(cinfo, 1, JTRC_JFIF_MINOR, b[5], b[6]); - /* Save info */ - cinfo->saw_JFIF_marker = TRUE; - cinfo->density_unit = b[7]; - cinfo->X_density = (b[8] << 8) + b[9]; - cinfo->Y_density = (b[10] << 8) + b[11]; - TRACEMS3(cinfo, 1, JTRC_JFIF, - cinfo->X_density, cinfo->Y_density, cinfo->density_unit); - if (b[12] | b[13]) - TRACEMS2(cinfo, 1, JTRC_JFIF_THUMBNAIL, b[12], b[13]); - if (length != ((INT32) b[12] * (INT32) b[13] * (INT32) 3)) - TRACEMS1(cinfo, 1, JTRC_JFIF_BADTHUMBNAILSIZE, (int) length); - } else { - /* Start of APP0 does not match "JFIF" */ - TRACEMS1(cinfo, 1, JTRC_APP0, (int) length + JFIF_LEN); - } - } else { - /* Too short to be JFIF marker */ - TRACEMS1(cinfo, 1, JTRC_APP0, (int) length); - } - - INPUT_SYNC(cinfo); - if (length > 0) /* skip any remaining data -- could be lots */ - (*cinfo->src->skip_input_data) (cinfo, (long) length); - - return TRUE; -} - - -METHODDEF boolean -get_app14 (j_decompress_ptr cinfo) -/* Process an APP14 marker */ -{ -#define ADOBE_LEN 12 - INT32 length; - UINT8 b[ADOBE_LEN]; - int buffp; - unsigned int version, flags0, flags1, transform; - INPUT_VARS(cinfo); - - INPUT_2BYTES(cinfo, length, return FALSE); - length -= 2; - - /* See if an Adobe APP14 marker is present */ - - if (length >= ADOBE_LEN) { - for (buffp = 0; buffp < ADOBE_LEN; buffp++) - INPUT_BYTE(cinfo, b[buffp], return FALSE); - length -= ADOBE_LEN; - - if (b[0]==0x41 && b[1]==0x64 && b[2]==0x6F && b[3]==0x62 && b[4]==0x65) { - /* Found Adobe APP14 marker */ - version = (b[5] << 8) + b[6]; - flags0 = (b[7] << 8) + b[8]; - flags1 = (b[9] << 8) + b[10]; - transform = b[11]; - TRACEMS4(cinfo, 1, JTRC_ADOBE, version, flags0, flags1, transform); - cinfo->saw_Adobe_marker = TRUE; - cinfo->Adobe_transform = (UINT8) transform; - } else { - /* Start of APP14 does not match "Adobe" */ - TRACEMS1(cinfo, 1, JTRC_APP14, (int) length + ADOBE_LEN); - } - } else { - /* Too short to be Adobe marker */ - TRACEMS1(cinfo, 1, JTRC_APP14, (int) length); - } - - INPUT_SYNC(cinfo); - if (length > 0) /* skip any remaining data -- could be lots */ - (*cinfo->src->skip_input_data) (cinfo, (long) length); - - return TRUE; -} - - -LOCAL boolean -get_dac (j_decompress_ptr cinfo) -/* Process a DAC marker */ -{ - INT32 length; - int index, val; - INPUT_VARS(cinfo); - - INPUT_2BYTES(cinfo, length, return FALSE); - length -= 2; - - while (length > 0) { - INPUT_BYTE(cinfo, index, return FALSE); - INPUT_BYTE(cinfo, val, return FALSE); - - length -= 2; - - TRACEMS2(cinfo, 1, JTRC_DAC, index, val); - - if (index < 0 || index >= (2*NUM_ARITH_TBLS)) - ERREXIT1(cinfo, JERR_DAC_INDEX, index); - - if (index >= NUM_ARITH_TBLS) { /* define AC table */ - cinfo->arith_ac_K[index-NUM_ARITH_TBLS] = (UINT8) val; - } else { /* define DC table */ - cinfo->arith_dc_L[index] = (UINT8) (val & 0x0F); - cinfo->arith_dc_U[index] = (UINT8) (val >> 4); - if (cinfo->arith_dc_L[index] > cinfo->arith_dc_U[index]) - ERREXIT1(cinfo, JERR_DAC_VALUE, val); - } - } - - INPUT_SYNC(cinfo); - return TRUE; -} - - -LOCAL boolean -get_dht (j_decompress_ptr cinfo) -/* Process a DHT marker */ -{ - INT32 length; - UINT8 bits[17]; - UINT8 huffval[256]; - int i, index, count; - JHUFF_TBL **htblptr; - INPUT_VARS(cinfo); - - INPUT_2BYTES(cinfo, length, return FALSE); - length -= 2; - - while (length > 0) { - INPUT_BYTE(cinfo, index, return FALSE); - - TRACEMS1(cinfo, 1, JTRC_DHT, index); - - bits[0] = 0; - count = 0; - for (i = 1; i <= 16; i++) { - INPUT_BYTE(cinfo, bits[i], return FALSE); - count += bits[i]; - } - - length -= 1 + 16; - - TRACEMS8(cinfo, 2, JTRC_HUFFBITS, - bits[1], bits[2], bits[3], bits[4], - bits[5], bits[6], bits[7], bits[8]); - TRACEMS8(cinfo, 2, JTRC_HUFFBITS, - bits[9], bits[10], bits[11], bits[12], - bits[13], bits[14], bits[15], bits[16]); - - if (count > 256 || ((INT32) count) > length) - ERREXIT(cinfo, JERR_DHT_COUNTS); - - for (i = 0; i < count; i++) - INPUT_BYTE(cinfo, huffval[i], return FALSE); - - length -= count; - - if (index & 0x10) { /* AC table definition */ - index -= 0x10; - htblptr = &cinfo->ac_huff_tbl_ptrs[index]; - } else { /* DC table definition */ - htblptr = &cinfo->dc_huff_tbl_ptrs[index]; - } - - if (index < 0 || index >= NUM_HUFF_TBLS) - ERREXIT1(cinfo, JERR_DHT_INDEX, index); - - if (*htblptr == NULL) - *htblptr = jpeg_alloc_huff_table((j_common_ptr) cinfo); - - MEMCOPY((*htblptr)->bits, bits, SIZEOF((*htblptr)->bits)); - MEMCOPY((*htblptr)->huffval, huffval, SIZEOF((*htblptr)->huffval)); - } - - INPUT_SYNC(cinfo); - return TRUE; -} - - -LOCAL boolean -get_dqt (j_decompress_ptr cinfo) -/* Process a DQT marker */ -{ - INT32 length; - int n, i, prec; - unsigned int tmp; - JQUANT_TBL *quant_ptr; - INPUT_VARS(cinfo); - - INPUT_2BYTES(cinfo, length, return FALSE); - length -= 2; - - while (length > 0) { - INPUT_BYTE(cinfo, n, return FALSE); - prec = n >> 4; - n &= 0x0F; - - TRACEMS2(cinfo, 1, JTRC_DQT, n, prec); - - if (n >= NUM_QUANT_TBLS) - ERREXIT1(cinfo, JERR_DQT_INDEX, n); - - if (cinfo->quant_tbl_ptrs[n] == NULL) - cinfo->quant_tbl_ptrs[n] = jpeg_alloc_quant_table((j_common_ptr) cinfo); - quant_ptr = cinfo->quant_tbl_ptrs[n]; - - for (i = 0; i < DCTSIZE2; i++) { - if (prec) - INPUT_2BYTES(cinfo, tmp, return FALSE); - else - INPUT_BYTE(cinfo, tmp, return FALSE); - quant_ptr->quantval[i] = (UINT16) tmp; - } - - for (i = 0; i < DCTSIZE2; i += 8) { - TRACEMS8(cinfo, 2, JTRC_QUANTVALS, - quant_ptr->quantval[i ], quant_ptr->quantval[i+1], - quant_ptr->quantval[i+2], quant_ptr->quantval[i+3], - quant_ptr->quantval[i+4], quant_ptr->quantval[i+5], - quant_ptr->quantval[i+6], quant_ptr->quantval[i+7]); - } - - length -= DCTSIZE2+1; - if (prec) length -= DCTSIZE2; - } - - INPUT_SYNC(cinfo); - return TRUE; -} - - -LOCAL boolean -get_dri (j_decompress_ptr cinfo) -/* Process a DRI marker */ -{ - INT32 length; - unsigned int tmp; - INPUT_VARS(cinfo); - - INPUT_2BYTES(cinfo, length, return FALSE); - - if (length != 4) - ERREXIT(cinfo, JERR_BAD_LENGTH); - - INPUT_2BYTES(cinfo, tmp, return FALSE); - - TRACEMS1(cinfo, 1, JTRC_DRI, tmp); - - cinfo->restart_interval = tmp; - - INPUT_SYNC(cinfo); - return TRUE; -} - - -METHODDEF boolean -skip_variable (j_decompress_ptr cinfo) -/* Skip over an unknown or uninteresting variable-length marker */ -{ - INT32 length; - INPUT_VARS(cinfo); - - INPUT_2BYTES(cinfo, length, return FALSE); - - TRACEMS2(cinfo, 1, JTRC_MISC_MARKER, cinfo->unread_marker, (int) length); - - INPUT_SYNC(cinfo); /* do before skip_input_data */ - (*cinfo->src->skip_input_data) (cinfo, (long) length - 2L); - - return TRUE; -} - - -/* - * Find the next JPEG marker, save it in cinfo->unread_marker. - * Returns FALSE if had to suspend before reaching a marker; - * in that case cinfo->unread_marker is unchanged. - * - * Note that the result might not be a valid marker code, - * but it will never be 0 or FF. - */ - -LOCAL boolean -next_marker (j_decompress_ptr cinfo) -{ - int c; - INPUT_VARS(cinfo); - - for (;;) { - INPUT_BYTE(cinfo, c, return FALSE); - /* Skip any non-FF bytes. - * This may look a bit inefficient, but it will not occur in a valid file. - * We sync after each discarded byte so that a suspending data source - * can discard the byte from its buffer. - */ - while (c != 0xFF) { - cinfo->marker->discarded_bytes++; - INPUT_SYNC(cinfo); - INPUT_BYTE(cinfo, c, return FALSE); - } - /* This loop swallows any duplicate FF bytes. Extra FFs are legal as - * pad bytes, so don't count them in discarded_bytes. We assume there - * will not be so many consecutive FF bytes as to overflow a suspending - * data source's input buffer. - */ - do { - INPUT_BYTE(cinfo, c, return FALSE); - } while (c == 0xFF); - if (c != 0) - break; /* found a valid marker, exit loop */ - /* Reach here if we found a stuffed-zero data sequence (FF/00). - * Discard it and loop back to try again. - */ - cinfo->marker->discarded_bytes += 2; - INPUT_SYNC(cinfo); - } - - if (cinfo->marker->discarded_bytes != 0) { - WARNMS2(cinfo, JWRN_EXTRANEOUS_DATA, cinfo->marker->discarded_bytes, c); - cinfo->marker->discarded_bytes = 0; - } - - cinfo->unread_marker = c; - - INPUT_SYNC(cinfo); - return TRUE; -} - - -LOCAL boolean -first_marker (j_decompress_ptr cinfo) -/* Like next_marker, but used to obtain the initial SOI marker. */ -/* For this marker, we do not allow preceding garbage or fill; otherwise, - * we might well scan an entire input file before realizing it ain't JPEG. - * If an application wants to process non-JFIF files, it must seek to the - * SOI before calling the JPEG library. - */ -{ - int c, c2; - INPUT_VARS(cinfo); - - INPUT_BYTE(cinfo, c, return FALSE); - INPUT_BYTE(cinfo, c2, return FALSE); - if (c != 0xFF || c2 != (int) M_SOI) - ERREXIT2(cinfo, JERR_NO_SOI, c, c2); - - cinfo->unread_marker = c2; - - INPUT_SYNC(cinfo); - return TRUE; -} - - -/* - * Read markers until SOS or EOI. - * - * Returns same codes as are defined for jpeg_consume_input: - * JPEG_SUSPENDED, JPEG_REACHED_SOS, or JPEG_REACHED_EOI. - */ - -METHODDEF int -read_markers (j_decompress_ptr cinfo) -{ - /* Outer loop repeats once for each marker. */ - for (;;) { - /* Collect the marker proper, unless we already did. */ - /* NB: first_marker() enforces the requirement that SOI appear first. */ - if (cinfo->unread_marker == 0) { - if (! cinfo->marker->saw_SOI) { - if (! first_marker(cinfo)) - return JPEG_SUSPENDED; - } else { - if (! next_marker(cinfo)) - return JPEG_SUSPENDED; - } - } - /* At this point cinfo->unread_marker contains the marker code and the - * input point is just past the marker proper, but before any parameters. - * A suspension will cause us to return with this state still true. - */ - switch (cinfo->unread_marker) { - case M_SOI: - if (! get_soi(cinfo)) - return JPEG_SUSPENDED; - break; - - case M_SOF0: /* Baseline */ - case M_SOF1: /* Extended sequential, Huffman */ - if (! get_sof(cinfo, FALSE, FALSE)) - return JPEG_SUSPENDED; - break; - - case M_SOF2: /* Progressive, Huffman */ - if (! get_sof(cinfo, TRUE, FALSE)) - return JPEG_SUSPENDED; - break; - - case M_SOF9: /* Extended sequential, arithmetic */ - if (! get_sof(cinfo, FALSE, TRUE)) - return JPEG_SUSPENDED; - break; - - case M_SOF10: /* Progressive, arithmetic */ - if (! get_sof(cinfo, TRUE, TRUE)) - return JPEG_SUSPENDED; - break; - - /* Currently unsupported SOFn types */ - case M_SOF3: /* Lossless, Huffman */ - case M_SOF5: /* Differential sequential, Huffman */ - case M_SOF6: /* Differential progressive, Huffman */ - case M_SOF7: /* Differential lossless, Huffman */ - case M_JPG: /* Reserved for JPEG extensions */ - case M_SOF11: /* Lossless, arithmetic */ - case M_SOF13: /* Differential sequential, arithmetic */ - case M_SOF14: /* Differential progressive, arithmetic */ - case M_SOF15: /* Differential lossless, arithmetic */ - ERREXIT1(cinfo, JERR_SOF_UNSUPPORTED, cinfo->unread_marker); - break; - - case M_SOS: - if (! get_sos(cinfo)) - return JPEG_SUSPENDED; - cinfo->unread_marker = 0; /* processed the marker */ - return JPEG_REACHED_SOS; - - case M_EOI: - TRACEMS(cinfo, 1, JTRC_EOI); - cinfo->unread_marker = 0; /* processed the marker */ - return JPEG_REACHED_EOI; - - case M_DAC: - if (! get_dac(cinfo)) - return JPEG_SUSPENDED; - break; - - case M_DHT: - if (! get_dht(cinfo)) - return JPEG_SUSPENDED; - break; - - case M_DQT: - if (! get_dqt(cinfo)) - return JPEG_SUSPENDED; - break; - - case M_DRI: - if (! get_dri(cinfo)) - return JPEG_SUSPENDED; - break; - - case M_APP0: - case M_APP1: - case M_APP2: - case M_APP3: - case M_APP4: - case M_APP5: - case M_APP6: - case M_APP7: - case M_APP8: - case M_APP9: - case M_APP10: - case M_APP11: - case M_APP12: - case M_APP13: - case M_APP14: - case M_APP15: - if (! (*cinfo->marker->process_APPn[cinfo->unread_marker - (int) M_APP0]) (cinfo)) - return JPEG_SUSPENDED; - break; - - case M_COM: - if (! (*cinfo->marker->process_COM) (cinfo)) - return JPEG_SUSPENDED; - break; - - case M_RST0: /* these are all parameterless */ - case M_RST1: - case M_RST2: - case M_RST3: - case M_RST4: - case M_RST5: - case M_RST6: - case M_RST7: - case M_TEM: - TRACEMS1(cinfo, 1, JTRC_PARMLESS_MARKER, cinfo->unread_marker); - break; - - case M_DNL: /* Ignore DNL ... perhaps the wrong thing */ - if (! skip_variable(cinfo)) - return JPEG_SUSPENDED; - break; - - default: /* must be DHP, EXP, JPGn, or RESn */ - /* For now, we treat the reserved markers as fatal errors since they are - * likely to be used to signal incompatible JPEG Part 3 extensions. - * Once the JPEG 3 version-number marker is well defined, this code - * ought to change! - */ - ERREXIT1(cinfo, JERR_UNKNOWN_MARKER, cinfo->unread_marker); - break; - } - /* Successfully processed marker, so reset state variable */ - cinfo->unread_marker = 0; - } /* end loop */ -} - - -/* - * Read a restart marker, which is expected to appear next in the datastream; - * if the marker is not there, take appropriate recovery action. - * Returns FALSE if suspension is required. - * - * This is called by the entropy decoder after it has read an appropriate - * number of MCUs. cinfo->unread_marker may be nonzero if the entropy decoder - * has already read a marker from the data source. Under normal conditions - * cinfo->unread_marker will be reset to 0 before returning; if not reset, - * it holds a marker which the decoder will be unable to read past. - */ - -METHODDEF boolean -read_restart_marker (j_decompress_ptr cinfo) -{ - /* Obtain a marker unless we already did. */ - /* Note that next_marker will complain if it skips any data. */ - if (cinfo->unread_marker == 0) { - if (! next_marker(cinfo)) - return FALSE; - } - - if (cinfo->unread_marker == - ((int) M_RST0 + cinfo->marker->next_restart_num)) { - /* Normal case --- swallow the marker and let entropy decoder continue */ - TRACEMS1(cinfo, 2, JTRC_RST, cinfo->marker->next_restart_num); - cinfo->unread_marker = 0; - } else { - /* Uh-oh, the restart markers have been messed up. */ - /* Let the data source manager determine how to resync. */ - if (! (*cinfo->src->resync_to_restart) (cinfo, - cinfo->marker->next_restart_num)) - return FALSE; - } - - /* Update next-restart state */ - cinfo->marker->next_restart_num = (cinfo->marker->next_restart_num + 1) & 7; - - return TRUE; -} - - -/* - * This is the default resync_to_restart method for data source managers - * to use if they don't have any better approach. Some data source managers - * may be able to back up, or may have additional knowledge about the data - * which permits a more intelligent recovery strategy; such managers would - * presumably supply their own resync method. - * - * read_restart_marker calls resync_to_restart if it finds a marker other than - * the restart marker it was expecting. (This code is *not* used unless - * a nonzero restart interval has been declared.) cinfo->unread_marker is - * the marker code actually found (might be anything, except 0 or FF). - * The desired restart marker number (0..7) is passed as a parameter. - * This routine is supposed to apply whatever error recovery strategy seems - * appropriate in order to position the input stream to the next data segment. - * Note that cinfo->unread_marker is treated as a marker appearing before - * the current data-source input point; usually it should be reset to zero - * before returning. - * Returns FALSE if suspension is required. - * - * This implementation is substantially constrained by wanting to treat the - * input as a data stream; this means we can't back up. Therefore, we have - * only the following actions to work with: - * 1. Simply discard the marker and let the entropy decoder resume at next - * byte of file. - * 2. Read forward until we find another marker, discarding intervening - * data. (In theory we could look ahead within the current bufferload, - * without having to discard data if we don't find the desired marker. - * This idea is not implemented here, in part because it makes behavior - * dependent on buffer size and chance buffer-boundary positions.) - * 3. Leave the marker unread (by failing to zero cinfo->unread_marker). - * This will cause the entropy decoder to process an empty data segment, - * inserting dummy zeroes, and then we will reprocess the marker. - * - * #2 is appropriate if we think the desired marker lies ahead, while #3 is - * appropriate if the found marker is a future restart marker (indicating - * that we have missed the desired restart marker, probably because it got - * corrupted). - * We apply #2 or #3 if the found marker is a restart marker no more than - * two counts behind or ahead of the expected one. We also apply #2 if the - * found marker is not a legal JPEG marker code (it's certainly bogus data). - * If the found marker is a restart marker more than 2 counts away, we do #1 - * (too much risk that the marker is erroneous; with luck we will be able to - * resync at some future point). - * For any valid non-restart JPEG marker, we apply #3. This keeps us from - * overrunning the end of a scan. An implementation limited to single-scan - * files might find it better to apply #2 for markers other than EOI, since - * any other marker would have to be bogus data in that case. - */ - -GLOBAL boolean -jpeg_resync_to_restart (j_decompress_ptr cinfo, int desired) -{ - int marker = cinfo->unread_marker; - int action = 1; - - /* Always put up a warning. */ - WARNMS2(cinfo, JWRN_MUST_RESYNC, marker, desired); - - /* Outer loop handles repeated decision after scanning forward. */ - for (;;) { - if (marker < (int) M_SOF0) - action = 2; /* invalid marker */ - else if (marker < (int) M_RST0 || marker > (int) M_RST7) - action = 3; /* valid non-restart marker */ - else { - if (marker == ((int) M_RST0 + ((desired+1) & 7)) || - marker == ((int) M_RST0 + ((desired+2) & 7))) - action = 3; /* one of the next two expected restarts */ - else if (marker == ((int) M_RST0 + ((desired-1) & 7)) || - marker == ((int) M_RST0 + ((desired-2) & 7))) - action = 2; /* a prior restart, so advance */ - else - action = 1; /* desired restart or too far away */ - } - TRACEMS2(cinfo, 4, JTRC_RECOVERY_ACTION, marker, action); - switch (action) { - case 1: - /* Discard marker and let entropy decoder resume processing. */ - cinfo->unread_marker = 0; - return TRUE; - case 2: - /* Scan to the next marker, and repeat the decision loop. */ - if (! next_marker(cinfo)) - return FALSE; - marker = cinfo->unread_marker; - break; - case 3: - /* Return without advancing past this marker. */ - /* Entropy decoder will be forced to process an empty segment. */ - return TRUE; - } - } /* end loop */ -} - - -/* - * Reset marker processing state to begin a fresh datastream. - */ - -METHODDEF void -reset_marker_reader (j_decompress_ptr cinfo) -{ - cinfo->comp_info = NULL; /* until allocated by get_sof */ - cinfo->input_scan_number = 0; /* no SOS seen yet */ - cinfo->unread_marker = 0; /* no pending marker */ - cinfo->marker->saw_SOI = FALSE; /* set internal state too */ - cinfo->marker->saw_SOF = FALSE; - cinfo->marker->discarded_bytes = 0; -} - - -/* - * Initialize the marker reader module. - * This is called only once, when the decompression object is created. - */ - -GLOBAL void -jinit_marker_reader (j_decompress_ptr cinfo) -{ - int i; - - /* Create subobject in permanent pool */ - cinfo->marker = (struct jpeg_marker_reader *) - (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT, - SIZEOF(struct jpeg_marker_reader)); - /* Initialize method pointers */ - cinfo->marker->reset_marker_reader = reset_marker_reader; - cinfo->marker->read_markers = read_markers; - cinfo->marker->read_restart_marker = read_restart_marker; - cinfo->marker->process_COM = skip_variable; - for (i = 0; i < 16; i++) - cinfo->marker->process_APPn[i] = skip_variable; - cinfo->marker->process_APPn[0] = get_app0; - cinfo->marker->process_APPn[14] = get_app14; - /* Reset marker processing state */ - reset_marker_reader(cinfo); -} diff --git a/engine/jpeg-6/jdmaster.c b/engine/jpeg-6/jdmaster.c deleted file mode 100644 index 18e0880..0000000 --- a/engine/jpeg-6/jdmaster.c +++ /dev/null @@ -1,557 +0,0 @@ -/* - * jdmaster.c - * - * Copyright (C) 1991-1995, Thomas G. Lane. - * This file is part of the Independent JPEG Group's software. - * For conditions of distribution and use, see the accompanying README file. - * - * This file contains master control logic for the JPEG decompressor. - * These routines are concerned with selecting the modules to be executed - * and with determining the number of passes and the work to be done in each - * pass. - */ - -#define JPEG_INTERNALS -#include "jinclude.h" -#include "jpeglib.h" - - -/* Private state */ - -typedef struct { - struct jpeg_decomp_master pub; /* public fields */ - - int pass_number; /* # of passes completed */ - - boolean using_merged_upsample; /* TRUE if using merged upsample/cconvert */ - - /* Saved references to initialized quantizer modules, - * in case we need to switch modes. - */ - struct jpeg_color_quantizer * quantizer_1pass; - struct jpeg_color_quantizer * quantizer_2pass; -} my_decomp_master; - -typedef my_decomp_master * my_master_ptr; - - -/* - * Determine whether merged upsample/color conversion should be used. - * CRUCIAL: this must match the actual capabilities of jdmerge.c! - */ - -LOCAL boolean -use_merged_upsample (j_decompress_ptr cinfo) -{ -#ifdef UPSAMPLE_MERGING_SUPPORTED - /* Merging is the equivalent of plain box-filter upsampling */ - if (cinfo->do_fancy_upsampling || cinfo->CCIR601_sampling) - return FALSE; - /* jdmerge.c only supports YCC=>RGB color conversion */ - if (cinfo->jpeg_color_space != JCS_YCbCr || cinfo->num_components != 3 || - cinfo->out_color_space != JCS_RGB || - cinfo->out_color_components != RGB_PIXELSIZE) - return FALSE; - /* and it only handles 2h1v or 2h2v sampling ratios */ - if (cinfo->comp_info[0].h_samp_factor != 2 || - cinfo->comp_info[1].h_samp_factor != 1 || - cinfo->comp_info[2].h_samp_factor != 1 || - cinfo->comp_info[0].v_samp_factor > 2 || - cinfo->comp_info[1].v_samp_factor != 1 || - cinfo->comp_info[2].v_samp_factor != 1) - return FALSE; - /* furthermore, it doesn't work if we've scaled the IDCTs differently */ - if (cinfo->comp_info[0].DCT_scaled_size != cinfo->min_DCT_scaled_size || - cinfo->comp_info[1].DCT_scaled_size != cinfo->min_DCT_scaled_size || - cinfo->comp_info[2].DCT_scaled_size != cinfo->min_DCT_scaled_size) - return FALSE; - /* ??? also need to test for upsample-time rescaling, when & if supported */ - return TRUE; /* by golly, it'll work... */ -#else - return FALSE; -#endif -} - - -/* - * Compute output image dimensions and related values. - * NOTE: this is exported for possible use by application. - * Hence it mustn't do anything that can't be done twice. - * Also note that it may be called before the master module is initialized! - */ - -GLOBAL void -jpeg_calc_output_dimensions (j_decompress_ptr cinfo) -/* Do computations that are needed before master selection phase */ -{ -#if 0 // JDC: commented out to remove warning - int ci; - jpeg_component_info *compptr; -#endif - - /* Prevent application from calling me at wrong times */ - if (cinfo->global_state != DSTATE_READY) - ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); - -#ifdef IDCT_SCALING_SUPPORTED - - /* Compute actual output image dimensions and DCT scaling choices. */ - if (cinfo->scale_num * 8 <= cinfo->scale_denom) { - /* Provide 1/8 scaling */ - cinfo->output_width = (JDIMENSION) - jdiv_round_up((long) cinfo->image_width, 8L); - cinfo->output_height = (JDIMENSION) - jdiv_round_up((long) cinfo->image_height, 8L); - cinfo->min_DCT_scaled_size = 1; - } else if (cinfo->scale_num * 4 <= cinfo->scale_denom) { - /* Provide 1/4 scaling */ - cinfo->output_width = (JDIMENSION) - jdiv_round_up((long) cinfo->image_width, 4L); - cinfo->output_height = (JDIMENSION) - jdiv_round_up((long) cinfo->image_height, 4L); - cinfo->min_DCT_scaled_size = 2; - } else if (cinfo->scale_num * 2 <= cinfo->scale_denom) { - /* Provide 1/2 scaling */ - cinfo->output_width = (JDIMENSION) - jdiv_round_up((long) cinfo->image_width, 2L); - cinfo->output_height = (JDIMENSION) - jdiv_round_up((long) cinfo->image_height, 2L); - cinfo->min_DCT_scaled_size = 4; - } else { - /* Provide 1/1 scaling */ - cinfo->output_width = cinfo->image_width; - cinfo->output_height = cinfo->image_height; - cinfo->min_DCT_scaled_size = DCTSIZE; - } - /* In selecting the actual DCT scaling for each component, we try to - * scale up the chroma components via IDCT scaling rather than upsampling. - * This saves time if the upsampler gets to use 1:1 scaling. - * Note this code assumes that the supported DCT scalings are powers of 2. - */ - for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; - ci++, compptr++) { - int ssize = cinfo->min_DCT_scaled_size; - while (ssize < DCTSIZE && - (compptr->h_samp_factor * ssize * 2 <= - cinfo->max_h_samp_factor * cinfo->min_DCT_scaled_size) && - (compptr->v_samp_factor * ssize * 2 <= - cinfo->max_v_samp_factor * cinfo->min_DCT_scaled_size)) { - ssize = ssize * 2; - } - compptr->DCT_scaled_size = ssize; - } - - /* Recompute downsampled dimensions of components; - * application needs to know these if using raw downsampled data. - */ - for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; - ci++, compptr++) { - /* Size in samples, after IDCT scaling */ - compptr->downsampled_width = (JDIMENSION) - jdiv_round_up((long) cinfo->image_width * - (long) (compptr->h_samp_factor * compptr->DCT_scaled_size), - (long) (cinfo->max_h_samp_factor * DCTSIZE)); - compptr->downsampled_height = (JDIMENSION) - jdiv_round_up((long) cinfo->image_height * - (long) (compptr->v_samp_factor * compptr->DCT_scaled_size), - (long) (cinfo->max_v_samp_factor * DCTSIZE)); - } - -#else /* !IDCT_SCALING_SUPPORTED */ - - /* Hardwire it to "no scaling" */ - cinfo->output_width = cinfo->image_width; - cinfo->output_height = cinfo->image_height; - /* jdinput.c has already initialized DCT_scaled_size to DCTSIZE, - * and has computed unscaled downsampled_width and downsampled_height. - */ - -#endif /* IDCT_SCALING_SUPPORTED */ - - /* Report number of components in selected colorspace. */ - /* Probably this should be in the color conversion module... */ - switch (cinfo->out_color_space) { - case JCS_GRAYSCALE: - cinfo->out_color_components = 1; - break; - case JCS_RGB: -#if RGB_PIXELSIZE != 3 - cinfo->out_color_components = RGB_PIXELSIZE; - break; -#endif /* else share code with YCbCr */ - case JCS_YCbCr: - cinfo->out_color_components = 3; - break; - case JCS_CMYK: - case JCS_YCCK: - cinfo->out_color_components = 4; - break; - default: /* else must be same colorspace as in file */ - cinfo->out_color_components = cinfo->num_components; - break; - } - cinfo->output_components = (cinfo->quantize_colors ? 1 : - cinfo->out_color_components); - - /* See if upsampler will want to emit more than one row at a time */ - if (use_merged_upsample(cinfo)) - cinfo->rec_outbuf_height = cinfo->max_v_samp_factor; - else - cinfo->rec_outbuf_height = 1; -} - - -/* - * Several decompression processes need to range-limit values to the range - * 0..MAXJSAMPLE; the input value may fall somewhat outside this range - * due to noise introduced by quantization, roundoff error, etc. These - * processes are inner loops and need to be as fast as possible. On most - * machines, particularly CPUs with pipelines or instruction prefetch, - * a (subscript-check-less) C table lookup - * x = sample_range_limit[x]; - * is faster than explicit tests - * if (x < 0) x = 0; - * else if (x > MAXJSAMPLE) x = MAXJSAMPLE; - * These processes all use a common table prepared by the routine below. - * - * For most steps we can mathematically guarantee that the initial value - * of x is within MAXJSAMPLE+1 of the legal range, so a table running from - * -(MAXJSAMPLE+1) to 2*MAXJSAMPLE+1 is sufficient. But for the initial - * limiting step (just after the IDCT), a wildly out-of-range value is - * possible if the input data is corrupt. To avoid any chance of indexing - * off the end of memory and getting a bad-pointer trap, we perform the - * post-IDCT limiting thus: - * x = range_limit[x & MASK]; - * where MASK is 2 bits wider than legal sample data, ie 10 bits for 8-bit - * samples. Under normal circumstances this is more than enough range and - * a correct output will be generated; with bogus input data the mask will - * cause wraparound, and we will safely generate a bogus-but-in-range output. - * For the post-IDCT step, we want to convert the data from signed to unsigned - * representation by adding CENTERJSAMPLE at the same time that we limit it. - * So the post-IDCT limiting table ends up looking like this: - * CENTERJSAMPLE,CENTERJSAMPLE+1,...,MAXJSAMPLE, - * MAXJSAMPLE (repeat 2*(MAXJSAMPLE+1)-CENTERJSAMPLE times), - * 0 (repeat 2*(MAXJSAMPLE+1)-CENTERJSAMPLE times), - * 0,1,...,CENTERJSAMPLE-1 - * Negative inputs select values from the upper half of the table after - * masking. - * - * We can save some space by overlapping the start of the post-IDCT table - * with the simpler range limiting table. The post-IDCT table begins at - * sample_range_limit + CENTERJSAMPLE. - * - * Note that the table is allocated in near data space on PCs; it's small - * enough and used often enough to justify this. - */ - -LOCAL void -prepare_range_limit_table (j_decompress_ptr cinfo) -/* Allocate and fill in the sample_range_limit table */ -{ - JSAMPLE * table; - int i; - - table = (JSAMPLE *) - (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, - (5 * (MAXJSAMPLE+1) + CENTERJSAMPLE) * SIZEOF(JSAMPLE)); - table += (MAXJSAMPLE+1); /* allow negative subscripts of simple table */ - cinfo->sample_range_limit = table; - /* First segment of "simple" table: limit[x] = 0 for x < 0 */ - MEMZERO(table - (MAXJSAMPLE+1), (MAXJSAMPLE+1) * SIZEOF(JSAMPLE)); - /* Main part of "simple" table: limit[x] = x */ - for (i = 0; i <= MAXJSAMPLE; i++) - table[i] = (JSAMPLE) i; - table += CENTERJSAMPLE; /* Point to where post-IDCT table starts */ - /* End of simple table, rest of first half of post-IDCT table */ - for (i = CENTERJSAMPLE; i < 2*(MAXJSAMPLE+1); i++) - table[i] = MAXJSAMPLE; - /* Second half of post-IDCT table */ - MEMZERO(table + (2 * (MAXJSAMPLE+1)), - (2 * (MAXJSAMPLE+1) - CENTERJSAMPLE) * SIZEOF(JSAMPLE)); - MEMCOPY(table + (4 * (MAXJSAMPLE+1) - CENTERJSAMPLE), - cinfo->sample_range_limit, CENTERJSAMPLE * SIZEOF(JSAMPLE)); -} - - -/* - * Master selection of decompression modules. - * This is done once at jpeg_start_decompress time. We determine - * which modules will be used and give them appropriate initialization calls. - * We also initialize the decompressor input side to begin consuming data. - * - * Since jpeg_read_header has finished, we know what is in the SOF - * and (first) SOS markers. We also have all the application parameter - * settings. - */ - -LOCAL void -master_selection (j_decompress_ptr cinfo) -{ - my_master_ptr master = (my_master_ptr) cinfo->master; - boolean use_c_buffer; - long samplesperrow; - JDIMENSION jd_samplesperrow; - - /* Initialize dimensions and other stuff */ - jpeg_calc_output_dimensions(cinfo); - prepare_range_limit_table(cinfo); - - /* Width of an output scanline must be representable as JDIMENSION. */ - samplesperrow = (long) cinfo->output_width * (long) cinfo->out_color_components; - jd_samplesperrow = (JDIMENSION) samplesperrow; - if ((long) jd_samplesperrow != samplesperrow) - ERREXIT(cinfo, JERR_WIDTH_OVERFLOW); - - /* Initialize my private state */ - master->pass_number = 0; - master->using_merged_upsample = use_merged_upsample(cinfo); - - /* Color quantizer selection */ - master->quantizer_1pass = NULL; - master->quantizer_2pass = NULL; - /* No mode changes if not using buffered-image mode. */ - if (! cinfo->quantize_colors || ! cinfo->buffered_image) { - cinfo->enable_1pass_quant = FALSE; - cinfo->enable_external_quant = FALSE; - cinfo->enable_2pass_quant = FALSE; - } - if (cinfo->quantize_colors) { - if (cinfo->raw_data_out) - ERREXIT(cinfo, JERR_NOTIMPL); - /* 2-pass quantizer only works in 3-component color space. */ - if (cinfo->out_color_components != 3) { - cinfo->enable_1pass_quant = TRUE; - cinfo->enable_external_quant = FALSE; - cinfo->enable_2pass_quant = FALSE; - cinfo->colormap = NULL; - } else if (cinfo->colormap != NULL) { - cinfo->enable_external_quant = TRUE; - } else if (cinfo->two_pass_quantize) { - cinfo->enable_2pass_quant = TRUE; - } else { - cinfo->enable_1pass_quant = TRUE; - } - - if (cinfo->enable_1pass_quant) { -#ifdef QUANT_1PASS_SUPPORTED - jinit_1pass_quantizer(cinfo); - master->quantizer_1pass = cinfo->cquantize; -#else - ERREXIT(cinfo, JERR_NOT_COMPILED); -#endif - } - - /* We use the 2-pass code to map to external colormaps. */ - if (cinfo->enable_2pass_quant || cinfo->enable_external_quant) { -#ifdef QUANT_2PASS_SUPPORTED - jinit_2pass_quantizer(cinfo); - master->quantizer_2pass = cinfo->cquantize; -#else - ERREXIT(cinfo, JERR_NOT_COMPILED); -#endif - } - /* If both quantizers are initialized, the 2-pass one is left active; - * this is necessary for starting with quantization to an external map. - */ - } - - /* Post-processing: in particular, color conversion first */ - if (! cinfo->raw_data_out) { - if (master->using_merged_upsample) { -#ifdef UPSAMPLE_MERGING_SUPPORTED - jinit_merged_upsampler(cinfo); /* does color conversion too */ -#else - ERREXIT(cinfo, JERR_NOT_COMPILED); -#endif - } else { - jinit_color_deconverter(cinfo); - jinit_upsampler(cinfo); - } - jinit_d_post_controller(cinfo, cinfo->enable_2pass_quant); - } - /* Inverse DCT */ - jinit_inverse_dct(cinfo); - /* Entropy decoding: either Huffman or arithmetic coding. */ - if (cinfo->arith_code) { - ERREXIT(cinfo, JERR_ARITH_NOTIMPL); - } else { - if (cinfo->progressive_mode) { -#ifdef D_PROGRESSIVE_SUPPORTED - jinit_phuff_decoder(cinfo); -#else - ERREXIT(cinfo, JERR_NOT_COMPILED); -#endif - } else - jinit_huff_decoder(cinfo); - } - - /* Initialize principal buffer controllers. */ - use_c_buffer = cinfo->inputctl->has_multiple_scans || cinfo->buffered_image; - jinit_d_coef_controller(cinfo, use_c_buffer); - - if (! cinfo->raw_data_out) - jinit_d_main_controller(cinfo, FALSE /* never need full buffer here */); - - /* We can now tell the memory manager to allocate virtual arrays. */ - (*cinfo->mem->realize_virt_arrays) ((j_common_ptr) cinfo); - - /* Initialize input side of decompressor to consume first scan. */ - (*cinfo->inputctl->start_input_pass) (cinfo); - -#ifdef D_MULTISCAN_FILES_SUPPORTED - /* If jpeg_start_decompress will read the whole file, initialize - * progress monitoring appropriately. The input step is counted - * as one pass. - */ - if (cinfo->progress != NULL && ! cinfo->buffered_image && - cinfo->inputctl->has_multiple_scans) { - int nscans; - /* Estimate number of scans to set pass_limit. */ - if (cinfo->progressive_mode) { - /* Arbitrarily estimate 2 interleaved DC scans + 3 AC scans/component. */ - nscans = 2 + 3 * cinfo->num_components; - } else { - /* For a nonprogressive multiscan file, estimate 1 scan per component. */ - nscans = cinfo->num_components; - } - cinfo->progress->pass_counter = 0L; - cinfo->progress->pass_limit = (long) cinfo->total_iMCU_rows * nscans; - cinfo->progress->completed_passes = 0; - cinfo->progress->total_passes = (cinfo->enable_2pass_quant ? 3 : 2); - /* Count the input pass as done */ - master->pass_number++; - } -#endif /* D_MULTISCAN_FILES_SUPPORTED */ -} - - -/* - * Per-pass setup. - * This is called at the beginning of each output pass. We determine which - * modules will be active during this pass and give them appropriate - * start_pass calls. We also set is_dummy_pass to indicate whether this - * is a "real" output pass or a dummy pass for color quantization. - * (In the latter case, jdapi.c will crank the pass to completion.) - */ - -METHODDEF void -prepare_for_output_pass (j_decompress_ptr cinfo) -{ - my_master_ptr master = (my_master_ptr) cinfo->master; - - if (master->pub.is_dummy_pass) { -#ifdef QUANT_2PASS_SUPPORTED - /* Final pass of 2-pass quantization */ - master->pub.is_dummy_pass = FALSE; - (*cinfo->cquantize->start_pass) (cinfo, FALSE); - (*cinfo->post->start_pass) (cinfo, JBUF_CRANK_DEST); - (*cinfo->main->start_pass) (cinfo, JBUF_CRANK_DEST); -#else - ERREXIT(cinfo, JERR_NOT_COMPILED); -#endif /* QUANT_2PASS_SUPPORTED */ - } else { - if (cinfo->quantize_colors && cinfo->colormap == NULL) { - /* Select new quantization method */ - if (cinfo->two_pass_quantize && cinfo->enable_2pass_quant) { - cinfo->cquantize = master->quantizer_2pass; - master->pub.is_dummy_pass = TRUE; - } else if (cinfo->enable_1pass_quant) { - cinfo->cquantize = master->quantizer_1pass; - } else { - ERREXIT(cinfo, JERR_MODE_CHANGE); - } - } - (*cinfo->idct->start_pass) (cinfo); - (*cinfo->coef->start_output_pass) (cinfo); - if (! cinfo->raw_data_out) { - if (! master->using_merged_upsample) - (*cinfo->cconvert->start_pass) (cinfo); - (*cinfo->upsample->start_pass) (cinfo); - if (cinfo->quantize_colors) - (*cinfo->cquantize->start_pass) (cinfo, master->pub.is_dummy_pass); - (*cinfo->post->start_pass) (cinfo, - (master->pub.is_dummy_pass ? JBUF_SAVE_AND_PASS : JBUF_PASS_THRU)); - (*cinfo->main->start_pass) (cinfo, JBUF_PASS_THRU); - } - } - - /* Set up progress monitor's pass info if present */ - if (cinfo->progress != NULL) { - cinfo->progress->completed_passes = master->pass_number; - cinfo->progress->total_passes = master->pass_number + - (master->pub.is_dummy_pass ? 2 : 1); - /* In buffered-image mode, we assume one more output pass if EOI not - * yet reached, but no more passes if EOI has been reached. - */ - if (cinfo->buffered_image && ! cinfo->inputctl->eoi_reached) { - cinfo->progress->total_passes += (cinfo->enable_2pass_quant ? 2 : 1); - } - } -} - - -/* - * Finish up at end of an output pass. - */ - -METHODDEF void -finish_output_pass (j_decompress_ptr cinfo) -{ - my_master_ptr master = (my_master_ptr) cinfo->master; - - if (cinfo->quantize_colors) - (*cinfo->cquantize->finish_pass) (cinfo); - master->pass_number++; -} - - -#ifdef D_MULTISCAN_FILES_SUPPORTED - -/* - * Switch to a new external colormap between output passes. - */ - -GLOBAL void -jpeg_new_colormap (j_decompress_ptr cinfo) -{ - my_master_ptr master = (my_master_ptr) cinfo->master; - - /* Prevent application from calling me at wrong times */ - if (cinfo->global_state != DSTATE_BUFIMAGE) - ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); - - if (cinfo->quantize_colors && cinfo->enable_external_quant && - cinfo->colormap != NULL) { - /* Select 2-pass quantizer for external colormap use */ - cinfo->cquantize = master->quantizer_2pass; - /* Notify quantizer of colormap change */ - (*cinfo->cquantize->new_color_map) (cinfo); - master->pub.is_dummy_pass = FALSE; /* just in case */ - } else - ERREXIT(cinfo, JERR_MODE_CHANGE); -} - -#endif /* D_MULTISCAN_FILES_SUPPORTED */ - - -/* - * Initialize master decompression control and select active modules. - * This is performed at the start of jpeg_start_decompress. - */ - -GLOBAL void -jinit_master_decompress (j_decompress_ptr cinfo) -{ - my_master_ptr master; - - master = (my_master_ptr) - (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, - SIZEOF(my_decomp_master)); - cinfo->master = (struct jpeg_decomp_master *) master; - master->pub.prepare_for_output_pass = prepare_for_output_pass; - master->pub.finish_output_pass = finish_output_pass; - - master->pub.is_dummy_pass = FALSE; - - master_selection(cinfo); -} diff --git a/engine/jpeg-6/jdmerge.c b/engine/jpeg-6/jdmerge.c deleted file mode 100644 index 95585fb..0000000 --- a/engine/jpeg-6/jdmerge.c +++ /dev/null @@ -1,400 +0,0 @@ -/* - * jdmerge.c - * - * Copyright (C) 1994-1995, Thomas G. Lane. - * This file is part of the Independent JPEG Group's software. - * For conditions of distribution and use, see the accompanying README file. - * - * This file contains code for merged upsampling/color conversion. - * - * This file combines functions from jdsample.c and jdcolor.c; - * read those files first to understand what's going on. - * - * When the chroma components are to be upsampled by simple replication - * (ie, box filtering), we can save some work in color conversion by - * calculating all the output pixels corresponding to a pair of chroma - * samples at one time. In the conversion equations - * R = Y + K1 * Cr - * G = Y + K2 * Cb + K3 * Cr - * B = Y + K4 * Cb - * only the Y term varies among the group of pixels corresponding to a pair - * of chroma samples, so the rest of the terms can be calculated just once. - * At typical sampling ratios, this eliminates half or three-quarters of the - * multiplications needed for color conversion. - * - * This file currently provides implementations for the following cases: - * YCbCr => RGB color conversion only. - * Sampling ratios of 2h1v or 2h2v. - * No scaling needed at upsample time. - * Corner-aligned (non-CCIR601) sampling alignment. - * Other special cases could be added, but in most applications these are - * the only common cases. (For uncommon cases we fall back on the more - * general code in jdsample.c and jdcolor.c.) - */ - -#define JPEG_INTERNALS -#include "jinclude.h" -#include "jpeglib.h" - -#ifdef UPSAMPLE_MERGING_SUPPORTED - - -/* Private subobject */ - -typedef struct { - struct jpeg_upsampler pub; /* public fields */ - - /* Pointer to routine to do actual upsampling/conversion of one row group */ - JMETHOD(void, upmethod, (j_decompress_ptr cinfo, - JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr, - JSAMPARRAY output_buf)); - - /* Private state for YCC->RGB conversion */ - int * Cr_r_tab; /* => table for Cr to R conversion */ - int * Cb_b_tab; /* => table for Cb to B conversion */ - INT32 * Cr_g_tab; /* => table for Cr to G conversion */ - INT32 * Cb_g_tab; /* => table for Cb to G conversion */ - - /* For 2:1 vertical sampling, we produce two output rows at a time. - * We need a "spare" row buffer to hold the second output row if the - * application provides just a one-row buffer; we also use the spare - * to discard the dummy last row if the image height is odd. - */ - JSAMPROW spare_row; - boolean spare_full; /* T if spare buffer is occupied */ - - JDIMENSION out_row_width; /* samples per output row */ - JDIMENSION rows_to_go; /* counts rows remaining in image */ -} my_upsampler; - -typedef my_upsampler * my_upsample_ptr; - -#define SCALEBITS 16 /* speediest right-shift on some machines */ -#define ONE_HALF ((INT32) 1 << (SCALEBITS-1)) -#define FIX(x) ((INT32) ((x) * (1L<RGB colorspace conversion. - * This is taken directly from jdcolor.c; see that file for more info. - */ - -LOCAL void -build_ycc_rgb_table (j_decompress_ptr cinfo) -{ - my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample; - int i; - INT32 x; - SHIFT_TEMPS - - upsample->Cr_r_tab = (int *) - (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, - (MAXJSAMPLE+1) * SIZEOF(int)); - upsample->Cb_b_tab = (int *) - (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, - (MAXJSAMPLE+1) * SIZEOF(int)); - upsample->Cr_g_tab = (INT32 *) - (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, - (MAXJSAMPLE+1) * SIZEOF(INT32)); - upsample->Cb_g_tab = (INT32 *) - (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, - (MAXJSAMPLE+1) * SIZEOF(INT32)); - - for (i = 0, x = -CENTERJSAMPLE; i <= MAXJSAMPLE; i++, x++) { - /* i is the actual input pixel value, in the range 0..MAXJSAMPLE */ - /* The Cb or Cr value we are thinking of is x = i - CENTERJSAMPLE */ - /* Cr=>R value is nearest int to 1.40200 * x */ - upsample->Cr_r_tab[i] = (int) - RIGHT_SHIFT(FIX(1.40200) * x + ONE_HALF, SCALEBITS); - /* Cb=>B value is nearest int to 1.77200 * x */ - upsample->Cb_b_tab[i] = (int) - RIGHT_SHIFT(FIX(1.77200) * x + ONE_HALF, SCALEBITS); - /* Cr=>G value is scaled-up -0.71414 * x */ - upsample->Cr_g_tab[i] = (- FIX(0.71414)) * x; - /* Cb=>G value is scaled-up -0.34414 * x */ - /* We also add in ONE_HALF so that need not do it in inner loop */ - upsample->Cb_g_tab[i] = (- FIX(0.34414)) * x + ONE_HALF; - } -} - - -/* - * Initialize for an upsampling pass. - */ - -METHODDEF void -start_pass_merged_upsample (j_decompress_ptr cinfo) -{ - my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample; - - /* Mark the spare buffer empty */ - upsample->spare_full = FALSE; - /* Initialize total-height counter for detecting bottom of image */ - upsample->rows_to_go = cinfo->output_height; -} - - -/* - * Control routine to do upsampling (and color conversion). - * - * The control routine just handles the row buffering considerations. - */ - -METHODDEF void -merged_2v_upsample (j_decompress_ptr cinfo, - JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr, - JDIMENSION in_row_groups_avail, - JSAMPARRAY output_buf, JDIMENSION *out_row_ctr, - JDIMENSION out_rows_avail) -/* 2:1 vertical sampling case: may need a spare row. */ -{ - my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample; - JSAMPROW work_ptrs[2]; - JDIMENSION num_rows; /* number of rows returned to caller */ - - if (upsample->spare_full) { - /* If we have a spare row saved from a previous cycle, just return it. */ - jcopy_sample_rows(& upsample->spare_row, 0, output_buf + *out_row_ctr, 0, - 1, upsample->out_row_width); - num_rows = 1; - upsample->spare_full = FALSE; - } else { - /* Figure number of rows to return to caller. */ - num_rows = 2; - /* Not more than the distance to the end of the image. */ - if (num_rows > upsample->rows_to_go) - num_rows = upsample->rows_to_go; - /* And not more than what the client can accept: */ - out_rows_avail -= *out_row_ctr; - if (num_rows > out_rows_avail) - num_rows = out_rows_avail; - /* Create output pointer array for upsampler. */ - work_ptrs[0] = output_buf[*out_row_ctr]; - if (num_rows > 1) { - work_ptrs[1] = output_buf[*out_row_ctr + 1]; - } else { - work_ptrs[1] = upsample->spare_row; - upsample->spare_full = TRUE; - } - /* Now do the upsampling. */ - (*upsample->upmethod) (cinfo, input_buf, *in_row_group_ctr, work_ptrs); - } - - /* Adjust counts */ - *out_row_ctr += num_rows; - upsample->rows_to_go -= num_rows; - /* When the buffer is emptied, declare this input row group consumed */ - if (! upsample->spare_full) - (*in_row_group_ctr)++; -} - - -METHODDEF void -merged_1v_upsample (j_decompress_ptr cinfo, - JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr, - JDIMENSION in_row_groups_avail, - JSAMPARRAY output_buf, JDIMENSION *out_row_ctr, - JDIMENSION out_rows_avail) -/* 1:1 vertical sampling case: much easier, never need a spare row. */ -{ - my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample; - - /* Just do the upsampling. */ - (*upsample->upmethod) (cinfo, input_buf, *in_row_group_ctr, - output_buf + *out_row_ctr); - /* Adjust counts */ - (*out_row_ctr)++; - (*in_row_group_ctr)++; -} - - -/* - * These are the routines invoked by the control routines to do - * the actual upsampling/conversion. One row group is processed per call. - * - * Note: since we may be writing directly into application-supplied buffers, - * we have to be honest about the output width; we can't assume the buffer - * has been rounded up to an even width. - */ - - -/* - * Upsample and color convert for the case of 2:1 horizontal and 1:1 vertical. - */ - -METHODDEF void -h2v1_merged_upsample (j_decompress_ptr cinfo, - JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr, - JSAMPARRAY output_buf) -{ - my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample; - register int y, cred, cgreen, cblue; - int cb, cr; - register JSAMPROW outptr; - JSAMPROW inptr0, inptr1, inptr2; - JDIMENSION col; - /* copy these pointers into registers if possible */ - register JSAMPLE * range_limit = cinfo->sample_range_limit; - int * Crrtab = upsample->Cr_r_tab; - int * Cbbtab = upsample->Cb_b_tab; - INT32 * Crgtab = upsample->Cr_g_tab; - INT32 * Cbgtab = upsample->Cb_g_tab; - SHIFT_TEMPS - - inptr0 = input_buf[0][in_row_group_ctr]; - inptr1 = input_buf[1][in_row_group_ctr]; - inptr2 = input_buf[2][in_row_group_ctr]; - outptr = output_buf[0]; - /* Loop for each pair of output pixels */ - for (col = cinfo->output_width >> 1; col > 0; col--) { - /* Do the chroma part of the calculation */ - cb = GETJSAMPLE(*inptr1++); - cr = GETJSAMPLE(*inptr2++); - cred = Crrtab[cr]; - cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS); - cblue = Cbbtab[cb]; - /* Fetch 2 Y values and emit 2 pixels */ - y = GETJSAMPLE(*inptr0++); - outptr[RGB_RED] = range_limit[y + cred]; - outptr[RGB_GREEN] = range_limit[y + cgreen]; - outptr[RGB_BLUE] = range_limit[y + cblue]; - outptr += RGB_PIXELSIZE; - y = GETJSAMPLE(*inptr0++); - outptr[RGB_RED] = range_limit[y + cred]; - outptr[RGB_GREEN] = range_limit[y + cgreen]; - outptr[RGB_BLUE] = range_limit[y + cblue]; - outptr += RGB_PIXELSIZE; - } - /* If image width is odd, do the last output column separately */ - if (cinfo->output_width & 1) { - cb = GETJSAMPLE(*inptr1); - cr = GETJSAMPLE(*inptr2); - cred = Crrtab[cr]; - cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS); - cblue = Cbbtab[cb]; - y = GETJSAMPLE(*inptr0); - outptr[RGB_RED] = range_limit[y + cred]; - outptr[RGB_GREEN] = range_limit[y + cgreen]; - outptr[RGB_BLUE] = range_limit[y + cblue]; - } -} - - -/* - * Upsample and color convert for the case of 2:1 horizontal and 2:1 vertical. - */ - -METHODDEF void -h2v2_merged_upsample (j_decompress_ptr cinfo, - JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr, - JSAMPARRAY output_buf) -{ - my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample; - register int y, cred, cgreen, cblue; - int cb, cr; - register JSAMPROW outptr0, outptr1; - JSAMPROW inptr00, inptr01, inptr1, inptr2; - JDIMENSION col; - /* copy these pointers into registers if possible */ - register JSAMPLE * range_limit = cinfo->sample_range_limit; - int * Crrtab = upsample->Cr_r_tab; - int * Cbbtab = upsample->Cb_b_tab; - INT32 * Crgtab = upsample->Cr_g_tab; - INT32 * Cbgtab = upsample->Cb_g_tab; - SHIFT_TEMPS - - inptr00 = input_buf[0][in_row_group_ctr*2]; - inptr01 = input_buf[0][in_row_group_ctr*2 + 1]; - inptr1 = input_buf[1][in_row_group_ctr]; - inptr2 = input_buf[2][in_row_group_ctr]; - outptr0 = output_buf[0]; - outptr1 = output_buf[1]; - /* Loop for each group of output pixels */ - for (col = cinfo->output_width >> 1; col > 0; col--) { - /* Do the chroma part of the calculation */ - cb = GETJSAMPLE(*inptr1++); - cr = GETJSAMPLE(*inptr2++); - cred = Crrtab[cr]; - cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS); - cblue = Cbbtab[cb]; - /* Fetch 4 Y values and emit 4 pixels */ - y = GETJSAMPLE(*inptr00++); - outptr0[RGB_RED] = range_limit[y + cred]; - outptr0[RGB_GREEN] = range_limit[y + cgreen]; - outptr0[RGB_BLUE] = range_limit[y + cblue]; - outptr0 += RGB_PIXELSIZE; - y = GETJSAMPLE(*inptr00++); - outptr0[RGB_RED] = range_limit[y + cred]; - outptr0[RGB_GREEN] = range_limit[y + cgreen]; - outptr0[RGB_BLUE] = range_limit[y + cblue]; - outptr0 += RGB_PIXELSIZE; - y = GETJSAMPLE(*inptr01++); - outptr1[RGB_RED] = range_limit[y + cred]; - outptr1[RGB_GREEN] = range_limit[y + cgreen]; - outptr1[RGB_BLUE] = range_limit[y + cblue]; - outptr1 += RGB_PIXELSIZE; - y = GETJSAMPLE(*inptr01++); - outptr1[RGB_RED] = range_limit[y + cred]; - outptr1[RGB_GREEN] = range_limit[y + cgreen]; - outptr1[RGB_BLUE] = range_limit[y + cblue]; - outptr1 += RGB_PIXELSIZE; - } - /* If image width is odd, do the last output column separately */ - if (cinfo->output_width & 1) { - cb = GETJSAMPLE(*inptr1); - cr = GETJSAMPLE(*inptr2); - cred = Crrtab[cr]; - cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS); - cblue = Cbbtab[cb]; - y = GETJSAMPLE(*inptr00); - outptr0[RGB_RED] = range_limit[y + cred]; - outptr0[RGB_GREEN] = range_limit[y + cgreen]; - outptr0[RGB_BLUE] = range_limit[y + cblue]; - y = GETJSAMPLE(*inptr01); - outptr1[RGB_RED] = range_limit[y + cred]; - outptr1[RGB_GREEN] = range_limit[y + cgreen]; - outptr1[RGB_BLUE] = range_limit[y + cblue]; - } -} - - -/* - * Module initialization routine for merged upsampling/color conversion. - * - * NB: this is called under the conditions determined by use_merged_upsample() - * in jdmaster.c. That routine MUST correspond to the actual capabilities - * of this module; no safety checks are made here. - */ - -GLOBAL void -jinit_merged_upsampler (j_decompress_ptr cinfo) -{ - my_upsample_ptr upsample; - - upsample = (my_upsample_ptr) - (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, - SIZEOF(my_upsampler)); - cinfo->upsample = (struct jpeg_upsampler *) upsample; - upsample->pub.start_pass = start_pass_merged_upsample; - upsample->pub.need_context_rows = FALSE; - - upsample->out_row_width = cinfo->output_width * cinfo->out_color_components; - - if (cinfo->max_v_samp_factor == 2) { - upsample->pub.upsample = merged_2v_upsample; - upsample->upmethod = h2v2_merged_upsample; - /* Allocate a spare row buffer */ - upsample->spare_row = (JSAMPROW) - (*cinfo->mem->alloc_large) ((j_common_ptr) cinfo, JPOOL_IMAGE, - (size_t) (upsample->out_row_width * SIZEOF(JSAMPLE))); - } else { - upsample->pub.upsample = merged_1v_upsample; - upsample->upmethod = h2v1_merged_upsample; - /* No spare row needed */ - upsample->spare_row = NULL; - } - - build_ycc_rgb_table(cinfo); -} - -#endif /* UPSAMPLE_MERGING_SUPPORTED */ diff --git a/engine/jpeg-6/jdphuff.c b/engine/jpeg-6/jdphuff.c deleted file mode 100644 index 025bfd8..0000000 --- a/engine/jpeg-6/jdphuff.c +++ /dev/null @@ -1,642 +0,0 @@ -/* - * jdphuff.c - * - * Copyright (C) 1995, Thomas G. Lane. - * This file is part of the Independent JPEG Group's software. - * For conditions of distribution and use, see the accompanying README file. - * - * This file contains Huffman entropy decoding routines for progressive JPEG. - * - * Much of the complexity here has to do with supporting input suspension. - * If the data source module demands suspension, we want to be able to back - * up to the start of the current MCU. To do this, we copy state variables - * into local working storage, and update them back to the permanent - * storage only upon successful completion of an MCU. - */ - -#define JPEG_INTERNALS -#include "jinclude.h" -#include "jpeglib.h" -#include "jdhuff.h" /* Declarations shared with jdhuff.c */ - - -#ifdef D_PROGRESSIVE_SUPPORTED - -/* - * Expanded entropy decoder object for progressive Huffman decoding. - * - * The savable_state subrecord contains fields that change within an MCU, - * but must not be updated permanently until we complete the MCU. - */ - -typedef struct { - unsigned int EOBRUN; /* remaining EOBs in EOBRUN */ - int last_dc_val[MAX_COMPS_IN_SCAN]; /* last DC coef for each component */ -} savable_state; - -/* This macro is to work around compilers with missing or broken - * structure assignment. You'll need to fix this code if you have - * such a compiler and you change MAX_COMPS_IN_SCAN. - */ - -#ifndef NO_STRUCT_ASSIGN -#define ASSIGN_STATE(dest,src) ((dest) = (src)) -#else -#if MAX_COMPS_IN_SCAN == 4 -#define ASSIGN_STATE(dest,src) \ - ((dest).EOBRUN = (src).EOBRUN, \ - (dest).last_dc_val[0] = (src).last_dc_val[0], \ - (dest).last_dc_val[1] = (src).last_dc_val[1], \ - (dest).last_dc_val[2] = (src).last_dc_val[2], \ - (dest).last_dc_val[3] = (src).last_dc_val[3]) -#endif -#endif - - -typedef struct { - struct jpeg_entropy_decoder pub; /* public fields */ - - /* These fields are loaded into local variables at start of each MCU. - * In case of suspension, we exit WITHOUT updating them. - */ - bitread_perm_state bitstate; /* Bit buffer at start of MCU */ - savable_state saved; /* Other state at start of MCU */ - - /* These fields are NOT loaded into local working state. */ - unsigned int restarts_to_go; /* MCUs left in this restart interval */ - - /* Pointers to derived tables (these workspaces have image lifespan) */ - d_derived_tbl * derived_tbls[NUM_HUFF_TBLS]; - - d_derived_tbl * ac_derived_tbl; /* active table during an AC scan */ -} phuff_entropy_decoder; - -typedef phuff_entropy_decoder * phuff_entropy_ptr; - -/* Forward declarations */ -METHODDEF boolean decode_mcu_DC_first JPP((j_decompress_ptr cinfo, - JBLOCKROW *MCU_data)); -METHODDEF boolean decode_mcu_AC_first JPP((j_decompress_ptr cinfo, - JBLOCKROW *MCU_data)); -METHODDEF boolean decode_mcu_DC_refine JPP((j_decompress_ptr cinfo, - JBLOCKROW *MCU_data)); -METHODDEF boolean decode_mcu_AC_refine JPP((j_decompress_ptr cinfo, - JBLOCKROW *MCU_data)); - - -/* - * Initialize for a Huffman-compressed scan. - */ - -METHODDEF void -start_pass_phuff_decoder (j_decompress_ptr cinfo) -{ - phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy; - boolean is_DC_band, bad; - int ci, coefi, tbl; - int *coef_bit_ptr; - jpeg_component_info * compptr; - - is_DC_band = (cinfo->Ss == 0); - - /* Validate scan parameters */ - bad = FALSE; - if (is_DC_band) { - if (cinfo->Se != 0) - bad = TRUE; - } else { - /* need not check Ss/Se < 0 since they came from unsigned bytes */ - if (cinfo->Ss > cinfo->Se || cinfo->Se >= DCTSIZE2) - bad = TRUE; - /* AC scans may have only one component */ - if (cinfo->comps_in_scan != 1) - bad = TRUE; - } - if (cinfo->Ah != 0) { - /* Successive approximation refinement scan: must have Al = Ah-1. */ - if (cinfo->Al != cinfo->Ah-1) - bad = TRUE; - } - if (cinfo->Al > 13) /* need not check for < 0 */ - bad = TRUE; - if (bad) - ERREXIT4(cinfo, JERR_BAD_PROGRESSION, - cinfo->Ss, cinfo->Se, cinfo->Ah, cinfo->Al); - /* Update progression status, and verify that scan order is legal. - * Note that inter-scan inconsistencies are treated as warnings - * not fatal errors ... not clear if this is right way to behave. - */ - for (ci = 0; ci < cinfo->comps_in_scan; ci++) { - int cindex = cinfo->cur_comp_info[ci]->component_index; - coef_bit_ptr = & cinfo->coef_bits[cindex][0]; - if (!is_DC_band && coef_bit_ptr[0] < 0) /* AC without prior DC scan */ - WARNMS2(cinfo, JWRN_BOGUS_PROGRESSION, cindex, 0); - for (coefi = cinfo->Ss; coefi <= cinfo->Se; coefi++) { - int expected = (coef_bit_ptr[coefi] < 0) ? 0 : coef_bit_ptr[coefi]; - if (cinfo->Ah != expected) - WARNMS2(cinfo, JWRN_BOGUS_PROGRESSION, cindex, coefi); - coef_bit_ptr[coefi] = cinfo->Al; - } - } - - /* Select MCU decoding routine */ - if (cinfo->Ah == 0) { - if (is_DC_band) - entropy->pub.decode_mcu = decode_mcu_DC_first; - else - entropy->pub.decode_mcu = decode_mcu_AC_first; - } else { - if (is_DC_band) - entropy->pub.decode_mcu = decode_mcu_DC_refine; - else - entropy->pub.decode_mcu = decode_mcu_AC_refine; - } - - for (ci = 0; ci < cinfo->comps_in_scan; ci++) { - compptr = cinfo->cur_comp_info[ci]; - /* Make sure requested tables are present, and compute derived tables. - * We may build same derived table more than once, but it's not expensive. - */ - if (is_DC_band) { - if (cinfo->Ah == 0) { /* DC refinement needs no table */ - tbl = compptr->dc_tbl_no; - if (tbl < 0 || tbl >= NUM_HUFF_TBLS || - cinfo->dc_huff_tbl_ptrs[tbl] == NULL) - ERREXIT1(cinfo, JERR_NO_HUFF_TABLE, tbl); - jpeg_make_d_derived_tbl(cinfo, cinfo->dc_huff_tbl_ptrs[tbl], - & entropy->derived_tbls[tbl]); - } - } else { - tbl = compptr->ac_tbl_no; - if (tbl < 0 || tbl >= NUM_HUFF_TBLS || - cinfo->ac_huff_tbl_ptrs[tbl] == NULL) - ERREXIT1(cinfo, JERR_NO_HUFF_TABLE, tbl); - jpeg_make_d_derived_tbl(cinfo, cinfo->ac_huff_tbl_ptrs[tbl], - & entropy->derived_tbls[tbl]); - /* remember the single active table */ - entropy->ac_derived_tbl = entropy->derived_tbls[tbl]; - } - /* Initialize DC predictions to 0 */ - entropy->saved.last_dc_val[ci] = 0; - } - - /* Initialize bitread state variables */ - entropy->bitstate.bits_left = 0; - entropy->bitstate.get_buffer = 0; /* unnecessary, but keeps Purify quiet */ - entropy->bitstate.printed_eod = FALSE; - - /* Initialize private state variables */ - entropy->saved.EOBRUN = 0; - - /* Initialize restart counter */ - entropy->restarts_to_go = cinfo->restart_interval; -} - - -/* - * Figure F.12: extend sign bit. - * On some machines, a shift and add will be faster than a table lookup. - */ - -#ifdef AVOID_TABLES - -#define HUFF_EXTEND(x,s) ((x) < (1<<((s)-1)) ? (x) + (((-1)<<(s)) + 1) : (x)) - -#else - -#define HUFF_EXTEND(x,s) ((x) < extend_test[s] ? (x) + extend_offset[s] : (x)) - -static const int extend_test[16] = /* entry n is 2**(n-1) */ - { 0, 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080, - 0x0100, 0x0200, 0x0400, 0x0800, 0x1000, 0x2000, 0x4000 }; - -static const int extend_offset[16] = /* entry n is (-1 << n) + 1 */ - { 0, ((-1)<<1) + 1, ((-1)<<2) + 1, ((-1)<<3) + 1, ((-1)<<4) + 1, - ((-1)<<5) + 1, ((-1)<<6) + 1, ((-1)<<7) + 1, ((-1)<<8) + 1, - ((-1)<<9) + 1, ((-1)<<10) + 1, ((-1)<<11) + 1, ((-1)<<12) + 1, - ((-1)<<13) + 1, ((-1)<<14) + 1, ((-1)<<15) + 1 }; - -#endif /* AVOID_TABLES */ - - -/* - * Check for a restart marker & resynchronize decoder. - * Returns FALSE if must suspend. - */ - -LOCAL boolean -process_restart (j_decompress_ptr cinfo) -{ - phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy; - int ci; - - /* Throw away any unused bits remaining in bit buffer; */ - /* include any full bytes in next_marker's count of discarded bytes */ - cinfo->marker->discarded_bytes += entropy->bitstate.bits_left / 8; - entropy->bitstate.bits_left = 0; - - /* Advance past the RSTn marker */ - if (! (*cinfo->marker->read_restart_marker) (cinfo)) - return FALSE; - - /* Re-initialize DC predictions to 0 */ - for (ci = 0; ci < cinfo->comps_in_scan; ci++) - entropy->saved.last_dc_val[ci] = 0; - /* Re-init EOB run count, too */ - entropy->saved.EOBRUN = 0; - - /* Reset restart counter */ - entropy->restarts_to_go = cinfo->restart_interval; - - /* Next segment can get another out-of-data warning */ - entropy->bitstate.printed_eod = FALSE; - - return TRUE; -} - - -/* - * Huffman MCU decoding. - * Each of these routines decodes and returns one MCU's worth of - * Huffman-compressed coefficients. - * The coefficients are reordered from zigzag order into natural array order, - * but are not dequantized. - * - * The i'th block of the MCU is stored into the block pointed to by - * MCU_data[i]. WE ASSUME THIS AREA IS INITIALLY ZEROED BY THE CALLER. - * - * We return FALSE if data source requested suspension. In that case no - * changes have been made to permanent state. (Exception: some output - * coefficients may already have been assigned. This is harmless for - * spectral selection, since we'll just re-assign them on the next call. - * Successive approximation AC refinement has to be more careful, however.) - */ - -/* - * MCU decoding for DC initial scan (either spectral selection, - * or first pass of successive approximation). - */ - -METHODDEF boolean -decode_mcu_DC_first (j_decompress_ptr cinfo, JBLOCKROW *MCU_data) -{ - phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy; - int Al = cinfo->Al; - register int s, r; - int blkn, ci; - JBLOCKROW block; - BITREAD_STATE_VARS; - savable_state state; - d_derived_tbl * tbl; - jpeg_component_info * compptr; - - /* Process restart marker if needed; may have to suspend */ - if (cinfo->restart_interval) { - if (entropy->restarts_to_go == 0) - if (! process_restart(cinfo)) - return FALSE; - } - - /* Load up working state */ - BITREAD_LOAD_STATE(cinfo,entropy->bitstate); - ASSIGN_STATE(state, entropy->saved); - - /* Outer loop handles each block in the MCU */ - - for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) { - block = MCU_data[blkn]; - ci = cinfo->MCU_membership[blkn]; - compptr = cinfo->cur_comp_info[ci]; - tbl = entropy->derived_tbls[compptr->dc_tbl_no]; - - /* Decode a single block's worth of coefficients */ - - /* Section F.2.2.1: decode the DC coefficient difference */ - HUFF_DECODE(s, br_state, tbl, return FALSE, label1); - if (s) { - CHECK_BIT_BUFFER(br_state, s, return FALSE); - r = GET_BITS(s); - s = HUFF_EXTEND(r, s); - } - - /* Convert DC difference to actual value, update last_dc_val */ - s += state.last_dc_val[ci]; - state.last_dc_val[ci] = s; - /* Scale and output the DC coefficient (assumes jpeg_natural_order[0]=0) */ - (*block)[0] = (JCOEF) (s << Al); - } - - /* Completed MCU, so update state */ - BITREAD_SAVE_STATE(cinfo,entropy->bitstate); - ASSIGN_STATE(entropy->saved, state); - - /* Account for restart interval (no-op if not using restarts) */ - entropy->restarts_to_go--; - - return TRUE; -} - - -/* - * MCU decoding for AC initial scan (either spectral selection, - * or first pass of successive approximation). - */ - -METHODDEF boolean -decode_mcu_AC_first (j_decompress_ptr cinfo, JBLOCKROW *MCU_data) -{ - phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy; - int Se = cinfo->Se; - int Al = cinfo->Al; - register int s, k, r; - unsigned int EOBRUN; - JBLOCKROW block; - BITREAD_STATE_VARS; - d_derived_tbl * tbl; - - /* Process restart marker if needed; may have to suspend */ - if (cinfo->restart_interval) { - if (entropy->restarts_to_go == 0) - if (! process_restart(cinfo)) - return FALSE; - } - - /* Load up working state. - * We can avoid loading/saving bitread state if in an EOB run. - */ - EOBRUN = entropy->saved.EOBRUN; /* only part of saved state we care about */ - - /* There is always only one block per MCU */ - - if (EOBRUN > 0) /* if it's a band of zeroes... */ - EOBRUN--; /* ...process it now (we do nothing) */ - else { - BITREAD_LOAD_STATE(cinfo,entropy->bitstate); - block = MCU_data[0]; - tbl = entropy->ac_derived_tbl; - - for (k = cinfo->Ss; k <= Se; k++) { - HUFF_DECODE(s, br_state, tbl, return FALSE, label2); - r = s >> 4; - s &= 15; - if (s) { - k += r; - CHECK_BIT_BUFFER(br_state, s, return FALSE); - r = GET_BITS(s); - s = HUFF_EXTEND(r, s); - /* Scale and output coefficient in natural (dezigzagged) order */ - (*block)[jpeg_natural_order[k]] = (JCOEF) (s << Al); - } else { - if (r == 15) { /* ZRL */ - k += 15; /* skip 15 zeroes in band */ - } else { /* EOBr, run length is 2^r + appended bits */ - EOBRUN = 1 << r; - if (r) { /* EOBr, r > 0 */ - CHECK_BIT_BUFFER(br_state, r, return FALSE); - r = GET_BITS(r); - EOBRUN += r; - } - EOBRUN--; /* this band is processed at this moment */ - break; /* force end-of-band */ - } - } - } - - BITREAD_SAVE_STATE(cinfo,entropy->bitstate); - } - - /* Completed MCU, so update state */ - entropy->saved.EOBRUN = EOBRUN; /* only part of saved state we care about */ - - /* Account for restart interval (no-op if not using restarts) */ - entropy->restarts_to_go--; - - return TRUE; -} - - -/* - * MCU decoding for DC successive approximation refinement scan. - * Note: we assume such scans can be multi-component, although the spec - * is not very clear on the point. - */ - -METHODDEF boolean -decode_mcu_DC_refine (j_decompress_ptr cinfo, JBLOCKROW *MCU_data) -{ - phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy; - int p1 = 1 << cinfo->Al; /* 1 in the bit position being coded */ - int blkn; - JBLOCKROW block; - BITREAD_STATE_VARS; - - /* Process restart marker if needed; may have to suspend */ - if (cinfo->restart_interval) { - if (entropy->restarts_to_go == 0) - if (! process_restart(cinfo)) - return FALSE; - } - - /* Load up working state */ - BITREAD_LOAD_STATE(cinfo,entropy->bitstate); - - /* Outer loop handles each block in the MCU */ - - for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) { - block = MCU_data[blkn]; - - /* Encoded data is simply the next bit of the two's-complement DC value */ - CHECK_BIT_BUFFER(br_state, 1, return FALSE); - if (GET_BITS(1)) - (*block)[0] |= p1; - /* Note: since we use |=, repeating the assignment later is safe */ - } - - /* Completed MCU, so update state */ - BITREAD_SAVE_STATE(cinfo,entropy->bitstate); - - /* Account for restart interval (no-op if not using restarts) */ - entropy->restarts_to_go--; - - return TRUE; -} - - -/* - * MCU decoding for AC successive approximation refinement scan. - */ - -METHODDEF boolean -decode_mcu_AC_refine (j_decompress_ptr cinfo, JBLOCKROW *MCU_data) -{ - phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy; - int Se = cinfo->Se; - int p1 = 1 << cinfo->Al; /* 1 in the bit position being coded */ - int m1 = (-1) << cinfo->Al; /* -1 in the bit position being coded */ - register int s, k, r; - unsigned int EOBRUN; - JBLOCKROW block; - JCOEFPTR thiscoef; - BITREAD_STATE_VARS; - d_derived_tbl * tbl; - int num_newnz; - int newnz_pos[DCTSIZE2]; - - /* Process restart marker if needed; may have to suspend */ - if (cinfo->restart_interval) { - if (entropy->restarts_to_go == 0) - if (! process_restart(cinfo)) - return FALSE; - } - - /* Load up working state */ - BITREAD_LOAD_STATE(cinfo,entropy->bitstate); - EOBRUN = entropy->saved.EOBRUN; /* only part of saved state we care about */ - - /* There is always only one block per MCU */ - block = MCU_data[0]; - tbl = entropy->ac_derived_tbl; - - /* If we are forced to suspend, we must undo the assignments to any newly - * nonzero coefficients in the block, because otherwise we'd get confused - * next time about which coefficients were already nonzero. - * But we need not undo addition of bits to already-nonzero coefficients; - * instead, we can test the current bit position to see if we already did it. - */ - num_newnz = 0; - - /* initialize coefficient loop counter to start of band */ - k = cinfo->Ss; - - if (EOBRUN == 0) { - for (; k <= Se; k++) { - HUFF_DECODE(s, br_state, tbl, goto undoit, label3); - r = s >> 4; - s &= 15; - if (s) { - if (s != 1) /* size of new coef should always be 1 */ - WARNMS(cinfo, JWRN_HUFF_BAD_CODE); - CHECK_BIT_BUFFER(br_state, 1, goto undoit); - if (GET_BITS(1)) - s = p1; /* newly nonzero coef is positive */ - else - s = m1; /* newly nonzero coef is negative */ - } else { - if (r != 15) { - EOBRUN = 1 << r; /* EOBr, run length is 2^r + appended bits */ - if (r) { - CHECK_BIT_BUFFER(br_state, r, goto undoit); - r = GET_BITS(r); - EOBRUN += r; - } - break; /* rest of block is handled by EOB logic */ - } - /* note s = 0 for processing ZRL */ - } - /* Advance over already-nonzero coefs and r still-zero coefs, - * appending correction bits to the nonzeroes. A correction bit is 1 - * if the absolute value of the coefficient must be increased. - */ - do { - thiscoef = *block + jpeg_natural_order[k]; - if (*thiscoef != 0) { - CHECK_BIT_BUFFER(br_state, 1, goto undoit); - if (GET_BITS(1)) { - if ((*thiscoef & p1) == 0) { /* do nothing if already changed it */ - if (*thiscoef >= 0) - *thiscoef += p1; - else - *thiscoef += m1; - } - } - } else { - if (--r < 0) - break; /* reached target zero coefficient */ - } - k++; - } while (k <= Se); - if (s) { - int pos = jpeg_natural_order[k]; - /* Output newly nonzero coefficient */ - (*block)[pos] = (JCOEF) s; - /* Remember its position in case we have to suspend */ - newnz_pos[num_newnz++] = pos; - } - } - } - - if (EOBRUN > 0) { - /* Scan any remaining coefficient positions after the end-of-band - * (the last newly nonzero coefficient, if any). Append a correction - * bit to each already-nonzero coefficient. A correction bit is 1 - * if the absolute value of the coefficient must be increased. - */ - for (; k <= Se; k++) { - thiscoef = *block + jpeg_natural_order[k]; - if (*thiscoef != 0) { - CHECK_BIT_BUFFER(br_state, 1, goto undoit); - if (GET_BITS(1)) { - if ((*thiscoef & p1) == 0) { /* do nothing if already changed it */ - if (*thiscoef >= 0) - *thiscoef += p1; - else - *thiscoef += m1; - } - } - } - } - /* Count one block completed in EOB run */ - EOBRUN--; - } - - /* Completed MCU, so update state */ - BITREAD_SAVE_STATE(cinfo,entropy->bitstate); - entropy->saved.EOBRUN = EOBRUN; /* only part of saved state we care about */ - - /* Account for restart interval (no-op if not using restarts) */ - entropy->restarts_to_go--; - - return TRUE; - -undoit: - /* Re-zero any output coefficients that we made newly nonzero */ - while (num_newnz > 0) - (*block)[newnz_pos[--num_newnz]] = 0; - - return FALSE; -} - - -/* - * Module initialization routine for progressive Huffman entropy decoding. - */ - -GLOBAL void -jinit_phuff_decoder (j_decompress_ptr cinfo) -{ - phuff_entropy_ptr entropy; - int *coef_bit_ptr; - int ci, i; - - entropy = (phuff_entropy_ptr) - (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, - SIZEOF(phuff_entropy_decoder)); - cinfo->entropy = (struct jpeg_entropy_decoder *) entropy; - entropy->pub.start_pass = start_pass_phuff_decoder; - - /* Mark derived tables unallocated */ - for (i = 0; i < NUM_HUFF_TBLS; i++) { - entropy->derived_tbls[i] = NULL; - } - - /* Create progression status table */ - cinfo->coef_bits = (int (*)[DCTSIZE2]) - (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, - cinfo->num_components*DCTSIZE2*SIZEOF(int)); - coef_bit_ptr = & cinfo->coef_bits[0][0]; - for (ci = 0; ci < cinfo->num_components; ci++) - for (i = 0; i < DCTSIZE2; i++) - *coef_bit_ptr++ = -1; -} - -#endif /* D_PROGRESSIVE_SUPPORTED */ diff --git a/engine/jpeg-6/jdpostct.c b/engine/jpeg-6/jdpostct.c deleted file mode 100644 index f612002..0000000 --- a/engine/jpeg-6/jdpostct.c +++ /dev/null @@ -1,290 +0,0 @@ -/* - * jdpostct.c - * - * Copyright (C) 1994-1995, Thomas G. Lane. - * This file is part of the Independent JPEG Group's software. - * For conditions of distribution and use, see the accompanying README file. - * - * This file contains the decompression postprocessing controller. - * This controller manages the upsampling, color conversion, and color - * quantization/reduction steps; specifically, it controls the buffering - * between upsample/color conversion and color quantization/reduction. - * - * If no color quantization/reduction is required, then this module has no - * work to do, and it just hands off to the upsample/color conversion code. - * An integrated upsample/convert/quantize process would replace this module - * entirely. - */ - -#define JPEG_INTERNALS -#include "jinclude.h" -#include "jpeglib.h" - - -/* Private buffer controller object */ - -typedef struct { - struct jpeg_d_post_controller pub; /* public fields */ - - /* Color quantization source buffer: this holds output data from - * the upsample/color conversion step to be passed to the quantizer. - * For two-pass color quantization, we need a full-image buffer; - * for one-pass operation, a strip buffer is sufficient. - */ - jvirt_sarray_ptr whole_image; /* virtual array, or NULL if one-pass */ - JSAMPARRAY buffer; /* strip buffer, or current strip of virtual */ - JDIMENSION strip_height; /* buffer size in rows */ - /* for two-pass mode only: */ - JDIMENSION starting_row; /* row # of first row in current strip */ - JDIMENSION next_row; /* index of next row to fill/empty in strip */ -} my_post_controller; - -typedef my_post_controller * my_post_ptr; - - -/* Forward declarations */ -METHODDEF void post_process_1pass - JPP((j_decompress_ptr cinfo, - JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr, - JDIMENSION in_row_groups_avail, - JSAMPARRAY output_buf, JDIMENSION *out_row_ctr, - JDIMENSION out_rows_avail)); -#ifdef QUANT_2PASS_SUPPORTED -METHODDEF void post_process_prepass - JPP((j_decompress_ptr cinfo, - JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr, - JDIMENSION in_row_groups_avail, - JSAMPARRAY output_buf, JDIMENSION *out_row_ctr, - JDIMENSION out_rows_avail)); -METHODDEF void post_process_2pass - JPP((j_decompress_ptr cinfo, - JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr, - JDIMENSION in_row_groups_avail, - JSAMPARRAY output_buf, JDIMENSION *out_row_ctr, - JDIMENSION out_rows_avail)); -#endif - - -/* - * Initialize for a processing pass. - */ - -METHODDEF void -start_pass_dpost (j_decompress_ptr cinfo, J_BUF_MODE pass_mode) -{ - my_post_ptr post = (my_post_ptr) cinfo->post; - - switch (pass_mode) { - case JBUF_PASS_THRU: - if (cinfo->quantize_colors) { - /* Single-pass processing with color quantization. */ - post->pub.post_process_data = post_process_1pass; - /* We could be doing buffered-image output before starting a 2-pass - * color quantization; in that case, jinit_d_post_controller did not - * allocate a strip buffer. Use the virtual-array buffer as workspace. - */ - if (post->buffer == NULL) { - post->buffer = (*cinfo->mem->access_virt_sarray) - ((j_common_ptr) cinfo, post->whole_image, - (JDIMENSION) 0, post->strip_height, TRUE); - } - } else { - /* For single-pass processing without color quantization, - * I have no work to do; just call the upsampler directly. - */ - post->pub.post_process_data = cinfo->upsample->upsample; - } - break; -#ifdef QUANT_2PASS_SUPPORTED - case JBUF_SAVE_AND_PASS: - /* First pass of 2-pass quantization */ - if (post->whole_image == NULL) - ERREXIT(cinfo, JERR_BAD_BUFFER_MODE); - post->pub.post_process_data = post_process_prepass; - break; - case JBUF_CRANK_DEST: - /* Second pass of 2-pass quantization */ - if (post->whole_image == NULL) - ERREXIT(cinfo, JERR_BAD_BUFFER_MODE); - post->pub.post_process_data = post_process_2pass; - break; -#endif /* QUANT_2PASS_SUPPORTED */ - default: - ERREXIT(cinfo, JERR_BAD_BUFFER_MODE); - break; - } - post->starting_row = post->next_row = 0; -} - - -/* - * Process some data in the one-pass (strip buffer) case. - * This is used for color precision reduction as well as one-pass quantization. - */ - -METHODDEF void -post_process_1pass (j_decompress_ptr cinfo, - JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr, - JDIMENSION in_row_groups_avail, - JSAMPARRAY output_buf, JDIMENSION *out_row_ctr, - JDIMENSION out_rows_avail) -{ - my_post_ptr post = (my_post_ptr) cinfo->post; - JDIMENSION num_rows, max_rows; - - /* Fill the buffer, but not more than what we can dump out in one go. */ - /* Note we rely on the upsampler to detect bottom of image. */ - max_rows = out_rows_avail - *out_row_ctr; - if (max_rows > post->strip_height) - max_rows = post->strip_height; - num_rows = 0; - (*cinfo->upsample->upsample) (cinfo, - input_buf, in_row_group_ctr, in_row_groups_avail, - post->buffer, &num_rows, max_rows); - /* Quantize and emit data. */ - (*cinfo->cquantize->color_quantize) (cinfo, - post->buffer, output_buf + *out_row_ctr, (int) num_rows); - *out_row_ctr += num_rows; -} - - -#ifdef QUANT_2PASS_SUPPORTED - -/* - * Process some data in the first pass of 2-pass quantization. - */ - -METHODDEF void -post_process_prepass (j_decompress_ptr cinfo, - JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr, - JDIMENSION in_row_groups_avail, - JSAMPARRAY output_buf, JDIMENSION *out_row_ctr, - JDIMENSION out_rows_avail) -{ - my_post_ptr post = (my_post_ptr) cinfo->post; - JDIMENSION old_next_row, num_rows; - - /* Reposition virtual buffer if at start of strip. */ - if (post->next_row == 0) { - post->buffer = (*cinfo->mem->access_virt_sarray) - ((j_common_ptr) cinfo, post->whole_image, - post->starting_row, post->strip_height, TRUE); - } - - /* Upsample some data (up to a strip height's worth). */ - old_next_row = post->next_row; - (*cinfo->upsample->upsample) (cinfo, - input_buf, in_row_group_ctr, in_row_groups_avail, - post->buffer, &post->next_row, post->strip_height); - - /* Allow quantizer to scan new data. No data is emitted, */ - /* but we advance out_row_ctr so outer loop can tell when we're done. */ - if (post->next_row > old_next_row) { - num_rows = post->next_row - old_next_row; - (*cinfo->cquantize->color_quantize) (cinfo, post->buffer + old_next_row, - (JSAMPARRAY) NULL, (int) num_rows); - *out_row_ctr += num_rows; - } - - /* Advance if we filled the strip. */ - if (post->next_row >= post->strip_height) { - post->starting_row += post->strip_height; - post->next_row = 0; - } -} - - -/* - * Process some data in the second pass of 2-pass quantization. - */ - -METHODDEF void -post_process_2pass (j_decompress_ptr cinfo, - JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr, - JDIMENSION in_row_groups_avail, - JSAMPARRAY output_buf, JDIMENSION *out_row_ctr, - JDIMENSION out_rows_avail) -{ - my_post_ptr post = (my_post_ptr) cinfo->post; - JDIMENSION num_rows, max_rows; - - /* Reposition virtual buffer if at start of strip. */ - if (post->next_row == 0) { - post->buffer = (*cinfo->mem->access_virt_sarray) - ((j_common_ptr) cinfo, post->whole_image, - post->starting_row, post->strip_height, FALSE); - } - - /* Determine number of rows to emit. */ - num_rows = post->strip_height - post->next_row; /* available in strip */ - max_rows = out_rows_avail - *out_row_ctr; /* available in output area */ - if (num_rows > max_rows) - num_rows = max_rows; - /* We have to check bottom of image here, can't depend on upsampler. */ - max_rows = cinfo->output_height - post->starting_row; - if (num_rows > max_rows) - num_rows = max_rows; - - /* Quantize and emit data. */ - (*cinfo->cquantize->color_quantize) (cinfo, - post->buffer + post->next_row, output_buf + *out_row_ctr, - (int) num_rows); - *out_row_ctr += num_rows; - - /* Advance if we filled the strip. */ - post->next_row += num_rows; - if (post->next_row >= post->strip_height) { - post->starting_row += post->strip_height; - post->next_row = 0; - } -} - -#endif /* QUANT_2PASS_SUPPORTED */ - - -/* - * Initialize postprocessing controller. - */ - -GLOBAL void -jinit_d_post_controller (j_decompress_ptr cinfo, boolean need_full_buffer) -{ - my_post_ptr post; - - post = (my_post_ptr) - (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, - SIZEOF(my_post_controller)); - cinfo->post = (struct jpeg_d_post_controller *) post; - post->pub.start_pass = start_pass_dpost; - post->whole_image = NULL; /* flag for no virtual arrays */ - post->buffer = NULL; /* flag for no strip buffer */ - - /* Create the quantization buffer, if needed */ - if (cinfo->quantize_colors) { - /* The buffer strip height is max_v_samp_factor, which is typically - * an efficient number of rows for upsampling to return. - * (In the presence of output rescaling, we might want to be smarter?) - */ - post->strip_height = (JDIMENSION) cinfo->max_v_samp_factor; - if (need_full_buffer) { - /* Two-pass color quantization: need full-image storage. */ - /* We round up the number of rows to a multiple of the strip height. */ -#ifdef QUANT_2PASS_SUPPORTED - post->whole_image = (*cinfo->mem->request_virt_sarray) - ((j_common_ptr) cinfo, JPOOL_IMAGE, FALSE, - cinfo->output_width * cinfo->out_color_components, - (JDIMENSION) jround_up((long) cinfo->output_height, - (long) post->strip_height), - post->strip_height); -#else - ERREXIT(cinfo, JERR_BAD_BUFFER_MODE); -#endif /* QUANT_2PASS_SUPPORTED */ - } else { - /* One-pass color quantization: just make a strip buffer. */ - post->buffer = (*cinfo->mem->alloc_sarray) - ((j_common_ptr) cinfo, JPOOL_IMAGE, - cinfo->output_width * cinfo->out_color_components, - post->strip_height); - } - } -} diff --git a/engine/jpeg-6/jdsample.c b/engine/jpeg-6/jdsample.c deleted file mode 100644 index 661e198..0000000 --- a/engine/jpeg-6/jdsample.c +++ /dev/null @@ -1,478 +0,0 @@ -/* - * jdsample.c - * - * Copyright (C) 1991-1994, Thomas G. Lane. - * This file is part of the Independent JPEG Group's software. - * For conditions of distribution and use, see the accompanying README file. - * - * This file contains upsampling routines. - * - * Upsampling input data is counted in "row groups". A row group - * is defined to be (v_samp_factor * DCT_scaled_size / min_DCT_scaled_size) - * sample rows of each component. Upsampling will normally produce - * max_v_samp_factor pixel rows from each row group (but this could vary - * if the upsampler is applying a scale factor of its own). - * - * An excellent reference for image resampling is - * Digital Image Warping, George Wolberg, 1990. - * Pub. by IEEE Computer Society Press, Los Alamitos, CA. ISBN 0-8186-8944-7. - */ - -#define JPEG_INTERNALS -#include "jinclude.h" -#include "jpeglib.h" - - -/* Pointer to routine to upsample a single component */ -typedef JMETHOD(void, upsample1_ptr, - (j_decompress_ptr cinfo, jpeg_component_info * compptr, - JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr)); - -/* Private subobject */ - -typedef struct { - struct jpeg_upsampler pub; /* public fields */ - - /* Color conversion buffer. When using separate upsampling and color - * conversion steps, this buffer holds one upsampled row group until it - * has been color converted and output. - * Note: we do not allocate any storage for component(s) which are full-size, - * ie do not need rescaling. The corresponding entry of color_buf[] is - * simply set to point to the input data array, thereby avoiding copying. - */ - JSAMPARRAY color_buf[MAX_COMPONENTS]; - - /* Per-component upsampling method pointers */ - upsample1_ptr methods[MAX_COMPONENTS]; - - int next_row_out; /* counts rows emitted from color_buf */ - JDIMENSION rows_to_go; /* counts rows remaining in image */ - - /* Height of an input row group for each component. */ - int rowgroup_height[MAX_COMPONENTS]; - - /* These arrays save pixel expansion factors so that int_expand need not - * recompute them each time. They are unused for other upsampling methods. - */ - UINT8 h_expand[MAX_COMPONENTS]; - UINT8 v_expand[MAX_COMPONENTS]; -} my_upsampler; - -typedef my_upsampler * my_upsample_ptr; - - -/* - * Initialize for an upsampling pass. - */ - -METHODDEF void -start_pass_upsample (j_decompress_ptr cinfo) -{ - my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample; - - /* Mark the conversion buffer empty */ - upsample->next_row_out = cinfo->max_v_samp_factor; - /* Initialize total-height counter for detecting bottom of image */ - upsample->rows_to_go = cinfo->output_height; -} - - -/* - * Control routine to do upsampling (and color conversion). - * - * In this version we upsample each component independently. - * We upsample one row group into the conversion buffer, then apply - * color conversion a row at a time. - */ - -METHODDEF void -sep_upsample (j_decompress_ptr cinfo, - JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr, - JDIMENSION in_row_groups_avail, - JSAMPARRAY output_buf, JDIMENSION *out_row_ctr, - JDIMENSION out_rows_avail) -{ - my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample; - int ci; - jpeg_component_info * compptr; - JDIMENSION num_rows; - - /* Fill the conversion buffer, if it's empty */ - if (upsample->next_row_out >= cinfo->max_v_samp_factor) { - for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; - ci++, compptr++) { - /* Invoke per-component upsample method. Notice we pass a POINTER - * to color_buf[ci], so that fullsize_upsample can change it. - */ - (*upsample->methods[ci]) (cinfo, compptr, - input_buf[ci] + (*in_row_group_ctr * upsample->rowgroup_height[ci]), - upsample->color_buf + ci); - } - upsample->next_row_out = 0; - } - - /* Color-convert and emit rows */ - - /* How many we have in the buffer: */ - num_rows = (JDIMENSION) (cinfo->max_v_samp_factor - upsample->next_row_out); - /* Not more than the distance to the end of the image. Need this test - * in case the image height is not a multiple of max_v_samp_factor: - */ - if (num_rows > upsample->rows_to_go) - num_rows = upsample->rows_to_go; - /* And not more than what the client can accept: */ - out_rows_avail -= *out_row_ctr; - if (num_rows > out_rows_avail) - num_rows = out_rows_avail; - - (*cinfo->cconvert->color_convert) (cinfo, upsample->color_buf, - (JDIMENSION) upsample->next_row_out, - output_buf + *out_row_ctr, - (int) num_rows); - - /* Adjust counts */ - *out_row_ctr += num_rows; - upsample->rows_to_go -= num_rows; - upsample->next_row_out += num_rows; - /* When the buffer is emptied, declare this input row group consumed */ - if (upsample->next_row_out >= cinfo->max_v_samp_factor) - (*in_row_group_ctr)++; -} - - -/* - * These are the routines invoked by sep_upsample to upsample pixel values - * of a single component. One row group is processed per call. - */ - - -/* - * For full-size components, we just make color_buf[ci] point at the - * input buffer, and thus avoid copying any data. Note that this is - * safe only because sep_upsample doesn't declare the input row group - * "consumed" until we are done color converting and emitting it. - */ - -METHODDEF void -fullsize_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr, - JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr) -{ - *output_data_ptr = input_data; -} - - -/* - * This is a no-op version used for "uninteresting" components. - * These components will not be referenced by color conversion. - */ - -METHODDEF void -noop_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr, - JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr) -{ - *output_data_ptr = NULL; /* safety check */ -} - - -/* - * This version handles any integral sampling ratios. - * This is not used for typical JPEG files, so it need not be fast. - * Nor, for that matter, is it particularly accurate: the algorithm is - * simple replication of the input pixel onto the corresponding output - * pixels. The hi-falutin sampling literature refers to this as a - * "box filter". A box filter tends to introduce visible artifacts, - * so if you are actually going to use 3:1 or 4:1 sampling ratios - * you would be well advised to improve this code. - */ - -METHODDEF void -int_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr, - JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr) -{ - my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample; - JSAMPARRAY output_data = *output_data_ptr; - register JSAMPROW inptr, outptr; - register JSAMPLE invalue; - register int h; - JSAMPROW outend; - int h_expand, v_expand; - int inrow, outrow; - - h_expand = upsample->h_expand[compptr->component_index]; - v_expand = upsample->v_expand[compptr->component_index]; - - inrow = outrow = 0; - while (outrow < cinfo->max_v_samp_factor) { - /* Generate one output row with proper horizontal expansion */ - inptr = input_data[inrow]; - outptr = output_data[outrow]; - outend = outptr + cinfo->output_width; - while (outptr < outend) { - invalue = *inptr++; /* don't need GETJSAMPLE() here */ - for (h = h_expand; h > 0; h--) { - *outptr++ = invalue; - } - } - /* Generate any additional output rows by duplicating the first one */ - if (v_expand > 1) { - jcopy_sample_rows(output_data, outrow, output_data, outrow+1, - v_expand-1, cinfo->output_width); - } - inrow++; - outrow += v_expand; - } -} - - -/* - * Fast processing for the common case of 2:1 horizontal and 1:1 vertical. - * It's still a box filter. - */ - -METHODDEF void -h2v1_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr, - JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr) -{ - JSAMPARRAY output_data = *output_data_ptr; - register JSAMPROW inptr, outptr; - register JSAMPLE invalue; - JSAMPROW outend; - int inrow; - - for (inrow = 0; inrow < cinfo->max_v_samp_factor; inrow++) { - inptr = input_data[inrow]; - outptr = output_data[inrow]; - outend = outptr + cinfo->output_width; - while (outptr < outend) { - invalue = *inptr++; /* don't need GETJSAMPLE() here */ - *outptr++ = invalue; - *outptr++ = invalue; - } - } -} - - -/* - * Fast processing for the common case of 2:1 horizontal and 2:1 vertical. - * It's still a box filter. - */ - -METHODDEF void -h2v2_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr, - JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr) -{ - JSAMPARRAY output_data = *output_data_ptr; - register JSAMPROW inptr, outptr; - register JSAMPLE invalue; - JSAMPROW outend; - int inrow, outrow; - - inrow = outrow = 0; - while (outrow < cinfo->max_v_samp_factor) { - inptr = input_data[inrow]; - outptr = output_data[outrow]; - outend = outptr + cinfo->output_width; - while (outptr < outend) { - invalue = *inptr++; /* don't need GETJSAMPLE() here */ - *outptr++ = invalue; - *outptr++ = invalue; - } - jcopy_sample_rows(output_data, outrow, output_data, outrow+1, - 1, cinfo->output_width); - inrow++; - outrow += 2; - } -} - - -/* - * Fancy processing for the common case of 2:1 horizontal and 1:1 vertical. - * - * The upsampling algorithm is linear interpolation between pixel centers, - * also known as a "triangle filter". This is a good compromise between - * speed and visual quality. The centers of the output pixels are 1/4 and 3/4 - * of the way between input pixel centers. - * - * A note about the "bias" calculations: when rounding fractional values to - * integer, we do not want to always round 0.5 up to the next integer. - * If we did that, we'd introduce a noticeable bias towards larger values. - * Instead, this code is arranged so that 0.5 will be rounded up or down at - * alternate pixel locations (a simple ordered dither pattern). - */ - -METHODDEF void -h2v1_fancy_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr, - JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr) -{ - JSAMPARRAY output_data = *output_data_ptr; - register JSAMPROW inptr, outptr; - register int invalue; - register JDIMENSION colctr; - int inrow; - - for (inrow = 0; inrow < cinfo->max_v_samp_factor; inrow++) { - inptr = input_data[inrow]; - outptr = output_data[inrow]; - /* Special case for first column */ - invalue = GETJSAMPLE(*inptr++); - *outptr++ = (JSAMPLE) invalue; - *outptr++ = (JSAMPLE) ((invalue * 3 + GETJSAMPLE(*inptr) + 2) >> 2); - - for (colctr = compptr->downsampled_width - 2; colctr > 0; colctr--) { - /* General case: 3/4 * nearer pixel + 1/4 * further pixel */ - invalue = GETJSAMPLE(*inptr++) * 3; - *outptr++ = (JSAMPLE) ((invalue + GETJSAMPLE(inptr[-2]) + 1) >> 2); - *outptr++ = (JSAMPLE) ((invalue + GETJSAMPLE(*inptr) + 2) >> 2); - } - - /* Special case for last column */ - invalue = GETJSAMPLE(*inptr); - *outptr++ = (JSAMPLE) ((invalue * 3 + GETJSAMPLE(inptr[-1]) + 1) >> 2); - *outptr++ = (JSAMPLE) invalue; - } -} - - -/* - * Fancy processing for the common case of 2:1 horizontal and 2:1 vertical. - * Again a triangle filter; see comments for h2v1 case, above. - * - * It is OK for us to reference the adjacent input rows because we demanded - * context from the main buffer controller (see initialization code). - */ - -METHODDEF void -h2v2_fancy_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr, - JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr) -{ - JSAMPARRAY output_data = *output_data_ptr; - register JSAMPROW inptr0, inptr1, outptr; -#if BITS_IN_JSAMPLE == 8 - register int thiscolsum, lastcolsum, nextcolsum; -#else - register INT32 thiscolsum, lastcolsum, nextcolsum; -#endif - register JDIMENSION colctr; - int inrow, outrow, v; - - inrow = outrow = 0; - while (outrow < cinfo->max_v_samp_factor) { - for (v = 0; v < 2; v++) { - /* inptr0 points to nearest input row, inptr1 points to next nearest */ - inptr0 = input_data[inrow]; - if (v == 0) /* next nearest is row above */ - inptr1 = input_data[inrow-1]; - else /* next nearest is row below */ - inptr1 = input_data[inrow+1]; - outptr = output_data[outrow++]; - - /* Special case for first column */ - thiscolsum = GETJSAMPLE(*inptr0++) * 3 + GETJSAMPLE(*inptr1++); - nextcolsum = GETJSAMPLE(*inptr0++) * 3 + GETJSAMPLE(*inptr1++); - *outptr++ = (JSAMPLE) ((thiscolsum * 4 + 8) >> 4); - *outptr++ = (JSAMPLE) ((thiscolsum * 3 + nextcolsum + 7) >> 4); - lastcolsum = thiscolsum; thiscolsum = nextcolsum; - - for (colctr = compptr->downsampled_width - 2; colctr > 0; colctr--) { - /* General case: 3/4 * nearer pixel + 1/4 * further pixel in each */ - /* dimension, thus 9/16, 3/16, 3/16, 1/16 overall */ - nextcolsum = GETJSAMPLE(*inptr0++) * 3 + GETJSAMPLE(*inptr1++); - *outptr++ = (JSAMPLE) ((thiscolsum * 3 + lastcolsum + 8) >> 4); - *outptr++ = (JSAMPLE) ((thiscolsum * 3 + nextcolsum + 7) >> 4); - lastcolsum = thiscolsum; thiscolsum = nextcolsum; - } - - /* Special case for last column */ - *outptr++ = (JSAMPLE) ((thiscolsum * 3 + lastcolsum + 8) >> 4); - *outptr++ = (JSAMPLE) ((thiscolsum * 4 + 7) >> 4); - } - inrow++; - } -} - - -/* - * Module initialization routine for upsampling. - */ - -GLOBAL void -jinit_upsampler (j_decompress_ptr cinfo) -{ - my_upsample_ptr upsample; - int ci; - jpeg_component_info * compptr; - boolean need_buffer, do_fancy; - int h_in_group, v_in_group, h_out_group, v_out_group; - - upsample = (my_upsample_ptr) - (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, - SIZEOF(my_upsampler)); - cinfo->upsample = (struct jpeg_upsampler *) upsample; - upsample->pub.start_pass = start_pass_upsample; - upsample->pub.upsample = sep_upsample; - upsample->pub.need_context_rows = FALSE; /* until we find out differently */ - - if (cinfo->CCIR601_sampling) /* this isn't supported */ - ERREXIT(cinfo, JERR_CCIR601_NOTIMPL); - - /* jdmainct.c doesn't support context rows when min_DCT_scaled_size = 1, - * so don't ask for it. - */ - do_fancy = cinfo->do_fancy_upsampling && cinfo->min_DCT_scaled_size > 1; - - /* Verify we can handle the sampling factors, select per-component methods, - * and create storage as needed. - */ - for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; - ci++, compptr++) { - /* Compute size of an "input group" after IDCT scaling. This many samples - * are to be converted to max_h_samp_factor * max_v_samp_factor pixels. - */ - h_in_group = (compptr->h_samp_factor * compptr->DCT_scaled_size) / - cinfo->min_DCT_scaled_size; - v_in_group = (compptr->v_samp_factor * compptr->DCT_scaled_size) / - cinfo->min_DCT_scaled_size; - h_out_group = cinfo->max_h_samp_factor; - v_out_group = cinfo->max_v_samp_factor; - upsample->rowgroup_height[ci] = v_in_group; /* save for use later */ - need_buffer = TRUE; - if (! compptr->component_needed) { - /* Don't bother to upsample an uninteresting component. */ - upsample->methods[ci] = noop_upsample; - need_buffer = FALSE; - } else if (h_in_group == h_out_group && v_in_group == v_out_group) { - /* Fullsize components can be processed without any work. */ - upsample->methods[ci] = fullsize_upsample; - need_buffer = FALSE; - } else if (h_in_group * 2 == h_out_group && - v_in_group == v_out_group) { - /* Special cases for 2h1v upsampling */ - if (do_fancy && compptr->downsampled_width > 2) - upsample->methods[ci] = h2v1_fancy_upsample; - else - upsample->methods[ci] = h2v1_upsample; - } else if (h_in_group * 2 == h_out_group && - v_in_group * 2 == v_out_group) { - /* Special cases for 2h2v upsampling */ - if (do_fancy && compptr->downsampled_width > 2) { - upsample->methods[ci] = h2v2_fancy_upsample; - upsample->pub.need_context_rows = TRUE; - } else - upsample->methods[ci] = h2v2_upsample; - } else if ((h_out_group % h_in_group) == 0 && - (v_out_group % v_in_group) == 0) { - /* Generic integral-factors upsampling method */ - upsample->methods[ci] = int_upsample; - upsample->h_expand[ci] = (UINT8) (h_out_group / h_in_group); - upsample->v_expand[ci] = (UINT8) (v_out_group / v_in_group); - } else - ERREXIT(cinfo, JERR_FRACT_SAMPLE_NOTIMPL); - if (need_buffer) { - upsample->color_buf[ci] = (*cinfo->mem->alloc_sarray) - ((j_common_ptr) cinfo, JPOOL_IMAGE, - (JDIMENSION) jround_up((long) cinfo->output_width, - (long) cinfo->max_h_samp_factor), - (JDIMENSION) cinfo->max_v_samp_factor); - } - } -} diff --git a/engine/jpeg-6/jdtrans.c b/engine/jpeg-6/jdtrans.c deleted file mode 100644 index 5c14adc..0000000 --- a/engine/jpeg-6/jdtrans.c +++ /dev/null @@ -1,122 +0,0 @@ -/* - * jdtrans.c - * - * Copyright (C) 1995, Thomas G. Lane. - * This file is part of the Independent JPEG Group's software. - * For conditions of distribution and use, see the accompanying README file. - * - * This file contains library routines for transcoding decompression, - * that is, reading raw DCT coefficient arrays from an input JPEG file. - * The routines in jdapimin.c will also be needed by a transcoder. - */ - -#define JPEG_INTERNALS -#include "jinclude.h" -#include "jpeglib.h" - - -/* Forward declarations */ -LOCAL void transdecode_master_selection JPP((j_decompress_ptr cinfo)); - - -/* - * Read the coefficient arrays from a JPEG file. - * jpeg_read_header must be completed before calling this. - * - * The entire image is read into a set of virtual coefficient-block arrays, - * one per component. The return value is a pointer to the array of - * virtual-array descriptors. These can be manipulated directly via the - * JPEG memory manager, or handed off to jpeg_write_coefficients(). - * To release the memory occupied by the virtual arrays, call - * jpeg_finish_decompress() when done with the data. - * - * Returns NULL if suspended. This case need be checked only if - * a suspending data source is used. - */ - -GLOBAL jvirt_barray_ptr * -jpeg_read_coefficients (j_decompress_ptr cinfo) -{ - if (cinfo->global_state == DSTATE_READY) { - /* First call: initialize active modules */ - transdecode_master_selection(cinfo); - cinfo->global_state = DSTATE_RDCOEFS; - } else if (cinfo->global_state != DSTATE_RDCOEFS) - ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); - /* Absorb whole file into the coef buffer */ - for (;;) { - int retcode; - /* Call progress monitor hook if present */ - if (cinfo->progress != NULL) - (*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo); - /* Absorb some more input */ - retcode = (*cinfo->inputctl->consume_input) (cinfo); - if (retcode == JPEG_SUSPENDED) - return NULL; - if (retcode == JPEG_REACHED_EOI) - break; - /* Advance progress counter if appropriate */ - if (cinfo->progress != NULL && - (retcode == JPEG_ROW_COMPLETED || retcode == JPEG_REACHED_SOS)) { - if (++cinfo->progress->pass_counter >= cinfo->progress->pass_limit) { - /* startup underestimated number of scans; ratchet up one scan */ - cinfo->progress->pass_limit += (long) cinfo->total_iMCU_rows; - } - } - } - /* Set state so that jpeg_finish_decompress does the right thing */ - cinfo->global_state = DSTATE_STOPPING; - return cinfo->coef->coef_arrays; -} - - -/* - * Master selection of decompression modules for transcoding. - * This substitutes for jdmaster.c's initialization of the full decompressor. - */ - -LOCAL void -transdecode_master_selection (j_decompress_ptr cinfo) -{ - /* Entropy decoding: either Huffman or arithmetic coding. */ - if (cinfo->arith_code) { - ERREXIT(cinfo, JERR_ARITH_NOTIMPL); - } else { - if (cinfo->progressive_mode) { -#ifdef D_PROGRESSIVE_SUPPORTED - jinit_phuff_decoder(cinfo); -#else - ERREXIT(cinfo, JERR_NOT_COMPILED); -#endif - } else - jinit_huff_decoder(cinfo); - } - - /* Always get a full-image coefficient buffer. */ - jinit_d_coef_controller(cinfo, TRUE); - - /* We can now tell the memory manager to allocate virtual arrays. */ - (*cinfo->mem->realize_virt_arrays) ((j_common_ptr) cinfo); - - /* Initialize input side of decompressor to consume first scan. */ - (*cinfo->inputctl->start_input_pass) (cinfo); - - /* Initialize progress monitoring. */ - if (cinfo->progress != NULL) { - int nscans; - /* Estimate number of scans to set pass_limit. */ - if (cinfo->progressive_mode) { - /* Arbitrarily estimate 2 interleaved DC scans + 3 AC scans/component. */ - nscans = 2 + 3 * cinfo->num_components; - } else if (cinfo->inputctl->has_multiple_scans) { - /* For a nonprogressive multiscan file, estimate 1 scan per component. */ - nscans = cinfo->num_components; - } else { - nscans = 1; - } - cinfo->progress->pass_counter = 0L; - cinfo->progress->pass_limit = (long) cinfo->total_iMCU_rows * nscans; - cinfo->progress->completed_passes = 0; - cinfo->progress->total_passes = 1; - } -} diff --git a/engine/jpeg-6/jerror.c b/engine/jpeg-6/jerror.c deleted file mode 100644 index 1324d5e..0000000 --- a/engine/jpeg-6/jerror.c +++ /dev/null @@ -1,232 +0,0 @@ -/* - * jerror.c - * - * Copyright (C) 1991-1994, Thomas G. Lane. - * This file is part of the Independent JPEG Group's software. - * For conditions of distribution and use, see the accompanying README file. - * - * This file contains simple error-reporting and trace-message routines. - * These are suitable for Unix-like systems and others where writing to - * stderr is the right thing to do. Many applications will want to replace - * some or all of these routines. - * - * These routines are used by both the compression and decompression code. - */ - -/* this is not a core library module, so it doesn't define JPEG_INTERNALS */ -#include "jinclude.h" -#include "jpeglib.h" -#include "jversion.h" -#include "jerror.h" - -//#include "../renderer/tr_local.h" - -#ifndef EXIT_FAILURE /* define exit() codes if not provided */ -#define EXIT_FAILURE 1 -#endif - - -/* - * Create the message string table. - * We do this from the master message list in jerror.h by re-reading - * jerror.h with a suitable definition for macro JMESSAGE. - * The message table is made an external symbol just in case any applications - * want to refer to it directly. - */ - -#ifdef NEED_SHORT_EXTERNAL_NAMES -#define jpeg_std_message_table jMsgTable -#endif - -#define JMESSAGE(code,string) string , - -const char * const jpeg_std_message_table[] = { -#include "jerror.h" - NULL -}; - - -/* - * Error exit handler: must not return to caller. - * - * Applications may override this if they want to get control back after - * an error. Typically one would longjmp somewhere instead of exiting. - * The setjmp buffer can be made a private field within an expanded error - * handler object. Note that the info needed to generate an error message - * is stored in the error object, so you can generate the message now or - * later, at your convenience. - * You should make sure that the JPEG object is cleaned up (with jpeg_abort - * or jpeg_destroy) at some point. - */ - -METHODDEF void -error_exit (j_common_ptr cinfo) -{ - char buffer[JMSG_LENGTH_MAX]; - - /* Create the message */ - (*cinfo->err->format_message) (cinfo, buffer); - - /* Let the memory manager delete any temp files before we die */ - jpeg_destroy(cinfo); - - Sys_Error( "%s\n", buffer ); -} - - -/* - * Actual output of an error or trace message. - * Applications may override this method to send JPEG messages somewhere - * other than stderr. - */ - -METHODDEF void -output_message (j_common_ptr cinfo) -{ - char buffer[JMSG_LENGTH_MAX]; - - /* Create the message */ - (*cinfo->err->format_message) (cinfo, buffer); - - /* Send it to stderr, adding a newline */ - Con_Printf("%s\n", buffer); -} - - -/* - * Decide whether to emit a trace or warning message. - * msg_level is one of: - * -1: recoverable corrupt-data warning, may want to abort. - * 0: important advisory messages (always display to user). - * 1: first level of tracing detail. - * 2,3,...: successively more detailed tracing messages. - * An application might override this method if it wanted to abort on warnings - * or change the policy about which messages to display. - */ - -METHODDEF void -emit_message (j_common_ptr cinfo, int msg_level) -{ - struct jpeg_error_mgr * err = cinfo->err; - - if (msg_level < 0) { - /* It's a warning message. Since corrupt files may generate many warnings, - * the policy implemented here is to show only the first warning, - * unless trace_level >= 3. - */ - if (err->num_warnings == 0 || err->trace_level >= 3) - (*err->output_message) (cinfo); - /* Always count warnings in num_warnings. */ - err->num_warnings++; - } else { - /* It's a trace message. Show it if trace_level >= msg_level. */ - if (err->trace_level >= msg_level) - (*err->output_message) (cinfo); - } -} - - -/* - * Format a message string for the most recent JPEG error or message. - * The message is stored into buffer, which should be at least JMSG_LENGTH_MAX - * characters. Note that no '\n' character is added to the string. - * Few applications should need to override this method. - */ - -METHODDEF void -format_message (j_common_ptr cinfo, char * buffer) -{ - struct jpeg_error_mgr * err = cinfo->err; - int msg_code = err->msg_code; - const char * msgtext = NULL; - const char * msgptr; - char ch; - boolean isstring; - - /* Look up message string in proper table */ - if (msg_code > 0 && msg_code <= err->last_jpeg_message) { - msgtext = err->jpeg_message_table[msg_code]; - } else if (err->addon_message_table != NULL && - msg_code >= err->first_addon_message && - msg_code <= err->last_addon_message) { - msgtext = err->addon_message_table[msg_code - err->first_addon_message]; - } - - /* Defend against bogus message number */ - if (msgtext == NULL) { - err->msg_parm.i[0] = msg_code; - msgtext = err->jpeg_message_table[0]; - } - - /* Check for string parameter, as indicated by %s in the message text */ - isstring = FALSE; - msgptr = msgtext; - while ((ch = *msgptr++) != '\0') { - if (ch == '%') { - if (*msgptr == 's') isstring = TRUE; - break; - } - } - - /* Format the message into the passed buffer */ - if (isstring) - sprintf(buffer, msgtext, err->msg_parm.s); - else - sprintf(buffer, msgtext, - err->msg_parm.i[0], err->msg_parm.i[1], - err->msg_parm.i[2], err->msg_parm.i[3], - err->msg_parm.i[4], err->msg_parm.i[5], - err->msg_parm.i[6], err->msg_parm.i[7]); -} - - -/* - * Reset error state variables at start of a new image. - * This is called during compression startup to reset trace/error - * processing to default state, without losing any application-specific - * method pointers. An application might possibly want to override - * this method if it has additional error processing state. - */ - -METHODDEF void -reset_error_mgr (j_common_ptr cinfo) -{ - cinfo->err->num_warnings = 0; - /* trace_level is not reset since it is an application-supplied parameter */ - cinfo->err->msg_code = 0; /* may be useful as a flag for "no error" */ -} - - -/* - * Fill in the standard error-handling methods in a jpeg_error_mgr object. - * Typical call is: - * struct jpeg_compress_struct cinfo; - * struct jpeg_error_mgr err; - * - * cinfo.err = jpeg_std_error(&err); - * after which the application may override some of the methods. - */ - -GLOBAL struct jpeg_error_mgr * -jpeg_std_error (struct jpeg_error_mgr * err) -{ - err->error_exit = error_exit; - err->emit_message = emit_message; - err->output_message = output_message; - err->format_message = format_message; - err->reset_error_mgr = reset_error_mgr; - - err->trace_level = 0; /* default = no tracing */ - err->num_warnings = 0; /* no warnings emitted yet */ - err->msg_code = 0; /* may be useful as a flag for "no error" */ - - /* Initialize message table pointers */ - err->jpeg_message_table = jpeg_std_message_table; - err->last_jpeg_message = (int) JMSG_LASTMSGCODE - 1; - - err->addon_message_table = NULL; - err->first_addon_message = 0; /* for safety */ - err->last_addon_message = 0; - - return err; -} diff --git a/engine/jpeg-6/jerror.h b/engine/jpeg-6/jerror.h deleted file mode 100644 index bf60e7e..0000000 --- a/engine/jpeg-6/jerror.h +++ /dev/null @@ -1,273 +0,0 @@ -/* - * jerror.h - * - * Copyright (C) 1994-1995, Thomas G. Lane. - * This file is part of the Independent JPEG Group's software. - * For conditions of distribution and use, see the accompanying README file. - * - * This file defines the error and message codes for the JPEG library. - * Edit this file to add new codes, or to translate the message strings to - * some other language. - * A set of error-reporting macros are defined too. Some applications using - * the JPEG library may wish to include this file to get the error codes - * and/or the macros. - */ - -/* - * To define the enum list of message codes, include this file without - * defining macro JMESSAGE. To create a message string table, include it - * again with a suitable JMESSAGE definition (see jerror.c for an example). - */ -#ifndef JMESSAGE -#ifndef JERROR_H -/* First time through, define the enum list */ -#define JMAKE_ENUM_LIST -#else -/* Repeated inclusions of this file are no-ops unless JMESSAGE is defined */ -#define JMESSAGE(code,string) -#endif /* JERROR_H */ -#endif /* JMESSAGE */ - -#ifdef JMAKE_ENUM_LIST - -typedef enum { - -#define JMESSAGE(code,string) code , - -#endif /* JMAKE_ENUM_LIST */ - -JMESSAGE(JMSG_NOMESSAGE, "Bogus message code %d") /* Must be first entry! */ - -/* For maintenance convenience, list is alphabetical by message code name */ -JMESSAGE(JERR_ARITH_NOTIMPL, - "Sorry, there are legal restrictions on arithmetic coding") -JMESSAGE(JERR_BAD_ALIGN_TYPE, "ALIGN_TYPE is wrong, please fix") -JMESSAGE(JERR_BAD_ALLOC_CHUNK, "MAX_ALLOC_CHUNK is wrong, please fix") -JMESSAGE(JERR_BAD_BUFFER_MODE, "Bogus buffer control mode") -JMESSAGE(JERR_BAD_COMPONENT_ID, "Invalid component ID %d in SOS") -JMESSAGE(JERR_BAD_DCTSIZE, "IDCT output block size %d not supported") -JMESSAGE(JERR_BAD_IN_COLORSPACE, "Bogus input colorspace") -JMESSAGE(JERR_BAD_J_COLORSPACE, "Bogus JPEG colorspace") -JMESSAGE(JERR_BAD_LENGTH, "Bogus marker length") -JMESSAGE(JERR_BAD_MCU_SIZE, "Sampling factors too large for interleaved scan") -JMESSAGE(JERR_BAD_POOL_ID, "Invalid memory pool code %d") -JMESSAGE(JERR_BAD_PRECISION, "Unsupported JPEG data precision %d") -JMESSAGE(JERR_BAD_PROGRESSION, - "Invalid progressive parameters Ss=%d Se=%d Ah=%d Al=%d") -JMESSAGE(JERR_BAD_PROG_SCRIPT, - "Invalid progressive parameters at scan script entry %d") -JMESSAGE(JERR_BAD_SAMPLING, "Bogus sampling factors") -JMESSAGE(JERR_BAD_SCAN_SCRIPT, "Invalid scan script at entry %d") -JMESSAGE(JERR_BAD_STATE, "Improper call to JPEG library in state %d") -JMESSAGE(JERR_BAD_VIRTUAL_ACCESS, "Bogus virtual array access") -JMESSAGE(JERR_BUFFER_SIZE, "Buffer passed to JPEG library is too small") -JMESSAGE(JERR_CANT_SUSPEND, "Suspension not allowed here") -JMESSAGE(JERR_CCIR601_NOTIMPL, "CCIR601 sampling not implemented yet") -JMESSAGE(JERR_COMPONENT_COUNT, "Too many color components: %d, max %d") -JMESSAGE(JERR_CONVERSION_NOTIMPL, "Unsupported color conversion request") -JMESSAGE(JERR_DAC_INDEX, "Bogus DAC index %d") -JMESSAGE(JERR_DAC_VALUE, "Bogus DAC value 0x%x") -JMESSAGE(JERR_DHT_COUNTS, "Bogus DHT counts") -JMESSAGE(JERR_DHT_INDEX, "Bogus DHT index %d") -JMESSAGE(JERR_DQT_INDEX, "Bogus DQT index %d") -JMESSAGE(JERR_EMPTY_IMAGE, "Empty JPEG image (DNL not supported)") -JMESSAGE(JERR_EMS_READ, "Read from EMS failed") -JMESSAGE(JERR_EMS_WRITE, "Write to EMS failed") -JMESSAGE(JERR_EOI_EXPECTED, "Didn't expect more than one scan") -JMESSAGE(JERR_FILE_READ, "Input file read error") -JMESSAGE(JERR_FILE_WRITE, "Output file write error --- out of disk space?") -JMESSAGE(JERR_FRACT_SAMPLE_NOTIMPL, "Fractional sampling not implemented yet") -JMESSAGE(JERR_HUFF_CLEN_OVERFLOW, "Huffman code size table overflow") -JMESSAGE(JERR_HUFF_MISSING_CODE, "Missing Huffman code table entry") -JMESSAGE(JERR_IMAGE_TOO_BIG, "Maximum supported image dimension is %u pixels") -JMESSAGE(JERR_INPUT_EMPTY, "Empty input file") -JMESSAGE(JERR_INPUT_EOF, "Premature end of input file") -JMESSAGE(JERR_MISMATCHED_QUANT_TABLE, - "Cannot transcode due to multiple use of quantization table %d") -JMESSAGE(JERR_MISSING_DATA, "Scan script does not transmit all data") -JMESSAGE(JERR_MODE_CHANGE, "Invalid color quantization mode change") -JMESSAGE(JERR_NOTIMPL, "Not implemented yet") -JMESSAGE(JERR_NOT_COMPILED, "Requested feature was omitted at compile time") -JMESSAGE(JERR_NO_BACKING_STORE, "Backing store not supported") -JMESSAGE(JERR_NO_HUFF_TABLE, "Huffman table 0x%02x was not defined") -JMESSAGE(JERR_NO_IMAGE, "JPEG datastream contains no image") -JMESSAGE(JERR_NO_QUANT_TABLE, "Quantization table 0x%02x was not defined") -JMESSAGE(JERR_NO_SOI, "Not a JPEG file: starts with 0x%02x 0x%02x") -JMESSAGE(JERR_OUT_OF_MEMORY, "Insufficient memory (case %d)") -JMESSAGE(JERR_QUANT_COMPONENTS, - "Cannot quantize more than %d color components") -JMESSAGE(JERR_QUANT_FEW_COLORS, "Cannot quantize to fewer than %d colors") -JMESSAGE(JERR_QUANT_MANY_COLORS, "Cannot quantize to more than %d colors") -JMESSAGE(JERR_SOF_DUPLICATE, "Invalid JPEG file structure: two SOF markers") -JMESSAGE(JERR_SOF_NO_SOS, "Invalid JPEG file structure: missing SOS marker") -JMESSAGE(JERR_SOF_UNSUPPORTED, "Unsupported JPEG process: SOF type 0x%02x") -JMESSAGE(JERR_SOI_DUPLICATE, "Invalid JPEG file structure: two SOI markers") -JMESSAGE(JERR_SOS_NO_SOF, "Invalid JPEG file structure: SOS before SOF") -JMESSAGE(JERR_TFILE_CREATE, "Failed to create temporary file %s") -JMESSAGE(JERR_TFILE_READ, "Read failed on temporary file") -JMESSAGE(JERR_TFILE_SEEK, "Seek failed on temporary file") -JMESSAGE(JERR_TFILE_WRITE, - "Write failed on temporary file --- out of disk space?") -JMESSAGE(JERR_TOO_LITTLE_DATA, "Application transferred too few scanlines") -JMESSAGE(JERR_UNKNOWN_MARKER, "Unsupported marker type 0x%02x") -JMESSAGE(JERR_VIRTUAL_BUG, "Virtual array controller messed up") -JMESSAGE(JERR_WIDTH_OVERFLOW, "Image too wide for this implementation") -JMESSAGE(JERR_XMS_READ, "Read from XMS failed") -JMESSAGE(JERR_XMS_WRITE, "Write to XMS failed") -JMESSAGE(JMSG_COPYRIGHT, JCOPYRIGHT) -JMESSAGE(JMSG_VERSION, JVERSION) -JMESSAGE(JTRC_16BIT_TABLES, - "Caution: quantization tables are too coarse for baseline JPEG") -JMESSAGE(JTRC_ADOBE, - "Adobe APP14 marker: version %d, flags 0x%04x 0x%04x, transform %d") -JMESSAGE(JTRC_APP0, "Unknown APP0 marker (not JFIF), length %u") -JMESSAGE(JTRC_APP14, "Unknown APP14 marker (not Adobe), length %u") -JMESSAGE(JTRC_DAC, "Define Arithmetic Table 0x%02x: 0x%02x") -JMESSAGE(JTRC_DHT, "Define Huffman Table 0x%02x") -JMESSAGE(JTRC_DQT, "Define Quantization Table %d precision %d") -JMESSAGE(JTRC_DRI, "Define Restart Interval %u") -JMESSAGE(JTRC_EMS_CLOSE, "Freed EMS handle %u") -JMESSAGE(JTRC_EMS_OPEN, "Obtained EMS handle %u") -JMESSAGE(JTRC_EOI, "End Of Image") -JMESSAGE(JTRC_HUFFBITS, " %3d %3d %3d %3d %3d %3d %3d %3d") -JMESSAGE(JTRC_JFIF, "JFIF APP0 marker, density %dx%d %d") -JMESSAGE(JTRC_JFIF_BADTHUMBNAILSIZE, - "Warning: thumbnail image size does not match data length %u") -JMESSAGE(JTRC_JFIF_MINOR, "Unknown JFIF minor revision number %d.%02d") -JMESSAGE(JTRC_JFIF_THUMBNAIL, " with %d x %d thumbnail image") -JMESSAGE(JTRC_MISC_MARKER, "Skipping marker 0x%02x, length %u") -JMESSAGE(JTRC_PARMLESS_MARKER, "Unexpected marker 0x%02x") -JMESSAGE(JTRC_QUANTVALS, " %4u %4u %4u %4u %4u %4u %4u %4u") -JMESSAGE(JTRC_QUANT_3_NCOLORS, "Quantizing to %d = %d*%d*%d colors") -JMESSAGE(JTRC_QUANT_NCOLORS, "Quantizing to %d colors") -JMESSAGE(JTRC_QUANT_SELECTED, "Selected %d colors for quantization") -JMESSAGE(JTRC_RECOVERY_ACTION, "At marker 0x%02x, recovery action %d") -JMESSAGE(JTRC_RST, "RST%d") -JMESSAGE(JTRC_SMOOTH_NOTIMPL, - "Smoothing not supported with nonstandard sampling ratios") -JMESSAGE(JTRC_SOF, "Start Of Frame 0x%02x: width=%u, height=%u, components=%d") -JMESSAGE(JTRC_SOF_COMPONENT, " Component %d: %dhx%dv q=%d") -JMESSAGE(JTRC_SOI, "Start of Image") -JMESSAGE(JTRC_SOS, "Start Of Scan: %d components") -JMESSAGE(JTRC_SOS_COMPONENT, " Component %d: dc=%d ac=%d") -JMESSAGE(JTRC_SOS_PARAMS, " Ss=%d, Se=%d, Ah=%d, Al=%d") -JMESSAGE(JTRC_TFILE_CLOSE, "Closed temporary file %s") -JMESSAGE(JTRC_TFILE_OPEN, "Opened temporary file %s") -JMESSAGE(JTRC_UNKNOWN_IDS, - "Unrecognized component IDs %d %d %d, assuming YCbCr") -JMESSAGE(JTRC_XMS_CLOSE, "Freed XMS handle %u") -JMESSAGE(JTRC_XMS_OPEN, "Obtained XMS handle %u") -JMESSAGE(JWRN_ADOBE_XFORM, "Unknown Adobe color transform code %d") -JMESSAGE(JWRN_BOGUS_PROGRESSION, - "Inconsistent progression sequence for component %d coefficient %d") -JMESSAGE(JWRN_EXTRANEOUS_DATA, - "Corrupt JPEG data: %u extraneous bytes before marker 0x%02x") -JMESSAGE(JWRN_HIT_MARKER, "Corrupt JPEG data: premature end of data segment") -JMESSAGE(JWRN_HUFF_BAD_CODE, "Corrupt JPEG data: bad Huffman code") -JMESSAGE(JWRN_JFIF_MAJOR, "Warning: unknown JFIF revision number %d.%02d") -JMESSAGE(JWRN_JPEG_EOF, "Premature end of JPEG file") -JMESSAGE(JWRN_MUST_RESYNC, - "Corrupt JPEG data: found marker 0x%02x instead of RST%d") -JMESSAGE(JWRN_NOT_SEQUENTIAL, "Invalid SOS parameters for sequential JPEG") -JMESSAGE(JWRN_TOO_MUCH_DATA, "Application transferred too many scanlines") - -#ifdef JMAKE_ENUM_LIST - - JMSG_LASTMSGCODE -} J_MESSAGE_CODE; - -#undef JMAKE_ENUM_LIST -#endif /* JMAKE_ENUM_LIST */ - -/* Zap JMESSAGE macro so that future re-inclusions do nothing by default */ -#undef JMESSAGE - - -#ifndef JERROR_H -#define JERROR_H - -/* Macros to simplify using the error and trace message stuff */ -/* The first parameter is either type of cinfo pointer */ - -/* Fatal errors (print message and exit) */ -#define ERREXIT(cinfo,code) \ - ((cinfo)->err->msg_code = (code), \ - (*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo))) -#define ERREXIT1(cinfo,code,p1) \ - ((cinfo)->err->msg_code = (code), \ - (cinfo)->err->msg_parm.i[0] = (p1), \ - (*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo))) -#define ERREXIT2(cinfo,code,p1,p2) \ - ((cinfo)->err->msg_code = (code), \ - (cinfo)->err->msg_parm.i[0] = (p1), \ - (cinfo)->err->msg_parm.i[1] = (p2), \ - (*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo))) -#define ERREXIT3(cinfo,code,p1,p2,p3) \ - ((cinfo)->err->msg_code = (code), \ - (cinfo)->err->msg_parm.i[0] = (p1), \ - (cinfo)->err->msg_parm.i[1] = (p2), \ - (cinfo)->err->msg_parm.i[2] = (p3), \ - (*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo))) -#define ERREXIT4(cinfo,code,p1,p2,p3,p4) \ - ((cinfo)->err->msg_code = (code), \ - (cinfo)->err->msg_parm.i[0] = (p1), \ - (cinfo)->err->msg_parm.i[1] = (p2), \ - (cinfo)->err->msg_parm.i[2] = (p3), \ - (cinfo)->err->msg_parm.i[3] = (p4), \ - (*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo))) -#define ERREXITS(cinfo,code,str) \ - ((cinfo)->err->msg_code = (code), \ - strncpy((cinfo)->err->msg_parm.s, (str), JMSG_STR_PARM_MAX), \ - (*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo))) - -#define MAKESTMT(stuff) do { stuff } while (0) - -/* Nonfatal errors (we can keep going, but the data is probably corrupt) */ -#define WARNMS(cinfo,code) \ - ((cinfo)->err->msg_code = (code), \ - (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), -1)) -#define WARNMS1(cinfo,code,p1) \ - ((cinfo)->err->msg_code = (code), \ - (cinfo)->err->msg_parm.i[0] = (p1), \ - (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), -1)) -#define WARNMS2(cinfo,code,p1,p2) \ - ((cinfo)->err->msg_code = (code), \ - (cinfo)->err->msg_parm.i[0] = (p1), \ - (cinfo)->err->msg_parm.i[1] = (p2), \ - (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), -1)) - -/* Informational/debugging messages */ -#define TRACEMS(cinfo,lvl,code) \ - ((cinfo)->err->msg_code = (code), \ - (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl))) -#define TRACEMS1(cinfo,lvl,code,p1) \ - ((cinfo)->err->msg_code = (code), \ - (cinfo)->err->msg_parm.i[0] = (p1), \ - (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl))) -#define TRACEMS2(cinfo,lvl,code,p1,p2) \ - ((cinfo)->err->msg_code = (code), \ - (cinfo)->err->msg_parm.i[0] = (p1), \ - (cinfo)->err->msg_parm.i[1] = (p2), \ - (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl))) -#define TRACEMS3(cinfo,lvl,code,p1,p2,p3) \ - MAKESTMT(int * _mp = (cinfo)->err->msg_parm.i; \ - _mp[0] = (p1); _mp[1] = (p2); _mp[2] = (p3); \ - (cinfo)->err->msg_code = (code); \ - (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)); ) -#define TRACEMS4(cinfo,lvl,code,p1,p2,p3,p4) \ - MAKESTMT(int * _mp = (cinfo)->err->msg_parm.i; \ - _mp[0] = (p1); _mp[1] = (p2); _mp[2] = (p3); _mp[3] = (p4); \ - (cinfo)->err->msg_code = (code); \ - (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)); ) -#define TRACEMS8(cinfo,lvl,code,p1,p2,p3,p4,p5,p6,p7,p8) \ - MAKESTMT(int * _mp = (cinfo)->err->msg_parm.i; \ - _mp[0] = (p1); _mp[1] = (p2); _mp[2] = (p3); _mp[3] = (p4); \ - _mp[4] = (p5); _mp[5] = (p6); _mp[6] = (p7); _mp[7] = (p8); \ - (cinfo)->err->msg_code = (code); \ - (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)); ) -#define TRACEMSS(cinfo,lvl,code,str) \ - ((cinfo)->err->msg_code = (code), \ - strncpy((cinfo)->err->msg_parm.s, (str), JMSG_STR_PARM_MAX), \ - (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl))) - -#endif /* JERROR_H */ diff --git a/engine/jpeg-6/jfdctflt.c b/engine/jpeg-6/jfdctflt.c deleted file mode 100644 index 21371eb..0000000 --- a/engine/jpeg-6/jfdctflt.c +++ /dev/null @@ -1,168 +0,0 @@ -/* - * jfdctflt.c - * - * Copyright (C) 1994, Thomas G. Lane. - * This file is part of the Independent JPEG Group's software. - * For conditions of distribution and use, see the accompanying README file. - * - * This file contains a floating-point implementation of the - * forward DCT (Discrete Cosine Transform). - * - * This implementation should be more accurate than either of the integer - * DCT implementations. However, it may not give the same results on all - * machines because of differences in roundoff behavior. Speed will depend - * on the hardware's floating point capacity. - * - * A 2-D DCT can be done by 1-D DCT on each row followed by 1-D DCT - * on each column. Direct algorithms are also available, but they are - * much more complex and seem not to be any faster when reduced to code. - * - * This implementation is based on Arai, Agui, and Nakajima's algorithm for - * scaled DCT. Their original paper (Trans. IEICE E-71(11):1095) is in - * Japanese, but the algorithm is described in the Pennebaker & Mitchell - * JPEG textbook (see REFERENCES section in file README). The following code - * is based directly on figure 4-8 in P&M. - * While an 8-point DCT cannot be done in less than 11 multiplies, it is - * possible to arrange the computation so that many of the multiplies are - * simple scalings of the final outputs. These multiplies can then be - * folded into the multiplications or divisions by the JPEG quantization - * table entries. The AA&N method leaves only 5 multiplies and 29 adds - * to be done in the DCT itself. - * The primary disadvantage of this method is that with a fixed-point - * implementation, accuracy is lost due to imprecise representation of the - * scaled quantization values. However, that problem does not arise if - * we use floating point arithmetic. - */ - -#define JPEG_INTERNALS -#include "jinclude.h" -#include "jpeglib.h" -#include "jdct.h" /* Private declarations for DCT subsystem */ - -#ifdef DCT_FLOAT_SUPPORTED - - -/* - * This module is specialized to the case DCTSIZE = 8. - */ - -#if DCTSIZE != 8 - Sorry, this code only copes with 8x8 DCTs. /* deliberate syntax err */ -#endif - - -/* - * Perform the forward DCT on one block of samples. - */ - -GLOBAL void -jpeg_fdct_float (FAST_FLOAT * data) -{ - FAST_FLOAT tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7; - FAST_FLOAT tmp10, tmp11, tmp12, tmp13; - FAST_FLOAT z1, z2, z3, z4, z5, z11, z13; - FAST_FLOAT *dataptr; - int ctr; - - /* Pass 1: process rows. */ - - dataptr = data; - for (ctr = DCTSIZE-1; ctr >= 0; ctr--) { - tmp0 = dataptr[0] + dataptr[7]; - tmp7 = dataptr[0] - dataptr[7]; - tmp1 = dataptr[1] + dataptr[6]; - tmp6 = dataptr[1] - dataptr[6]; - tmp2 = dataptr[2] + dataptr[5]; - tmp5 = dataptr[2] - dataptr[5]; - tmp3 = dataptr[3] + dataptr[4]; - tmp4 = dataptr[3] - dataptr[4]; - - /* Even part */ - - tmp10 = tmp0 + tmp3; /* phase 2 */ - tmp13 = tmp0 - tmp3; - tmp11 = tmp1 + tmp2; - tmp12 = tmp1 - tmp2; - - dataptr[0] = tmp10 + tmp11; /* phase 3 */ - dataptr[4] = tmp10 - tmp11; - - z1 = (tmp12 + tmp13) * ((FAST_FLOAT) 0.707106781); /* c4 */ - dataptr[2] = tmp13 + z1; /* phase 5 */ - dataptr[6] = tmp13 - z1; - - /* Odd part */ - - tmp10 = tmp4 + tmp5; /* phase 2 */ - tmp11 = tmp5 + tmp6; - tmp12 = tmp6 + tmp7; - - /* The rotator is modified from fig 4-8 to avoid extra negations. */ - z5 = (tmp10 - tmp12) * ((FAST_FLOAT) 0.382683433); /* c6 */ - z2 = ((FAST_FLOAT) 0.541196100) * tmp10 + z5; /* c2-c6 */ - z4 = ((FAST_FLOAT) 1.306562965) * tmp12 + z5; /* c2+c6 */ - z3 = tmp11 * ((FAST_FLOAT) 0.707106781); /* c4 */ - - z11 = tmp7 + z3; /* phase 5 */ - z13 = tmp7 - z3; - - dataptr[5] = z13 + z2; /* phase 6 */ - dataptr[3] = z13 - z2; - dataptr[1] = z11 + z4; - dataptr[7] = z11 - z4; - - dataptr += DCTSIZE; /* advance pointer to next row */ - } - - /* Pass 2: process columns. */ - - dataptr = data; - for (ctr = DCTSIZE-1; ctr >= 0; ctr--) { - tmp0 = dataptr[DCTSIZE*0] + dataptr[DCTSIZE*7]; - tmp7 = dataptr[DCTSIZE*0] - dataptr[DCTSIZE*7]; - tmp1 = dataptr[DCTSIZE*1] + dataptr[DCTSIZE*6]; - tmp6 = dataptr[DCTSIZE*1] - dataptr[DCTSIZE*6]; - tmp2 = dataptr[DCTSIZE*2] + dataptr[DCTSIZE*5]; - tmp5 = dataptr[DCTSIZE*2] - dataptr[DCTSIZE*5]; - tmp3 = dataptr[DCTSIZE*3] + dataptr[DCTSIZE*4]; - tmp4 = dataptr[DCTSIZE*3] - dataptr[DCTSIZE*4]; - - /* Even part */ - - tmp10 = tmp0 + tmp3; /* phase 2 */ - tmp13 = tmp0 - tmp3; - tmp11 = tmp1 + tmp2; - tmp12 = tmp1 - tmp2; - - dataptr[DCTSIZE*0] = tmp10 + tmp11; /* phase 3 */ - dataptr[DCTSIZE*4] = tmp10 - tmp11; - - z1 = (tmp12 + tmp13) * ((FAST_FLOAT) 0.707106781); /* c4 */ - dataptr[DCTSIZE*2] = tmp13 + z1; /* phase 5 */ - dataptr[DCTSIZE*6] = tmp13 - z1; - - /* Odd part */ - - tmp10 = tmp4 + tmp5; /* phase 2 */ - tmp11 = tmp5 + tmp6; - tmp12 = tmp6 + tmp7; - - /* The rotator is modified from fig 4-8 to avoid extra negations. */ - z5 = (tmp10 - tmp12) * ((FAST_FLOAT) 0.382683433); /* c6 */ - z2 = ((FAST_FLOAT) 0.541196100) * tmp10 + z5; /* c2-c6 */ - z4 = ((FAST_FLOAT) 1.306562965) * tmp12 + z5; /* c2+c6 */ - z3 = tmp11 * ((FAST_FLOAT) 0.707106781); /* c4 */ - - z11 = tmp7 + z3; /* phase 5 */ - z13 = tmp7 - z3; - - dataptr[DCTSIZE*5] = z13 + z2; /* phase 6 */ - dataptr[DCTSIZE*3] = z13 - z2; - dataptr[DCTSIZE*1] = z11 + z4; - dataptr[DCTSIZE*7] = z11 - z4; - - dataptr++; /* advance pointer to next column */ - } -} - -#endif /* DCT_FLOAT_SUPPORTED */ diff --git a/engine/jpeg-6/jfdctfst.c b/engine/jpeg-6/jfdctfst.c deleted file mode 100644 index a52d7b7..0000000 --- a/engine/jpeg-6/jfdctfst.c +++ /dev/null @@ -1,224 +0,0 @@ -/* - * jfdctfst.c - * - * Copyright (C) 1994, Thomas G. Lane. - * This file is part of the Independent JPEG Group's software. - * For conditions of distribution and use, see the accompanying README file. - * - * This file contains a fast, not so accurate integer implementation of the - * forward DCT (Discrete Cosine Transform). - * - * A 2-D DCT can be done by 1-D DCT on each row followed by 1-D DCT - * on each column. Direct algorithms are also available, but they are - * much more complex and seem not to be any faster when reduced to code. - * - * This implementation is based on Arai, Agui, and Nakajima's algorithm for - * scaled DCT. Their original paper (Trans. IEICE E-71(11):1095) is in - * Japanese, but the algorithm is described in the Pennebaker & Mitchell - * JPEG textbook (see REFERENCES section in file README). The following code - * is based directly on figure 4-8 in P&M. - * While an 8-point DCT cannot be done in less than 11 multiplies, it is - * possible to arrange the computation so that many of the multiplies are - * simple scalings of the final outputs. These multiplies can then be - * folded into the multiplications or divisions by the JPEG quantization - * table entries. The AA&N method leaves only 5 multiplies and 29 adds - * to be done in the DCT itself. - * The primary disadvantage of this method is that with fixed-point math, - * accuracy is lost due to imprecise representation of the scaled - * quantization values. The smaller the quantization table entry, the less - * precise the scaled value, so this implementation does worse with high- - * quality-setting files than with low-quality ones. - */ - -#define JPEG_INTERNALS -#include "jinclude.h" -#include "jpeglib.h" -#include "jdct.h" /* Private declarations for DCT subsystem */ - -#ifdef DCT_IFAST_SUPPORTED - - -/* - * This module is specialized to the case DCTSIZE = 8. - */ - -#if DCTSIZE != 8 - Sorry, this code only copes with 8x8 DCTs. /* deliberate syntax err */ -#endif - - -/* Scaling decisions are generally the same as in the LL&M algorithm; - * see jfdctint.c for more details. However, we choose to descale - * (right shift) multiplication products as soon as they are formed, - * rather than carrying additional fractional bits into subsequent additions. - * This compromises accuracy slightly, but it lets us save a few shifts. - * More importantly, 16-bit arithmetic is then adequate (for 8-bit samples) - * everywhere except in the multiplications proper; this saves a good deal - * of work on 16-bit-int machines. - * - * Again to save a few shifts, the intermediate results between pass 1 and - * pass 2 are not upscaled, but are represented only to integral precision. - * - * A final compromise is to represent the multiplicative constants to only - * 8 fractional bits, rather than 13. This saves some shifting work on some - * machines, and may also reduce the cost of multiplication (since there - * are fewer one-bits in the constants). - */ - -#define CONST_BITS 8 - - -/* Some C compilers fail to reduce "FIX(constant)" at compile time, thus - * causing a lot of useless floating-point operations at run time. - * To get around this we use the following pre-calculated constants. - * If you change CONST_BITS you may want to add appropriate values. - * (With a reasonable C compiler, you can just rely on the FIX() macro...) - */ - -#if CONST_BITS == 8 -#define FIX_0_382683433 ((INT32) 98) /* FIX(0.382683433) */ -#define FIX_0_541196100 ((INT32) 139) /* FIX(0.541196100) */ -#define FIX_0_707106781 ((INT32) 181) /* FIX(0.707106781) */ -#define FIX_1_306562965 ((INT32) 334) /* FIX(1.306562965) */ -#else -#define FIX_0_382683433 FIX(0.382683433) -#define FIX_0_541196100 FIX(0.541196100) -#define FIX_0_707106781 FIX(0.707106781) -#define FIX_1_306562965 FIX(1.306562965) -#endif - - -/* We can gain a little more speed, with a further compromise in accuracy, - * by omitting the addition in a descaling shift. This yields an incorrectly - * rounded result half the time... - */ - -#ifndef USE_ACCURATE_ROUNDING -#undef DESCALE -#define DESCALE(x,n) RIGHT_SHIFT(x, n) -#endif - - -/* Multiply a DCTELEM variable by an INT32 constant, and immediately - * descale to yield a DCTELEM result. - */ - -#define MULTIPLY(var,const) ((DCTELEM) DESCALE((var) * (const), CONST_BITS)) - - -/* - * Perform the forward DCT on one block of samples. - */ - -GLOBAL void -jpeg_fdct_ifast (DCTELEM * data) -{ - DCTELEM tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7; - DCTELEM tmp10, tmp11, tmp12, tmp13; - DCTELEM z1, z2, z3, z4, z5, z11, z13; - DCTELEM *dataptr; - int ctr; - SHIFT_TEMPS - - /* Pass 1: process rows. */ - - dataptr = data; - for (ctr = DCTSIZE-1; ctr >= 0; ctr--) { - tmp0 = dataptr[0] + dataptr[7]; - tmp7 = dataptr[0] - dataptr[7]; - tmp1 = dataptr[1] + dataptr[6]; - tmp6 = dataptr[1] - dataptr[6]; - tmp2 = dataptr[2] + dataptr[5]; - tmp5 = dataptr[2] - dataptr[5]; - tmp3 = dataptr[3] + dataptr[4]; - tmp4 = dataptr[3] - dataptr[4]; - - /* Even part */ - - tmp10 = tmp0 + tmp3; /* phase 2 */ - tmp13 = tmp0 - tmp3; - tmp11 = tmp1 + tmp2; - tmp12 = tmp1 - tmp2; - - dataptr[0] = tmp10 + tmp11; /* phase 3 */ - dataptr[4] = tmp10 - tmp11; - - z1 = MULTIPLY(tmp12 + tmp13, FIX_0_707106781); /* c4 */ - dataptr[2] = tmp13 + z1; /* phase 5 */ - dataptr[6] = tmp13 - z1; - - /* Odd part */ - - tmp10 = tmp4 + tmp5; /* phase 2 */ - tmp11 = tmp5 + tmp6; - tmp12 = tmp6 + tmp7; - - /* The rotator is modified from fig 4-8 to avoid extra negations. */ - z5 = MULTIPLY(tmp10 - tmp12, FIX_0_382683433); /* c6 */ - z2 = MULTIPLY(tmp10, FIX_0_541196100) + z5; /* c2-c6 */ - z4 = MULTIPLY(tmp12, FIX_1_306562965) + z5; /* c2+c6 */ - z3 = MULTIPLY(tmp11, FIX_0_707106781); /* c4 */ - - z11 = tmp7 + z3; /* phase 5 */ - z13 = tmp7 - z3; - - dataptr[5] = z13 + z2; /* phase 6 */ - dataptr[3] = z13 - z2; - dataptr[1] = z11 + z4; - dataptr[7] = z11 - z4; - - dataptr += DCTSIZE; /* advance pointer to next row */ - } - - /* Pass 2: process columns. */ - - dataptr = data; - for (ctr = DCTSIZE-1; ctr >= 0; ctr--) { - tmp0 = dataptr[DCTSIZE*0] + dataptr[DCTSIZE*7]; - tmp7 = dataptr[DCTSIZE*0] - dataptr[DCTSIZE*7]; - tmp1 = dataptr[DCTSIZE*1] + dataptr[DCTSIZE*6]; - tmp6 = dataptr[DCTSIZE*1] - dataptr[DCTSIZE*6]; - tmp2 = dataptr[DCTSIZE*2] + dataptr[DCTSIZE*5]; - tmp5 = dataptr[DCTSIZE*2] - dataptr[DCTSIZE*5]; - tmp3 = dataptr[DCTSIZE*3] + dataptr[DCTSIZE*4]; - tmp4 = dataptr[DCTSIZE*3] - dataptr[DCTSIZE*4]; - - /* Even part */ - - tmp10 = tmp0 + tmp3; /* phase 2 */ - tmp13 = tmp0 - tmp3; - tmp11 = tmp1 + tmp2; - tmp12 = tmp1 - tmp2; - - dataptr[DCTSIZE*0] = tmp10 + tmp11; /* phase 3 */ - dataptr[DCTSIZE*4] = tmp10 - tmp11; - - z1 = MULTIPLY(tmp12 + tmp13, FIX_0_707106781); /* c4 */ - dataptr[DCTSIZE*2] = tmp13 + z1; /* phase 5 */ - dataptr[DCTSIZE*6] = tmp13 - z1; - - /* Odd part */ - - tmp10 = tmp4 + tmp5; /* phase 2 */ - tmp11 = tmp5 + tmp6; - tmp12 = tmp6 + tmp7; - - /* The rotator is modified from fig 4-8 to avoid extra negations. */ - z5 = MULTIPLY(tmp10 - tmp12, FIX_0_382683433); /* c6 */ - z2 = MULTIPLY(tmp10, FIX_0_541196100) + z5; /* c2-c6 */ - z4 = MULTIPLY(tmp12, FIX_1_306562965) + z5; /* c2+c6 */ - z3 = MULTIPLY(tmp11, FIX_0_707106781); /* c4 */ - - z11 = tmp7 + z3; /* phase 5 */ - z13 = tmp7 - z3; - - dataptr[DCTSIZE*5] = z13 + z2; /* phase 6 */ - dataptr[DCTSIZE*3] = z13 - z2; - dataptr[DCTSIZE*1] = z11 + z4; - dataptr[DCTSIZE*7] = z11 - z4; - - dataptr++; /* advance pointer to next column */ - } -} - -#endif /* DCT_IFAST_SUPPORTED */ diff --git a/engine/jpeg-6/jfdctint.c b/engine/jpeg-6/jfdctint.c deleted file mode 100644 index 7df0433..0000000 --- a/engine/jpeg-6/jfdctint.c +++ /dev/null @@ -1,283 +0,0 @@ -/* - * jfdctint.c - * - * Copyright (C) 1991-1994, Thomas G. Lane. - * This file is part of the Independent JPEG Group's software. - * For conditions of distribution and use, see the accompanying README file. - * - * This file contains a slow-but-accurate integer implementation of the - * forward DCT (Discrete Cosine Transform). - * - * A 2-D DCT can be done by 1-D DCT on each row followed by 1-D DCT - * on each column. Direct algorithms are also available, but they are - * much more complex and seem not to be any faster when reduced to code. - * - * This implementation is based on an algorithm described in - * C. Loeffler, A. Ligtenberg and G. Moschytz, "Practical Fast 1-D DCT - * Algorithms with 11 Multiplications", Proc. Int'l. Conf. on Acoustics, - * Speech, and Signal Processing 1989 (ICASSP '89), pp. 988-991. - * The primary algorithm described there uses 11 multiplies and 29 adds. - * We use their alternate method with 12 multiplies and 32 adds. - * The advantage of this method is that no data path contains more than one - * multiplication; this allows a very simple and accurate implementation in - * scaled fixed-point arithmetic, with a minimal number of shifts. - */ - -#define JPEG_INTERNALS -#include "jinclude.h" -#include "jpeglib.h" -#include "jdct.h" /* Private declarations for DCT subsystem */ - -#ifdef DCT_ISLOW_SUPPORTED - - -/* - * This module is specialized to the case DCTSIZE = 8. - */ - -#if DCTSIZE != 8 - Sorry, this code only copes with 8x8 DCTs. /* deliberate syntax err */ -#endif - - -/* - * The poop on this scaling stuff is as follows: - * - * Each 1-D DCT step produces outputs which are a factor of sqrt(N) - * larger than the true DCT outputs. The final outputs are therefore - * a factor of N larger than desired; since N=8 this can be cured by - * a simple right shift at the end of the algorithm. The advantage of - * this arrangement is that we save two multiplications per 1-D DCT, - * because the y0 and y4 outputs need not be divided by sqrt(N). - * In the IJG code, this factor of 8 is removed by the quantization step - * (in jcdctmgr.c), NOT in this module. - * - * We have to do addition and subtraction of the integer inputs, which - * is no problem, and multiplication by fractional constants, which is - * a problem to do in integer arithmetic. We multiply all the constants - * by CONST_SCALE and convert them to integer constants (thus retaining - * CONST_BITS bits of precision in the constants). After doing a - * multiplication we have to divide the product by CONST_SCALE, with proper - * rounding, to produce the correct output. This division can be done - * cheaply as a right shift of CONST_BITS bits. We postpone shifting - * as long as possible so that partial sums can be added together with - * full fractional precision. - * - * The outputs of the first pass are scaled up by PASS1_BITS bits so that - * they are represented to better-than-integral precision. These outputs - * require BITS_IN_JSAMPLE + PASS1_BITS + 3 bits; this fits in a 16-bit word - * with the recommended scaling. (For 12-bit sample data, the intermediate - * array is INT32 anyway.) - * - * To avoid overflow of the 32-bit intermediate results in pass 2, we must - * have BITS_IN_JSAMPLE + CONST_BITS + PASS1_BITS <= 26. Error analysis - * shows that the values given below are the most effective. - */ - -#if BITS_IN_JSAMPLE == 8 -#define CONST_BITS 13 -#define PASS1_BITS 2 -#else -#define CONST_BITS 13 -#define PASS1_BITS 1 /* lose a little precision to avoid overflow */ -#endif - -/* Some C compilers fail to reduce "FIX(constant)" at compile time, thus - * causing a lot of useless floating-point operations at run time. - * To get around this we use the following pre-calculated constants. - * If you change CONST_BITS you may want to add appropriate values. - * (With a reasonable C compiler, you can just rely on the FIX() macro...) - */ - -#if CONST_BITS == 13 -#define FIX_0_298631336 ((INT32) 2446) /* FIX(0.298631336) */ -#define FIX_0_390180644 ((INT32) 3196) /* FIX(0.390180644) */ -#define FIX_0_541196100 ((INT32) 4433) /* FIX(0.541196100) */ -#define FIX_0_765366865 ((INT32) 6270) /* FIX(0.765366865) */ -#define FIX_0_899976223 ((INT32) 7373) /* FIX(0.899976223) */ -#define FIX_1_175875602 ((INT32) 9633) /* FIX(1.175875602) */ -#define FIX_1_501321110 ((INT32) 12299) /* FIX(1.501321110) */ -#define FIX_1_847759065 ((INT32) 15137) /* FIX(1.847759065) */ -#define FIX_1_961570560 ((INT32) 16069) /* FIX(1.961570560) */ -#define FIX_2_053119869 ((INT32) 16819) /* FIX(2.053119869) */ -#define FIX_2_562915447 ((INT32) 20995) /* FIX(2.562915447) */ -#define FIX_3_072711026 ((INT32) 25172) /* FIX(3.072711026) */ -#else -#define FIX_0_298631336 FIX(0.298631336) -#define FIX_0_390180644 FIX(0.390180644) -#define FIX_0_541196100 FIX(0.541196100) -#define FIX_0_765366865 FIX(0.765366865) -#define FIX_0_899976223 FIX(0.899976223) -#define FIX_1_175875602 FIX(1.175875602) -#define FIX_1_501321110 FIX(1.501321110) -#define FIX_1_847759065 FIX(1.847759065) -#define FIX_1_961570560 FIX(1.961570560) -#define FIX_2_053119869 FIX(2.053119869) -#define FIX_2_562915447 FIX(2.562915447) -#define FIX_3_072711026 FIX(3.072711026) -#endif - - -/* Multiply an INT32 variable by an INT32 constant to yield an INT32 result. - * For 8-bit samples with the recommended scaling, all the variable - * and constant values involved are no more than 16 bits wide, so a - * 16x16->32 bit multiply can be used instead of a full 32x32 multiply. - * For 12-bit samples, a full 32-bit multiplication will be needed. - */ - -#if BITS_IN_JSAMPLE == 8 -#define MULTIPLY(var,const) MULTIPLY16C16(var,const) -#else -#define MULTIPLY(var,const) ((var) * (const)) -#endif - - -/* - * Perform the forward DCT on one block of samples. - */ - -GLOBAL void -jpeg_fdct_islow (DCTELEM * data) -{ - INT32 tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7; - INT32 tmp10, tmp11, tmp12, tmp13; - INT32 z1, z2, z3, z4, z5; - DCTELEM *dataptr; - int ctr; - SHIFT_TEMPS - - /* Pass 1: process rows. */ - /* Note results are scaled up by sqrt(8) compared to a true DCT; */ - /* furthermore, we scale the results by 2**PASS1_BITS. */ - - dataptr = data; - for (ctr = DCTSIZE-1; ctr >= 0; ctr--) { - tmp0 = dataptr[0] + dataptr[7]; - tmp7 = dataptr[0] - dataptr[7]; - tmp1 = dataptr[1] + dataptr[6]; - tmp6 = dataptr[1] - dataptr[6]; - tmp2 = dataptr[2] + dataptr[5]; - tmp5 = dataptr[2] - dataptr[5]; - tmp3 = dataptr[3] + dataptr[4]; - tmp4 = dataptr[3] - dataptr[4]; - - /* Even part per LL&M figure 1 --- note that published figure is faulty; - * rotator "sqrt(2)*c1" should be "sqrt(2)*c6". - */ - - tmp10 = tmp0 + tmp3; - tmp13 = tmp0 - tmp3; - tmp11 = tmp1 + tmp2; - tmp12 = tmp1 - tmp2; - - dataptr[0] = (DCTELEM) ((tmp10 + tmp11) << PASS1_BITS); - dataptr[4] = (DCTELEM) ((tmp10 - tmp11) << PASS1_BITS); - - z1 = MULTIPLY(tmp12 + tmp13, FIX_0_541196100); - dataptr[2] = (DCTELEM) DESCALE(z1 + MULTIPLY(tmp13, FIX_0_765366865), - CONST_BITS-PASS1_BITS); - dataptr[6] = (DCTELEM) DESCALE(z1 + MULTIPLY(tmp12, - FIX_1_847759065), - CONST_BITS-PASS1_BITS); - - /* Odd part per figure 8 --- note paper omits factor of sqrt(2). - * cK represents cos(K*pi/16). - * i0..i3 in the paper are tmp4..tmp7 here. - */ - - z1 = tmp4 + tmp7; - z2 = tmp5 + tmp6; - z3 = tmp4 + tmp6; - z4 = tmp5 + tmp7; - z5 = MULTIPLY(z3 + z4, FIX_1_175875602); /* sqrt(2) * c3 */ - - tmp4 = MULTIPLY(tmp4, FIX_0_298631336); /* sqrt(2) * (-c1+c3+c5-c7) */ - tmp5 = MULTIPLY(tmp5, FIX_2_053119869); /* sqrt(2) * ( c1+c3-c5+c7) */ - tmp6 = MULTIPLY(tmp6, FIX_3_072711026); /* sqrt(2) * ( c1+c3+c5-c7) */ - tmp7 = MULTIPLY(tmp7, FIX_1_501321110); /* sqrt(2) * ( c1+c3-c5-c7) */ - z1 = MULTIPLY(z1, - FIX_0_899976223); /* sqrt(2) * (c7-c3) */ - z2 = MULTIPLY(z2, - FIX_2_562915447); /* sqrt(2) * (-c1-c3) */ - z3 = MULTIPLY(z3, - FIX_1_961570560); /* sqrt(2) * (-c3-c5) */ - z4 = MULTIPLY(z4, - FIX_0_390180644); /* sqrt(2) * (c5-c3) */ - - z3 += z5; - z4 += z5; - - dataptr[7] = (DCTELEM) DESCALE(tmp4 + z1 + z3, CONST_BITS-PASS1_BITS); - dataptr[5] = (DCTELEM) DESCALE(tmp5 + z2 + z4, CONST_BITS-PASS1_BITS); - dataptr[3] = (DCTELEM) DESCALE(tmp6 + z2 + z3, CONST_BITS-PASS1_BITS); - dataptr[1] = (DCTELEM) DESCALE(tmp7 + z1 + z4, CONST_BITS-PASS1_BITS); - - dataptr += DCTSIZE; /* advance pointer to next row */ - } - - /* Pass 2: process columns. - * We remove the PASS1_BITS scaling, but leave the results scaled up - * by an overall factor of 8. - */ - - dataptr = data; - for (ctr = DCTSIZE-1; ctr >= 0; ctr--) { - tmp0 = dataptr[DCTSIZE*0] + dataptr[DCTSIZE*7]; - tmp7 = dataptr[DCTSIZE*0] - dataptr[DCTSIZE*7]; - tmp1 = dataptr[DCTSIZE*1] + dataptr[DCTSIZE*6]; - tmp6 = dataptr[DCTSIZE*1] - dataptr[DCTSIZE*6]; - tmp2 = dataptr[DCTSIZE*2] + dataptr[DCTSIZE*5]; - tmp5 = dataptr[DCTSIZE*2] - dataptr[DCTSIZE*5]; - tmp3 = dataptr[DCTSIZE*3] + dataptr[DCTSIZE*4]; - tmp4 = dataptr[DCTSIZE*3] - dataptr[DCTSIZE*4]; - - /* Even part per LL&M figure 1 --- note that published figure is faulty; - * rotator "sqrt(2)*c1" should be "sqrt(2)*c6". - */ - - tmp10 = tmp0 + tmp3; - tmp13 = tmp0 - tmp3; - tmp11 = tmp1 + tmp2; - tmp12 = tmp1 - tmp2; - - dataptr[DCTSIZE*0] = (DCTELEM) DESCALE(tmp10 + tmp11, PASS1_BITS); - dataptr[DCTSIZE*4] = (DCTELEM) DESCALE(tmp10 - tmp11, PASS1_BITS); - - z1 = MULTIPLY(tmp12 + tmp13, FIX_0_541196100); - dataptr[DCTSIZE*2] = (DCTELEM) DESCALE(z1 + MULTIPLY(tmp13, FIX_0_765366865), - CONST_BITS+PASS1_BITS); - dataptr[DCTSIZE*6] = (DCTELEM) DESCALE(z1 + MULTIPLY(tmp12, - FIX_1_847759065), - CONST_BITS+PASS1_BITS); - - /* Odd part per figure 8 --- note paper omits factor of sqrt(2). - * cK represents cos(K*pi/16). - * i0..i3 in the paper are tmp4..tmp7 here. - */ - - z1 = tmp4 + tmp7; - z2 = tmp5 + tmp6; - z3 = tmp4 + tmp6; - z4 = tmp5 + tmp7; - z5 = MULTIPLY(z3 + z4, FIX_1_175875602); /* sqrt(2) * c3 */ - - tmp4 = MULTIPLY(tmp4, FIX_0_298631336); /* sqrt(2) * (-c1+c3+c5-c7) */ - tmp5 = MULTIPLY(tmp5, FIX_2_053119869); /* sqrt(2) * ( c1+c3-c5+c7) */ - tmp6 = MULTIPLY(tmp6, FIX_3_072711026); /* sqrt(2) * ( c1+c3+c5-c7) */ - tmp7 = MULTIPLY(tmp7, FIX_1_501321110); /* sqrt(2) * ( c1+c3-c5-c7) */ - z1 = MULTIPLY(z1, - FIX_0_899976223); /* sqrt(2) * (c7-c3) */ - z2 = MULTIPLY(z2, - FIX_2_562915447); /* sqrt(2) * (-c1-c3) */ - z3 = MULTIPLY(z3, - FIX_1_961570560); /* sqrt(2) * (-c3-c5) */ - z4 = MULTIPLY(z4, - FIX_0_390180644); /* sqrt(2) * (c5-c3) */ - - z3 += z5; - z4 += z5; - - dataptr[DCTSIZE*7] = (DCTELEM) DESCALE(tmp4 + z1 + z3, - CONST_BITS+PASS1_BITS); - dataptr[DCTSIZE*5] = (DCTELEM) DESCALE(tmp5 + z2 + z4, - CONST_BITS+PASS1_BITS); - dataptr[DCTSIZE*3] = (DCTELEM) DESCALE(tmp6 + z2 + z3, - CONST_BITS+PASS1_BITS); - dataptr[DCTSIZE*1] = (DCTELEM) DESCALE(tmp7 + z1 + z4, - CONST_BITS+PASS1_BITS); - - dataptr++; /* advance pointer to next column */ - } -} - -#endif /* DCT_ISLOW_SUPPORTED */ diff --git a/engine/jpeg-6/jidctflt.c b/engine/jpeg-6/jidctflt.c deleted file mode 100644 index 847919e..0000000 --- a/engine/jpeg-6/jidctflt.c +++ /dev/null @@ -1,241 +0,0 @@ -/* - * jidctflt.c - * - * Copyright (C) 1994, Thomas G. Lane. - * This file is part of the Independent JPEG Group's software. - * For conditions of distribution and use, see the accompanying README file. - * - * This file contains a floating-point implementation of the - * inverse DCT (Discrete Cosine Transform). In the IJG code, this routine - * must also perform dequantization of the input coefficients. - * - * This implementation should be more accurate than either of the integer - * IDCT implementations. However, it may not give the same results on all - * machines because of differences in roundoff behavior. Speed will depend - * on the hardware's floating point capacity. - * - * A 2-D IDCT can be done by 1-D IDCT on each column followed by 1-D IDCT - * on each row (or vice versa, but it's more convenient to emit a row at - * a time). Direct algorithms are also available, but they are much more - * complex and seem not to be any faster when reduced to code. - * - * This implementation is based on Arai, Agui, and Nakajima's algorithm for - * scaled DCT. Their original paper (Trans. IEICE E-71(11):1095) is in - * Japanese, but the algorithm is described in the Pennebaker & Mitchell - * JPEG textbook (see REFERENCES section in file README). The following code - * is based directly on figure 4-8 in P&M. - * While an 8-point DCT cannot be done in less than 11 multiplies, it is - * possible to arrange the computation so that many of the multiplies are - * simple scalings of the final outputs. These multiplies can then be - * folded into the multiplications or divisions by the JPEG quantization - * table entries. The AA&N method leaves only 5 multiplies and 29 adds - * to be done in the DCT itself. - * The primary disadvantage of this method is that with a fixed-point - * implementation, accuracy is lost due to imprecise representation of the - * scaled quantization values. However, that problem does not arise if - * we use floating point arithmetic. - */ - -#define JPEG_INTERNALS -#include "jinclude.h" -#include "jpeglib.h" -#include "jdct.h" /* Private declarations for DCT subsystem */ - -#ifdef DCT_FLOAT_SUPPORTED - - -/* - * This module is specialized to the case DCTSIZE = 8. - */ - -#if DCTSIZE != 8 - Sorry, this code only copes with 8x8 DCTs. /* deliberate syntax err */ -#endif - - -/* Dequantize a coefficient by multiplying it by the multiplier-table - * entry; produce a float result. - */ - -#define DEQUANTIZE(coef,quantval) (((FAST_FLOAT) (coef)) * (quantval)) - - -/* - * Perform dequantization and inverse DCT on one block of coefficients. - */ - -GLOBAL void -jpeg_idct_float (j_decompress_ptr cinfo, jpeg_component_info * compptr, - JCOEFPTR coef_block, - JSAMPARRAY output_buf, JDIMENSION output_col) -{ - FAST_FLOAT tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7; - FAST_FLOAT tmp10, tmp11, tmp12, tmp13; - FAST_FLOAT z5, z10, z11, z12, z13; - JCOEFPTR inptr; - FLOAT_MULT_TYPE * quantptr; - FAST_FLOAT * wsptr; - JSAMPROW outptr; - JSAMPLE *range_limit = IDCT_range_limit(cinfo); - int ctr; - FAST_FLOAT workspace[DCTSIZE2]; /* buffers data between passes */ - SHIFT_TEMPS - - /* Pass 1: process columns from input, store into work array. */ - - inptr = coef_block; - quantptr = (FLOAT_MULT_TYPE *) compptr->dct_table; - wsptr = workspace; - for (ctr = DCTSIZE; ctr > 0; ctr--) { - /* Due to quantization, we will usually find that many of the input - * coefficients are zero, especially the AC terms. We can exploit this - * by short-circuiting the IDCT calculation for any column in which all - * the AC terms are zero. In that case each output is equal to the - * DC coefficient (with scale factor as needed). - * With typical images and quantization tables, half or more of the - * column DCT calculations can be simplified this way. - */ - - if ((inptr[DCTSIZE*1] | inptr[DCTSIZE*2] | inptr[DCTSIZE*3] | - inptr[DCTSIZE*4] | inptr[DCTSIZE*5] | inptr[DCTSIZE*6] | - inptr[DCTSIZE*7]) == 0) { - /* AC terms all zero */ - FAST_FLOAT dcval = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]); - - wsptr[DCTSIZE*0] = dcval; - wsptr[DCTSIZE*1] = dcval; - wsptr[DCTSIZE*2] = dcval; - wsptr[DCTSIZE*3] = dcval; - wsptr[DCTSIZE*4] = dcval; - wsptr[DCTSIZE*5] = dcval; - wsptr[DCTSIZE*6] = dcval; - wsptr[DCTSIZE*7] = dcval; - - inptr++; /* advance pointers to next column */ - quantptr++; - wsptr++; - continue; - } - - /* Even part */ - - tmp0 = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]); - tmp1 = DEQUANTIZE(inptr[DCTSIZE*2], quantptr[DCTSIZE*2]); - tmp2 = DEQUANTIZE(inptr[DCTSIZE*4], quantptr[DCTSIZE*4]); - tmp3 = DEQUANTIZE(inptr[DCTSIZE*6], quantptr[DCTSIZE*6]); - - tmp10 = tmp0 + tmp2; /* phase 3 */ - tmp11 = tmp0 - tmp2; - - tmp13 = tmp1 + tmp3; /* phases 5-3 */ - tmp12 = (tmp1 - tmp3) * ((FAST_FLOAT) 1.414213562) - tmp13; /* 2*c4 */ - - tmp0 = tmp10 + tmp13; /* phase 2 */ - tmp3 = tmp10 - tmp13; - tmp1 = tmp11 + tmp12; - tmp2 = tmp11 - tmp12; - - /* Odd part */ - - tmp4 = DEQUANTIZE(inptr[DCTSIZE*1], quantptr[DCTSIZE*1]); - tmp5 = DEQUANTIZE(inptr[DCTSIZE*3], quantptr[DCTSIZE*3]); - tmp6 = DEQUANTIZE(inptr[DCTSIZE*5], quantptr[DCTSIZE*5]); - tmp7 = DEQUANTIZE(inptr[DCTSIZE*7], quantptr[DCTSIZE*7]); - - z13 = tmp6 + tmp5; /* phase 6 */ - z10 = tmp6 - tmp5; - z11 = tmp4 + tmp7; - z12 = tmp4 - tmp7; - - tmp7 = z11 + z13; /* phase 5 */ - tmp11 = (z11 - z13) * ((FAST_FLOAT) 1.414213562); /* 2*c4 */ - - z5 = (z10 + z12) * ((FAST_FLOAT) 1.847759065); /* 2*c2 */ - tmp10 = ((FAST_FLOAT) 1.082392200) * z12 - z5; /* 2*(c2-c6) */ - tmp12 = ((FAST_FLOAT) -2.613125930) * z10 + z5; /* -2*(c2+c6) */ - - tmp6 = tmp12 - tmp7; /* phase 2 */ - tmp5 = tmp11 - tmp6; - tmp4 = tmp10 + tmp5; - - wsptr[DCTSIZE*0] = tmp0 + tmp7; - wsptr[DCTSIZE*7] = tmp0 - tmp7; - wsptr[DCTSIZE*1] = tmp1 + tmp6; - wsptr[DCTSIZE*6] = tmp1 - tmp6; - wsptr[DCTSIZE*2] = tmp2 + tmp5; - wsptr[DCTSIZE*5] = tmp2 - tmp5; - wsptr[DCTSIZE*4] = tmp3 + tmp4; - wsptr[DCTSIZE*3] = tmp3 - tmp4; - - inptr++; /* advance pointers to next column */ - quantptr++; - wsptr++; - } - - /* Pass 2: process rows from work array, store into output array. */ - /* Note that we must descale the results by a factor of 8 == 2**3. */ - - wsptr = workspace; - for (ctr = 0; ctr < DCTSIZE; ctr++) { - outptr = output_buf[ctr] + output_col; - /* Rows of zeroes can be exploited in the same way as we did with columns. - * However, the column calculation has created many nonzero AC terms, so - * the simplification applies less often (typically 5% to 10% of the time). - * And testing floats for zero is relatively expensive, so we don't bother. - */ - - /* Even part */ - - tmp10 = wsptr[0] + wsptr[4]; - tmp11 = wsptr[0] - wsptr[4]; - - tmp13 = wsptr[2] + wsptr[6]; - tmp12 = (wsptr[2] - wsptr[6]) * ((FAST_FLOAT) 1.414213562) - tmp13; - - tmp0 = tmp10 + tmp13; - tmp3 = tmp10 - tmp13; - tmp1 = tmp11 + tmp12; - tmp2 = tmp11 - tmp12; - - /* Odd part */ - - z13 = wsptr[5] + wsptr[3]; - z10 = wsptr[5] - wsptr[3]; - z11 = wsptr[1] + wsptr[7]; - z12 = wsptr[1] - wsptr[7]; - - tmp7 = z11 + z13; - tmp11 = (z11 - z13) * ((FAST_FLOAT) 1.414213562); - - z5 = (z10 + z12) * ((FAST_FLOAT) 1.847759065); /* 2*c2 */ - tmp10 = ((FAST_FLOAT) 1.082392200) * z12 - z5; /* 2*(c2-c6) */ - tmp12 = ((FAST_FLOAT) -2.613125930) * z10 + z5; /* -2*(c2+c6) */ - - tmp6 = tmp12 - tmp7; - tmp5 = tmp11 - tmp6; - tmp4 = tmp10 + tmp5; - - /* Final output stage: scale down by a factor of 8 and range-limit */ - - outptr[0] = range_limit[(int) DESCALE((INT32) (tmp0 + tmp7), 3) - & RANGE_MASK]; - outptr[7] = range_limit[(int) DESCALE((INT32) (tmp0 - tmp7), 3) - & RANGE_MASK]; - outptr[1] = range_limit[(int) DESCALE((INT32) (tmp1 + tmp6), 3) - & RANGE_MASK]; - outptr[6] = range_limit[(int) DESCALE((INT32) (tmp1 - tmp6), 3) - & RANGE_MASK]; - outptr[2] = range_limit[(int) DESCALE((INT32) (tmp2 + tmp5), 3) - & RANGE_MASK]; - outptr[5] = range_limit[(int) DESCALE((INT32) (tmp2 - tmp5), 3) - & RANGE_MASK]; - outptr[4] = range_limit[(int) DESCALE((INT32) (tmp3 + tmp4), 3) - & RANGE_MASK]; - outptr[3] = range_limit[(int) DESCALE((INT32) (tmp3 - tmp4), 3) - & RANGE_MASK]; - - wsptr += DCTSIZE; /* advance pointer to next row */ - } -} - -#endif /* DCT_FLOAT_SUPPORTED */ diff --git a/engine/jpeg-6/jidctfst.c b/engine/jpeg-6/jidctfst.c deleted file mode 100644 index 5736817..0000000 --- a/engine/jpeg-6/jidctfst.c +++ /dev/null @@ -1,367 +0,0 @@ -/* - * jidctfst.c - * - * Copyright (C) 1994-1995, Thomas G. Lane. - * This file is part of the Independent JPEG Group's software. - * For conditions of distribution and use, see the accompanying README file. - * - * This file contains a fast, not so accurate integer implementation of the - * inverse DCT (Discrete Cosine Transform). In the IJG code, this routine - * must also perform dequantization of the input coefficients. - * - * A 2-D IDCT can be done by 1-D IDCT on each column followed by 1-D IDCT - * on each row (or vice versa, but it's more convenient to emit a row at - * a time). Direct algorithms are also available, but they are much more - * complex and seem not to be any faster when reduced to code. - * - * This implementation is based on Arai, Agui, and Nakajima's algorithm for - * scaled DCT. Their original paper (Trans. IEICE E-71(11):1095) is in - * Japanese, but the algorithm is described in the Pennebaker & Mitchell - * JPEG textbook (see REFERENCES section in file README). The following code - * is based directly on figure 4-8 in P&M. - * While an 8-point DCT cannot be done in less than 11 multiplies, it is - * possible to arrange the computation so that many of the multiplies are - * simple scalings of the final outputs. These multiplies can then be - * folded into the multiplications or divisions by the JPEG quantization - * table entries. The AA&N method leaves only 5 multiplies and 29 adds - * to be done in the DCT itself. - * The primary disadvantage of this method is that with fixed-point math, - * accuracy is lost due to imprecise representation of the scaled - * quantization values. The smaller the quantization table entry, the less - * precise the scaled value, so this implementation does worse with high- - * quality-setting files than with low-quality ones. - */ - -#define JPEG_INTERNALS -#include "jinclude.h" -#include "jpeglib.h" -#include "jdct.h" /* Private declarations for DCT subsystem */ - -#ifdef DCT_IFAST_SUPPORTED - - -/* - * This module is specialized to the case DCTSIZE = 8. - */ - -#if DCTSIZE != 8 - Sorry, this code only copes with 8x8 DCTs. /* deliberate syntax err */ -#endif - - -/* Scaling decisions are generally the same as in the LL&M algorithm; - * see jidctint.c for more details. However, we choose to descale - * (right shift) multiplication products as soon as they are formed, - * rather than carrying additional fractional bits into subsequent additions. - * This compromises accuracy slightly, but it lets us save a few shifts. - * More importantly, 16-bit arithmetic is then adequate (for 8-bit samples) - * everywhere except in the multiplications proper; this saves a good deal - * of work on 16-bit-int machines. - * - * The dequantized coefficients are not integers because the AA&N scaling - * factors have been incorporated. We represent them scaled up by PASS1_BITS, - * so that the first and second IDCT rounds have the same input scaling. - * For 8-bit JSAMPLEs, we choose IFAST_SCALE_BITS = PASS1_BITS so as to - * avoid a descaling shift; this compromises accuracy rather drastically - * for small quantization table entries, but it saves a lot of shifts. - * For 12-bit JSAMPLEs, there's no hope of using 16x16 multiplies anyway, - * so we use a much larger scaling factor to preserve accuracy. - * - * A final compromise is to represent the multiplicative constants to only - * 8 fractional bits, rather than 13. This saves some shifting work on some - * machines, and may also reduce the cost of multiplication (since there - * are fewer one-bits in the constants). - */ - -#if BITS_IN_JSAMPLE == 8 -#define CONST_BITS 8 -#define PASS1_BITS 2 -#else -#define CONST_BITS 8 -#define PASS1_BITS 1 /* lose a little precision to avoid overflow */ -#endif - -/* Some C compilers fail to reduce "FIX(constant)" at compile time, thus - * causing a lot of useless floating-point operations at run time. - * To get around this we use the following pre-calculated constants. - * If you change CONST_BITS you may want to add appropriate values. - * (With a reasonable C compiler, you can just rely on the FIX() macro...) - */ - -#if CONST_BITS == 8 -#define FIX_1_082392200 ((INT32) 277) /* FIX(1.082392200) */ -#define FIX_1_414213562 ((INT32) 362) /* FIX(1.414213562) */ -#define FIX_1_847759065 ((INT32) 473) /* FIX(1.847759065) */ -#define FIX_2_613125930 ((INT32) 669) /* FIX(2.613125930) */ -#else -#define FIX_1_082392200 FIX(1.082392200) -#define FIX_1_414213562 FIX(1.414213562) -#define FIX_1_847759065 FIX(1.847759065) -#define FIX_2_613125930 FIX(2.613125930) -#endif - - -/* We can gain a little more speed, with a further compromise in accuracy, - * by omitting the addition in a descaling shift. This yields an incorrectly - * rounded result half the time... - */ - -#ifndef USE_ACCURATE_ROUNDING -#undef DESCALE -#define DESCALE(x,n) RIGHT_SHIFT(x, n) -#endif - - -/* Multiply a DCTELEM variable by an INT32 constant, and immediately - * descale to yield a DCTELEM result. - */ - -#define MULTIPLY(var,const) ((DCTELEM) DESCALE((var) * (const), CONST_BITS)) - - -/* Dequantize a coefficient by multiplying it by the multiplier-table - * entry; produce a DCTELEM result. For 8-bit data a 16x16->16 - * multiplication will do. For 12-bit data, the multiplier table is - * declared INT32, so a 32-bit multiply will be used. - */ - -#if BITS_IN_JSAMPLE == 8 -#define DEQUANTIZE(coef,quantval) (((IFAST_MULT_TYPE) (coef)) * (quantval)) -#else -#define DEQUANTIZE(coef,quantval) \ - DESCALE((coef)*(quantval), IFAST_SCALE_BITS-PASS1_BITS) -#endif - - -/* Like DESCALE, but applies to a DCTELEM and produces an int. - * We assume that int right shift is unsigned if INT32 right shift is. - */ - -#ifdef RIGHT_SHIFT_IS_UNSIGNED -#define ISHIFT_TEMPS DCTELEM ishift_temp; -#if BITS_IN_JSAMPLE == 8 -#define DCTELEMBITS 16 /* DCTELEM may be 16 or 32 bits */ -#else -#define DCTELEMBITS 32 /* DCTELEM must be 32 bits */ -#endif -#define IRIGHT_SHIFT(x,shft) \ - ((ishift_temp = (x)) < 0 ? \ - (ishift_temp >> (shft)) | ((~((DCTELEM) 0)) << (DCTELEMBITS-(shft))) : \ - (ishift_temp >> (shft))) -#else -#define ISHIFT_TEMPS -#define IRIGHT_SHIFT(x,shft) ((x) >> (shft)) -#endif - -#ifdef USE_ACCURATE_ROUNDING -#define IDESCALE(x,n) ((int) IRIGHT_SHIFT((x) + (1 << ((n)-1)), n)) -#else -#define IDESCALE(x,n) ((int) IRIGHT_SHIFT(x, n)) -#endif - - -/* - * Perform dequantization and inverse DCT on one block of coefficients. - */ - -GLOBAL void -jpeg_idct_ifast (j_decompress_ptr cinfo, jpeg_component_info * compptr, - JCOEFPTR coef_block, - JSAMPARRAY output_buf, JDIMENSION output_col) -{ - DCTELEM tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7; - DCTELEM tmp10, tmp11, tmp12, tmp13; - DCTELEM z5, z10, z11, z12, z13; - JCOEFPTR inptr; - IFAST_MULT_TYPE * quantptr; - int * wsptr; - JSAMPROW outptr; - JSAMPLE *range_limit = IDCT_range_limit(cinfo); - int ctr; - int workspace[DCTSIZE2]; /* buffers data between passes */ - SHIFT_TEMPS /* for DESCALE */ - ISHIFT_TEMPS /* for IDESCALE */ - - /* Pass 1: process columns from input, store into work array. */ - - inptr = coef_block; - quantptr = (IFAST_MULT_TYPE *) compptr->dct_table; - wsptr = workspace; - for (ctr = DCTSIZE; ctr > 0; ctr--) { - /* Due to quantization, we will usually find that many of the input - * coefficients are zero, especially the AC terms. We can exploit this - * by short-circuiting the IDCT calculation for any column in which all - * the AC terms are zero. In that case each output is equal to the - * DC coefficient (with scale factor as needed). - * With typical images and quantization tables, half or more of the - * column DCT calculations can be simplified this way. - */ - - if ((inptr[DCTSIZE*1] | inptr[DCTSIZE*2] | inptr[DCTSIZE*3] | - inptr[DCTSIZE*4] | inptr[DCTSIZE*5] | inptr[DCTSIZE*6] | - inptr[DCTSIZE*7]) == 0) { - /* AC terms all zero */ - int dcval = (int) DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]); - - wsptr[DCTSIZE*0] = dcval; - wsptr[DCTSIZE*1] = dcval; - wsptr[DCTSIZE*2] = dcval; - wsptr[DCTSIZE*3] = dcval; - wsptr[DCTSIZE*4] = dcval; - wsptr[DCTSIZE*5] = dcval; - wsptr[DCTSIZE*6] = dcval; - wsptr[DCTSIZE*7] = dcval; - - inptr++; /* advance pointers to next column */ - quantptr++; - wsptr++; - continue; - } - - /* Even part */ - - tmp0 = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]); - tmp1 = DEQUANTIZE(inptr[DCTSIZE*2], quantptr[DCTSIZE*2]); - tmp2 = DEQUANTIZE(inptr[DCTSIZE*4], quantptr[DCTSIZE*4]); - tmp3 = DEQUANTIZE(inptr[DCTSIZE*6], quantptr[DCTSIZE*6]); - - tmp10 = tmp0 + tmp2; /* phase 3 */ - tmp11 = tmp0 - tmp2; - - tmp13 = tmp1 + tmp3; /* phases 5-3 */ - tmp12 = MULTIPLY(tmp1 - tmp3, FIX_1_414213562) - tmp13; /* 2*c4 */ - - tmp0 = tmp10 + tmp13; /* phase 2 */ - tmp3 = tmp10 - tmp13; - tmp1 = tmp11 + tmp12; - tmp2 = tmp11 - tmp12; - - /* Odd part */ - - tmp4 = DEQUANTIZE(inptr[DCTSIZE*1], quantptr[DCTSIZE*1]); - tmp5 = DEQUANTIZE(inptr[DCTSIZE*3], quantptr[DCTSIZE*3]); - tmp6 = DEQUANTIZE(inptr[DCTSIZE*5], quantptr[DCTSIZE*5]); - tmp7 = DEQUANTIZE(inptr[DCTSIZE*7], quantptr[DCTSIZE*7]); - - z13 = tmp6 + tmp5; /* phase 6 */ - z10 = tmp6 - tmp5; - z11 = tmp4 + tmp7; - z12 = tmp4 - tmp7; - - tmp7 = z11 + z13; /* phase 5 */ - tmp11 = MULTIPLY(z11 - z13, FIX_1_414213562); /* 2*c4 */ - - z5 = MULTIPLY(z10 + z12, FIX_1_847759065); /* 2*c2 */ - tmp10 = MULTIPLY(z12, FIX_1_082392200) - z5; /* 2*(c2-c6) */ - tmp12 = MULTIPLY(z10, - FIX_2_613125930) + z5; /* -2*(c2+c6) */ - - tmp6 = tmp12 - tmp7; /* phase 2 */ - tmp5 = tmp11 - tmp6; - tmp4 = tmp10 + tmp5; - - wsptr[DCTSIZE*0] = (int) (tmp0 + tmp7); - wsptr[DCTSIZE*7] = (int) (tmp0 - tmp7); - wsptr[DCTSIZE*1] = (int) (tmp1 + tmp6); - wsptr[DCTSIZE*6] = (int) (tmp1 - tmp6); - wsptr[DCTSIZE*2] = (int) (tmp2 + tmp5); - wsptr[DCTSIZE*5] = (int) (tmp2 - tmp5); - wsptr[DCTSIZE*4] = (int) (tmp3 + tmp4); - wsptr[DCTSIZE*3] = (int) (tmp3 - tmp4); - - inptr++; /* advance pointers to next column */ - quantptr++; - wsptr++; - } - - /* Pass 2: process rows from work array, store into output array. */ - /* Note that we must descale the results by a factor of 8 == 2**3, */ - /* and also undo the PASS1_BITS scaling. */ - - wsptr = workspace; - for (ctr = 0; ctr < DCTSIZE; ctr++) { - outptr = output_buf[ctr] + output_col; - /* Rows of zeroes can be exploited in the same way as we did with columns. - * However, the column calculation has created many nonzero AC terms, so - * the simplification applies less often (typically 5% to 10% of the time). - * On machines with very fast multiplication, it's possible that the - * test takes more time than it's worth. In that case this section - * may be commented out. - */ - -#ifndef NO_ZERO_ROW_TEST - if ((wsptr[1] | wsptr[2] | wsptr[3] | wsptr[4] | wsptr[5] | wsptr[6] | - wsptr[7]) == 0) { - /* AC terms all zero */ - JSAMPLE dcval = range_limit[IDESCALE(wsptr[0], PASS1_BITS+3) - & RANGE_MASK]; - - outptr[0] = dcval; - outptr[1] = dcval; - outptr[2] = dcval; - outptr[3] = dcval; - outptr[4] = dcval; - outptr[5] = dcval; - outptr[6] = dcval; - outptr[7] = dcval; - - wsptr += DCTSIZE; /* advance pointer to next row */ - continue; - } -#endif - - /* Even part */ - - tmp10 = ((DCTELEM) wsptr[0] + (DCTELEM) wsptr[4]); - tmp11 = ((DCTELEM) wsptr[0] - (DCTELEM) wsptr[4]); - - tmp13 = ((DCTELEM) wsptr[2] + (DCTELEM) wsptr[6]); - tmp12 = MULTIPLY((DCTELEM) wsptr[2] - (DCTELEM) wsptr[6], FIX_1_414213562) - - tmp13; - - tmp0 = tmp10 + tmp13; - tmp3 = tmp10 - tmp13; - tmp1 = tmp11 + tmp12; - tmp2 = tmp11 - tmp12; - - /* Odd part */ - - z13 = (DCTELEM) wsptr[5] + (DCTELEM) wsptr[3]; - z10 = (DCTELEM) wsptr[5] - (DCTELEM) wsptr[3]; - z11 = (DCTELEM) wsptr[1] + (DCTELEM) wsptr[7]; - z12 = (DCTELEM) wsptr[1] - (DCTELEM) wsptr[7]; - - tmp7 = z11 + z13; /* phase 5 */ - tmp11 = MULTIPLY(z11 - z13, FIX_1_414213562); /* 2*c4 */ - - z5 = MULTIPLY(z10 + z12, FIX_1_847759065); /* 2*c2 */ - tmp10 = MULTIPLY(z12, FIX_1_082392200) - z5; /* 2*(c2-c6) */ - tmp12 = MULTIPLY(z10, - FIX_2_613125930) + z5; /* -2*(c2+c6) */ - - tmp6 = tmp12 - tmp7; /* phase 2 */ - tmp5 = tmp11 - tmp6; - tmp4 = tmp10 + tmp5; - - /* Final output stage: scale down by a factor of 8 and range-limit */ - - outptr[0] = range_limit[IDESCALE(tmp0 + tmp7, PASS1_BITS+3) - & RANGE_MASK]; - outptr[7] = range_limit[IDESCALE(tmp0 - tmp7, PASS1_BITS+3) - & RANGE_MASK]; - outptr[1] = range_limit[IDESCALE(tmp1 + tmp6, PASS1_BITS+3) - & RANGE_MASK]; - outptr[6] = range_limit[IDESCALE(tmp1 - tmp6, PASS1_BITS+3) - & RANGE_MASK]; - outptr[2] = range_limit[IDESCALE(tmp2 + tmp5, PASS1_BITS+3) - & RANGE_MASK]; - outptr[5] = range_limit[IDESCALE(tmp2 - tmp5, PASS1_BITS+3) - & RANGE_MASK]; - outptr[4] = range_limit[IDESCALE(tmp3 + tmp4, PASS1_BITS+3) - & RANGE_MASK]; - outptr[3] = range_limit[IDESCALE(tmp3 - tmp4, PASS1_BITS+3) - & RANGE_MASK]; - - wsptr += DCTSIZE; /* advance pointer to next row */ - } -} - -#endif /* DCT_IFAST_SUPPORTED */ diff --git a/engine/jpeg-6/jidctint.c b/engine/jpeg-6/jidctint.c deleted file mode 100644 index f25b08d..0000000 --- a/engine/jpeg-6/jidctint.c +++ /dev/null @@ -1,388 +0,0 @@ -/* - * jidctint.c - * - * Copyright (C) 1991-1994, Thomas G. Lane. - * This file is part of the Independent JPEG Group's software. - * For conditions of distribution and use, see the accompanying README file. - * - * This file contains a slow-but-accurate integer implementation of the - * inverse DCT (Discrete Cosine Transform). In the IJG code, this routine - * must also perform dequantization of the input coefficients. - * - * A 2-D IDCT can be done by 1-D IDCT on each column followed by 1-D IDCT - * on each row (or vice versa, but it's more convenient to emit a row at - * a time). Direct algorithms are also available, but they are much more - * complex and seem not to be any faster when reduced to code. - * - * This implementation is based on an algorithm described in - * C. Loeffler, A. Ligtenberg and G. Moschytz, "Practical Fast 1-D DCT - * Algorithms with 11 Multiplications", Proc. Int'l. Conf. on Acoustics, - * Speech, and Signal Processing 1989 (ICASSP '89), pp. 988-991. - * The primary algorithm described there uses 11 multiplies and 29 adds. - * We use their alternate method with 12 multiplies and 32 adds. - * The advantage of this method is that no data path contains more than one - * multiplication; this allows a very simple and accurate implementation in - * scaled fixed-point arithmetic, with a minimal number of shifts. - */ - -#define JPEG_INTERNALS -#include "jinclude.h" -#include "jpeglib.h" -#include "jdct.h" /* Private declarations for DCT subsystem */ - -#ifdef DCT_ISLOW_SUPPORTED - - -/* - * This module is specialized to the case DCTSIZE = 8. - */ - -#if DCTSIZE != 8 - Sorry, this code only copes with 8x8 DCTs. /* deliberate syntax err */ -#endif - - -/* - * The poop on this scaling stuff is as follows: - * - * Each 1-D IDCT step produces outputs which are a factor of sqrt(N) - * larger than the true IDCT outputs. The final outputs are therefore - * a factor of N larger than desired; since N=8 this can be cured by - * a simple right shift at the end of the algorithm. The advantage of - * this arrangement is that we save two multiplications per 1-D IDCT, - * because the y0 and y4 inputs need not be divided by sqrt(N). - * - * We have to do addition and subtraction of the integer inputs, which - * is no problem, and multiplication by fractional constants, which is - * a problem to do in integer arithmetic. We multiply all the constants - * by CONST_SCALE and convert them to integer constants (thus retaining - * CONST_BITS bits of precision in the constants). After doing a - * multiplication we have to divide the product by CONST_SCALE, with proper - * rounding, to produce the correct output. This division can be done - * cheaply as a right shift of CONST_BITS bits. We postpone shifting - * as long as possible so that partial sums can be added together with - * full fractional precision. - * - * The outputs of the first pass are scaled up by PASS1_BITS bits so that - * they are represented to better-than-integral precision. These outputs - * require BITS_IN_JSAMPLE + PASS1_BITS + 3 bits; this fits in a 16-bit word - * with the recommended scaling. (To scale up 12-bit sample data further, an - * intermediate INT32 array would be needed.) - * - * To avoid overflow of the 32-bit intermediate results in pass 2, we must - * have BITS_IN_JSAMPLE + CONST_BITS + PASS1_BITS <= 26. Error analysis - * shows that the values given below are the most effective. - */ - -#if BITS_IN_JSAMPLE == 8 -#define CONST_BITS 13 -#define PASS1_BITS 2 -#else -#define CONST_BITS 13 -#define PASS1_BITS 1 /* lose a little precision to avoid overflow */ -#endif - -/* Some C compilers fail to reduce "FIX(constant)" at compile time, thus - * causing a lot of useless floating-point operations at run time. - * To get around this we use the following pre-calculated constants. - * If you change CONST_BITS you may want to add appropriate values. - * (With a reasonable C compiler, you can just rely on the FIX() macro...) - */ - -#if CONST_BITS == 13 -#define FIX_0_298631336 ((INT32) 2446) /* FIX(0.298631336) */ -#define FIX_0_390180644 ((INT32) 3196) /* FIX(0.390180644) */ -#define FIX_0_541196100 ((INT32) 4433) /* FIX(0.541196100) */ -#define FIX_0_765366865 ((INT32) 6270) /* FIX(0.765366865) */ -#define FIX_0_899976223 ((INT32) 7373) /* FIX(0.899976223) */ -#define FIX_1_175875602 ((INT32) 9633) /* FIX(1.175875602) */ -#define FIX_1_501321110 ((INT32) 12299) /* FIX(1.501321110) */ -#define FIX_1_847759065 ((INT32) 15137) /* FIX(1.847759065) */ -#define FIX_1_961570560 ((INT32) 16069) /* FIX(1.961570560) */ -#define FIX_2_053119869 ((INT32) 16819) /* FIX(2.053119869) */ -#define FIX_2_562915447 ((INT32) 20995) /* FIX(2.562915447) */ -#define FIX_3_072711026 ((INT32) 25172) /* FIX(3.072711026) */ -#else -#define FIX_0_298631336 FIX(0.298631336) -#define FIX_0_390180644 FIX(0.390180644) -#define FIX_0_541196100 FIX(0.541196100) -#define FIX_0_765366865 FIX(0.765366865) -#define FIX_0_899976223 FIX(0.899976223) -#define FIX_1_175875602 FIX(1.175875602) -#define FIX_1_501321110 FIX(1.501321110) -#define FIX_1_847759065 FIX(1.847759065) -#define FIX_1_961570560 FIX(1.961570560) -#define FIX_2_053119869 FIX(2.053119869) -#define FIX_2_562915447 FIX(2.562915447) -#define FIX_3_072711026 FIX(3.072711026) -#endif - - -/* Multiply an INT32 variable by an INT32 constant to yield an INT32 result. - * For 8-bit samples with the recommended scaling, all the variable - * and constant values involved are no more than 16 bits wide, so a - * 16x16->32 bit multiply can be used instead of a full 32x32 multiply. - * For 12-bit samples, a full 32-bit multiplication will be needed. - */ - -#if BITS_IN_JSAMPLE == 8 -#define MULTIPLY(var,const) MULTIPLY16C16(var,const) -#else -#define MULTIPLY(var,const) ((var) * (const)) -#endif - - -/* Dequantize a coefficient by multiplying it by the multiplier-table - * entry; produce an int result. In this module, both inputs and result - * are 16 bits or less, so either int or short multiply will work. - */ - -#define DEQUANTIZE(coef,quantval) (((ISLOW_MULT_TYPE) (coef)) * (quantval)) - - -/* - * Perform dequantization and inverse DCT on one block of coefficients. - */ - -GLOBAL void -jpeg_idct_islow (j_decompress_ptr cinfo, jpeg_component_info * compptr, - JCOEFPTR coef_block, - JSAMPARRAY output_buf, JDIMENSION output_col) -{ - INT32 tmp0, tmp1, tmp2, tmp3; - INT32 tmp10, tmp11, tmp12, tmp13; - INT32 z1, z2, z3, z4, z5; - JCOEFPTR inptr; - ISLOW_MULT_TYPE * quantptr; - int * wsptr; - JSAMPROW outptr; - JSAMPLE *range_limit = IDCT_range_limit(cinfo); - int ctr; - int workspace[DCTSIZE2]; /* buffers data between passes */ - SHIFT_TEMPS - - /* Pass 1: process columns from input, store into work array. */ - /* Note results are scaled up by sqrt(8) compared to a true IDCT; */ - /* furthermore, we scale the results by 2**PASS1_BITS. */ - - inptr = coef_block; - quantptr = (ISLOW_MULT_TYPE *) compptr->dct_table; - wsptr = workspace; - for (ctr = DCTSIZE; ctr > 0; ctr--) { - /* Due to quantization, we will usually find that many of the input - * coefficients are zero, especially the AC terms. We can exploit this - * by short-circuiting the IDCT calculation for any column in which all - * the AC terms are zero. In that case each output is equal to the - * DC coefficient (with scale factor as needed). - * With typical images and quantization tables, half or more of the - * column DCT calculations can be simplified this way. - */ - - if ((inptr[DCTSIZE*1] | inptr[DCTSIZE*2] | inptr[DCTSIZE*3] | - inptr[DCTSIZE*4] | inptr[DCTSIZE*5] | inptr[DCTSIZE*6] | - inptr[DCTSIZE*7]) == 0) { - /* AC terms all zero */ - int dcval = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]) << PASS1_BITS; - - wsptr[DCTSIZE*0] = dcval; - wsptr[DCTSIZE*1] = dcval; - wsptr[DCTSIZE*2] = dcval; - wsptr[DCTSIZE*3] = dcval; - wsptr[DCTSIZE*4] = dcval; - wsptr[DCTSIZE*5] = dcval; - wsptr[DCTSIZE*6] = dcval; - wsptr[DCTSIZE*7] = dcval; - - inptr++; /* advance pointers to next column */ - quantptr++; - wsptr++; - continue; - } - - /* Even part: reverse the even part of the forward DCT. */ - /* The rotator is sqrt(2)*c(-6). */ - - z2 = DEQUANTIZE(inptr[DCTSIZE*2], quantptr[DCTSIZE*2]); - z3 = DEQUANTIZE(inptr[DCTSIZE*6], quantptr[DCTSIZE*6]); - - z1 = MULTIPLY(z2 + z3, FIX_0_541196100); - tmp2 = z1 + MULTIPLY(z3, - FIX_1_847759065); - tmp3 = z1 + MULTIPLY(z2, FIX_0_765366865); - - z2 = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]); - z3 = DEQUANTIZE(inptr[DCTSIZE*4], quantptr[DCTSIZE*4]); - - tmp0 = (z2 + z3) << CONST_BITS; - tmp1 = (z2 - z3) << CONST_BITS; - - tmp10 = tmp0 + tmp3; - tmp13 = tmp0 - tmp3; - tmp11 = tmp1 + tmp2; - tmp12 = tmp1 - tmp2; - - /* Odd part per figure 8; the matrix is unitary and hence its - * transpose is its inverse. i0..i3 are y7,y5,y3,y1 respectively. - */ - - tmp0 = DEQUANTIZE(inptr[DCTSIZE*7], quantptr[DCTSIZE*7]); - tmp1 = DEQUANTIZE(inptr[DCTSIZE*5], quantptr[DCTSIZE*5]); - tmp2 = DEQUANTIZE(inptr[DCTSIZE*3], quantptr[DCTSIZE*3]); - tmp3 = DEQUANTIZE(inptr[DCTSIZE*1], quantptr[DCTSIZE*1]); - - z1 = tmp0 + tmp3; - z2 = tmp1 + tmp2; - z3 = tmp0 + tmp2; - z4 = tmp1 + tmp3; - z5 = MULTIPLY(z3 + z4, FIX_1_175875602); /* sqrt(2) * c3 */ - - tmp0 = MULTIPLY(tmp0, FIX_0_298631336); /* sqrt(2) * (-c1+c3+c5-c7) */ - tmp1 = MULTIPLY(tmp1, FIX_2_053119869); /* sqrt(2) * ( c1+c3-c5+c7) */ - tmp2 = MULTIPLY(tmp2, FIX_3_072711026); /* sqrt(2) * ( c1+c3+c5-c7) */ - tmp3 = MULTIPLY(tmp3, FIX_1_501321110); /* sqrt(2) * ( c1+c3-c5-c7) */ - z1 = MULTIPLY(z1, - FIX_0_899976223); /* sqrt(2) * (c7-c3) */ - z2 = MULTIPLY(z2, - FIX_2_562915447); /* sqrt(2) * (-c1-c3) */ - z3 = MULTIPLY(z3, - FIX_1_961570560); /* sqrt(2) * (-c3-c5) */ - z4 = MULTIPLY(z4, - FIX_0_390180644); /* sqrt(2) * (c5-c3) */ - - z3 += z5; - z4 += z5; - - tmp0 += z1 + z3; - tmp1 += z2 + z4; - tmp2 += z2 + z3; - tmp3 += z1 + z4; - - /* Final output stage: inputs are tmp10..tmp13, tmp0..tmp3 */ - - wsptr[DCTSIZE*0] = (int) DESCALE(tmp10 + tmp3, CONST_BITS-PASS1_BITS); - wsptr[DCTSIZE*7] = (int) DESCALE(tmp10 - tmp3, CONST_BITS-PASS1_BITS); - wsptr[DCTSIZE*1] = (int) DESCALE(tmp11 + tmp2, CONST_BITS-PASS1_BITS); - wsptr[DCTSIZE*6] = (int) DESCALE(tmp11 - tmp2, CONST_BITS-PASS1_BITS); - wsptr[DCTSIZE*2] = (int) DESCALE(tmp12 + tmp1, CONST_BITS-PASS1_BITS); - wsptr[DCTSIZE*5] = (int) DESCALE(tmp12 - tmp1, CONST_BITS-PASS1_BITS); - wsptr[DCTSIZE*3] = (int) DESCALE(tmp13 + tmp0, CONST_BITS-PASS1_BITS); - wsptr[DCTSIZE*4] = (int) DESCALE(tmp13 - tmp0, CONST_BITS-PASS1_BITS); - - inptr++; /* advance pointers to next column */ - quantptr++; - wsptr++; - } - - /* Pass 2: process rows from work array, store into output array. */ - /* Note that we must descale the results by a factor of 8 == 2**3, */ - /* and also undo the PASS1_BITS scaling. */ - - wsptr = workspace; - for (ctr = 0; ctr < DCTSIZE; ctr++) { - outptr = output_buf[ctr] + output_col; - /* Rows of zeroes can be exploited in the same way as we did with columns. - * However, the column calculation has created many nonzero AC terms, so - * the simplification applies less often (typically 5% to 10% of the time). - * On machines with very fast multiplication, it's possible that the - * test takes more time than it's worth. In that case this section - * may be commented out. - */ - -#ifndef NO_ZERO_ROW_TEST - if ((wsptr[1] | wsptr[2] | wsptr[3] | wsptr[4] | wsptr[5] | wsptr[6] | - wsptr[7]) == 0) { - /* AC terms all zero */ - JSAMPLE dcval = range_limit[(int) DESCALE((INT32) wsptr[0], PASS1_BITS+3) - & RANGE_MASK]; - - outptr[0] = dcval; - outptr[1] = dcval; - outptr[2] = dcval; - outptr[3] = dcval; - outptr[4] = dcval; - outptr[5] = dcval; - outptr[6] = dcval; - outptr[7] = dcval; - - wsptr += DCTSIZE; /* advance pointer to next row */ - continue; - } -#endif - - /* Even part: reverse the even part of the forward DCT. */ - /* The rotator is sqrt(2)*c(-6). */ - - z2 = (INT32) wsptr[2]; - z3 = (INT32) wsptr[6]; - - z1 = MULTIPLY(z2 + z3, FIX_0_541196100); - tmp2 = z1 + MULTIPLY(z3, - FIX_1_847759065); - tmp3 = z1 + MULTIPLY(z2, FIX_0_765366865); - - tmp0 = ((INT32) wsptr[0] + (INT32) wsptr[4]) << CONST_BITS; - tmp1 = ((INT32) wsptr[0] - (INT32) wsptr[4]) << CONST_BITS; - - tmp10 = tmp0 + tmp3; - tmp13 = tmp0 - tmp3; - tmp11 = tmp1 + tmp2; - tmp12 = tmp1 - tmp2; - - /* Odd part per figure 8; the matrix is unitary and hence its - * transpose is its inverse. i0..i3 are y7,y5,y3,y1 respectively. - */ - - tmp0 = (INT32) wsptr[7]; - tmp1 = (INT32) wsptr[5]; - tmp2 = (INT32) wsptr[3]; - tmp3 = (INT32) wsptr[1]; - - z1 = tmp0 + tmp3; - z2 = tmp1 + tmp2; - z3 = tmp0 + tmp2; - z4 = tmp1 + tmp3; - z5 = MULTIPLY(z3 + z4, FIX_1_175875602); /* sqrt(2) * c3 */ - - tmp0 = MULTIPLY(tmp0, FIX_0_298631336); /* sqrt(2) * (-c1+c3+c5-c7) */ - tmp1 = MULTIPLY(tmp1, FIX_2_053119869); /* sqrt(2) * ( c1+c3-c5+c7) */ - tmp2 = MULTIPLY(tmp2, FIX_3_072711026); /* sqrt(2) * ( c1+c3+c5-c7) */ - tmp3 = MULTIPLY(tmp3, FIX_1_501321110); /* sqrt(2) * ( c1+c3-c5-c7) */ - z1 = MULTIPLY(z1, - FIX_0_899976223); /* sqrt(2) * (c7-c3) */ - z2 = MULTIPLY(z2, - FIX_2_562915447); /* sqrt(2) * (-c1-c3) */ - z3 = MULTIPLY(z3, - FIX_1_961570560); /* sqrt(2) * (-c3-c5) */ - z4 = MULTIPLY(z4, - FIX_0_390180644); /* sqrt(2) * (c5-c3) */ - - z3 += z5; - z4 += z5; - - tmp0 += z1 + z3; - tmp1 += z2 + z4; - tmp2 += z2 + z3; - tmp3 += z1 + z4; - - /* Final output stage: inputs are tmp10..tmp13, tmp0..tmp3 */ - - outptr[0] = range_limit[(int) DESCALE(tmp10 + tmp3, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[7] = range_limit[(int) DESCALE(tmp10 - tmp3, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[1] = range_limit[(int) DESCALE(tmp11 + tmp2, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[6] = range_limit[(int) DESCALE(tmp11 - tmp2, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[2] = range_limit[(int) DESCALE(tmp12 + tmp1, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[5] = range_limit[(int) DESCALE(tmp12 - tmp1, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[3] = range_limit[(int) DESCALE(tmp13 + tmp0, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[4] = range_limit[(int) DESCALE(tmp13 - tmp0, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - - wsptr += DCTSIZE; /* advance pointer to next row */ - } -} - -#endif /* DCT_ISLOW_SUPPORTED */ diff --git a/engine/jpeg-6/jidctred.c b/engine/jpeg-6/jidctred.c deleted file mode 100644 index 019c339..0000000 --- a/engine/jpeg-6/jidctred.c +++ /dev/null @@ -1,397 +0,0 @@ -/* - * jidctred.c - * - * Copyright (C) 1994, Thomas G. Lane. - * This file is part of the Independent JPEG Group's software. - * For conditions of distribution and use, see the accompanying README file. - * - * This file contains inverse-DCT routines that produce reduced-size output: - * either 4x4, 2x2, or 1x1 pixels from an 8x8 DCT block. - * - * The implementation is based on the Loeffler, Ligtenberg and Moschytz (LL&M) - * algorithm used in jidctint.c. We simply replace each 8-to-8 1-D IDCT step - * with an 8-to-4 step that produces the four averages of two adjacent outputs - * (or an 8-to-2 step producing two averages of four outputs, for 2x2 output). - * These steps were derived by computing the corresponding values at the end - * of the normal LL&M code, then simplifying as much as possible. - * - * 1x1 is trivial: just take the DC coefficient divided by 8. - * - * See jidctint.c for additional comments. - */ - -#define JPEG_INTERNALS -#include "jinclude.h" -#include "jpeglib.h" -#include "jdct.h" /* Private declarations for DCT subsystem */ - -#ifdef IDCT_SCALING_SUPPORTED - - -/* - * This module is specialized to the case DCTSIZE = 8. - */ - -#if DCTSIZE != 8 - Sorry, this code only copes with 8x8 DCTs. /* deliberate syntax err */ -#endif - - -/* Scaling is the same as in jidctint.c. */ - -#if BITS_IN_JSAMPLE == 8 -#define CONST_BITS 13 -#define PASS1_BITS 2 -#else -#define CONST_BITS 13 -#define PASS1_BITS 1 /* lose a little precision to avoid overflow */ -#endif - -/* Some C compilers fail to reduce "FIX(constant)" at compile time, thus - * causing a lot of useless floating-point operations at run time. - * To get around this we use the following pre-calculated constants. - * If you change CONST_BITS you may want to add appropriate values. - * (With a reasonable C compiler, you can just rely on the FIX() macro...) - */ - -#if CONST_BITS == 13 -#define FIX_0_211164243 ((INT32) 1730) /* FIX(0.211164243) */ -#define FIX_0_509795579 ((INT32) 4176) /* FIX(0.509795579) */ -#define FIX_0_601344887 ((INT32) 4926) /* FIX(0.601344887) */ -#define FIX_0_720959822 ((INT32) 5906) /* FIX(0.720959822) */ -#define FIX_0_765366865 ((INT32) 6270) /* FIX(0.765366865) */ -#define FIX_0_850430095 ((INT32) 6967) /* FIX(0.850430095) */ -#define FIX_0_899976223 ((INT32) 7373) /* FIX(0.899976223) */ -#define FIX_1_061594337 ((INT32) 8697) /* FIX(1.061594337) */ -#define FIX_1_272758580 ((INT32) 10426) /* FIX(1.272758580) */ -#define FIX_1_451774981 ((INT32) 11893) /* FIX(1.451774981) */ -#define FIX_1_847759065 ((INT32) 15137) /* FIX(1.847759065) */ -#define FIX_2_172734803 ((INT32) 17799) /* FIX(2.172734803) */ -#define FIX_2_562915447 ((INT32) 20995) /* FIX(2.562915447) */ -#define FIX_3_624509785 ((INT32) 29692) /* FIX(3.624509785) */ -#else -#define FIX_0_211164243 FIX(0.211164243) -#define FIX_0_509795579 FIX(0.509795579) -#define FIX_0_601344887 FIX(0.601344887) -#define FIX_0_720959822 FIX(0.720959822) -#define FIX_0_765366865 FIX(0.765366865) -#define FIX_0_850430095 FIX(0.850430095) -#define FIX_0_899976223 FIX(0.899976223) -#define FIX_1_061594337 FIX(1.061594337) -#define FIX_1_272758580 FIX(1.272758580) -#define FIX_1_451774981 FIX(1.451774981) -#define FIX_1_847759065 FIX(1.847759065) -#define FIX_2_172734803 FIX(2.172734803) -#define FIX_2_562915447 FIX(2.562915447) -#define FIX_3_624509785 FIX(3.624509785) -#endif - - -/* Multiply an INT32 variable by an INT32 constant to yield an INT32 result. - * For 8-bit samples with the recommended scaling, all the variable - * and constant values involved are no more than 16 bits wide, so a - * 16x16->32 bit multiply can be used instead of a full 32x32 multiply. - * For 12-bit samples, a full 32-bit multiplication will be needed. - */ - -#if BITS_IN_JSAMPLE == 8 -#define MULTIPLY(var,const) MULTIPLY16C16(var,const) -#else -#define MULTIPLY(var,const) ((var) * (const)) -#endif - - -/* Dequantize a coefficient by multiplying it by the multiplier-table - * entry; produce an int result. In this module, both inputs and result - * are 16 bits or less, so either int or short multiply will work. - */ - -#define DEQUANTIZE(coef,quantval) (((ISLOW_MULT_TYPE) (coef)) * (quantval)) - - -/* - * Perform dequantization and inverse DCT on one block of coefficients, - * producing a reduced-size 4x4 output block. - */ - -GLOBAL void -jpeg_idct_4x4 (j_decompress_ptr cinfo, jpeg_component_info * compptr, - JCOEFPTR coef_block, - JSAMPARRAY output_buf, JDIMENSION output_col) -{ - INT32 tmp0, tmp2, tmp10, tmp12; - INT32 z1, z2, z3, z4; - JCOEFPTR inptr; - ISLOW_MULT_TYPE * quantptr; - int * wsptr; - JSAMPROW outptr; - JSAMPLE *range_limit = IDCT_range_limit(cinfo); - int ctr; - int workspace[DCTSIZE*4]; /* buffers data between passes */ - SHIFT_TEMPS - - /* Pass 1: process columns from input, store into work array. */ - - inptr = coef_block; - quantptr = (ISLOW_MULT_TYPE *) compptr->dct_table; - wsptr = workspace; - for (ctr = DCTSIZE; ctr > 0; inptr++, quantptr++, wsptr++, ctr--) { - /* Don't bother to process column 4, because second pass won't use it */ - if (ctr == DCTSIZE-4) - continue; - if ((inptr[DCTSIZE*1] | inptr[DCTSIZE*2] | inptr[DCTSIZE*3] | - inptr[DCTSIZE*5] | inptr[DCTSIZE*6] | inptr[DCTSIZE*7]) == 0) { - /* AC terms all zero; we need not examine term 4 for 4x4 output */ - int dcval = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]) << PASS1_BITS; - - wsptr[DCTSIZE*0] = dcval; - wsptr[DCTSIZE*1] = dcval; - wsptr[DCTSIZE*2] = dcval; - wsptr[DCTSIZE*3] = dcval; - - continue; - } - - /* Even part */ - - tmp0 = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]); - tmp0 <<= (CONST_BITS+1); - - z2 = DEQUANTIZE(inptr[DCTSIZE*2], quantptr[DCTSIZE*2]); - z3 = DEQUANTIZE(inptr[DCTSIZE*6], quantptr[DCTSIZE*6]); - - tmp2 = MULTIPLY(z2, FIX_1_847759065) + MULTIPLY(z3, - FIX_0_765366865); - - tmp10 = tmp0 + tmp2; - tmp12 = tmp0 - tmp2; - - /* Odd part */ - - z1 = DEQUANTIZE(inptr[DCTSIZE*7], quantptr[DCTSIZE*7]); - z2 = DEQUANTIZE(inptr[DCTSIZE*5], quantptr[DCTSIZE*5]); - z3 = DEQUANTIZE(inptr[DCTSIZE*3], quantptr[DCTSIZE*3]); - z4 = DEQUANTIZE(inptr[DCTSIZE*1], quantptr[DCTSIZE*1]); - - tmp0 = MULTIPLY(z1, - FIX_0_211164243) /* sqrt(2) * (c3-c1) */ - + MULTIPLY(z2, FIX_1_451774981) /* sqrt(2) * (c3+c7) */ - + MULTIPLY(z3, - FIX_2_172734803) /* sqrt(2) * (-c1-c5) */ - + MULTIPLY(z4, FIX_1_061594337); /* sqrt(2) * (c5+c7) */ - - tmp2 = MULTIPLY(z1, - FIX_0_509795579) /* sqrt(2) * (c7-c5) */ - + MULTIPLY(z2, - FIX_0_601344887) /* sqrt(2) * (c5-c1) */ - + MULTIPLY(z3, FIX_0_899976223) /* sqrt(2) * (c3-c7) */ - + MULTIPLY(z4, FIX_2_562915447); /* sqrt(2) * (c1+c3) */ - - /* Final output stage */ - - wsptr[DCTSIZE*0] = (int) DESCALE(tmp10 + tmp2, CONST_BITS-PASS1_BITS+1); - wsptr[DCTSIZE*3] = (int) DESCALE(tmp10 - tmp2, CONST_BITS-PASS1_BITS+1); - wsptr[DCTSIZE*1] = (int) DESCALE(tmp12 + tmp0, CONST_BITS-PASS1_BITS+1); - wsptr[DCTSIZE*2] = (int) DESCALE(tmp12 - tmp0, CONST_BITS-PASS1_BITS+1); - } - - /* Pass 2: process 4 rows from work array, store into output array. */ - - wsptr = workspace; - for (ctr = 0; ctr < 4; ctr++) { - outptr = output_buf[ctr] + output_col; - /* It's not clear whether a zero row test is worthwhile here ... */ - -#ifndef NO_ZERO_ROW_TEST - if ((wsptr[1] | wsptr[2] | wsptr[3] | wsptr[5] | wsptr[6] | - wsptr[7]) == 0) { - /* AC terms all zero */ - JSAMPLE dcval = range_limit[(int) DESCALE((INT32) wsptr[0], PASS1_BITS+3) - & RANGE_MASK]; - - outptr[0] = dcval; - outptr[1] = dcval; - outptr[2] = dcval; - outptr[3] = dcval; - - wsptr += DCTSIZE; /* advance pointer to next row */ - continue; - } -#endif - - /* Even part */ - - tmp0 = ((INT32) wsptr[0]) << (CONST_BITS+1); - - tmp2 = MULTIPLY((INT32) wsptr[2], FIX_1_847759065) - + MULTIPLY((INT32) wsptr[6], - FIX_0_765366865); - - tmp10 = tmp0 + tmp2; - tmp12 = tmp0 - tmp2; - - /* Odd part */ - - z1 = (INT32) wsptr[7]; - z2 = (INT32) wsptr[5]; - z3 = (INT32) wsptr[3]; - z4 = (INT32) wsptr[1]; - - tmp0 = MULTIPLY(z1, - FIX_0_211164243) /* sqrt(2) * (c3-c1) */ - + MULTIPLY(z2, FIX_1_451774981) /* sqrt(2) * (c3+c7) */ - + MULTIPLY(z3, - FIX_2_172734803) /* sqrt(2) * (-c1-c5) */ - + MULTIPLY(z4, FIX_1_061594337); /* sqrt(2) * (c5+c7) */ - - tmp2 = MULTIPLY(z1, - FIX_0_509795579) /* sqrt(2) * (c7-c5) */ - + MULTIPLY(z2, - FIX_0_601344887) /* sqrt(2) * (c5-c1) */ - + MULTIPLY(z3, FIX_0_899976223) /* sqrt(2) * (c3-c7) */ - + MULTIPLY(z4, FIX_2_562915447); /* sqrt(2) * (c1+c3) */ - - /* Final output stage */ - - outptr[0] = range_limit[(int) DESCALE(tmp10 + tmp2, - CONST_BITS+PASS1_BITS+3+1) - & RANGE_MASK]; - outptr[3] = range_limit[(int) DESCALE(tmp10 - tmp2, - CONST_BITS+PASS1_BITS+3+1) - & RANGE_MASK]; - outptr[1] = range_limit[(int) DESCALE(tmp12 + tmp0, - CONST_BITS+PASS1_BITS+3+1) - & RANGE_MASK]; - outptr[2] = range_limit[(int) DESCALE(tmp12 - tmp0, - CONST_BITS+PASS1_BITS+3+1) - & RANGE_MASK]; - - wsptr += DCTSIZE; /* advance pointer to next row */ - } -} - - -/* - * Perform dequantization and inverse DCT on one block of coefficients, - * producing a reduced-size 2x2 output block. - */ - -GLOBAL void -jpeg_idct_2x2 (j_decompress_ptr cinfo, jpeg_component_info * compptr, - JCOEFPTR coef_block, - JSAMPARRAY output_buf, JDIMENSION output_col) -{ - INT32 tmp0, tmp10, z1; - JCOEFPTR inptr; - ISLOW_MULT_TYPE * quantptr; - int * wsptr; - JSAMPROW outptr; - JSAMPLE *range_limit = IDCT_range_limit(cinfo); - int ctr; - int workspace[DCTSIZE*2]; /* buffers data between passes */ - SHIFT_TEMPS - - /* Pass 1: process columns from input, store into work array. */ - - inptr = coef_block; - quantptr = (ISLOW_MULT_TYPE *) compptr->dct_table; - wsptr = workspace; - for (ctr = DCTSIZE; ctr > 0; inptr++, quantptr++, wsptr++, ctr--) { - /* Don't bother to process columns 2,4,6 */ - if (ctr == DCTSIZE-2 || ctr == DCTSIZE-4 || ctr == DCTSIZE-6) - continue; - if ((inptr[DCTSIZE*1] | inptr[DCTSIZE*3] | - inptr[DCTSIZE*5] | inptr[DCTSIZE*7]) == 0) { - /* AC terms all zero; we need not examine terms 2,4,6 for 2x2 output */ - int dcval = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]) << PASS1_BITS; - - wsptr[DCTSIZE*0] = dcval; - wsptr[DCTSIZE*1] = dcval; - - continue; - } - - /* Even part */ - - z1 = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]); - tmp10 = z1 << (CONST_BITS+2); - - /* Odd part */ - - z1 = DEQUANTIZE(inptr[DCTSIZE*7], quantptr[DCTSIZE*7]); - tmp0 = MULTIPLY(z1, - FIX_0_720959822); /* sqrt(2) * (c7-c5+c3-c1) */ - z1 = DEQUANTIZE(inptr[DCTSIZE*5], quantptr[DCTSIZE*5]); - tmp0 += MULTIPLY(z1, FIX_0_850430095); /* sqrt(2) * (-c1+c3+c5+c7) */ - z1 = DEQUANTIZE(inptr[DCTSIZE*3], quantptr[DCTSIZE*3]); - tmp0 += MULTIPLY(z1, - FIX_1_272758580); /* sqrt(2) * (-c1+c3-c5-c7) */ - z1 = DEQUANTIZE(inptr[DCTSIZE*1], quantptr[DCTSIZE*1]); - tmp0 += MULTIPLY(z1, FIX_3_624509785); /* sqrt(2) * (c1+c3+c5+c7) */ - - /* Final output stage */ - - wsptr[DCTSIZE*0] = (int) DESCALE(tmp10 + tmp0, CONST_BITS-PASS1_BITS+2); - wsptr[DCTSIZE*1] = (int) DESCALE(tmp10 - tmp0, CONST_BITS-PASS1_BITS+2); - } - - /* Pass 2: process 2 rows from work array, store into output array. */ - - wsptr = workspace; - for (ctr = 0; ctr < 2; ctr++) { - outptr = output_buf[ctr] + output_col; - /* It's not clear whether a zero row test is worthwhile here ... */ - -#ifndef NO_ZERO_ROW_TEST - if ((wsptr[1] | wsptr[3] | wsptr[5] | wsptr[7]) == 0) { - /* AC terms all zero */ - JSAMPLE dcval = range_limit[(int) DESCALE((INT32) wsptr[0], PASS1_BITS+3) - & RANGE_MASK]; - - outptr[0] = dcval; - outptr[1] = dcval; - - wsptr += DCTSIZE; /* advance pointer to next row */ - continue; - } -#endif - - /* Even part */ - - tmp10 = ((INT32) wsptr[0]) << (CONST_BITS+2); - - /* Odd part */ - - tmp0 = MULTIPLY((INT32) wsptr[7], - FIX_0_720959822) /* sqrt(2) * (c7-c5+c3-c1) */ - + MULTIPLY((INT32) wsptr[5], FIX_0_850430095) /* sqrt(2) * (-c1+c3+c5+c7) */ - + MULTIPLY((INT32) wsptr[3], - FIX_1_272758580) /* sqrt(2) * (-c1+c3-c5-c7) */ - + MULTIPLY((INT32) wsptr[1], FIX_3_624509785); /* sqrt(2) * (c1+c3+c5+c7) */ - - /* Final output stage */ - - outptr[0] = range_limit[(int) DESCALE(tmp10 + tmp0, - CONST_BITS+PASS1_BITS+3+2) - & RANGE_MASK]; - outptr[1] = range_limit[(int) DESCALE(tmp10 - tmp0, - CONST_BITS+PASS1_BITS+3+2) - & RANGE_MASK]; - - wsptr += DCTSIZE; /* advance pointer to next row */ - } -} - - -/* - * Perform dequantization and inverse DCT on one block of coefficients, - * producing a reduced-size 1x1 output block. - */ - -GLOBAL void -jpeg_idct_1x1 (j_decompress_ptr cinfo, jpeg_component_info * compptr, - JCOEFPTR coef_block, - JSAMPARRAY output_buf, JDIMENSION output_col) -{ - int dcval; - ISLOW_MULT_TYPE * quantptr; - JSAMPLE *range_limit = IDCT_range_limit(cinfo); - SHIFT_TEMPS - - /* We hardly need an inverse DCT routine for this: just take the - * average pixel value, which is one-eighth of the DC coefficient. - */ - quantptr = (ISLOW_MULT_TYPE *) compptr->dct_table; - dcval = DEQUANTIZE(coef_block[0], quantptr[0]); - dcval = (int) DESCALE((INT32) dcval, 3); - - output_buf[0][output_col] = range_limit[dcval & RANGE_MASK]; -} - -#endif /* IDCT_SCALING_SUPPORTED */ diff --git a/engine/jpeg-6/jinclude.h b/engine/jpeg-6/jinclude.h deleted file mode 100644 index eadcd19..0000000 --- a/engine/jpeg-6/jinclude.h +++ /dev/null @@ -1,116 +0,0 @@ -/* - * jinclude.h - * - * Copyright (C) 1991-1994, Thomas G. Lane. - * This file is part of the Independent JPEG Group's software. - * For conditions of distribution and use, see the accompanying README file. - * - * This file exists to provide a single place to fix any problems with - * including the wrong system include files. (Common problems are taken - * care of by the standard jconfig symbols, but on really weird systems - * you may have to edit this file.) - * - * NOTE: this file is NOT intended to be included by applications using the - * JPEG library. Most applications need only include jpeglib.h. - */ - - -#ifdef _WIN32 - -#pragma warning(disable : 4018) // signed/unsigned mismatch -#pragma warning(disable : 4032) -#pragma warning(disable : 4051) -#pragma warning(disable : 4057) // slightly different base types -#pragma warning(disable : 4100) // unreferenced formal parameter -#pragma warning(disable : 4115) -#pragma warning(disable : 4125) // decimal digit terminates octal escape sequence -#pragma warning(disable : 4127) // conditional expression is constant -#pragma warning(disable : 4136) -#pragma warning(disable : 4152) // nonstandard extension, function/data pointer conversion in expression -#pragma warning(disable : 4201) -#pragma warning(disable : 4214) -#pragma warning(disable : 4244) -#pragma warning(disable : 4305) // truncation from const double to float -#pragma warning(disable : 4310) // cast truncates constant value -#pragma warning(disable: 4505) // unreferenced local function has been removed -#pragma warning(disable : 4514) -#pragma warning(disable : 4702) // unreachable code -#pragma warning(disable : 4711) // selected for automatic inline expansion -#pragma warning(disable : 4220) // varargs matches remaining parameters -#pragma warning(disable : 4761) // integral size mismatch -#endif - -/* Include auto-config file to find out which system include files we need. */ - -#include "../jpeg-6/jconfig.h" /* auto configuration options */ -#define JCONFIG_INCLUDED /* so that jpeglib.h doesn't do it again */ - -/* - * We need the NULL macro and size_t typedef. - * On an ANSI-conforming system it is sufficient to include . - * Otherwise, we get them from or ; we may have to - * pull in as well. - * Note that the core JPEG library does not require ; - * only the default error handler and data source/destination modules do. - * But we must pull it in because of the references to FILE in jpeglib.h. - * You can remove those references if you want to compile without . - */ - -#ifdef HAVE_STDDEF_H -#include -#endif - -#ifdef HAVE_STDLIB_H -#include -#endif - -#ifdef NEED_SYS_TYPES_H -#include -#endif - -#include - -/* - * We need memory copying and zeroing functions, plus strncpy(). - * ANSI and System V implementations declare these in . - * BSD doesn't have the mem() functions, but it does have bcopy()/bzero(). - * Some systems may declare memset and memcpy in . - * - * NOTE: we assume the size parameters to these functions are of type size_t. - * Change the casts in these macros if not! - */ - -#ifdef NEED_BSD_STRINGS - -#include -#define MEMZERO(target,size) bzero((void *)(target), (size_t)(size)) -#define MEMCOPY(dest,src,size) bcopy((const void *)(src), (void *)(dest), (size_t)(size)) - -#else /* not BSD, assume ANSI/SysV string lib */ - -#include -#define MEMZERO(target,size) memset((void *)(target), 0, (size_t)(size)) -#define MEMCOPY(dest,src,size) memcpy((void *)(dest), (const void *)(src), (size_t)(size)) - -#endif - -/* - * In ANSI C, and indeed any rational implementation, size_t is also the - * type returned by sizeof(). However, it seems there are some irrational - * implementations out there, in which sizeof() returns an int even though - * size_t is defined as long or unsigned long. To ensure consistent results - * we always use this SIZEOF() macro in place of using sizeof() directly. - */ - -#define SIZEOF(object) ((size_t) sizeof(object)) - -/* - * The modules that use fread() and fwrite() always invoke them through - * these macros. On some systems you may need to twiddle the argument casts. - * CAUTION: argument order is different from underlying functions! - */ - -#define JFREAD(file,buf,sizeofbuf) \ - ((size_t) fread((void *) (buf), (size_t) 1, (size_t) (sizeofbuf), (file))) -#define JFWRITE(file,buf,sizeofbuf) \ - ((size_t) fwrite((const void *) (buf), (size_t) 1, (size_t) (sizeofbuf), (file))) diff --git a/engine/jpeg-6/jload.c b/engine/jpeg-6/jload.c deleted file mode 100644 index dc82555..0000000 --- a/engine/jpeg-6/jload.c +++ /dev/null @@ -1,145 +0,0 @@ - -#include "../game/q_shared.h" -#include "../qcommon/qcommon.h" - -/* - * Include file for users of JPEG library. - * You will need to have included system headers that define at least - * the typedefs FILE and size_t before you can include jpeglib.h. - * (stdio.h is sufficient on ANSI-conforming systems.) - * You may also wish to include "jerror.h". - */ - -#include "jpeglib.h" - - -int LoadJPG( const char *filename, unsigned char **pic, int *width, int *height ) { - /* This struct contains the JPEG decompression parameters and pointers to - * working space (which is allocated as needed by the JPEG library). - */ - struct jpeg_decompress_struct cinfo; - /* We use our private extension JPEG error handler. - * Note that this struct must live as long as the main JPEG parameter - * struct, to avoid dangling-pointer problems. - */ - /* This struct represents a JPEG error handler. It is declared separately - * because applications often want to supply a specialized error handler - * (see the second half of this file for an example). But here we just - * take the easy way out and use the standard error handler, which will - * print a message on stderr and call exit() if compression fails. - * Note that this struct must live as long as the main JPEG parameter - * struct, to avoid dangling-pointer problems. - */ - struct jpeg_error_mgr jerr; - /* More stuff */ - fileHandle_t infile; /* source file */ - JSAMPARRAY buffer; /* Output row buffer */ - int row_stride; /* physical row width in output buffer */ - unsigned char *out; - - /* In this example we want to open the input file before doing anything else, - * so that the setjmp() error recovery below can assume the file is open. - * VERY IMPORTANT: use "b" option to fopen() if you are on a machine that - * requires it in order to read binary files. - */ - - FS_FOpenFileRead( filename, &infile, qfalse ); - if (infile == 0) { - return 0; - } - - /* Step 1: allocate and initialize JPEG decompression object */ - - /* We have to set up the error handler first, in case the initialization - * step fails. (Unlikely, but it could happen if you are out of memory.) - * This routine fills in the contents of struct jerr, and returns jerr's - * address which we place into the link field in cinfo. - */ - cinfo.err = jpeg_std_error(&jerr); - - /* Now we can initialize the JPEG decompression object. */ - jpeg_create_decompress(&cinfo); - - /* Step 2: specify data source (eg, a file) */ - - jpeg_stdio_src(&cinfo, infile); - - /* Step 3: read file parameters with jpeg_read_header() */ - - (void) jpeg_read_header(&cinfo, TRUE); - /* We can ignore the return value from jpeg_read_header since - * (a) suspension is not possible with the stdio data source, and - * (b) we passed TRUE to reject a tables-only JPEG file as an error. - * See libjpeg.doc for more info. - */ - - /* Step 4: set parameters for decompression */ - - /* In this example, we don't need to change any of the defaults set by - * jpeg_read_header(), so we do nothing here. - */ - - /* Step 5: Start decompressor */ - - (void) jpeg_start_decompress(&cinfo); - /* We can ignore the return value since suspension is not possible - * with the stdio data source. - */ - - /* We may need to do some setup of our own at this point before reading - * the data. After jpeg_start_decompress() we have the correct scaled - * output image dimensions available, as well as the output colormap - * if we asked for color quantization. - * In this example, we need to make an output work buffer of the right size. - */ - /* JSAMPLEs per row in output buffer */ - row_stride = cinfo.output_width * cinfo.output_components; - - out = Z_Malloc(cinfo.output_width*cinfo.output_height*cinfo.output_components); - - *pic = out; - *width = cinfo.output_width; - *height = cinfo.output_height; - - /* Step 6: while (scan lines remain to be read) */ - /* jpeg_read_scanlines(...); */ - - /* Here we use the library's state variable cinfo.output_scanline as the - * loop counter, so that we don't have to keep track ourselves. - */ - while (cinfo.output_scanline < cinfo.output_height) { - /* jpeg_read_scanlines expects an array of pointers to scanlines. - * Here the array is only one element long, but you could ask for - * more than one scanline at a time if that's more convenient. - */ - buffer = (JSAMPARRAY)out+(row_stride*cinfo.output_scanline); - (void) jpeg_read_scanlines(&cinfo, buffer, 1); - } - - /* Step 7: Finish decompression */ - - (void) jpeg_finish_decompress(&cinfo); - /* We can ignore the return value since suspension is not possible - * with the stdio data source. - */ - - /* Step 8: Release JPEG decompression object */ - - /* This is an important step since it will release a good deal of memory. */ - jpeg_destroy_decompress(&cinfo); - - /* After finish_decompress, we can close the input file. - * Here we postpone it until after no more JPEG errors are possible, - * so as to simplify the setjmp error logic above. (Actually, I don't - * think that jpeg_destroy can do an error exit, but why assume anything...) - */ - FS_FCloseFile(infile); - - /* At this point you may want to check to see whether any corrupt-data - * warnings occurred (test whether jerr.pub.num_warnings is nonzero). - */ - - /* And we're done! */ - return 1; -} - diff --git a/engine/jpeg-6/jmemansi.c b/engine/jpeg-6/jmemansi.c deleted file mode 100644 index 70010f9..0000000 --- a/engine/jpeg-6/jmemansi.c +++ /dev/null @@ -1,167 +0,0 @@ -/* - * jmemansi.c - * - * Copyright (C) 1992-1994, Thomas G. Lane. - * This file is part of the Independent JPEG Group's software. - * For conditions of distribution and use, see the accompanying README file. - * - * This file provides a simple generic implementation of the system- - * dependent portion of the JPEG memory manager. This implementation - * assumes that you have the ANSI-standard library routine tmpfile(). - * Also, the problem of determining the amount of memory available - * is shoved onto the user. - */ - -#define JPEG_INTERNALS -#include "jinclude.h" -#include "jpeglib.h" -#include "jmemsys.h" /* import the system-dependent declarations */ - -#ifndef HAVE_STDLIB_H /* should declare malloc(),free() */ -extern void * malloc JPP((size_t size)); -extern void free JPP((void *ptr)); -#endif - -#ifndef SEEK_SET /* pre-ANSI systems may not define this; */ -#define SEEK_SET 0 /* if not, assume 0 is correct */ -#endif - - -/* - * Memory allocation and freeing are controlled by the regular library - * routines malloc() and free(). - */ - -GLOBAL void * -jpeg_get_small (j_common_ptr cinfo, size_t sizeofobject) -{ - return (void *) malloc(sizeofobject); -} - -GLOBAL void -jpeg_free_small (j_common_ptr cinfo, void * object, size_t sizeofobject) -{ - free(object); -} - - -/* - * "Large" objects are treated the same as "small" ones. - * NB: although we include FAR keywords in the routine declarations, - * this file won't actually work in 80x86 small/medium model; at least, - * you probably won't be able to process useful-size images in only 64KB. - */ - -GLOBAL void FAR * -jpeg_get_large (j_common_ptr cinfo, size_t sizeofobject) -{ - return (void FAR *) malloc(sizeofobject); -} - -GLOBAL void -jpeg_free_large (j_common_ptr cinfo, void FAR * object, size_t sizeofobject) -{ - free(object); -} - - -/* - * This routine computes the total memory space available for allocation. - * It's impossible to do this in a portable way; our current solution is - * to make the user tell us (with a default value set at compile time). - * If you can actually get the available space, it's a good idea to subtract - * a slop factor of 5% or so. - */ - -#ifndef DEFAULT_MAX_MEM /* so can override from makefile */ -#define DEFAULT_MAX_MEM 1000000L /* default: one megabyte */ -#endif - -GLOBAL long -jpeg_mem_available (j_common_ptr cinfo, long min_bytes_needed, - long max_bytes_needed, long already_allocated) -{ - return cinfo->mem->max_memory_to_use - already_allocated; -} - - -/* - * Backing store (temporary file) management. - * Backing store objects are only used when the value returned by - * jpeg_mem_available is less than the total space needed. You can dispense - * with these routines if you have plenty of virtual memory; see jmemnobs.c. - */ - - -METHODDEF void -read_backing_store (j_common_ptr cinfo, backing_store_ptr info, - void FAR * buffer_address, - long file_offset, long byte_count) -{ - if (fseek(info->temp_file, file_offset, SEEK_SET)) - ERREXIT(cinfo, JERR_TFILE_SEEK); - if (JFREAD(info->temp_file, buffer_address, byte_count) - != (size_t) byte_count) - ERREXIT(cinfo, JERR_TFILE_READ); -} - - -METHODDEF void -write_backing_store (j_common_ptr cinfo, backing_store_ptr info, - void FAR * buffer_address, - long file_offset, long byte_count) -{ - if (fseek(info->temp_file, file_offset, SEEK_SET)) - ERREXIT(cinfo, JERR_TFILE_SEEK); - if (JFWRITE(info->temp_file, buffer_address, byte_count) - != (size_t) byte_count) - ERREXIT(cinfo, JERR_TFILE_WRITE); -} - - -METHODDEF void -close_backing_store (j_common_ptr cinfo, backing_store_ptr info) -{ - fclose(info->temp_file); - /* Since this implementation uses tmpfile() to create the file, - * no explicit file deletion is needed. - */ -} - - -/* - * Initial opening of a backing-store object. - * - * This version uses tmpfile(), which constructs a suitable file name - * behind the scenes. We don't have to use info->temp_name[] at all; - * indeed, we can't even find out the actual name of the temp file. - */ - -GLOBAL void -jpeg_open_backing_store (j_common_ptr cinfo, backing_store_ptr info, - long total_bytes_needed) -{ - if ((info->temp_file = tmpfile()) == NULL) - ERREXITS(cinfo, JERR_TFILE_CREATE, ""); - info->read_backing_store = read_backing_store; - info->write_backing_store = write_backing_store; - info->close_backing_store = close_backing_store; -} - - -/* - * These routines take care of any system-dependent initialization and - * cleanup required. - */ - -GLOBAL long -jpeg_mem_init (j_common_ptr cinfo) -{ - return DEFAULT_MAX_MEM; /* default for max_memory_to_use */ -} - -GLOBAL void -jpeg_mem_term (j_common_ptr cinfo) -{ - /* no work */ -} diff --git a/engine/jpeg-6/jmemdos.c b/engine/jpeg-6/jmemdos.c deleted file mode 100644 index 4db8ec5..0000000 --- a/engine/jpeg-6/jmemdos.c +++ /dev/null @@ -1,634 +0,0 @@ -/* - * jmemdos.c - * - * Copyright (C) 1992-1994, Thomas G. Lane. - * This file is part of the Independent JPEG Group's software. - * For conditions of distribution and use, see the accompanying README file. - * - * This file provides an MS-DOS-compatible implementation of the system- - * dependent portion of the JPEG memory manager. Temporary data can be - * stored in extended or expanded memory as well as in regular DOS files. - * - * If you use this file, you must be sure that NEED_FAR_POINTERS is defined - * if you compile in a small-data memory model; it should NOT be defined if - * you use a large-data memory model. This file is not recommended if you - * are using a flat-memory-space 386 environment such as DJGCC or Watcom C. - * Also, this code will NOT work if struct fields are aligned on greater than - * 2-byte boundaries. - * - * Based on code contributed by Ge' Weijers. - */ - -/* - * If you have both extended and expanded memory, you may want to change the - * order in which they are tried in jopen_backing_store. On a 286 machine - * expanded memory is usually faster, since extended memory access involves - * an expensive protected-mode-and-back switch. On 386 and better, extended - * memory is usually faster. As distributed, the code tries extended memory - * first (what? not everyone has a 386? :-). - * - * You can disable use of extended/expanded memory entirely by altering these - * definitions or overriding them from the Makefile (eg, -DEMS_SUPPORTED=0). - */ - -#ifndef XMS_SUPPORTED -#define XMS_SUPPORTED 1 -#endif -#ifndef EMS_SUPPORTED -#define EMS_SUPPORTED 1 -#endif - - -#define JPEG_INTERNALS -#include "jinclude.h" -#include "jpeglib.h" -#include "jmemsys.h" /* import the system-dependent declarations */ - -#ifndef HAVE_STDLIB_H /* should declare these */ -extern void * malloc JPP((size_t size)); -extern void free JPP((void *ptr)); -extern char * getenv JPP((const char * name)); -#endif - -#ifdef NEED_FAR_POINTERS - -#ifdef __TURBOC__ -/* These definitions work for Borland C (Turbo C) */ -#include /* need farmalloc(), farfree() */ -#define far_malloc(x) farmalloc(x) -#define far_free(x) farfree(x) -#else -/* These definitions work for Microsoft C and compatible compilers */ -#include /* need _fmalloc(), _ffree() */ -#define far_malloc(x) _fmalloc(x) -#define far_free(x) _ffree(x) -#endif - -#else /* not NEED_FAR_POINTERS */ - -#define far_malloc(x) malloc(x) -#define far_free(x) free(x) - -#endif /* NEED_FAR_POINTERS */ - -#ifdef DONT_USE_B_MODE /* define mode parameters for fopen() */ -#define READ_BINARY "r" -#else -#define READ_BINARY "rb" -#endif - -#if MAX_ALLOC_CHUNK >= 65535L /* make sure jconfig.h got this right */ - MAX_ALLOC_CHUNK should be less than 64K. /* deliberate syntax error */ -#endif - - -/* - * Declarations for assembly-language support routines (see jmemdosa.asm). - * - * The functions are declared "far" as are all pointer arguments; - * this ensures the assembly source code will work regardless of the - * compiler memory model. We assume "short" is 16 bits, "long" is 32. - */ - -typedef void far * XMSDRIVER; /* actually a pointer to code */ -typedef struct { /* registers for calling XMS driver */ - unsigned short ax, dx, bx; - void far * ds_si; - } XMScontext; -typedef struct { /* registers for calling EMS driver */ - unsigned short ax, dx, bx; - void far * ds_si; - } EMScontext; - -EXTERN short far jdos_open JPP((short far * handle, char far * filename)); -EXTERN short far jdos_close JPP((short handle)); -EXTERN short far jdos_seek JPP((short handle, long offset)); -EXTERN short far jdos_read JPP((short handle, void far * buffer, - unsigned short count)); -EXTERN short far jdos_write JPP((short handle, void far * buffer, - unsigned short count)); -EXTERN void far jxms_getdriver JPP((XMSDRIVER far *)); -EXTERN void far jxms_calldriver JPP((XMSDRIVER, XMScontext far *)); -EXTERN short far jems_available JPP((void)); -EXTERN void far jems_calldriver JPP((EMScontext far *)); - - -/* - * Selection of a file name for a temporary file. - * This is highly system-dependent, and you may want to customize it. - */ - -static int next_file_num; /* to distinguish among several temp files */ - -LOCAL void -select_file_name (char * fname) -{ - const char * env; - char * ptr; - FILE * tfile; - - /* Keep generating file names till we find one that's not in use */ - for (;;) { - /* Get temp directory name from environment TMP or TEMP variable; - * if none, use "." - */ - if ((env = (const char *) getenv("TMP")) == NULL) - if ((env = (const char *) getenv("TEMP")) == NULL) - env = "."; - if (*env == '\0') /* null string means "." */ - env = "."; - ptr = fname; /* copy name to fname */ - while (*env != '\0') - *ptr++ = *env++; - if (ptr[-1] != '\\' && ptr[-1] != '/') - *ptr++ = '\\'; /* append backslash if not in env variable */ - /* Append a suitable file name */ - next_file_num++; /* advance counter */ - sprintf(ptr, "JPG%03d.TMP", next_file_num); - /* Probe to see if file name is already in use */ - if ((tfile = fopen(fname, READ_BINARY)) == NULL) - break; - fclose(tfile); /* oops, it's there; close tfile & try again */ - } -} - - -/* - * Near-memory allocation and freeing are controlled by the regular library - * routines malloc() and free(). - */ - -GLOBAL void * -jpeg_get_small (j_common_ptr cinfo, size_t sizeofobject) -{ - return (void *) malloc(sizeofobject); -} - -GLOBAL void -jpeg_free_small (j_common_ptr cinfo, void * object, size_t sizeofobject) -{ - free(object); -} - - -/* - * "Large" objects are allocated in far memory, if possible - */ - -GLOBAL void FAR * -jpeg_get_large (j_common_ptr cinfo, size_t sizeofobject) -{ - return (void FAR *) far_malloc(sizeofobject); -} - -GLOBAL void -jpeg_free_large (j_common_ptr cinfo, void FAR * object, size_t sizeofobject) -{ - far_free(object); -} - - -/* - * This routine computes the total memory space available for allocation. - * It's impossible to do this in a portable way; our current solution is - * to make the user tell us (with a default value set at compile time). - * If you can actually get the available space, it's a good idea to subtract - * a slop factor of 5% or so. - */ - -#ifndef DEFAULT_MAX_MEM /* so can override from makefile */ -#define DEFAULT_MAX_MEM 300000L /* for total usage about 450K */ -#endif - -GLOBAL long -jpeg_mem_available (j_common_ptr cinfo, long min_bytes_needed, - long max_bytes_needed, long already_allocated) -{ - return cinfo->mem->max_memory_to_use - already_allocated; -} - - -/* - * Backing store (temporary file) management. - * Backing store objects are only used when the value returned by - * jpeg_mem_available is less than the total space needed. You can dispense - * with these routines if you have plenty of virtual memory; see jmemnobs.c. - */ - -/* - * For MS-DOS we support three types of backing storage: - * 1. Conventional DOS files. We access these by direct DOS calls rather - * than via the stdio package. This provides a bit better performance, - * but the real reason is that the buffers to be read or written are FAR. - * The stdio library for small-data memory models can't cope with that. - * 2. Extended memory, accessed per the XMS V2.0 specification. - * 3. Expanded memory, accessed per the LIM/EMS 4.0 specification. - * You'll need copies of those specs to make sense of the related code. - * The specs are available by Internet FTP from the SIMTEL archives - * (oak.oakland.edu and its various mirror sites). See files - * pub/msdos/microsoft/xms20.arc and pub/msdos/info/limems41.zip. - */ - - -/* - * Access methods for a DOS file. - */ - - -METHODDEF void -read_file_store (j_common_ptr cinfo, backing_store_ptr info, - void FAR * buffer_address, - long file_offset, long byte_count) -{ - if (jdos_seek(info->handle.file_handle, file_offset)) - ERREXIT(cinfo, JERR_TFILE_SEEK); - /* Since MAX_ALLOC_CHUNK is less than 64K, byte_count will be too. */ - if (byte_count > 65535L) /* safety check */ - ERREXIT(cinfo, JERR_BAD_ALLOC_CHUNK); - if (jdos_read(info->handle.file_handle, buffer_address, - (unsigned short) byte_count)) - ERREXIT(cinfo, JERR_TFILE_READ); -} - - -METHODDEF void -write_file_store (j_common_ptr cinfo, backing_store_ptr info, - void FAR * buffer_address, - long file_offset, long byte_count) -{ - if (jdos_seek(info->handle.file_handle, file_offset)) - ERREXIT(cinfo, JERR_TFILE_SEEK); - /* Since MAX_ALLOC_CHUNK is less than 64K, byte_count will be too. */ - if (byte_count > 65535L) /* safety check */ - ERREXIT(cinfo, JERR_BAD_ALLOC_CHUNK); - if (jdos_write(info->handle.file_handle, buffer_address, - (unsigned short) byte_count)) - ERREXIT(cinfo, JERR_TFILE_WRITE); -} - - -METHODDEF void -close_file_store (j_common_ptr cinfo, backing_store_ptr info) -{ - jdos_close(info->handle.file_handle); /* close the file */ - remove(info->temp_name); /* delete the file */ -/* If your system doesn't have remove(), try unlink() instead. - * remove() is the ANSI-standard name for this function, but - * unlink() was more common in pre-ANSI systems. - */ - TRACEMSS(cinfo, 1, JTRC_TFILE_CLOSE, info->temp_name); -} - - -LOCAL boolean -open_file_store (j_common_ptr cinfo, backing_store_ptr info, - long total_bytes_needed) -{ - short handle; - - select_file_name(info->temp_name); - if (jdos_open((short far *) & handle, (char far *) info->temp_name)) { - /* might as well exit since jpeg_open_backing_store will fail anyway */ - ERREXITS(cinfo, JERR_TFILE_CREATE, info->temp_name); - return FALSE; - } - info->handle.file_handle = handle; - info->read_backing_store = read_file_store; - info->write_backing_store = write_file_store; - info->close_backing_store = close_file_store; - TRACEMSS(cinfo, 1, JTRC_TFILE_OPEN, info->temp_name); - return TRUE; /* succeeded */ -} - - -/* - * Access methods for extended memory. - */ - -#if XMS_SUPPORTED - -static XMSDRIVER xms_driver; /* saved address of XMS driver */ - -typedef union { /* either long offset or real-mode pointer */ - long offset; - void far * ptr; - } XMSPTR; - -typedef struct { /* XMS move specification structure */ - long length; - XMSH src_handle; - XMSPTR src; - XMSH dst_handle; - XMSPTR dst; - } XMSspec; - -#define ODD(X) (((X) & 1L) != 0) - - -METHODDEF void -read_xms_store (j_common_ptr cinfo, backing_store_ptr info, - void FAR * buffer_address, - long file_offset, long byte_count) -{ - XMScontext ctx; - XMSspec spec; - char endbuffer[2]; - - /* The XMS driver can't cope with an odd length, so handle the last byte - * specially if byte_count is odd. We don't expect this to be common. - */ - - spec.length = byte_count & (~ 1L); - spec.src_handle = info->handle.xms_handle; - spec.src.offset = file_offset; - spec.dst_handle = 0; - spec.dst.ptr = buffer_address; - - ctx.ds_si = (void far *) & spec; - ctx.ax = 0x0b00; /* EMB move */ - jxms_calldriver(xms_driver, (XMScontext far *) & ctx); - if (ctx.ax != 1) - ERREXIT(cinfo, JERR_XMS_READ); - - if (ODD(byte_count)) { - read_xms_store(cinfo, info, (void FAR *) endbuffer, - file_offset + byte_count - 1L, 2L); - ((char FAR *) buffer_address)[byte_count - 1L] = endbuffer[0]; - } -} - - -METHODDEF void -write_xms_store (j_common_ptr cinfo, backing_store_ptr info, - void FAR * buffer_address, - long file_offset, long byte_count) -{ - XMScontext ctx; - XMSspec spec; - char endbuffer[2]; - - /* The XMS driver can't cope with an odd length, so handle the last byte - * specially if byte_count is odd. We don't expect this to be common. - */ - - spec.length = byte_count & (~ 1L); - spec.src_handle = 0; - spec.src.ptr = buffer_address; - spec.dst_handle = info->handle.xms_handle; - spec.dst.offset = file_offset; - - ctx.ds_si = (void far *) & spec; - ctx.ax = 0x0b00; /* EMB move */ - jxms_calldriver(xms_driver, (XMScontext far *) & ctx); - if (ctx.ax != 1) - ERREXIT(cinfo, JERR_XMS_WRITE); - - if (ODD(byte_count)) { - read_xms_store(cinfo, info, (void FAR *) endbuffer, - file_offset + byte_count - 1L, 2L); - endbuffer[0] = ((char FAR *) buffer_address)[byte_count - 1L]; - write_xms_store(cinfo, info, (void FAR *) endbuffer, - file_offset + byte_count - 1L, 2L); - } -} - - -METHODDEF void -close_xms_store (j_common_ptr cinfo, backing_store_ptr info) -{ - XMScontext ctx; - - ctx.dx = info->handle.xms_handle; - ctx.ax = 0x0a00; - jxms_calldriver(xms_driver, (XMScontext far *) & ctx); - TRACEMS1(cinfo, 1, JTRC_XMS_CLOSE, info->handle.xms_handle); - /* we ignore any error return from the driver */ -} - - -LOCAL boolean -open_xms_store (j_common_ptr cinfo, backing_store_ptr info, - long total_bytes_needed) -{ - XMScontext ctx; - - /* Get address of XMS driver */ - jxms_getdriver((XMSDRIVER far *) & xms_driver); - if (xms_driver == NULL) - return FALSE; /* no driver to be had */ - - /* Get version number, must be >= 2.00 */ - ctx.ax = 0x0000; - jxms_calldriver(xms_driver, (XMScontext far *) & ctx); - if (ctx.ax < (unsigned short) 0x0200) - return FALSE; - - /* Try to get space (expressed in kilobytes) */ - ctx.dx = (unsigned short) ((total_bytes_needed + 1023L) >> 10); - ctx.ax = 0x0900; - jxms_calldriver(xms_driver, (XMScontext far *) & ctx); - if (ctx.ax != 1) - return FALSE; - - /* Succeeded, save the handle and away we go */ - info->handle.xms_handle = ctx.dx; - info->read_backing_store = read_xms_store; - info->write_backing_store = write_xms_store; - info->close_backing_store = close_xms_store; - TRACEMS1(cinfo, 1, JTRC_XMS_OPEN, ctx.dx); - return TRUE; /* succeeded */ -} - -#endif /* XMS_SUPPORTED */ - - -/* - * Access methods for expanded memory. - */ - -#if EMS_SUPPORTED - -/* The EMS move specification structure requires word and long fields aligned - * at odd byte boundaries. Some compilers will align struct fields at even - * byte boundaries. While it's usually possible to force byte alignment, - * that causes an overall performance penalty and may pose problems in merging - * JPEG into a larger application. Instead we accept some rather dirty code - * here. Note this code would fail if the hardware did not allow odd-byte - * word & long accesses, but all 80x86 CPUs do. - */ - -typedef void far * EMSPTR; - -typedef union { /* EMS move specification structure */ - long length; /* It's easy to access first 4 bytes */ - char bytes[18]; /* Misaligned fields in here! */ - } EMSspec; - -/* Macros for accessing misaligned fields */ -#define FIELD_AT(spec,offset,type) (*((type *) &(spec.bytes[offset]))) -#define SRC_TYPE(spec) FIELD_AT(spec,4,char) -#define SRC_HANDLE(spec) FIELD_AT(spec,5,EMSH) -#define SRC_OFFSET(spec) FIELD_AT(spec,7,unsigned short) -#define SRC_PAGE(spec) FIELD_AT(spec,9,unsigned short) -#define SRC_PTR(spec) FIELD_AT(spec,7,EMSPTR) -#define DST_TYPE(spec) FIELD_AT(spec,11,char) -#define DST_HANDLE(spec) FIELD_AT(spec,12,EMSH) -#define DST_OFFSET(spec) FIELD_AT(spec,14,unsigned short) -#define DST_PAGE(spec) FIELD_AT(spec,16,unsigned short) -#define DST_PTR(spec) FIELD_AT(spec,14,EMSPTR) - -#define EMSPAGESIZE 16384L /* gospel, see the EMS specs */ - -#define HIBYTE(W) (((W) >> 8) & 0xFF) -#define LOBYTE(W) ((W) & 0xFF) - - -METHODDEF void -read_ems_store (j_common_ptr cinfo, backing_store_ptr info, - void FAR * buffer_address, - long file_offset, long byte_count) -{ - EMScontext ctx; - EMSspec spec; - - spec.length = byte_count; - SRC_TYPE(spec) = 1; - SRC_HANDLE(spec) = info->handle.ems_handle; - SRC_PAGE(spec) = (unsigned short) (file_offset / EMSPAGESIZE); - SRC_OFFSET(spec) = (unsigned short) (file_offset % EMSPAGESIZE); - DST_TYPE(spec) = 0; - DST_HANDLE(spec) = 0; - DST_PTR(spec) = buffer_address; - - ctx.ds_si = (void far *) & spec; - ctx.ax = 0x5700; /* move memory region */ - jems_calldriver((EMScontext far *) & ctx); - if (HIBYTE(ctx.ax) != 0) - ERREXIT(cinfo, JERR_EMS_READ); -} - - -METHODDEF void -write_ems_store (j_common_ptr cinfo, backing_store_ptr info, - void FAR * buffer_address, - long file_offset, long byte_count) -{ - EMScontext ctx; - EMSspec spec; - - spec.length = byte_count; - SRC_TYPE(spec) = 0; - SRC_HANDLE(spec) = 0; - SRC_PTR(spec) = buffer_address; - DST_TYPE(spec) = 1; - DST_HANDLE(spec) = info->handle.ems_handle; - DST_PAGE(spec) = (unsigned short) (file_offset / EMSPAGESIZE); - DST_OFFSET(spec) = (unsigned short) (file_offset % EMSPAGESIZE); - - ctx.ds_si = (void far *) & spec; - ctx.ax = 0x5700; /* move memory region */ - jems_calldriver((EMScontext far *) & ctx); - if (HIBYTE(ctx.ax) != 0) - ERREXIT(cinfo, JERR_EMS_WRITE); -} - - -METHODDEF void -close_ems_store (j_common_ptr cinfo, backing_store_ptr info) -{ - EMScontext ctx; - - ctx.ax = 0x4500; - ctx.dx = info->handle.ems_handle; - jems_calldriver((EMScontext far *) & ctx); - TRACEMS1(cinfo, 1, JTRC_EMS_CLOSE, info->handle.ems_handle); - /* we ignore any error return from the driver */ -} - - -LOCAL boolean -open_ems_store (j_common_ptr cinfo, backing_store_ptr info, - long total_bytes_needed) -{ - EMScontext ctx; - - /* Is EMS driver there? */ - if (! jems_available()) - return FALSE; - - /* Get status, make sure EMS is OK */ - ctx.ax = 0x4000; - jems_calldriver((EMScontext far *) & ctx); - if (HIBYTE(ctx.ax) != 0) - return FALSE; - - /* Get version, must be >= 4.0 */ - ctx.ax = 0x4600; - jems_calldriver((EMScontext far *) & ctx); - if (HIBYTE(ctx.ax) != 0 || LOBYTE(ctx.ax) < 0x40) - return FALSE; - - /* Try to allocate requested space */ - ctx.ax = 0x4300; - ctx.bx = (unsigned short) ((total_bytes_needed + EMSPAGESIZE-1L) / EMSPAGESIZE); - jems_calldriver((EMScontext far *) & ctx); - if (HIBYTE(ctx.ax) != 0) - return FALSE; - - /* Succeeded, save the handle and away we go */ - info->handle.ems_handle = ctx.dx; - info->read_backing_store = read_ems_store; - info->write_backing_store = write_ems_store; - info->close_backing_store = close_ems_store; - TRACEMS1(cinfo, 1, JTRC_EMS_OPEN, ctx.dx); - return TRUE; /* succeeded */ -} - -#endif /* EMS_SUPPORTED */ - - -/* - * Initial opening of a backing-store object. - */ - -GLOBAL void -jpeg_open_backing_store (j_common_ptr cinfo, backing_store_ptr info, - long total_bytes_needed) -{ - /* Try extended memory, then expanded memory, then regular file. */ -#if XMS_SUPPORTED - if (open_xms_store(cinfo, info, total_bytes_needed)) - return; -#endif -#if EMS_SUPPORTED - if (open_ems_store(cinfo, info, total_bytes_needed)) - return; -#endif - if (open_file_store(cinfo, info, total_bytes_needed)) - return; - ERREXITS(cinfo, JERR_TFILE_CREATE, ""); -} - - -/* - * These routines take care of any system-dependent initialization and - * cleanup required. - */ - -GLOBAL long -jpeg_mem_init (j_common_ptr cinfo) -{ - next_file_num = 0; /* initialize temp file name generator */ - return DEFAULT_MAX_MEM; /* default for max_memory_to_use */ -} - -GLOBAL void -jpeg_mem_term (j_common_ptr cinfo) -{ - /* Microsoft C, at least in v6.00A, will not successfully reclaim freed - * blocks of size > 32Kbytes unless we give it a kick in the rear, like so: - */ -#ifdef NEED_FHEAPMIN - _fheapmin(); -#endif -} diff --git a/engine/jpeg-6/jmemmgr.c b/engine/jpeg-6/jmemmgr.c deleted file mode 100644 index dc3e1c7..0000000 --- a/engine/jpeg-6/jmemmgr.c +++ /dev/null @@ -1,1115 +0,0 @@ -/* - * jmemmgr.c - * - * Copyright (C) 1991-1995, Thomas G. Lane. - * This file is part of the Independent JPEG Group's software. - * For conditions of distribution and use, see the accompanying README file. - * - * This file contains the JPEG system-independent memory management - * routines. This code is usable across a wide variety of machines; most - * of the system dependencies have been isolated in a separate file. - * The major functions provided here are: - * * pool-based allocation and freeing of memory; - * * policy decisions about how to divide available memory among the - * virtual arrays; - * * control logic for swapping virtual arrays between main memory and - * backing storage. - * The separate system-dependent file provides the actual backing-storage - * access code, and it contains the policy decision about how much total - * main memory to use. - * This file is system-dependent in the sense that some of its functions - * are unnecessary in some systems. For example, if there is enough virtual - * memory so that backing storage will never be used, much of the virtual - * array control logic could be removed. (Of course, if you have that much - * memory then you shouldn't care about a little bit of unused code...) - */ - -#define JPEG_INTERNALS -#define AM_MEMORY_MANAGER /* we define jvirt_Xarray_control structs */ -#include "jinclude.h" -#include "jpeglib.h" -#include "jmemsys.h" /* import the system-dependent declarations */ - -#ifndef NO_GETENV -#ifndef HAVE_STDLIB_H /* should declare getenv() */ -extern char * getenv JPP((const char * name)); -#endif -#endif - - -/* - * Some important notes: - * The allocation routines provided here must never return NULL. - * They should exit to error_exit if unsuccessful. - * - * It's not a good idea to try to merge the sarray and barray routines, - * even though they are textually almost the same, because samples are - * usually stored as bytes while coefficients are shorts or ints. Thus, - * in machines where byte pointers have a different representation from - * word pointers, the resulting machine code could not be the same. - */ - - -/* - * Many machines require storage alignment: longs must start on 4-byte - * boundaries, doubles on 8-byte boundaries, etc. On such machines, malloc() - * always returns pointers that are multiples of the worst-case alignment - * requirement, and we had better do so too. - * There isn't any really portable way to determine the worst-case alignment - * requirement. This module assumes that the alignment requirement is - * multiples of sizeof(ALIGN_TYPE). - * By default, we define ALIGN_TYPE as double. This is necessary on some - * workstations (where doubles really do need 8-byte alignment) and will work - * fine on nearly everything. If your machine has lesser alignment needs, - * you can save a few bytes by making ALIGN_TYPE smaller. - * The only place I know of where this will NOT work is certain Macintosh - * 680x0 compilers that define double as a 10-byte IEEE extended float. - * Doing 10-byte alignment is counterproductive because longwords won't be - * aligned well. Put "#define ALIGN_TYPE long" in jconfig.h if you have - * such a compiler. - */ - -#ifndef ALIGN_TYPE /* so can override from jconfig.h */ -#define ALIGN_TYPE double -#endif - - -/* - * We allocate objects from "pools", where each pool is gotten with a single - * request to jpeg_get_small() or jpeg_get_large(). There is no per-object - * overhead within a pool, except for alignment padding. Each pool has a - * header with a link to the next pool of the same class. - * Small and large pool headers are identical except that the latter's - * link pointer must be FAR on 80x86 machines. - * Notice that the "real" header fields are union'ed with a dummy ALIGN_TYPE - * field. This forces the compiler to make SIZEOF(small_pool_hdr) a multiple - * of the alignment requirement of ALIGN_TYPE. - */ - -typedef union small_pool_struct * small_pool_ptr; - -typedef union small_pool_struct { - struct { - small_pool_ptr next; /* next in list of pools */ - size_t bytes_used; /* how many bytes already used within pool */ - size_t bytes_left; /* bytes still available in this pool */ - } hdr; - ALIGN_TYPE dummy; /* included in union to ensure alignment */ -} small_pool_hdr; - -typedef union large_pool_struct FAR * large_pool_ptr; - -typedef union large_pool_struct { - struct { - large_pool_ptr next; /* next in list of pools */ - size_t bytes_used; /* how many bytes already used within pool */ - size_t bytes_left; /* bytes still available in this pool */ - } hdr; - ALIGN_TYPE dummy; /* included in union to ensure alignment */ -} large_pool_hdr; - - -/* - * Here is the full definition of a memory manager object. - */ - -typedef struct { - struct jpeg_memory_mgr pub; /* public fields */ - - /* Each pool identifier (lifetime class) names a linked list of pools. */ - small_pool_ptr small_list[JPOOL_NUMPOOLS]; - large_pool_ptr large_list[JPOOL_NUMPOOLS]; - - /* Since we only have one lifetime class of virtual arrays, only one - * linked list is necessary (for each datatype). Note that the virtual - * array control blocks being linked together are actually stored somewhere - * in the small-pool list. - */ - jvirt_sarray_ptr virt_sarray_list; - jvirt_barray_ptr virt_barray_list; - - /* This counts total space obtained from jpeg_get_small/large */ - long total_space_allocated; - - /* alloc_sarray and alloc_barray set this value for use by virtual - * array routines. - */ - JDIMENSION last_rowsperchunk; /* from most recent alloc_sarray/barray */ -} my_memory_mgr; - -typedef my_memory_mgr * my_mem_ptr; - - -/* - * The control blocks for virtual arrays. - * Note that these blocks are allocated in the "small" pool area. - * System-dependent info for the associated backing store (if any) is hidden - * inside the backing_store_info struct. - */ - -struct jvirt_sarray_control { - JSAMPARRAY mem_buffer; /* => the in-memory buffer */ - JDIMENSION rows_in_array; /* total virtual array height */ - JDIMENSION samplesperrow; /* width of array (and of memory buffer) */ - JDIMENSION maxaccess; /* max rows accessed by access_virt_sarray */ - JDIMENSION rows_in_mem; /* height of memory buffer */ - JDIMENSION rowsperchunk; /* allocation chunk size in mem_buffer */ - JDIMENSION cur_start_row; /* first logical row # in the buffer */ - JDIMENSION first_undef_row; /* row # of first uninitialized row */ - boolean pre_zero; /* pre-zero mode requested? */ - boolean dirty; /* do current buffer contents need written? */ - boolean b_s_open; /* is backing-store data valid? */ - jvirt_sarray_ptr next; /* link to next virtual sarray control block */ - backing_store_info b_s_info; /* System-dependent control info */ -}; - -struct jvirt_barray_control { - JBLOCKARRAY mem_buffer; /* => the in-memory buffer */ - JDIMENSION rows_in_array; /* total virtual array height */ - JDIMENSION blocksperrow; /* width of array (and of memory buffer) */ - JDIMENSION maxaccess; /* max rows accessed by access_virt_barray */ - JDIMENSION rows_in_mem; /* height of memory buffer */ - JDIMENSION rowsperchunk; /* allocation chunk size in mem_buffer */ - JDIMENSION cur_start_row; /* first logical row # in the buffer */ - JDIMENSION first_undef_row; /* row # of first uninitialized row */ - boolean pre_zero; /* pre-zero mode requested? */ - boolean dirty; /* do current buffer contents need written? */ - boolean b_s_open; /* is backing-store data valid? */ - jvirt_barray_ptr next; /* link to next virtual barray control block */ - backing_store_info b_s_info; /* System-dependent control info */ -}; - - -#ifdef MEM_STATS /* optional extra stuff for statistics */ - -LOCAL void -print_mem_stats (j_common_ptr cinfo, int pool_id) -{ - my_mem_ptr mem = (my_mem_ptr) cinfo->mem; - small_pool_ptr shdr_ptr; - large_pool_ptr lhdr_ptr; - - /* Since this is only a debugging stub, we can cheat a little by using - * fprintf directly rather than going through the trace message code. - * This is helpful because message parm array can't handle longs. - */ - fprintf(stderr, "Freeing pool %d, total space = %ld\n", - pool_id, mem->total_space_allocated); - - for (lhdr_ptr = mem->large_list[pool_id]; lhdr_ptr != NULL; - lhdr_ptr = lhdr_ptr->hdr.next) { - fprintf(stderr, " Large chunk used %ld\n", - (long) lhdr_ptr->hdr.bytes_used); - } - - for (shdr_ptr = mem->small_list[pool_id]; shdr_ptr != NULL; - shdr_ptr = shdr_ptr->hdr.next) { - fprintf(stderr, " Small chunk used %ld free %ld\n", - (long) shdr_ptr->hdr.bytes_used, - (long) shdr_ptr->hdr.bytes_left); - } -} - -#endif /* MEM_STATS */ - - -LOCAL void -out_of_memory (j_common_ptr cinfo, int which) -/* Report an out-of-memory error and stop execution */ -/* If we compiled MEM_STATS support, report alloc requests before dying */ -{ -#ifdef MEM_STATS - cinfo->err->trace_level = 2; /* force self_destruct to report stats */ -#endif - ERREXIT1(cinfo, JERR_OUT_OF_MEMORY, which); -} - - -/* - * Allocation of "small" objects. - * - * For these, we use pooled storage. When a new pool must be created, - * we try to get enough space for the current request plus a "slop" factor, - * where the slop will be the amount of leftover space in the new pool. - * The speed vs. space tradeoff is largely determined by the slop values. - * A different slop value is provided for each pool class (lifetime), - * and we also distinguish the first pool of a class from later ones. - * NOTE: the values given work fairly well on both 16- and 32-bit-int - * machines, but may be too small if longs are 64 bits or more. - */ - -static const size_t first_pool_slop[JPOOL_NUMPOOLS] = -{ - 1600, /* first PERMANENT pool */ - 16000 /* first IMAGE pool */ -}; - -static const size_t extra_pool_slop[JPOOL_NUMPOOLS] = -{ - 0, /* additional PERMANENT pools */ - 5000 /* additional IMAGE pools */ -}; - -#define MIN_SLOP 50 /* greater than 0 to avoid futile looping */ - - -METHODDEF void * -alloc_small (j_common_ptr cinfo, int pool_id, size_t sizeofobject) -/* Allocate a "small" object */ -{ - my_mem_ptr mem = (my_mem_ptr) cinfo->mem; - small_pool_ptr hdr_ptr, prev_hdr_ptr; - char * data_ptr; - size_t odd_bytes, min_request, slop; - - /* Check for unsatisfiable request (do now to ensure no overflow below) */ - if (sizeofobject > (size_t) (MAX_ALLOC_CHUNK-SIZEOF(small_pool_hdr))) - out_of_memory(cinfo, 1); /* request exceeds malloc's ability */ - - /* Round up the requested size to a multiple of SIZEOF(ALIGN_TYPE) */ - odd_bytes = sizeofobject % SIZEOF(ALIGN_TYPE); - if (odd_bytes > 0) - sizeofobject += SIZEOF(ALIGN_TYPE) - odd_bytes; - - /* See if space is available in any existing pool */ - if (pool_id < 0 || pool_id >= JPOOL_NUMPOOLS) - ERREXIT1(cinfo, JERR_BAD_POOL_ID, pool_id); /* safety check */ - prev_hdr_ptr = NULL; - hdr_ptr = mem->small_list[pool_id]; - while (hdr_ptr != NULL) { - if (hdr_ptr->hdr.bytes_left >= sizeofobject) - break; /* found pool with enough space */ - prev_hdr_ptr = hdr_ptr; - hdr_ptr = hdr_ptr->hdr.next; - } - - /* Time to make a new pool? */ - if (hdr_ptr == NULL) { - /* min_request is what we need now, slop is what will be leftover */ - min_request = sizeofobject + SIZEOF(small_pool_hdr); - if (prev_hdr_ptr == NULL) /* first pool in class? */ - slop = first_pool_slop[pool_id]; - else - slop = extra_pool_slop[pool_id]; - /* Don't ask for more than MAX_ALLOC_CHUNK */ - if (slop > (size_t) (MAX_ALLOC_CHUNK-min_request)) - slop = (size_t) (MAX_ALLOC_CHUNK-min_request); - /* Try to get space, if fail reduce slop and try again */ - for (;;) { - hdr_ptr = (small_pool_ptr) jpeg_get_small(cinfo, min_request + slop); - if (hdr_ptr != NULL) - break; - slop /= 2; - if (slop < MIN_SLOP) /* give up when it gets real small */ - out_of_memory(cinfo, 2); /* jpeg_get_small failed */ - } - mem->total_space_allocated += min_request + slop; - /* Success, initialize the new pool header and add to end of list */ - hdr_ptr->hdr.next = NULL; - hdr_ptr->hdr.bytes_used = 0; - hdr_ptr->hdr.bytes_left = sizeofobject + slop; - if (prev_hdr_ptr == NULL) /* first pool in class? */ - mem->small_list[pool_id] = hdr_ptr; - else - prev_hdr_ptr->hdr.next = hdr_ptr; - } - - /* OK, allocate the object from the current pool */ - data_ptr = (char *) (hdr_ptr + 1); /* point to first data byte in pool */ - data_ptr += hdr_ptr->hdr.bytes_used; /* point to place for object */ - hdr_ptr->hdr.bytes_used += sizeofobject; - hdr_ptr->hdr.bytes_left -= sizeofobject; - - return (void *) data_ptr; -} - - -/* - * Allocation of "large" objects. - * - * The external semantics of these are the same as "small" objects, - * except that FAR pointers are used on 80x86. However the pool - * management heuristics are quite different. We assume that each - * request is large enough that it may as well be passed directly to - * jpeg_get_large; the pool management just links everything together - * so that we can free it all on demand. - * Note: the major use of "large" objects is in JSAMPARRAY and JBLOCKARRAY - * structures. The routines that create these structures (see below) - * deliberately bunch rows together to ensure a large request size. - */ - -METHODDEF void FAR * -alloc_large (j_common_ptr cinfo, int pool_id, size_t sizeofobject) -/* Allocate a "large" object */ -{ - my_mem_ptr mem = (my_mem_ptr) cinfo->mem; - large_pool_ptr hdr_ptr; - size_t odd_bytes; - - /* Check for unsatisfiable request (do now to ensure no overflow below) */ - if (sizeofobject > (size_t) (MAX_ALLOC_CHUNK-SIZEOF(large_pool_hdr))) - out_of_memory(cinfo, 3); /* request exceeds malloc's ability */ - - /* Round up the requested size to a multiple of SIZEOF(ALIGN_TYPE) */ - odd_bytes = sizeofobject % SIZEOF(ALIGN_TYPE); - if (odd_bytes > 0) - sizeofobject += SIZEOF(ALIGN_TYPE) - odd_bytes; - - /* Always make a new pool */ - if (pool_id < 0 || pool_id >= JPOOL_NUMPOOLS) - ERREXIT1(cinfo, JERR_BAD_POOL_ID, pool_id); /* safety check */ - - hdr_ptr = (large_pool_ptr) jpeg_get_large(cinfo, sizeofobject + - SIZEOF(large_pool_hdr)); - if (hdr_ptr == NULL) - out_of_memory(cinfo, 4); /* jpeg_get_large failed */ - mem->total_space_allocated += sizeofobject + SIZEOF(large_pool_hdr); - - /* Success, initialize the new pool header and add to list */ - hdr_ptr->hdr.next = mem->large_list[pool_id]; - /* We maintain space counts in each pool header for statistical purposes, - * even though they are not needed for allocation. - */ - hdr_ptr->hdr.bytes_used = sizeofobject; - hdr_ptr->hdr.bytes_left = 0; - mem->large_list[pool_id] = hdr_ptr; - - return (void FAR *) (hdr_ptr + 1); /* point to first data byte in pool */ -} - - -/* - * Creation of 2-D sample arrays. - * The pointers are in near heap, the samples themselves in FAR heap. - * - * To minimize allocation overhead and to allow I/O of large contiguous - * blocks, we allocate the sample rows in groups of as many rows as possible - * without exceeding MAX_ALLOC_CHUNK total bytes per allocation request. - * NB: the virtual array control routines, later in this file, know about - * this chunking of rows. The rowsperchunk value is left in the mem manager - * object so that it can be saved away if this sarray is the workspace for - * a virtual array. - */ - -METHODDEF JSAMPARRAY -alloc_sarray (j_common_ptr cinfo, int pool_id, - JDIMENSION samplesperrow, JDIMENSION numrows) -/* Allocate a 2-D sample array */ -{ - my_mem_ptr mem = (my_mem_ptr) cinfo->mem; - JSAMPARRAY result; - JSAMPROW workspace; - JDIMENSION rowsperchunk, currow, i; - long ltemp; - - /* Calculate max # of rows allowed in one allocation chunk */ - ltemp = (MAX_ALLOC_CHUNK-SIZEOF(large_pool_hdr)) / - ((long) samplesperrow * SIZEOF(JSAMPLE)); - if (ltemp <= 0) - ERREXIT(cinfo, JERR_WIDTH_OVERFLOW); - if (ltemp < (long) numrows) - rowsperchunk = (JDIMENSION) ltemp; - else - rowsperchunk = numrows; - mem->last_rowsperchunk = rowsperchunk; - - /* Get space for row pointers (small object) */ - result = (JSAMPARRAY) alloc_small(cinfo, pool_id, - (size_t) (numrows * SIZEOF(JSAMPROW))); - - /* Get the rows themselves (large objects) */ - currow = 0; - while (currow < numrows) { - rowsperchunk = MIN(rowsperchunk, numrows - currow); - workspace = (JSAMPROW) alloc_large(cinfo, pool_id, - (size_t) ((size_t) rowsperchunk * (size_t) samplesperrow - * SIZEOF(JSAMPLE))); - for (i = rowsperchunk; i > 0; i--) { - result[currow++] = workspace; - workspace += samplesperrow; - } - } - - return result; -} - - -/* - * Creation of 2-D coefficient-block arrays. - * This is essentially the same as the code for sample arrays, above. - */ - -METHODDEF JBLOCKARRAY -alloc_barray (j_common_ptr cinfo, int pool_id, - JDIMENSION blocksperrow, JDIMENSION numrows) -/* Allocate a 2-D coefficient-block array */ -{ - my_mem_ptr mem = (my_mem_ptr) cinfo->mem; - JBLOCKARRAY result; - JBLOCKROW workspace; - JDIMENSION rowsperchunk, currow, i; - long ltemp; - - /* Calculate max # of rows allowed in one allocation chunk */ - ltemp = (MAX_ALLOC_CHUNK-SIZEOF(large_pool_hdr)) / - ((long) blocksperrow * SIZEOF(JBLOCK)); - if (ltemp <= 0) - ERREXIT(cinfo, JERR_WIDTH_OVERFLOW); - if (ltemp < (long) numrows) - rowsperchunk = (JDIMENSION) ltemp; - else - rowsperchunk = numrows; - mem->last_rowsperchunk = rowsperchunk; - - /* Get space for row pointers (small object) */ - result = (JBLOCKARRAY) alloc_small(cinfo, pool_id, - (size_t) (numrows * SIZEOF(JBLOCKROW))); - - /* Get the rows themselves (large objects) */ - currow = 0; - while (currow < numrows) { - rowsperchunk = MIN(rowsperchunk, numrows - currow); - workspace = (JBLOCKROW) alloc_large(cinfo, pool_id, - (size_t) ((size_t) rowsperchunk * (size_t) blocksperrow - * SIZEOF(JBLOCK))); - for (i = rowsperchunk; i > 0; i--) { - result[currow++] = workspace; - workspace += blocksperrow; - } - } - - return result; -} - - -/* - * About virtual array management: - * - * The above "normal" array routines are only used to allocate strip buffers - * (as wide as the image, but just a few rows high). Full-image-sized buffers - * are handled as "virtual" arrays. The array is still accessed a strip at a - * time, but the memory manager must save the whole array for repeated - * accesses. The intended implementation is that there is a strip buffer in - * memory (as high as is possible given the desired memory limit), plus a - * backing file that holds the rest of the array. - * - * The request_virt_array routines are told the total size of the image and - * the maximum number of rows that will be accessed at once. The in-memory - * buffer must be at least as large as the maxaccess value. - * - * The request routines create control blocks but not the in-memory buffers. - * That is postponed until realize_virt_arrays is called. At that time the - * total amount of space needed is known (approximately, anyway), so free - * memory can be divided up fairly. - * - * The access_virt_array routines are responsible for making a specific strip - * area accessible (after reading or writing the backing file, if necessary). - * Note that the access routines are told whether the caller intends to modify - * the accessed strip; during a read-only pass this saves having to rewrite - * data to disk. The access routines are also responsible for pre-zeroing - * any newly accessed rows, if pre-zeroing was requested. - * - * In current usage, the access requests are usually for nonoverlapping - * strips; that is, successive access start_row numbers differ by exactly - * num_rows = maxaccess. This means we can get good performance with simple - * buffer dump/reload logic, by making the in-memory buffer be a multiple - * of the access height; then there will never be accesses across bufferload - * boundaries. The code will still work with overlapping access requests, - * but it doesn't handle bufferload overlaps very efficiently. - */ - - -METHODDEF jvirt_sarray_ptr -request_virt_sarray (j_common_ptr cinfo, int pool_id, boolean pre_zero, - JDIMENSION samplesperrow, JDIMENSION numrows, - JDIMENSION maxaccess) -/* Request a virtual 2-D sample array */ -{ - my_mem_ptr mem = (my_mem_ptr) cinfo->mem; - jvirt_sarray_ptr result; - - /* Only IMAGE-lifetime virtual arrays are currently supported */ - if (pool_id != JPOOL_IMAGE) - ERREXIT1(cinfo, JERR_BAD_POOL_ID, pool_id); /* safety check */ - - /* get control block */ - result = (jvirt_sarray_ptr) alloc_small(cinfo, pool_id, - SIZEOF(struct jvirt_sarray_control)); - - result->mem_buffer = NULL; /* marks array not yet realized */ - result->rows_in_array = numrows; - result->samplesperrow = samplesperrow; - result->maxaccess = maxaccess; - result->pre_zero = pre_zero; - result->b_s_open = FALSE; /* no associated backing-store object */ - result->next = mem->virt_sarray_list; /* add to list of virtual arrays */ - mem->virt_sarray_list = result; - - return result; -} - - -METHODDEF jvirt_barray_ptr -request_virt_barray (j_common_ptr cinfo, int pool_id, boolean pre_zero, - JDIMENSION blocksperrow, JDIMENSION numrows, - JDIMENSION maxaccess) -/* Request a virtual 2-D coefficient-block array */ -{ - my_mem_ptr mem = (my_mem_ptr) cinfo->mem; - jvirt_barray_ptr result; - - /* Only IMAGE-lifetime virtual arrays are currently supported */ - if (pool_id != JPOOL_IMAGE) - ERREXIT1(cinfo, JERR_BAD_POOL_ID, pool_id); /* safety check */ - - /* get control block */ - result = (jvirt_barray_ptr) alloc_small(cinfo, pool_id, - SIZEOF(struct jvirt_barray_control)); - - result->mem_buffer = NULL; /* marks array not yet realized */ - result->rows_in_array = numrows; - result->blocksperrow = blocksperrow; - result->maxaccess = maxaccess; - result->pre_zero = pre_zero; - result->b_s_open = FALSE; /* no associated backing-store object */ - result->next = mem->virt_barray_list; /* add to list of virtual arrays */ - mem->virt_barray_list = result; - - return result; -} - - -METHODDEF void -realize_virt_arrays (j_common_ptr cinfo) -/* Allocate the in-memory buffers for any unrealized virtual arrays */ -{ - my_mem_ptr mem = (my_mem_ptr) cinfo->mem; - long space_per_minheight, maximum_space, avail_mem; - long minheights, max_minheights; - jvirt_sarray_ptr sptr; - jvirt_barray_ptr bptr; - - /* Compute the minimum space needed (maxaccess rows in each buffer) - * and the maximum space needed (full image height in each buffer). - * These may be of use to the system-dependent jpeg_mem_available routine. - */ - space_per_minheight = 0; - maximum_space = 0; - for (sptr = mem->virt_sarray_list; sptr != NULL; sptr = sptr->next) { - if (sptr->mem_buffer == NULL) { /* if not realized yet */ - space_per_minheight += (long) sptr->maxaccess * - (long) sptr->samplesperrow * SIZEOF(JSAMPLE); - maximum_space += (long) sptr->rows_in_array * - (long) sptr->samplesperrow * SIZEOF(JSAMPLE); - } - } - for (bptr = mem->virt_barray_list; bptr != NULL; bptr = bptr->next) { - if (bptr->mem_buffer == NULL) { /* if not realized yet */ - space_per_minheight += (long) bptr->maxaccess * - (long) bptr->blocksperrow * SIZEOF(JBLOCK); - maximum_space += (long) bptr->rows_in_array * - (long) bptr->blocksperrow * SIZEOF(JBLOCK); - } - } - - if (space_per_minheight <= 0) - return; /* no unrealized arrays, no work */ - - /* Determine amount of memory to actually use; this is system-dependent. */ - avail_mem = jpeg_mem_available(cinfo, space_per_minheight, maximum_space, - mem->total_space_allocated); - - /* If the maximum space needed is available, make all the buffers full - * height; otherwise parcel it out with the same number of minheights - * in each buffer. - */ - if (avail_mem >= maximum_space) - max_minheights = 1000000000L; - else { - max_minheights = avail_mem / space_per_minheight; - /* If there doesn't seem to be enough space, try to get the minimum - * anyway. This allows a "stub" implementation of jpeg_mem_available(). - */ - if (max_minheights <= 0) - max_minheights = 1; - } - - /* Allocate the in-memory buffers and initialize backing store as needed. */ - - for (sptr = mem->virt_sarray_list; sptr != NULL; sptr = sptr->next) { - if (sptr->mem_buffer == NULL) { /* if not realized yet */ - minheights = ((long) sptr->rows_in_array - 1L) / sptr->maxaccess + 1L; - if (minheights <= max_minheights) { - /* This buffer fits in memory */ - sptr->rows_in_mem = sptr->rows_in_array; - } else { - /* It doesn't fit in memory, create backing store. */ - sptr->rows_in_mem = (JDIMENSION) (max_minheights * sptr->maxaccess); - jpeg_open_backing_store(cinfo, & sptr->b_s_info, - (long) sptr->rows_in_array * - (long) sptr->samplesperrow * - (long) SIZEOF(JSAMPLE)); - sptr->b_s_open = TRUE; - } - sptr->mem_buffer = alloc_sarray(cinfo, JPOOL_IMAGE, - sptr->samplesperrow, sptr->rows_in_mem); - sptr->rowsperchunk = mem->last_rowsperchunk; - sptr->cur_start_row = 0; - sptr->first_undef_row = 0; - sptr->dirty = FALSE; - } - } - - for (bptr = mem->virt_barray_list; bptr != NULL; bptr = bptr->next) { - if (bptr->mem_buffer == NULL) { /* if not realized yet */ - minheights = ((long) bptr->rows_in_array - 1L) / bptr->maxaccess + 1L; - if (minheights <= max_minheights) { - /* This buffer fits in memory */ - bptr->rows_in_mem = bptr->rows_in_array; - } else { - /* It doesn't fit in memory, create backing store. */ - bptr->rows_in_mem = (JDIMENSION) (max_minheights * bptr->maxaccess); - jpeg_open_backing_store(cinfo, & bptr->b_s_info, - (long) bptr->rows_in_array * - (long) bptr->blocksperrow * - (long) SIZEOF(JBLOCK)); - bptr->b_s_open = TRUE; - } - bptr->mem_buffer = alloc_barray(cinfo, JPOOL_IMAGE, - bptr->blocksperrow, bptr->rows_in_mem); - bptr->rowsperchunk = mem->last_rowsperchunk; - bptr->cur_start_row = 0; - bptr->first_undef_row = 0; - bptr->dirty = FALSE; - } - } -} - - -LOCAL void -do_sarray_io (j_common_ptr cinfo, jvirt_sarray_ptr ptr, boolean writing) -/* Do backing store read or write of a virtual sample array */ -{ - long bytesperrow, file_offset, byte_count, rows, thisrow, i; - - bytesperrow = (long) ptr->samplesperrow * SIZEOF(JSAMPLE); - file_offset = ptr->cur_start_row * bytesperrow; - /* Loop to read or write each allocation chunk in mem_buffer */ - for (i = 0; i < (long) ptr->rows_in_mem; i += ptr->rowsperchunk) { - /* One chunk, but check for short chunk at end of buffer */ - rows = MIN((long) ptr->rowsperchunk, (long) ptr->rows_in_mem - i); - /* Transfer no more than is currently defined */ - thisrow = (long) ptr->cur_start_row + i; - rows = MIN(rows, (long) ptr->first_undef_row - thisrow); - /* Transfer no more than fits in file */ - rows = MIN(rows, (long) ptr->rows_in_array - thisrow); - if (rows <= 0) /* this chunk might be past end of file! */ - break; - byte_count = rows * bytesperrow; - if (writing) - (*ptr->b_s_info.write_backing_store) (cinfo, & ptr->b_s_info, - (void FAR *) ptr->mem_buffer[i], - file_offset, byte_count); - else - (*ptr->b_s_info.read_backing_store) (cinfo, & ptr->b_s_info, - (void FAR *) ptr->mem_buffer[i], - file_offset, byte_count); - file_offset += byte_count; - } -} - - -LOCAL void -do_barray_io (j_common_ptr cinfo, jvirt_barray_ptr ptr, boolean writing) -/* Do backing store read or write of a virtual coefficient-block array */ -{ - long bytesperrow, file_offset, byte_count, rows, thisrow, i; - - bytesperrow = (long) ptr->blocksperrow * SIZEOF(JBLOCK); - file_offset = ptr->cur_start_row * bytesperrow; - /* Loop to read or write each allocation chunk in mem_buffer */ - for (i = 0; i < (long) ptr->rows_in_mem; i += ptr->rowsperchunk) { - /* One chunk, but check for short chunk at end of buffer */ - rows = MIN((long) ptr->rowsperchunk, (long) ptr->rows_in_mem - i); - /* Transfer no more than is currently defined */ - thisrow = (long) ptr->cur_start_row + i; - rows = MIN(rows, (long) ptr->first_undef_row - thisrow); - /* Transfer no more than fits in file */ - rows = MIN(rows, (long) ptr->rows_in_array - thisrow); - if (rows <= 0) /* this chunk might be past end of file! */ - break; - byte_count = rows * bytesperrow; - if (writing) - (*ptr->b_s_info.write_backing_store) (cinfo, & ptr->b_s_info, - (void FAR *) ptr->mem_buffer[i], - file_offset, byte_count); - else - (*ptr->b_s_info.read_backing_store) (cinfo, & ptr->b_s_info, - (void FAR *) ptr->mem_buffer[i], - file_offset, byte_count); - file_offset += byte_count; - } -} - - -METHODDEF JSAMPARRAY -access_virt_sarray (j_common_ptr cinfo, jvirt_sarray_ptr ptr, - JDIMENSION start_row, JDIMENSION num_rows, - boolean writable) -/* Access the part of a virtual sample array starting at start_row */ -/* and extending for num_rows rows. writable is true if */ -/* caller intends to modify the accessed area. */ -{ - JDIMENSION end_row = start_row + num_rows; - JDIMENSION undef_row; - - /* debugging check */ - if (end_row > ptr->rows_in_array || num_rows > ptr->maxaccess || - ptr->mem_buffer == NULL) - ERREXIT(cinfo, JERR_BAD_VIRTUAL_ACCESS); - - /* Make the desired part of the virtual array accessible */ - if (start_row < ptr->cur_start_row || - end_row > ptr->cur_start_row+ptr->rows_in_mem) { - if (! ptr->b_s_open) - ERREXIT(cinfo, JERR_VIRTUAL_BUG); - /* Flush old buffer contents if necessary */ - if (ptr->dirty) { - do_sarray_io(cinfo, ptr, TRUE); - ptr->dirty = FALSE; - } - /* Decide what part of virtual array to access. - * Algorithm: if target address > current window, assume forward scan, - * load starting at target address. If target address < current window, - * assume backward scan, load so that target area is top of window. - * Note that when switching from forward write to forward read, will have - * start_row = 0, so the limiting case applies and we load from 0 anyway. - */ - if (start_row > ptr->cur_start_row) { - ptr->cur_start_row = start_row; - } else { - /* use long arithmetic here to avoid overflow & unsigned problems */ - long ltemp; - - ltemp = (long) end_row - (long) ptr->rows_in_mem; - if (ltemp < 0) - ltemp = 0; /* don't fall off front end of file */ - ptr->cur_start_row = (JDIMENSION) ltemp; - } - /* Read in the selected part of the array. - * During the initial write pass, we will do no actual read - * because the selected part is all undefined. - */ - do_sarray_io(cinfo, ptr, FALSE); - } - /* Ensure the accessed part of the array is defined; prezero if needed. - * To improve locality of access, we only prezero the part of the array - * that the caller is about to access, not the entire in-memory array. - */ - if (ptr->first_undef_row < end_row) { - if (ptr->first_undef_row < start_row) { - if (writable) /* writer skipped over a section of array */ - ERREXIT(cinfo, JERR_BAD_VIRTUAL_ACCESS); - undef_row = start_row; /* but reader is allowed to read ahead */ - } else { - undef_row = ptr->first_undef_row; - } - if (writable) - ptr->first_undef_row = end_row; - if (ptr->pre_zero) { - size_t bytesperrow = (size_t) ptr->samplesperrow * SIZEOF(JSAMPLE); - undef_row -= ptr->cur_start_row; /* make indexes relative to buffer */ - end_row -= ptr->cur_start_row; - while (undef_row < end_row) { - jzero_far((void FAR *) ptr->mem_buffer[undef_row], bytesperrow); - undef_row++; - } - } else { - if (! writable) /* reader looking at undefined data */ - ERREXIT(cinfo, JERR_BAD_VIRTUAL_ACCESS); - } - } - /* Flag the buffer dirty if caller will write in it */ - if (writable) - ptr->dirty = TRUE; - /* Return address of proper part of the buffer */ - return ptr->mem_buffer + (start_row - ptr->cur_start_row); -} - - -METHODDEF JBLOCKARRAY -access_virt_barray (j_common_ptr cinfo, jvirt_barray_ptr ptr, - JDIMENSION start_row, JDIMENSION num_rows, - boolean writable) -/* Access the part of a virtual block array starting at start_row */ -/* and extending for num_rows rows. writable is true if */ -/* caller intends to modify the accessed area. */ -{ - JDIMENSION end_row = start_row + num_rows; - JDIMENSION undef_row; - - /* debugging check */ - if (end_row > ptr->rows_in_array || num_rows > ptr->maxaccess || - ptr->mem_buffer == NULL) - ERREXIT(cinfo, JERR_BAD_VIRTUAL_ACCESS); - - /* Make the desired part of the virtual array accessible */ - if (start_row < ptr->cur_start_row || - end_row > ptr->cur_start_row+ptr->rows_in_mem) { - if (! ptr->b_s_open) - ERREXIT(cinfo, JERR_VIRTUAL_BUG); - /* Flush old buffer contents if necessary */ - if (ptr->dirty) { - do_barray_io(cinfo, ptr, TRUE); - ptr->dirty = FALSE; - } - /* Decide what part of virtual array to access. - * Algorithm: if target address > current window, assume forward scan, - * load starting at target address. If target address < current window, - * assume backward scan, load so that target area is top of window. - * Note that when switching from forward write to forward read, will have - * start_row = 0, so the limiting case applies and we load from 0 anyway. - */ - if (start_row > ptr->cur_start_row) { - ptr->cur_start_row = start_row; - } else { - /* use long arithmetic here to avoid overflow & unsigned problems */ - long ltemp; - - ltemp = (long) end_row - (long) ptr->rows_in_mem; - if (ltemp < 0) - ltemp = 0; /* don't fall off front end of file */ - ptr->cur_start_row = (JDIMENSION) ltemp; - } - /* Read in the selected part of the array. - * During the initial write pass, we will do no actual read - * because the selected part is all undefined. - */ - do_barray_io(cinfo, ptr, FALSE); - } - /* Ensure the accessed part of the array is defined; prezero if needed. - * To improve locality of access, we only prezero the part of the array - * that the caller is about to access, not the entire in-memory array. - */ - if (ptr->first_undef_row < end_row) { - if (ptr->first_undef_row < start_row) { - if (writable) /* writer skipped over a section of array */ - ERREXIT(cinfo, JERR_BAD_VIRTUAL_ACCESS); - undef_row = start_row; /* but reader is allowed to read ahead */ - } else { - undef_row = ptr->first_undef_row; - } - if (writable) - ptr->first_undef_row = end_row; - if (ptr->pre_zero) { - size_t bytesperrow = (size_t) ptr->blocksperrow * SIZEOF(JBLOCK); - undef_row -= ptr->cur_start_row; /* make indexes relative to buffer */ - end_row -= ptr->cur_start_row; - while (undef_row < end_row) { - jzero_far((void FAR *) ptr->mem_buffer[undef_row], bytesperrow); - undef_row++; - } - } else { - if (! writable) /* reader looking at undefined data */ - ERREXIT(cinfo, JERR_BAD_VIRTUAL_ACCESS); - } - } - /* Flag the buffer dirty if caller will write in it */ - if (writable) - ptr->dirty = TRUE; - /* Return address of proper part of the buffer */ - return ptr->mem_buffer + (start_row - ptr->cur_start_row); -} - - -/* - * Release all objects belonging to a specified pool. - */ - -METHODDEF void -free_pool (j_common_ptr cinfo, int pool_id) -{ - my_mem_ptr mem = (my_mem_ptr) cinfo->mem; - small_pool_ptr shdr_ptr; - large_pool_ptr lhdr_ptr; - size_t space_freed; - - if (pool_id < 0 || pool_id >= JPOOL_NUMPOOLS) - ERREXIT1(cinfo, JERR_BAD_POOL_ID, pool_id); /* safety check */ - -#ifdef MEM_STATS - if (cinfo->err->trace_level > 1) - print_mem_stats(cinfo, pool_id); /* print pool's memory usage statistics */ -#endif - - /* If freeing IMAGE pool, close any virtual arrays first */ - if (pool_id == JPOOL_IMAGE) { - jvirt_sarray_ptr sptr; - jvirt_barray_ptr bptr; - - for (sptr = mem->virt_sarray_list; sptr != NULL; sptr = sptr->next) { - if (sptr->b_s_open) { /* there may be no backing store */ - sptr->b_s_open = FALSE; /* prevent recursive close if error */ - (*sptr->b_s_info.close_backing_store) (cinfo, & sptr->b_s_info); - } - } - mem->virt_sarray_list = NULL; - for (bptr = mem->virt_barray_list; bptr != NULL; bptr = bptr->next) { - if (bptr->b_s_open) { /* there may be no backing store */ - bptr->b_s_open = FALSE; /* prevent recursive close if error */ - (*bptr->b_s_info.close_backing_store) (cinfo, & bptr->b_s_info); - } - } - mem->virt_barray_list = NULL; - } - - /* Release large objects */ - lhdr_ptr = mem->large_list[pool_id]; - mem->large_list[pool_id] = NULL; - - while (lhdr_ptr != NULL) { - large_pool_ptr next_lhdr_ptr = lhdr_ptr->hdr.next; - space_freed = lhdr_ptr->hdr.bytes_used + - lhdr_ptr->hdr.bytes_left + - SIZEOF(large_pool_hdr); - jpeg_free_large(cinfo, (void FAR *) lhdr_ptr, space_freed); - mem->total_space_allocated -= space_freed; - lhdr_ptr = next_lhdr_ptr; - } - - /* Release small objects */ - shdr_ptr = mem->small_list[pool_id]; - mem->small_list[pool_id] = NULL; - - while (shdr_ptr != NULL) { - small_pool_ptr next_shdr_ptr = shdr_ptr->hdr.next; - space_freed = shdr_ptr->hdr.bytes_used + - shdr_ptr->hdr.bytes_left + - SIZEOF(small_pool_hdr); - jpeg_free_small(cinfo, (void *) shdr_ptr, space_freed); - mem->total_space_allocated -= space_freed; - shdr_ptr = next_shdr_ptr; - } -} - - -/* - * Close up shop entirely. - * Note that this cannot be called unless cinfo->mem is non-NULL. - */ - -METHODDEF void -self_destruct (j_common_ptr cinfo) -{ - int pool; - - /* Close all backing store, release all memory. - * Releasing pools in reverse order might help avoid fragmentation - * with some (brain-damaged) malloc libraries. - */ - for (pool = JPOOL_NUMPOOLS-1; pool >= JPOOL_PERMANENT; pool--) { - free_pool(cinfo, pool); - } - - /* Release the memory manager control block too. */ - jpeg_free_small(cinfo, (void *) cinfo->mem, SIZEOF(my_memory_mgr)); - cinfo->mem = NULL; /* ensures I will be called only once */ - - jpeg_mem_term(cinfo); /* system-dependent cleanup */ -} - - -/* - * Memory manager initialization. - * When this is called, only the error manager pointer is valid in cinfo! - */ - -GLOBAL void -jinit_memory_mgr (j_common_ptr cinfo) -{ - my_mem_ptr mem; - long max_to_use; - int pool; - size_t test_mac; - - cinfo->mem = NULL; /* for safety if init fails */ - - /* Check for configuration errors. - * SIZEOF(ALIGN_TYPE) should be a power of 2; otherwise, it probably - * doesn't reflect any real hardware alignment requirement. - * The test is a little tricky: for X>0, X and X-1 have no one-bits - * in common if and only if X is a power of 2, ie has only one one-bit. - * Some compilers may give an "unreachable code" warning here; ignore it. - */ - if ((SIZEOF(ALIGN_TYPE) & (SIZEOF(ALIGN_TYPE)-1)) != 0) - ERREXIT(cinfo, JERR_BAD_ALIGN_TYPE); - /* MAX_ALLOC_CHUNK must be representable as type size_t, and must be - * a multiple of SIZEOF(ALIGN_TYPE). - * Again, an "unreachable code" warning may be ignored here. - * But a "constant too large" warning means you need to fix MAX_ALLOC_CHUNK. - */ - test_mac = (size_t) MAX_ALLOC_CHUNK; - if ((long) test_mac != MAX_ALLOC_CHUNK || - (MAX_ALLOC_CHUNK % SIZEOF(ALIGN_TYPE)) != 0) - ERREXIT(cinfo, JERR_BAD_ALLOC_CHUNK); - - max_to_use = jpeg_mem_init(cinfo); /* system-dependent initialization */ - - /* Attempt to allocate memory manager's control block */ - mem = (my_mem_ptr) jpeg_get_small(cinfo, SIZEOF(my_memory_mgr)); - - if (mem == NULL) { - jpeg_mem_term(cinfo); /* system-dependent cleanup */ - ERREXIT1(cinfo, JERR_OUT_OF_MEMORY, 0); - } - - /* OK, fill in the method pointers */ - mem->pub.alloc_small = alloc_small; - mem->pub.alloc_large = alloc_large; - mem->pub.alloc_sarray = alloc_sarray; - mem->pub.alloc_barray = alloc_barray; - mem->pub.request_virt_sarray = request_virt_sarray; - mem->pub.request_virt_barray = request_virt_barray; - mem->pub.realize_virt_arrays = realize_virt_arrays; - mem->pub.access_virt_sarray = access_virt_sarray; - mem->pub.access_virt_barray = access_virt_barray; - mem->pub.free_pool = free_pool; - mem->pub.self_destruct = self_destruct; - - /* Initialize working state */ - mem->pub.max_memory_to_use = max_to_use; - - for (pool = JPOOL_NUMPOOLS-1; pool >= JPOOL_PERMANENT; pool--) { - mem->small_list[pool] = NULL; - mem->large_list[pool] = NULL; - } - mem->virt_sarray_list = NULL; - mem->virt_barray_list = NULL; - - mem->total_space_allocated = SIZEOF(my_memory_mgr); - - /* Declare ourselves open for business */ - cinfo->mem = & mem->pub; - - /* Check for an environment variable JPEGMEM; if found, override the - * default max_memory setting from jpeg_mem_init. Note that the - * surrounding application may again override this value. - * If your system doesn't support getenv(), define NO_GETENV to disable - * this feature. - */ -#ifndef NO_GETENV - { char * memenv; - - if ((memenv = getenv("JPEGMEM")) != NULL) { - char ch = 'x'; - - if (sscanf(memenv, "%ld%c", &max_to_use, &ch) > 0) { - if (ch == 'm' || ch == 'M') - max_to_use *= 1000L; - mem->pub.max_memory_to_use = max_to_use * 1000L; - } - } - } -#endif - -} diff --git a/engine/jpeg-6/jmemname.c b/engine/jpeg-6/jmemname.c deleted file mode 100644 index ba826fb..0000000 --- a/engine/jpeg-6/jmemname.c +++ /dev/null @@ -1,271 +0,0 @@ -/* - * jmemname.c - * - * Copyright (C) 1992-1994, Thomas G. Lane. - * This file is part of the Independent JPEG Group's software. - * For conditions of distribution and use, see the accompanying README file. - * - * This file provides a generic implementation of the system-dependent - * portion of the JPEG memory manager. This implementation assumes that - * you must explicitly construct a name for each temp file. - * Also, the problem of determining the amount of memory available - * is shoved onto the user. - */ - -#define JPEG_INTERNALS -#include "jinclude.h" -#include "jpeglib.h" -#include "jmemsys.h" /* import the system-dependent declarations */ - -#ifndef HAVE_STDLIB_H /* should declare malloc(),free() */ -extern void * malloc JPP((size_t size)); -extern void free JPP((void *ptr)); -#endif - -#ifndef SEEK_SET /* pre-ANSI systems may not define this; */ -#define SEEK_SET 0 /* if not, assume 0 is correct */ -#endif - -#ifdef DONT_USE_B_MODE /* define mode parameters for fopen() */ -#define READ_BINARY "r" -#define RW_BINARY "w+" -#else -#define READ_BINARY "rb" -#define RW_BINARY "w+b" -#endif - - -/* - * Selection of a file name for a temporary file. - * This is system-dependent! - * - * The code as given is suitable for most Unix systems, and it is easily - * modified for most non-Unix systems. Some notes: - * 1. The temp file is created in the directory named by TEMP_DIRECTORY. - * The default value is /usr/tmp, which is the conventional place for - * creating large temp files on Unix. On other systems you'll probably - * want to change the file location. You can do this by editing the - * #define, or (preferred) by defining TEMP_DIRECTORY in jconfig.h. - * - * 2. If you need to change the file name as well as its location, - * you can override the TEMP_FILE_NAME macro. (Note that this is - * actually a printf format string; it must contain %s and %d.) - * Few people should need to do this. - * - * 3. mktemp() is used to ensure that multiple processes running - * simultaneously won't select the same file names. If your system - * doesn't have mktemp(), define NO_MKTEMP to do it the hard way. - * (If you don't have , also define NO_ERRNO_H.) - * - * 4. You probably want to define NEED_SIGNAL_CATCHER so that cjpeg.c/djpeg.c - * will cause the temp files to be removed if you stop the program early. - */ - -#ifndef TEMP_DIRECTORY /* can override from jconfig.h or Makefile */ -#define TEMP_DIRECTORY "/usr/tmp/" /* recommended setting for Unix */ -#endif - -static int next_file_num; /* to distinguish among several temp files */ - -#ifdef NO_MKTEMP - -#ifndef TEMP_FILE_NAME /* can override from jconfig.h or Makefile */ -#define TEMP_FILE_NAME "%sJPG%03d.TMP" -#endif - -#ifndef NO_ERRNO_H -#include /* to define ENOENT */ -#endif - -/* ANSI C specifies that errno is a macro, but on older systems it's more - * likely to be a plain int variable. And not all versions of errno.h - * bother to declare it, so we have to in order to be most portable. Thus: - */ -#ifndef errno -extern int errno; -#endif - - -LOCAL void -select_file_name (char * fname) -{ - FILE * tfile; - - /* Keep generating file names till we find one that's not in use */ - for (;;) { - next_file_num++; /* advance counter */ - sprintf(fname, TEMP_FILE_NAME, TEMP_DIRECTORY, next_file_num); - if ((tfile = fopen(fname, READ_BINARY)) == NULL) { - /* fopen could have failed for a reason other than the file not - * being there; for example, file there but unreadable. - * If isn't available, then we cannot test the cause. - */ -#ifdef ENOENT - if (errno != ENOENT) - continue; -#endif - break; - } - fclose(tfile); /* oops, it's there; close tfile & try again */ - } -} - -#else /* ! NO_MKTEMP */ - -/* Note that mktemp() requires the initial filename to end in six X's */ -#ifndef TEMP_FILE_NAME /* can override from jconfig.h or Makefile */ -#define TEMP_FILE_NAME "%sJPG%dXXXXXX" -#endif - -LOCAL void -select_file_name (char * fname) -{ - next_file_num++; /* advance counter */ - sprintf(fname, TEMP_FILE_NAME, TEMP_DIRECTORY, next_file_num); - mktemp(fname); /* make sure file name is unique */ - /* mktemp replaces the trailing XXXXXX with a unique string of characters */ -} - -#endif /* NO_MKTEMP */ - - -/* - * Memory allocation and freeing are controlled by the regular library - * routines malloc() and free(). - */ - -GLOBAL void * -jpeg_get_small (j_common_ptr cinfo, size_t sizeofobject) -{ - return (void *) malloc(sizeofobject); -} - -GLOBAL void -jpeg_free_small (j_common_ptr cinfo, void * object, size_t sizeofobject) -{ - free(object); -} - - -/* - * "Large" objects are treated the same as "small" ones. - * NB: although we include FAR keywords in the routine declarations, - * this file won't actually work in 80x86 small/medium model; at least, - * you probably won't be able to process useful-size images in only 64KB. - */ - -GLOBAL void FAR * -jpeg_get_large (j_common_ptr cinfo, size_t sizeofobject) -{ - return (void FAR *) malloc(sizeofobject); -} - -GLOBAL void -jpeg_free_large (j_common_ptr cinfo, void FAR * object, size_t sizeofobject) -{ - free(object); -} - - -/* - * This routine computes the total memory space available for allocation. - * It's impossible to do this in a portable way; our current solution is - * to make the user tell us (with a default value set at compile time). - * If you can actually get the available space, it's a good idea to subtract - * a slop factor of 5% or so. - */ - -#ifndef DEFAULT_MAX_MEM /* so can override from makefile */ -#define DEFAULT_MAX_MEM 1000000L /* default: one megabyte */ -#endif - -GLOBAL long -jpeg_mem_available (j_common_ptr cinfo, long min_bytes_needed, - long max_bytes_needed, long already_allocated) -{ - return cinfo->mem->max_memory_to_use - already_allocated; -} - - -/* - * Backing store (temporary file) management. - * Backing store objects are only used when the value returned by - * jpeg_mem_available is less than the total space needed. You can dispense - * with these routines if you have plenty of virtual memory; see jmemnobs.c. - */ - - -METHODDEF void -read_backing_store (j_common_ptr cinfo, backing_store_ptr info, - void FAR * buffer_address, - long file_offset, long byte_count) -{ - if (fseek(info->temp_file, file_offset, SEEK_SET)) - ERREXIT(cinfo, JERR_TFILE_SEEK); - if (JFREAD(info->temp_file, buffer_address, byte_count) - != (size_t) byte_count) - ERREXIT(cinfo, JERR_TFILE_READ); -} - - -METHODDEF void -write_backing_store (j_common_ptr cinfo, backing_store_ptr info, - void FAR * buffer_address, - long file_offset, long byte_count) -{ - if (fseek(info->temp_file, file_offset, SEEK_SET)) - ERREXIT(cinfo, JERR_TFILE_SEEK); - if (JFWRITE(info->temp_file, buffer_address, byte_count) - != (size_t) byte_count) - ERREXIT(cinfo, JERR_TFILE_WRITE); -} - - -METHODDEF void -close_backing_store (j_common_ptr cinfo, backing_store_ptr info) -{ - fclose(info->temp_file); /* close the file */ - unlink(info->temp_name); /* delete the file */ -/* If your system doesn't have unlink(), use remove() instead. - * remove() is the ANSI-standard name for this function, but if - * your system was ANSI you'd be using jmemansi.c, right? - */ - TRACEMSS(cinfo, 1, JTRC_TFILE_CLOSE, info->temp_name); -} - - -/* - * Initial opening of a backing-store object. - */ - -GLOBAL void -jpeg_open_backing_store (j_common_ptr cinfo, backing_store_ptr info, - long total_bytes_needed) -{ - select_file_name(info->temp_name); - if ((info->temp_file = fopen(info->temp_name, RW_BINARY)) == NULL) - ERREXITS(cinfo, JERR_TFILE_CREATE, info->temp_name); - info->read_backing_store = read_backing_store; - info->write_backing_store = write_backing_store; - info->close_backing_store = close_backing_store; - TRACEMSS(cinfo, 1, JTRC_TFILE_OPEN, info->temp_name); -} - - -/* - * These routines take care of any system-dependent initialization and - * cleanup required. - */ - -GLOBAL long -jpeg_mem_init (j_common_ptr cinfo) -{ - next_file_num = 0; /* initialize temp file name generator */ - return DEFAULT_MAX_MEM; /* default for max_memory_to_use */ -} - -GLOBAL void -jpeg_mem_term (j_common_ptr cinfo) -{ - /* no work */ -} diff --git a/engine/jpeg-6/jmemnobs.c b/engine/jpeg-6/jmemnobs.c deleted file mode 100644 index 9ca2fb7..0000000 --- a/engine/jpeg-6/jmemnobs.c +++ /dev/null @@ -1,106 +0,0 @@ -/* - * jmemnobs.c - * - * Copyright (C) 1992-1994, Thomas G. Lane. - * This file is part of the Independent JPEG Group's software. - * For conditions of distribution and use, see the accompanying README file. - * - * This file provides a really simple implementation of the system- - * dependent portion of the JPEG memory manager. This implementation - * assumes that no backing-store files are needed: all required space - * can be obtained from ri.Malloc(). - * This is very portable in the sense that it'll compile on almost anything, - * but you'd better have lots of main memory (or virtual memory) if you want - * to process big images. - * Note that the max_memory_to_use option is ignored by this implementation. - */ - -#define JPEG_INTERNALS -#include "jinclude.h" -#include "jpeglib.h" -#include "jmemsys.h" /* import the system-dependent declarations */ - -//#include "../renderer/tr_local.h" -#include "../code/quakedef.h" - -/* - * Memory allocation and ri.Freeing are controlled by the regular library - * routines ri.Malloc() and ri.Free(). - */ - -GLOBAL void * -jpeg_get_small (j_common_ptr cinfo, size_t sizeofobject) -{ - return (void *) malloc(sizeofobject); -} - -GLOBAL void -jpeg_free_small (j_common_ptr cinfo, void * object, size_t sizeofobject) -{ - free(object); -} - - -/* - * "Large" objects are treated the same as "small" ones. - * NB: although we include FAR keywords in the routine declarations, - * this file won't actually work in 80x86 small/medium model; at least, - * you probably won't be able to process useful-size images in only 64KB. - */ - -GLOBAL void FAR * -jpeg_get_large (j_common_ptr cinfo, size_t sizeofobject) -{ - return (void FAR *) malloc(sizeofobject); -} - -GLOBAL void -jpeg_free_large (j_common_ptr cinfo, void FAR * object, size_t sizeofobject) -{ - free(object); -} - - -/* - * This routine computes the total memory space available for allocation. - * Here we always say, "we got all you want bud!" - */ - -GLOBAL long -jpeg_mem_available (j_common_ptr cinfo, long min_bytes_needed, - long max_bytes_needed, long already_allocated) -{ - return max_bytes_needed; -} - - -/* - * Backing store (temporary file) management. - * Since jpeg_mem_available always promised the moon, - * this should never be called and we can just error out. - */ - -GLOBAL void -jpeg_open_backing_store (j_common_ptr cinfo, backing_store_ptr info, - long total_bytes_needed) -{ - ERREXIT(cinfo, JERR_NO_BACKING_STORE); -} - - -/* - * These routines take care of any system-dependent initialization and - * cleanup required. Here, there isn't any. - */ - -GLOBAL long -jpeg_mem_init (j_common_ptr cinfo) -{ - return 0; /* just set max_memory_to_use to 0 */ -} - -GLOBAL void -jpeg_mem_term (j_common_ptr cinfo) -{ - /* no work */ -} diff --git a/engine/jpeg-6/jmemsys.h b/engine/jpeg-6/jmemsys.h deleted file mode 100644 index 033d29a..0000000 --- a/engine/jpeg-6/jmemsys.h +++ /dev/null @@ -1,182 +0,0 @@ -/* - * jmemsys.h - * - * Copyright (C) 1992-1994, Thomas G. Lane. - * This file is part of the Independent JPEG Group's software. - * For conditions of distribution and use, see the accompanying README file. - * - * This include file defines the interface between the system-independent - * and system-dependent portions of the JPEG memory manager. No other - * modules need include it. (The system-independent portion is jmemmgr.c; - * there are several different versions of the system-dependent portion.) - * - * This file works as-is for the system-dependent memory managers supplied - * in the IJG distribution. You may need to modify it if you write a - * custom memory manager. If system-dependent changes are needed in - * this file, the best method is to #ifdef them based on a configuration - * symbol supplied in jconfig.h, as we have done with USE_MSDOS_MEMMGR. - */ - - -/* Short forms of external names for systems with brain-damaged linkers. */ - -#ifdef NEED_SHORT_EXTERNAL_NAMES -#define jpeg_get_small jGetSmall -#define jpeg_free_small jFreeSmall -#define jpeg_get_large jGetLarge -#define jpeg_free_large jFreeLarge -#define jpeg_mem_available jMemAvail -#define jpeg_open_backing_store jOpenBackStore -#define jpeg_mem_init jMemInit -#define jpeg_mem_term jMemTerm -#endif /* NEED_SHORT_EXTERNAL_NAMES */ - - -/* - * These two functions are used to allocate and release small chunks of - * memory. (Typically the total amount requested through jpeg_get_small is - * no more than 20K or so; this will be requested in chunks of a few K each.) - * Behavior should be the same as for the standard library functions malloc - * and free; in particular, jpeg_get_small must return NULL on failure. - * On most systems, these ARE malloc and free. jpeg_free_small is passed the - * size of the object being freed, just in case it's needed. - * On an 80x86 machine using small-data memory model, these manage near heap. - */ - -EXTERN void * jpeg_get_small JPP((j_common_ptr cinfo, size_t sizeofobject)); -EXTERN void jpeg_free_small JPP((j_common_ptr cinfo, void * object, - size_t sizeofobject)); - -/* - * These two functions are used to allocate and release large chunks of - * memory (up to the total free space designated by jpeg_mem_available). - * The interface is the same as above, except that on an 80x86 machine, - * far pointers are used. On most other machines these are identical to - * the jpeg_get/free_small routines; but we keep them separate anyway, - * in case a different allocation strategy is desirable for large chunks. - */ - -EXTERN void FAR * jpeg_get_large JPP((j_common_ptr cinfo,size_t sizeofobject)); -EXTERN void jpeg_free_large JPP((j_common_ptr cinfo, void FAR * object, - size_t sizeofobject)); - -/* - * The macro MAX_ALLOC_CHUNK designates the maximum number of bytes that may - * be requested in a single call to jpeg_get_large (and jpeg_get_small for that - * matter, but that case should never come into play). This macro is needed - * to model the 64Kb-segment-size limit of far addressing on 80x86 machines. - * On those machines, we expect that jconfig.h will provide a proper value. - * On machines with 32-bit flat address spaces, any large constant may be used. - * - * NB: jmemmgr.c expects that MAX_ALLOC_CHUNK will be representable as type - * size_t and will be a multiple of sizeof(align_type). - */ - -#ifndef MAX_ALLOC_CHUNK /* may be overridden in jconfig.h */ -#define MAX_ALLOC_CHUNK 1000000000L -#endif - -/* - * This routine computes the total space still available for allocation by - * jpeg_get_large. If more space than this is needed, backing store will be - * used. NOTE: any memory already allocated must not be counted. - * - * There is a minimum space requirement, corresponding to the minimum - * feasible buffer sizes; jmemmgr.c will request that much space even if - * jpeg_mem_available returns zero. The maximum space needed, enough to hold - * all working storage in memory, is also passed in case it is useful. - * Finally, the total space already allocated is passed. If no better - * method is available, cinfo->mem->max_memory_to_use - already_allocated - * is often a suitable calculation. - * - * It is OK for jpeg_mem_available to underestimate the space available - * (that'll just lead to more backing-store access than is really necessary). - * However, an overestimate will lead to failure. Hence it's wise to subtract - * a slop factor from the true available space. 5% should be enough. - * - * On machines with lots of virtual memory, any large constant may be returned. - * Conversely, zero may be returned to always use the minimum amount of memory. - */ - -EXTERN long jpeg_mem_available JPP((j_common_ptr cinfo, - long min_bytes_needed, - long max_bytes_needed, - long already_allocated)); - - -/* - * This structure holds whatever state is needed to access a single - * backing-store object. The read/write/close method pointers are called - * by jmemmgr.c to manipulate the backing-store object; all other fields - * are private to the system-dependent backing store routines. - */ - -#define TEMP_NAME_LENGTH 64 /* max length of a temporary file's name */ - -#ifdef USE_MSDOS_MEMMGR /* DOS-specific junk */ - -typedef unsigned short XMSH; /* type of extended-memory handles */ -typedef unsigned short EMSH; /* type of expanded-memory handles */ - -typedef union { - short file_handle; /* DOS file handle if it's a temp file */ - XMSH xms_handle; /* handle if it's a chunk of XMS */ - EMSH ems_handle; /* handle if it's a chunk of EMS */ -} handle_union; - -#endif /* USE_MSDOS_MEMMGR */ - -typedef struct backing_store_struct * backing_store_ptr; - -typedef struct backing_store_struct { - /* Methods for reading/writing/closing this backing-store object */ - JMETHOD(void, read_backing_store, (j_common_ptr cinfo, - backing_store_ptr info, - void FAR * buffer_address, - long file_offset, long byte_count)); - JMETHOD(void, write_backing_store, (j_common_ptr cinfo, - backing_store_ptr info, - void FAR * buffer_address, - long file_offset, long byte_count)); - JMETHOD(void, close_backing_store, (j_common_ptr cinfo, - backing_store_ptr info)); - - /* Private fields for system-dependent backing-store management */ -#ifdef USE_MSDOS_MEMMGR - /* For the MS-DOS manager (jmemdos.c), we need: */ - handle_union handle; /* reference to backing-store storage object */ - char temp_name[TEMP_NAME_LENGTH]; /* name if it's a file */ -#else - /* For a typical implementation with temp files, we need: */ - FILE * temp_file; /* stdio reference to temp file */ - char temp_name[TEMP_NAME_LENGTH]; /* name of temp file */ -#endif -} backing_store_info; - -/* - * Initial opening of a backing-store object. This must fill in the - * read/write/close pointers in the object. The read/write routines - * may take an error exit if the specified maximum file size is exceeded. - * (If jpeg_mem_available always returns a large value, this routine can - * just take an error exit.) - */ - -EXTERN void jpeg_open_backing_store JPP((j_common_ptr cinfo, - backing_store_ptr info, - long total_bytes_needed)); - - -/* - * These routines take care of any system-dependent initialization and - * cleanup required. jpeg_mem_init will be called before anything is - * allocated (and, therefore, nothing in cinfo is of use except the error - * manager pointer). It should return a suitable default value for - * max_memory_to_use; this may subsequently be overridden by the surrounding - * application. (Note that max_memory_to_use is only important if - * jpeg_mem_available chooses to consult it ... no one else will.) - * jpeg_mem_term may assume that all requested memory has been freed and that - * all opened backing-store objects have been closed. - */ - -EXTERN long jpeg_mem_init JPP((j_common_ptr cinfo)); -EXTERN void jpeg_mem_term JPP((j_common_ptr cinfo)); diff --git a/engine/jpeg-6/jmorecfg.h b/engine/jpeg-6/jmorecfg.h deleted file mode 100644 index 1fc0a19..0000000 --- a/engine/jpeg-6/jmorecfg.h +++ /dev/null @@ -1,348 +0,0 @@ -/* - * jmorecfg.h - * - * Copyright (C) 1991-1995, Thomas G. Lane. - * This file is part of the Independent JPEG Group's software. - * For conditions of distribution and use, see the accompanying README file. - * - * This file contains additional configuration options that customize the - * JPEG software for special applications or support machine-dependent - * optimizations. Most users will not need to touch this file. - */ - - -/* - * Define BITS_IN_JSAMPLE as either - * 8 for 8-bit sample values (the usual setting) - * 12 for 12-bit sample values - * Only 8 and 12 are legal data precisions for lossy JPEG according to the - * JPEG standard, and the IJG code does not support anything else! - * We do not support run-time selection of data precision, sorry. - */ - -#define BITS_IN_JSAMPLE 8 /* use 8 or 12 */ - - -/* - * Maximum number of components (color channels) allowed in JPEG image. - * To meet the letter of the JPEG spec, set this to 255. However, darn - * few applications need more than 4 channels (maybe 5 for CMYK + alpha - * mask). We recommend 10 as a reasonable compromise; use 4 if you are - * really short on memory. (Each allowed component costs a hundred or so - * bytes of storage, whether actually used in an image or not.) - */ - -#define MAX_COMPONENTS 10 /* maximum number of image components */ - - -/* - * Basic data types. - * You may need to change these if you have a machine with unusual data - * type sizes; for example, "char" not 8 bits, "short" not 16 bits, - * or "long" not 32 bits. We don't care whether "int" is 16 or 32 bits, - * but it had better be at least 16. - */ - -/* Representation of a single sample (pixel element value). - * We frequently allocate large arrays of these, so it's important to keep - * them small. But if you have memory to burn and access to char or short - * arrays is very slow on your hardware, you might want to change these. - */ - -#if BITS_IN_JSAMPLE == 8 -/* JSAMPLE should be the smallest type that will hold the values 0..255. - * You can use a signed char by having GETJSAMPLE mask it with 0xFF. - */ - -#ifdef HAVE_UNSIGNED_CHAR - -typedef unsigned char JSAMPLE; -#define GETJSAMPLE(value) ((int) (value)) - -#else /* not HAVE_UNSIGNED_CHAR */ - -typedef char JSAMPLE; -#ifdef CHAR_IS_UNSIGNED -#define GETJSAMPLE(value) ((int) (value)) -#else -#define GETJSAMPLE(value) ((int) (value) & 0xFF) -#endif /* CHAR_IS_UNSIGNED */ - -#endif /* HAVE_UNSIGNED_CHAR */ - -#define MAXJSAMPLE 255 -#define CENTERJSAMPLE 128 - -#endif /* BITS_IN_JSAMPLE == 8 */ - - -#if BITS_IN_JSAMPLE == 12 -/* JSAMPLE should be the smallest type that will hold the values 0..4095. - * On nearly all machines "short" will do nicely. - */ - -typedef short JSAMPLE; -#define GETJSAMPLE(value) ((int) (value)) - -#define MAXJSAMPLE 4095 -#define CENTERJSAMPLE 2048 - -#endif /* BITS_IN_JSAMPLE == 12 */ - - -/* Representation of a DCT frequency coefficient. - * This should be a signed value of at least 16 bits; "short" is usually OK. - * Again, we allocate large arrays of these, but you can change to int - * if you have memory to burn and "short" is really slow. - */ - -typedef short JCOEF; - - -/* Compressed datastreams are represented as arrays of JOCTET. - * These must be EXACTLY 8 bits wide, at least once they are written to - * external storage. Note that when using the stdio data source/destination - * managers, this is also the data type passed to fread/fwrite. - */ - -#ifdef HAVE_UNSIGNED_CHAR - -typedef unsigned char JOCTET; -#define GETJOCTET(value) (value) - -#else /* not HAVE_UNSIGNED_CHAR */ - -typedef char JOCTET; -#ifdef CHAR_IS_UNSIGNED -#define GETJOCTET(value) (value) -#else -#define GETJOCTET(value) ((value) & 0xFF) -#endif /* CHAR_IS_UNSIGNED */ - -#endif /* HAVE_UNSIGNED_CHAR */ - - -/* These typedefs are used for various table entries and so forth. - * They must be at least as wide as specified; but making them too big - * won't cost a huge amount of memory, so we don't provide special - * extraction code like we did for JSAMPLE. (In other words, these - * typedefs live at a different point on the speed/space tradeoff curve.) - */ - -/* UINT8 must hold at least the values 0..255. */ - -#ifdef HAVE_UNSIGNED_CHAR -typedef unsigned char UINT8; -#else /* not HAVE_UNSIGNED_CHAR */ -#ifdef CHAR_IS_UNSIGNED -typedef char UINT8; -#else /* not CHAR_IS_UNSIGNED */ -typedef short UINT8; -#endif /* CHAR_IS_UNSIGNED */ -#endif /* HAVE_UNSIGNED_CHAR */ - -/* UINT16 must hold at least the values 0..65535. */ - -#ifdef HAVE_UNSIGNED_SHORT -typedef unsigned short UINT16; -#else /* not HAVE_UNSIGNED_SHORT */ -typedef unsigned int UINT16; -#endif /* HAVE_UNSIGNED_SHORT */ - -typedef long INT32; - -/* INT16 must hold at least the values -32768..32767. */ - -#ifndef XMD_H /* X11/xmd.h correctly defines INT16 */ -typedef short INT16; -#endif - -/* INT32 must hold at least signed 32-bit values. */ - -//#ifndef XMD_H /* X11/xmd.h correctly defines INT32 */ -//typedef long INT32; -//#endif - -/* Datatype used for image dimensions. The JPEG standard only supports - * images up to 64K*64K due to 16-bit fields in SOF markers. Therefore - * "unsigned int" is sufficient on all machines. However, if you need to - * handle larger images and you don't mind deviating from the spec, you - * can change this datatype. - */ - -typedef unsigned int JDIMENSION; - -#define JPEG_MAX_DIMENSION 65500L /* a tad under 64K to prevent overflows */ - - -/* These defines are used in all function definitions and extern declarations. - * You could modify them if you need to change function linkage conventions. - * Another application is to make all functions global for use with debuggers - * or code profilers that require it. - */ - -#define METHODDEF static /* a function called through method pointers */ -#define LOCAL static /* a function used only in its module */ -#define GLOBAL /* a function referenced thru EXTERNs */ -#define EXTERN extern /* a reference to a GLOBAL function */ - - -/* Here is the pseudo-keyword for declaring pointers that must be "far" - * on 80x86 machines. Most of the specialized coding for 80x86 is handled - * by just saying "FAR *" where such a pointer is needed. In a few places - * explicit coding is needed; see uses of the NEED_FAR_POINTERS symbol. - */ - -#ifdef NEED_FAR_POINTERS -#undef FAR -#define FAR far -#else -#undef FAR -#define FAR -#endif - - -/* - * On a few systems, type boolean and/or its values FALSE, TRUE may appear - * in standard header files. Or you may have conflicts with application- - * specific header files that you want to include together with these files. - * Defining HAVE_BOOLEAN before including jpeglib.h should make it work. - */ - -//#ifndef HAVE_BOOLEAN -//typedef int boolean; -//#endif -#ifndef FALSE /* in case these macros already exist */ -#define FALSE 0 /* values of boolean */ -#endif -#ifndef TRUE -#define TRUE 1 -#endif - - -/* - * The remaining options affect code selection within the JPEG library, - * but they don't need to be visible to most applications using the library. - * To minimize application namespace pollution, the symbols won't be - * defined unless JPEG_INTERNALS or JPEG_INTERNAL_OPTIONS has been defined. - */ - -#ifdef JPEG_INTERNALS -#define JPEG_INTERNAL_OPTIONS -#endif - -#ifdef JPEG_INTERNAL_OPTIONS - - -/* - * These defines indicate whether to include various optional functions. - * Undefining some of these symbols will produce a smaller but less capable - * library. Note that you can leave certain source files out of the - * compilation/linking process if you've #undef'd the corresponding symbols. - * (You may HAVE to do that if your compiler doesn't like null source files.) - */ - -/* Arithmetic coding is unsupported for legal reasons. Complaints to IBM. */ - -/* Capability options common to encoder and decoder: */ - -#undef DCT_ISLOW_SUPPORTED /* slow but accurate integer algorithm */ -#undef DCT_IFAST_SUPPORTED /* faster, less accurate integer method */ -#define DCT_FLOAT_SUPPORTED /* floating-point: accurate, fast on fast HW */ - -/* Encoder capability options: */ - -#undef C_ARITH_CODING_SUPPORTED /* Arithmetic coding back end? */ -#define C_MULTISCAN_FILES_SUPPORTED /* Multiple-scan JPEG files? */ -#define C_PROGRESSIVE_SUPPORTED /* Progressive JPEG? (Requires MULTISCAN)*/ -#define ENTROPY_OPT_SUPPORTED /* Optimization of entropy coding parms? */ -/* Note: if you selected 12-bit data precision, it is dangerous to turn off - * ENTROPY_OPT_SUPPORTED. The standard Huffman tables are only good for 8-bit - * precision, so jchuff.c normally uses entropy optimization to compute - * usable tables for higher precision. If you don't want to do optimization, - * you'll have to supply different default Huffman tables. - * The exact same statements apply for progressive JPEG: the default tables - * don't work for progressive mode. (This may get fixed, however.) - */ -#define INPUT_SMOOTHING_SUPPORTED /* Input image smoothing option? */ - -/* Decoder capability options: */ - -#undef D_ARITH_CODING_SUPPORTED /* Arithmetic coding back end? */ -#undef D_MULTISCAN_FILES_SUPPORTED /* Multiple-scan JPEG files? */ -#undef D_PROGRESSIVE_SUPPORTED /* Progressive JPEG? (Requires MULTISCAN)*/ -#undef BLOCK_SMOOTHING_SUPPORTED /* Block smoothing? (Progressive only) */ -#undef IDCT_SCALING_SUPPORTED /* Output rescaling via IDCT? */ -#undef UPSAMPLE_SCALING_SUPPORTED /* Output rescaling at upsample stage? */ -#undef UPSAMPLE_MERGING_SUPPORTED /* Fast path for sloppy upsampling? */ -#undef QUANT_1PASS_SUPPORTED /* 1-pass color quantization? */ -#undef QUANT_2PASS_SUPPORTED /* 2-pass color quantization? */ - -/* more capability options later, no doubt */ - - -/* - * Ordering of RGB data in scanlines passed to or from the application. - * If your application wants to deal with data in the order B,G,R, just - * change these macros. You can also deal with formats such as R,G,B,X - * (one extra byte per pixel) by changing RGB_PIXELSIZE. Note that changing - * the offsets will also change the order in which colormap data is organized. - * RESTRICTIONS: - * 1. The sample applications cjpeg,djpeg do NOT support modified RGB formats. - * 2. These macros only affect RGB<=>YCbCr color conversion, so they are not - * useful if you are using JPEG color spaces other than YCbCr or grayscale. - * 3. The color quantizer modules will not behave desirably if RGB_PIXELSIZE - * is not 3 (they don't understand about dummy color components!). So you - * can't use color quantization if you change that value. - */ - -#define RGB_RED 0 /* Offset of Red in an RGB scanline element */ -#define RGB_GREEN 1 /* Offset of Green */ -#define RGB_BLUE 2 /* Offset of Blue */ -#define RGB_PIXELSIZE 4 /* JSAMPLEs per RGB scanline element */ - - -/* Definitions for speed-related optimizations. */ - - -/* If your compiler supports inline functions, define INLINE - * as the inline keyword; otherwise define it as empty. - */ - -#ifndef INLINE -#ifdef __GNUC__ /* for instance, GNU C knows about inline */ -#define INLINE __inline__ -#endif -#ifndef INLINE -#define INLINE /* default is to define it as empty */ -#endif -#endif - - -/* On some machines (notably 68000 series) "int" is 32 bits, but multiplying - * two 16-bit shorts is faster than multiplying two ints. Define MULTIPLIER - * as short on such a machine. MULTIPLIER must be at least 16 bits wide. - */ - -#ifndef MULTIPLIER -#define MULTIPLIER int /* type for fastest integer multiply */ -#endif - - -/* FAST_FLOAT should be either float or double, whichever is done faster - * by your compiler. (Note that this type is only used in the floating point - * DCT routines, so it only matters if you've defined DCT_FLOAT_SUPPORTED.) - * Typically, float is faster in ANSI C compilers, while double is faster in - * pre-ANSI compilers (because they insist on converting to double anyway). - * The code below therefore chooses float if we have ANSI-style prototypes. - */ - -#ifndef FAST_FLOAT -#ifdef HAVE_PROTOTYPES -#define FAST_FLOAT float -#else -#define FAST_FLOAT double -#endif -#endif - -#endif /* JPEG_INTERNAL_OPTIONS */ diff --git a/engine/jpeg-6/jpegint.h b/engine/jpeg-6/jpegint.h deleted file mode 100644 index ab5bee2..0000000 --- a/engine/jpeg-6/jpegint.h +++ /dev/null @@ -1,388 +0,0 @@ -/* - * jpegint.h - * - * Copyright (C) 1991-1995, Thomas G. Lane. - * This file is part of the Independent JPEG Group's software. - * For conditions of distribution and use, see the accompanying README file. - * - * This file provides common declarations for the various JPEG modules. - * These declarations are considered internal to the JPEG library; most - * applications using the library shouldn't need to include this file. - */ - - -/* Declarations for both compression & decompression */ - -typedef enum { /* Operating modes for buffer controllers */ - JBUF_PASS_THRU, /* Plain stripwise operation */ - /* Remaining modes require a full-image buffer to have been created */ - JBUF_SAVE_SOURCE, /* Run source subobject only, save output */ - JBUF_CRANK_DEST, /* Run dest subobject only, using saved data */ - JBUF_SAVE_AND_PASS /* Run both subobjects, save output */ -} J_BUF_MODE; - -/* Values of global_state field (jdapi.c has some dependencies on ordering!) */ -#define CSTATE_START 100 /* after create_compress */ -#define CSTATE_SCANNING 101 /* start_compress done, write_scanlines OK */ -#define CSTATE_RAW_OK 102 /* start_compress done, write_raw_data OK */ -#define CSTATE_WRCOEFS 103 /* jpeg_write_coefficients done */ -#define DSTATE_START 200 /* after create_decompress */ -#define DSTATE_INHEADER 201 /* reading header markers, no SOS yet */ -#define DSTATE_READY 202 /* found SOS, ready for start_decompress */ -#define DSTATE_PRELOAD 203 /* reading multiscan file in start_decompress*/ -#define DSTATE_PRESCAN 204 /* performing dummy pass for 2-pass quant */ -#define DSTATE_SCANNING 205 /* start_decompress done, read_scanlines OK */ -#define DSTATE_RAW_OK 206 /* start_decompress done, read_raw_data OK */ -#define DSTATE_BUFIMAGE 207 /* expecting jpeg_start_output */ -#define DSTATE_BUFPOST 208 /* looking for SOS/EOI in jpeg_finish_output */ -#define DSTATE_RDCOEFS 209 /* reading file in jpeg_read_coefficients */ -#define DSTATE_STOPPING 210 /* looking for EOI in jpeg_finish_decompress */ - - -/* Declarations for compression modules */ - -/* Master control module */ -struct jpeg_comp_master { - JMETHOD(void, prepare_for_pass, (j_compress_ptr cinfo)); - JMETHOD(void, pass_startup, (j_compress_ptr cinfo)); - JMETHOD(void, finish_pass, (j_compress_ptr cinfo)); - - /* State variables made visible to other modules */ - boolean call_pass_startup; /* True if pass_startup must be called */ - boolean is_last_pass; /* True during last pass */ -}; - -/* Main buffer control (downsampled-data buffer) */ -struct jpeg_c_main_controller { - JMETHOD(void, start_pass, (j_compress_ptr cinfo, J_BUF_MODE pass_mode)); - JMETHOD(void, process_data, (j_compress_ptr cinfo, - JSAMPARRAY input_buf, JDIMENSION *in_row_ctr, - JDIMENSION in_rows_avail)); -}; - -/* Compression preprocessing (downsampling input buffer control) */ -struct jpeg_c_prep_controller { - JMETHOD(void, start_pass, (j_compress_ptr cinfo, J_BUF_MODE pass_mode)); - JMETHOD(void, pre_process_data, (j_compress_ptr cinfo, - JSAMPARRAY input_buf, - JDIMENSION *in_row_ctr, - JDIMENSION in_rows_avail, - JSAMPIMAGE output_buf, - JDIMENSION *out_row_group_ctr, - JDIMENSION out_row_groups_avail)); -}; - -/* Coefficient buffer control */ -struct jpeg_c_coef_controller { - JMETHOD(void, start_pass, (j_compress_ptr cinfo, J_BUF_MODE pass_mode)); - JMETHOD(boolean, compress_data, (j_compress_ptr cinfo, - JSAMPIMAGE input_buf)); -}; - -/* Colorspace conversion */ -struct jpeg_color_converter { - JMETHOD(void, start_pass, (j_compress_ptr cinfo)); - JMETHOD(void, color_convert, (j_compress_ptr cinfo, - JSAMPARRAY input_buf, JSAMPIMAGE output_buf, - JDIMENSION output_row, int num_rows)); -}; - -/* Downsampling */ -struct jpeg_downsampler { - JMETHOD(void, start_pass, (j_compress_ptr cinfo)); - JMETHOD(void, downsample, (j_compress_ptr cinfo, - JSAMPIMAGE input_buf, JDIMENSION in_row_index, - JSAMPIMAGE output_buf, - JDIMENSION out_row_group_index)); - - boolean need_context_rows; /* TRUE if need rows above & below */ -}; - -/* Forward DCT (also controls coefficient quantization) */ -struct jpeg_forward_dct { - JMETHOD(void, start_pass, (j_compress_ptr cinfo)); - /* perhaps this should be an array??? */ - JMETHOD(void, forward_DCT, (j_compress_ptr cinfo, - jpeg_component_info * compptr, - JSAMPARRAY sample_data, JBLOCKROW coef_blocks, - JDIMENSION start_row, JDIMENSION start_col, - JDIMENSION num_blocks)); -}; - -/* Entropy encoding */ -struct jpeg_entropy_encoder { - JMETHOD(void, start_pass, (j_compress_ptr cinfo, boolean gather_statistics)); - JMETHOD(boolean, encode_mcu, (j_compress_ptr cinfo, JBLOCKROW *MCU_data)); - JMETHOD(void, finish_pass, (j_compress_ptr cinfo)); -}; - -/* Marker writing */ -struct jpeg_marker_writer { - /* write_any_marker is exported for use by applications */ - /* Probably only COM and APPn markers should be written */ - JMETHOD(void, write_any_marker, (j_compress_ptr cinfo, int marker, - const JOCTET *dataptr, unsigned int datalen)); - JMETHOD(void, write_file_header, (j_compress_ptr cinfo)); - JMETHOD(void, write_frame_header, (j_compress_ptr cinfo)); - JMETHOD(void, write_scan_header, (j_compress_ptr cinfo)); - JMETHOD(void, write_file_trailer, (j_compress_ptr cinfo)); - JMETHOD(void, write_tables_only, (j_compress_ptr cinfo)); -}; - - -/* Declarations for decompression modules */ - -/* Master control module */ -struct jpeg_decomp_master { - JMETHOD(void, prepare_for_output_pass, (j_decompress_ptr cinfo)); - JMETHOD(void, finish_output_pass, (j_decompress_ptr cinfo)); - - /* State variables made visible to other modules */ - boolean is_dummy_pass; /* True during 1st pass for 2-pass quant */ -}; - -/* Input control module */ -struct jpeg_input_controller { - JMETHOD(int, consume_input, (j_decompress_ptr cinfo)); - JMETHOD(void, reset_input_controller, (j_decompress_ptr cinfo)); - JMETHOD(void, start_input_pass, (j_decompress_ptr cinfo)); - JMETHOD(void, finish_input_pass, (j_decompress_ptr cinfo)); - - /* State variables made visible to other modules */ - boolean has_multiple_scans; /* True if file has multiple scans */ - boolean eoi_reached; /* True when EOI has been consumed */ -}; - -/* Main buffer control (downsampled-data buffer) */ -struct jpeg_d_main_controller { - JMETHOD(void, start_pass, (j_decompress_ptr cinfo, J_BUF_MODE pass_mode)); - JMETHOD(void, process_data, (j_decompress_ptr cinfo, - JSAMPARRAY output_buf, JDIMENSION *out_row_ctr, - JDIMENSION out_rows_avail)); -}; - -/* Coefficient buffer control */ -struct jpeg_d_coef_controller { - JMETHOD(void, start_input_pass, (j_decompress_ptr cinfo)); - JMETHOD(int, consume_data, (j_decompress_ptr cinfo)); - JMETHOD(void, start_output_pass, (j_decompress_ptr cinfo)); - JMETHOD(int, decompress_data, (j_decompress_ptr cinfo, - JSAMPIMAGE output_buf)); - /* Pointer to array of coefficient virtual arrays, or NULL if none */ - jvirt_barray_ptr *coef_arrays; -}; - -/* Decompression postprocessing (color quantization buffer control) */ -struct jpeg_d_post_controller { - JMETHOD(void, start_pass, (j_decompress_ptr cinfo, J_BUF_MODE pass_mode)); - JMETHOD(void, post_process_data, (j_decompress_ptr cinfo, - JSAMPIMAGE input_buf, - JDIMENSION *in_row_group_ctr, - JDIMENSION in_row_groups_avail, - JSAMPARRAY output_buf, - JDIMENSION *out_row_ctr, - JDIMENSION out_rows_avail)); -}; - -/* Marker reading & parsing */ -struct jpeg_marker_reader { - JMETHOD(void, reset_marker_reader, (j_decompress_ptr cinfo)); - /* Read markers until SOS or EOI. - * Returns same codes as are defined for jpeg_consume_input: - * JPEG_SUSPENDED, JPEG_REACHED_SOS, or JPEG_REACHED_EOI. - */ - JMETHOD(int, read_markers, (j_decompress_ptr cinfo)); - /* Read a restart marker --- exported for use by entropy decoder only */ - jpeg_marker_parser_method read_restart_marker; - /* Application-overridable marker processing methods */ - jpeg_marker_parser_method process_COM; - jpeg_marker_parser_method process_APPn[16]; - - /* State of marker reader --- nominally internal, but applications - * supplying COM or APPn handlers might like to know the state. - */ - boolean saw_SOI; /* found SOI? */ - boolean saw_SOF; /* found SOF? */ - int next_restart_num; /* next restart number expected (0-7) */ - unsigned int discarded_bytes; /* # of bytes skipped looking for a marker */ -}; - -/* Entropy decoding */ -struct jpeg_entropy_decoder { - JMETHOD(void, start_pass, (j_decompress_ptr cinfo)); - JMETHOD(boolean, decode_mcu, (j_decompress_ptr cinfo, - JBLOCKROW *MCU_data)); -}; - -/* Inverse DCT (also performs dequantization) */ -typedef JMETHOD(void, inverse_DCT_method_ptr, - (j_decompress_ptr cinfo, jpeg_component_info * compptr, - JCOEFPTR coef_block, - JSAMPARRAY output_buf, JDIMENSION output_col)); - -struct jpeg_inverse_dct { - JMETHOD(void, start_pass, (j_decompress_ptr cinfo)); - /* It is useful to allow each component to have a separate IDCT method. */ - inverse_DCT_method_ptr inverse_DCT[MAX_COMPONENTS]; -}; - -/* Upsampling (note that upsampler must also call color converter) */ -struct jpeg_upsampler { - JMETHOD(void, start_pass, (j_decompress_ptr cinfo)); - JMETHOD(void, upsample, (j_decompress_ptr cinfo, - JSAMPIMAGE input_buf, - JDIMENSION *in_row_group_ctr, - JDIMENSION in_row_groups_avail, - JSAMPARRAY output_buf, - JDIMENSION *out_row_ctr, - JDIMENSION out_rows_avail)); - - boolean need_context_rows; /* TRUE if need rows above & below */ -}; - -/* Colorspace conversion */ -struct jpeg_color_deconverter { - JMETHOD(void, start_pass, (j_decompress_ptr cinfo)); - JMETHOD(void, color_convert, (j_decompress_ptr cinfo, - JSAMPIMAGE input_buf, JDIMENSION input_row, - JSAMPARRAY output_buf, int num_rows)); -}; - -/* Color quantization or color precision reduction */ -struct jpeg_color_quantizer { - JMETHOD(void, start_pass, (j_decompress_ptr cinfo, boolean is_pre_scan)); - JMETHOD(void, color_quantize, (j_decompress_ptr cinfo, - JSAMPARRAY input_buf, JSAMPARRAY output_buf, - int num_rows)); - JMETHOD(void, finish_pass, (j_decompress_ptr cinfo)); - JMETHOD(void, new_color_map, (j_decompress_ptr cinfo)); -}; - - -/* Miscellaneous useful macros */ - -#undef MAX -#define MAX(a,b) ((a) > (b) ? (a) : (b)) -#undef MIN -#define MIN(a,b) ((a) < (b) ? (a) : (b)) - - -/* We assume that right shift corresponds to signed division by 2 with - * rounding towards minus infinity. This is correct for typical "arithmetic - * shift" instructions that shift in copies of the sign bit. But some - * C compilers implement >> with an unsigned shift. For these machines you - * must define RIGHT_SHIFT_IS_UNSIGNED. - * RIGHT_SHIFT provides a proper signed right shift of an INT32 quantity. - * It is only applied with constant shift counts. SHIFT_TEMPS must be - * included in the variables of any routine using RIGHT_SHIFT. - */ - -#ifdef RIGHT_SHIFT_IS_UNSIGNED -#define SHIFT_TEMPS INT32 shift_temp; -#define RIGHT_SHIFT(x,shft) \ - ((shift_temp = (x)) < 0 ? \ - (shift_temp >> (shft)) | ((~((INT32) 0)) << (32-(shft))) : \ - (shift_temp >> (shft))) -#else -#define SHIFT_TEMPS -#define RIGHT_SHIFT(x,shft) ((x) >> (shft)) -#endif - - -/* Short forms of external names for systems with brain-damaged linkers. */ - -#ifdef NEED_SHORT_EXTERNAL_NAMES -#define jinit_compress_master jICompress -#define jinit_c_master_control jICMaster -#define jinit_c_main_controller jICMainC -#define jinit_c_prep_controller jICPrepC -#define jinit_c_coef_controller jICCoefC -#define jinit_color_converter jICColor -#define jinit_downsampler jIDownsampler -#define jinit_forward_dct jIFDCT -#define jinit_huff_encoder jIHEncoder -#define jinit_phuff_encoder jIPHEncoder -#define jinit_marker_writer jIMWriter -#define jinit_master_decompress jIDMaster -#define jinit_d_main_controller jIDMainC -#define jinit_d_coef_controller jIDCoefC -#define jinit_d_post_controller jIDPostC -#define jinit_input_controller jIInCtlr -#define jinit_marker_reader jIMReader -#define jinit_huff_decoder jIHDecoder -#define jinit_phuff_decoder jIPHDecoder -#define jinit_inverse_dct jIIDCT -#define jinit_upsampler jIUpsampler -#define jinit_color_deconverter jIDColor -#define jinit_1pass_quantizer jI1Quant -#define jinit_2pass_quantizer jI2Quant -#define jinit_merged_upsampler jIMUpsampler -#define jinit_memory_mgr jIMemMgr -#define jdiv_round_up jDivRound -#define jround_up jRound -#define jcopy_sample_rows jCopySamples -#define jcopy_block_row jCopyBlocks -#define jzero_far jZeroFar -#define jpeg_zigzag_order jZIGTable -#define jpeg_natural_order jZAGTable -#endif /* NEED_SHORT_EXTERNAL_NAMES */ - - -/* Compression module initialization routines */ -EXTERN void jinit_compress_master JPP((j_compress_ptr cinfo)); -EXTERN void jinit_c_master_control JPP((j_compress_ptr cinfo, - boolean transcode_only)); -EXTERN void jinit_c_main_controller JPP((j_compress_ptr cinfo, - boolean need_full_buffer)); -EXTERN void jinit_c_prep_controller JPP((j_compress_ptr cinfo, - boolean need_full_buffer)); -EXTERN void jinit_c_coef_controller JPP((j_compress_ptr cinfo, - boolean need_full_buffer)); -EXTERN void jinit_color_converter JPP((j_compress_ptr cinfo)); -EXTERN void jinit_downsampler JPP((j_compress_ptr cinfo)); -EXTERN void jinit_forward_dct JPP((j_compress_ptr cinfo)); -EXTERN void jinit_huff_encoder JPP((j_compress_ptr cinfo)); -EXTERN void jinit_phuff_encoder JPP((j_compress_ptr cinfo)); -EXTERN void jinit_marker_writer JPP((j_compress_ptr cinfo)); -/* Decompression module initialization routines */ -EXTERN void jinit_master_decompress JPP((j_decompress_ptr cinfo)); -EXTERN void jinit_d_main_controller JPP((j_decompress_ptr cinfo, - boolean need_full_buffer)); -EXTERN void jinit_d_coef_controller JPP((j_decompress_ptr cinfo, - boolean need_full_buffer)); -EXTERN void jinit_d_post_controller JPP((j_decompress_ptr cinfo, - boolean need_full_buffer)); -EXTERN void jinit_input_controller JPP((j_decompress_ptr cinfo)); -EXTERN void jinit_marker_reader JPP((j_decompress_ptr cinfo)); -EXTERN void jinit_huff_decoder JPP((j_decompress_ptr cinfo)); -EXTERN void jinit_phuff_decoder JPP((j_decompress_ptr cinfo)); -EXTERN void jinit_inverse_dct JPP((j_decompress_ptr cinfo)); -EXTERN void jinit_upsampler JPP((j_decompress_ptr cinfo)); -EXTERN void jinit_color_deconverter JPP((j_decompress_ptr cinfo)); -EXTERN void jinit_1pass_quantizer JPP((j_decompress_ptr cinfo)); -EXTERN void jinit_2pass_quantizer JPP((j_decompress_ptr cinfo)); -EXTERN void jinit_merged_upsampler JPP((j_decompress_ptr cinfo)); -/* Memory manager initialization */ -EXTERN void jinit_memory_mgr JPP((j_common_ptr cinfo)); - -/* Utility routines in jutils.c */ -EXTERN long jdiv_round_up JPP((long a, long b)); -EXTERN long jround_up JPP((long a, long b)); -EXTERN void jcopy_sample_rows JPP((JSAMPARRAY input_array, int source_row, - JSAMPARRAY output_array, int dest_row, - int num_rows, JDIMENSION num_cols)); -EXTERN void jcopy_block_row JPP((JBLOCKROW input_row, JBLOCKROW output_row, - JDIMENSION num_blocks)); -EXTERN void jzero_far JPP((void FAR * target, size_t bytestozero)); -/* Constant tables in jutils.c */ -extern const int jpeg_zigzag_order[]; /* natural coef order to zigzag order */ -extern const int jpeg_natural_order[]; /* zigzag coef order to natural order */ - -/* Suppress undefined-structure complaints if necessary. */ - -#ifdef INCOMPLETE_TYPES_BROKEN -#ifndef AM_MEMORY_MANAGER /* only jmemmgr.c defines these */ -struct jvirt_sarray_control { long dummy; }; -struct jvirt_barray_control { long dummy; }; -#endif -#endif /* INCOMPLETE_TYPES_BROKEN */ diff --git a/engine/jpeg-6/jpeglib.h b/engine/jpeg-6/jpeglib.h deleted file mode 100644 index edfdda1..0000000 --- a/engine/jpeg-6/jpeglib.h +++ /dev/null @@ -1,1051 +0,0 @@ -/* - * jpeglib.h - * - * Copyright (C) 1991-1995, Thomas G. Lane. - * This file is part of the Independent JPEG Group's software. - * For conditions of distribution and use, see the accompanying README file. - * - * This file defines the application interface for the JPEG library. - * Most applications using the library need only include this file, - * and perhaps jerror.h if they want to know the exact error codes. - */ - -#ifndef JPEGLIB_H -#define JPEGLIB_H - -typedef unsigned char boolean; -/* - * First we include the configuration files that record how this - * installation of the JPEG library is set up. jconfig.h can be - * generated automatically for many systems. jmorecfg.h contains - * manual configuration options that most people need not worry about. - */ - -#ifndef JCONFIG_INCLUDED /* in case jinclude.h already did */ -#include "../jpeg-6/jconfig.h" /* widely used configuration options */ -#endif -#include "../jpeg-6/jmorecfg.h" /* seldom changed options */ - - -/* Version ID for the JPEG library. - * Might be useful for tests like "#if JPEG_LIB_VERSION >= 60". - */ - -#define JPEG_LIB_VERSION 60 /* Version 6 */ - - -/* Various constants determining the sizes of things. - * All of these are specified by the JPEG standard, so don't change them - * if you want to be compatible. - */ - -#define DCTSIZE 8 /* The basic DCT block is 8x8 samples */ -#define DCTSIZE2 64 /* DCTSIZE squared; # of elements in a block */ -#define NUM_QUANT_TBLS 4 /* Quantization tables are numbered 0..3 */ -#define NUM_HUFF_TBLS 4 /* Huffman tables are numbered 0..3 */ -#define NUM_ARITH_TBLS 16 /* Arith-coding tables are numbered 0..15 */ -#define MAX_COMPS_IN_SCAN 4 /* JPEG limit on # of components in one scan */ -#define MAX_SAMP_FACTOR 4 /* JPEG limit on sampling factors */ -/* Unfortunately, some bozo at Adobe saw no reason to be bound by the standard; - * the PostScript DCT filter can emit files with many more than 10 blocks/MCU. - * If you happen to run across such a file, you can up D_MAX_BLOCKS_IN_MCU - * to handle it. We even let you do this from the jconfig.h file. However, - * we strongly discourage changing C_MAX_BLOCKS_IN_MCU; just because Adobe - * sometimes emits noncompliant files doesn't mean you should too. - */ -#define C_MAX_BLOCKS_IN_MCU 10 /* compressor's limit on blocks per MCU */ -#ifndef D_MAX_BLOCKS_IN_MCU -#define D_MAX_BLOCKS_IN_MCU 10 /* decompressor's limit on blocks per MCU */ -#endif - - -/* This macro is used to declare a "method", that is, a function pointer. - * We want to supply prototype parameters if the compiler can cope. - * Note that the arglist parameter must be parenthesized! - */ - -#ifdef HAVE_PROTOTYPES -#define JMETHOD(type,methodname,arglist) type (*methodname) arglist -#else -#define JMETHOD(type,methodname,arglist) type (*methodname) () -#endif - - -/* Data structures for images (arrays of samples and of DCT coefficients). - * On 80x86 machines, the image arrays are too big for near pointers, - * but the pointer arrays can fit in near memory. - */ - -typedef JSAMPLE FAR *JSAMPROW; /* ptr to one image row of pixel samples. */ -typedef JSAMPROW *JSAMPARRAY; /* ptr to some rows (a 2-D sample array) */ -typedef JSAMPARRAY *JSAMPIMAGE; /* a 3-D sample array: top index is color */ - -typedef JCOEF JBLOCK[DCTSIZE2]; /* one block of coefficients */ -typedef JBLOCK FAR *JBLOCKROW; /* pointer to one row of coefficient blocks */ -typedef JBLOCKROW *JBLOCKARRAY; /* a 2-D array of coefficient blocks */ -typedef JBLOCKARRAY *JBLOCKIMAGE; /* a 3-D array of coefficient blocks */ - -typedef JCOEF FAR *JCOEFPTR; /* useful in a couple of places */ - - -/* Types for JPEG compression parameters and working tables. */ - - -/* DCT coefficient quantization tables. */ - -typedef struct { - /* This field directly represents the contents of a JPEG DQT marker. - * Note: the values are always given in zigzag order. - */ - UINT16 quantval[DCTSIZE2]; /* quantization step for each coefficient */ - /* This field is used only during compression. It's initialized FALSE when - * the table is created, and set TRUE when it's been output to the file. - * You could suppress output of a table by setting this to TRUE. - * (See jpeg_suppress_tables for an example.) - */ - boolean sent_table; /* TRUE when table has been output */ -} JQUANT_TBL; - - -/* Huffman coding tables. */ - -typedef struct { - /* These two fields directly represent the contents of a JPEG DHT marker */ - UINT8 bits[17]; /* bits[k] = # of symbols with codes of */ - /* length k bits; bits[0] is unused */ - UINT8 huffval[256]; /* The symbols, in order of incr code length */ - /* This field is used only during compression. It's initialized FALSE when - * the table is created, and set TRUE when it's been output to the file. - * You could suppress output of a table by setting this to TRUE. - * (See jpeg_suppress_tables for an example.) - */ - boolean sent_table; /* TRUE when table has been output */ -} JHUFF_TBL; - - -/* Basic info about one component (color channel). */ - -typedef struct { - /* These values are fixed over the whole image. */ - /* For compression, they must be supplied by parameter setup; */ - /* for decompression, they are read from the SOF marker. */ - int component_id; /* identifier for this component (0..255) */ - int component_index; /* its index in SOF or cinfo->comp_info[] */ - int h_samp_factor; /* horizontal sampling factor (1..4) */ - int v_samp_factor; /* vertical sampling factor (1..4) */ - int quant_tbl_no; /* quantization table selector (0..3) */ - /* These values may vary between scans. */ - /* For compression, they must be supplied by parameter setup; */ - /* for decompression, they are read from the SOS marker. */ - /* The decompressor output side may not use these variables. */ - int dc_tbl_no; /* DC entropy table selector (0..3) */ - int ac_tbl_no; /* AC entropy table selector (0..3) */ - - /* Remaining fields should be treated as private by applications. */ - - /* These values are computed during compression or decompression startup: */ - /* Component's size in DCT blocks. - * Any dummy blocks added to complete an MCU are not counted; therefore - * these values do not depend on whether a scan is interleaved or not. - */ - JDIMENSION width_in_blocks; - JDIMENSION height_in_blocks; - /* Size of a DCT block in samples. Always DCTSIZE for compression. - * For decompression this is the size of the output from one DCT block, - * reflecting any scaling we choose to apply during the IDCT step. - * Values of 1,2,4,8 are likely to be supported. Note that different - * components may receive different IDCT scalings. - */ - int DCT_scaled_size; - /* The downsampled dimensions are the component's actual, unpadded number - * of samples at the main buffer (preprocessing/compression interface), thus - * downsampled_width = ceil(image_width * Hi/Hmax) - * and similarly for height. For decompression, IDCT scaling is included, so - * downsampled_width = ceil(image_width * Hi/Hmax * DCT_scaled_size/DCTSIZE) - */ - JDIMENSION downsampled_width; /* actual width in samples */ - JDIMENSION downsampled_height; /* actual height in samples */ - /* This flag is used only for decompression. In cases where some of the - * components will be ignored (eg grayscale output from YCbCr image), - * we can skip most computations for the unused components. - */ - boolean component_needed; /* do we need the value of this component? */ - - /* These values are computed before starting a scan of the component. */ - /* The decompressor output side may not use these variables. */ - int MCU_width; /* number of blocks per MCU, horizontally */ - int MCU_height; /* number of blocks per MCU, vertically */ - int MCU_blocks; /* MCU_width * MCU_height */ - int MCU_sample_width; /* MCU width in samples, MCU_width*DCT_scaled_size */ - int last_col_width; /* # of non-dummy blocks across in last MCU */ - int last_row_height; /* # of non-dummy blocks down in last MCU */ - - /* Saved quantization table for component; NULL if none yet saved. - * See jdinput.c comments about the need for this information. - * This field is not currently used by the compressor. - */ - JQUANT_TBL * quant_table; - - /* Private per-component storage for DCT or IDCT subsystem. */ - void * dct_table; -} jpeg_component_info; - - -/* The script for encoding a multiple-scan file is an array of these: */ - -typedef struct { - int comps_in_scan; /* number of components encoded in this scan */ - int component_index[MAX_COMPS_IN_SCAN]; /* their SOF/comp_info[] indexes */ - int Ss, Se; /* progressive JPEG spectral selection parms */ - int Ah, Al; /* progressive JPEG successive approx. parms */ -} jpeg_scan_info; - - -/* Known color spaces. */ - -typedef enum { - JCS_UNKNOWN, /* error/unspecified */ - JCS_GRAYSCALE, /* monochrome */ - JCS_RGB, /* red/green/blue */ - JCS_YCbCr, /* Y/Cb/Cr (also known as YUV) */ - JCS_CMYK, /* C/M/Y/K */ - JCS_YCCK /* Y/Cb/Cr/K */ -} J_COLOR_SPACE; - -/* DCT/IDCT algorithm options. */ - -typedef enum { - JDCT_ISLOW, /* slow but accurate integer algorithm */ - JDCT_IFAST, /* faster, less accurate integer method */ - JDCT_FLOAT /* floating-point: accurate, fast on fast HW */ -} J_DCT_METHOD; - -#ifndef JDCT_DEFAULT /* may be overridden in jconfig.h */ -#define JDCT_DEFAULT JDCT_ISLOW -#endif -#ifndef JDCT_FASTEST /* may be overridden in jconfig.h */ -#define JDCT_FASTEST JDCT_IFAST -#endif - -/* Dithering options for decompression. */ - -typedef enum { - JDITHER_NONE, /* no dithering */ - JDITHER_ORDERED, /* simple ordered dither */ - JDITHER_FS /* Floyd-Steinberg error diffusion dither */ -} J_DITHER_MODE; - - -/* Common fields between JPEG compression and decompression master structs. */ - -#define jpeg_common_fields \ - struct jpeg_error_mgr * err; /* Error handler module */\ - struct jpeg_memory_mgr * mem; /* Memory manager module */\ - struct jpeg_progress_mgr * progress; /* Progress monitor, or NULL if none */\ - boolean is_decompressor; /* so common code can tell which is which */\ - int global_state /* for checking call sequence validity */ - -/* Routines that are to be used by both halves of the library are declared - * to receive a pointer to this structure. There are no actual instances of - * jpeg_common_struct, only of jpeg_compress_struct and jpeg_decompress_struct. - */ -struct jpeg_common_struct { - jpeg_common_fields; /* Fields common to both master struct types */ - /* Additional fields follow in an actual jpeg_compress_struct or - * jpeg_decompress_struct. All three structs must agree on these - * initial fields! (This would be a lot cleaner in C++.) - */ -}; - -typedef struct jpeg_common_struct * j_common_ptr; -typedef struct jpeg_compress_struct * j_compress_ptr; -typedef struct jpeg_decompress_struct * j_decompress_ptr; - - -/* Master record for a compression instance */ - -struct jpeg_compress_struct { - jpeg_common_fields; /* Fields shared with jpeg_decompress_struct */ - - /* Destination for compressed data */ - struct jpeg_destination_mgr * dest; - - /* Description of source image --- these fields must be filled in by - * outer application before starting compression. in_color_space must - * be correct before you can even call jpeg_set_defaults(). - */ - - JDIMENSION image_width; /* input image width */ - JDIMENSION image_height; /* input image height */ - int input_components; /* # of color components in input image */ - J_COLOR_SPACE in_color_space; /* colorspace of input image */ - - double input_gamma; /* image gamma of input image */ - - /* Compression parameters --- these fields must be set before calling - * jpeg_start_compress(). We recommend calling jpeg_set_defaults() to - * initialize everything to reasonable defaults, then changing anything - * the application specifically wants to change. That way you won't get - * burnt when new parameters are added. Also note that there are several - * helper routines to simplify changing parameters. - */ - - int data_precision; /* bits of precision in image data */ - - int num_components; /* # of color components in JPEG image */ - J_COLOR_SPACE jpeg_color_space; /* colorspace of JPEG image */ - - jpeg_component_info * comp_info; - /* comp_info[i] describes component that appears i'th in SOF */ - - JQUANT_TBL * quant_tbl_ptrs[NUM_QUANT_TBLS]; - /* ptrs to coefficient quantization tables, or NULL if not defined */ - - JHUFF_TBL * dc_huff_tbl_ptrs[NUM_HUFF_TBLS]; - JHUFF_TBL * ac_huff_tbl_ptrs[NUM_HUFF_TBLS]; - /* ptrs to Huffman coding tables, or NULL if not defined */ - - UINT8 arith_dc_L[NUM_ARITH_TBLS]; /* L values for DC arith-coding tables */ - UINT8 arith_dc_U[NUM_ARITH_TBLS]; /* U values for DC arith-coding tables */ - UINT8 arith_ac_K[NUM_ARITH_TBLS]; /* Kx values for AC arith-coding tables */ - - int num_scans; /* # of entries in scan_info array */ - const jpeg_scan_info * scan_info; /* script for multi-scan file, or NULL */ - /* The default value of scan_info is NULL, which causes a single-scan - * sequential JPEG file to be emitted. To create a multi-scan file, - * set num_scans and scan_info to point to an array of scan definitions. - */ - - boolean raw_data_in; /* TRUE=caller supplies downsampled data */ - boolean arith_code; /* TRUE=arithmetic coding, FALSE=Huffman */ - boolean optimize_coding; /* TRUE=optimize entropy encoding parms */ - boolean CCIR601_sampling; /* TRUE=first samples are cosited */ - int smoothing_factor; /* 1..100, or 0 for no input smoothing */ - J_DCT_METHOD dct_method; /* DCT algorithm selector */ - - /* The restart interval can be specified in absolute MCUs by setting - * restart_interval, or in MCU rows by setting restart_in_rows - * (in which case the correct restart_interval will be figured - * for each scan). - */ - unsigned int restart_interval; /* MCUs per restart, or 0 for no restart */ - int restart_in_rows; /* if > 0, MCU rows per restart interval */ - - /* Parameters controlling emission of special markers. */ - - boolean write_JFIF_header; /* should a JFIF marker be written? */ - /* These three values are not used by the JPEG code, merely copied */ - /* into the JFIF APP0 marker. density_unit can be 0 for unknown, */ - /* 1 for dots/inch, or 2 for dots/cm. Note that the pixel aspect */ - /* ratio is defined by X_density/Y_density even when density_unit=0. */ - UINT8 density_unit; /* JFIF code for pixel size units */ - UINT16 X_density; /* Horizontal pixel density */ - UINT16 Y_density; /* Vertical pixel density */ - boolean write_Adobe_marker; /* should an Adobe marker be written? */ - - /* State variable: index of next scanline to be written to - * jpeg_write_scanlines(). Application may use this to control its - * processing loop, e.g., "while (next_scanline < image_height)". - */ - - JDIMENSION next_scanline; /* 0 .. image_height-1 */ - - /* Remaining fields are known throughout compressor, but generally - * should not be touched by a surrounding application. - */ - - /* - * These fields are computed during compression startup - */ - boolean progressive_mode; /* TRUE if scan script uses progressive mode */ - int max_h_samp_factor; /* largest h_samp_factor */ - int max_v_samp_factor; /* largest v_samp_factor */ - - JDIMENSION total_iMCU_rows; /* # of iMCU rows to be input to coef ctlr */ - /* The coefficient controller receives data in units of MCU rows as defined - * for fully interleaved scans (whether the JPEG file is interleaved or not). - * There are v_samp_factor * DCTSIZE sample rows of each component in an - * "iMCU" (interleaved MCU) row. - */ - - /* - * These fields are valid during any one scan. - * They describe the components and MCUs actually appearing in the scan. - */ - int comps_in_scan; /* # of JPEG components in this scan */ - jpeg_component_info * cur_comp_info[MAX_COMPS_IN_SCAN]; - /* *cur_comp_info[i] describes component that appears i'th in SOS */ - - JDIMENSION MCUs_per_row; /* # of MCUs across the image */ - JDIMENSION MCU_rows_in_scan; /* # of MCU rows in the image */ - - int blocks_in_MCU; /* # of DCT blocks per MCU */ - int MCU_membership[C_MAX_BLOCKS_IN_MCU]; - /* MCU_membership[i] is index in cur_comp_info of component owning */ - /* i'th block in an MCU */ - - int Ss, Se, Ah, Al; /* progressive JPEG parameters for scan */ - - /* - * Links to compression subobjects (methods and private variables of modules) - */ - struct jpeg_comp_master * master; - struct jpeg_c_main_controller * main; - struct jpeg_c_prep_controller * prep; - struct jpeg_c_coef_controller * coef; - struct jpeg_marker_writer * marker; - struct jpeg_color_converter * cconvert; - struct jpeg_downsampler * downsample; - struct jpeg_forward_dct * fdct; - struct jpeg_entropy_encoder * entropy; -}; - - -/* Master record for a decompression instance */ - -struct jpeg_decompress_struct { - jpeg_common_fields; /* Fields shared with jpeg_compress_struct */ - - /* Source of compressed data */ - struct jpeg_source_mgr * src; - - /* Basic description of image --- filled in by jpeg_read_header(). */ - /* Application may inspect these values to decide how to process image. */ - - JDIMENSION image_width; /* nominal image width (from SOF marker) */ - JDIMENSION image_height; /* nominal image height */ - int num_components; /* # of color components in JPEG image */ - J_COLOR_SPACE jpeg_color_space; /* colorspace of JPEG image */ - - /* Decompression processing parameters --- these fields must be set before - * calling jpeg_start_decompress(). Note that jpeg_read_header() initializes - * them to default values. - */ - - J_COLOR_SPACE out_color_space; /* colorspace for output */ - - unsigned int scale_num, scale_denom; /* fraction by which to scale image */ - - double output_gamma; /* image gamma wanted in output */ - - boolean buffered_image; /* TRUE=multiple output passes */ - boolean raw_data_out; /* TRUE=downsampled data wanted */ - - J_DCT_METHOD dct_method; /* IDCT algorithm selector */ - boolean do_fancy_upsampling; /* TRUE=apply fancy upsampling */ - boolean do_block_smoothing; /* TRUE=apply interblock smoothing */ - - boolean quantize_colors; /* TRUE=colormapped output wanted */ - /* the following are ignored if not quantize_colors: */ - J_DITHER_MODE dither_mode; /* type of color dithering to use */ - boolean two_pass_quantize; /* TRUE=use two-pass color quantization */ - int desired_number_of_colors; /* max # colors to use in created colormap */ - /* these are significant only in buffered-image mode: */ - boolean enable_1pass_quant; /* enable future use of 1-pass quantizer */ - boolean enable_external_quant;/* enable future use of external colormap */ - boolean enable_2pass_quant; /* enable future use of 2-pass quantizer */ - - /* Description of actual output image that will be returned to application. - * These fields are computed by jpeg_start_decompress(). - * You can also use jpeg_calc_output_dimensions() to determine these values - * in advance of calling jpeg_start_decompress(). - */ - - JDIMENSION output_width; /* scaled image width */ - JDIMENSION output_height; /* scaled image height */ - int out_color_components; /* # of color components in out_color_space */ - int output_components; /* # of color components returned */ - /* output_components is 1 (a colormap index) when quantizing colors; - * otherwise it equals out_color_components. - */ - int rec_outbuf_height; /* min recommended height of scanline buffer */ - /* If the buffer passed to jpeg_read_scanlines() is less than this many rows - * high, space and time will be wasted due to unnecessary data copying. - * Usually rec_outbuf_height will be 1 or 2, at most 4. - */ - - /* When quantizing colors, the output colormap is described by these fields. - * The application can supply a colormap by setting colormap non-NULL before - * calling jpeg_start_decompress; otherwise a colormap is created during - * jpeg_start_decompress or jpeg_start_output. - * The map has out_color_components rows and actual_number_of_colors columns. - */ - int actual_number_of_colors; /* number of entries in use */ - JSAMPARRAY colormap; /* The color map as a 2-D pixel array */ - - /* State variables: these variables indicate the progress of decompression. - * The application may examine these but must not modify them. - */ - - /* Row index of next scanline to be read from jpeg_read_scanlines(). - * Application may use this to control its processing loop, e.g., - * "while (output_scanline < output_height)". - */ - JDIMENSION output_scanline; /* 0 .. output_height-1 */ - - /* Current input scan number and number of iMCU rows completed in scan. - * These indicate the progress of the decompressor input side. - */ - int input_scan_number; /* Number of SOS markers seen so far */ - JDIMENSION input_iMCU_row; /* Number of iMCU rows completed */ - - /* The "output scan number" is the notional scan being displayed by the - * output side. The decompressor will not allow output scan/row number - * to get ahead of input scan/row, but it can fall arbitrarily far behind. - */ - int output_scan_number; /* Nominal scan number being displayed */ - JDIMENSION output_iMCU_row; /* Number of iMCU rows read */ - - /* Current progression status. coef_bits[c][i] indicates the precision - * with which component c's DCT coefficient i (in zigzag order) is known. - * It is -1 when no data has yet been received, otherwise it is the point - * transform (shift) value for the most recent scan of the coefficient - * (thus, 0 at completion of the progression). - * This pointer is NULL when reading a non-progressive file. - */ - int (*coef_bits)[DCTSIZE2]; /* -1 or current Al value for each coef */ - - /* Internal JPEG parameters --- the application usually need not look at - * these fields. Note that the decompressor output side may not use - * any parameters that can change between scans. - */ - - /* Quantization and Huffman tables are carried forward across input - * datastreams when processing abbreviated JPEG datastreams. - */ - - JQUANT_TBL * quant_tbl_ptrs[NUM_QUANT_TBLS]; - /* ptrs to coefficient quantization tables, or NULL if not defined */ - - JHUFF_TBL * dc_huff_tbl_ptrs[NUM_HUFF_TBLS]; - JHUFF_TBL * ac_huff_tbl_ptrs[NUM_HUFF_TBLS]; - /* ptrs to Huffman coding tables, or NULL if not defined */ - - /* These parameters are never carried across datastreams, since they - * are given in SOF/SOS markers or defined to be reset by SOI. - */ - - int data_precision; /* bits of precision in image data */ - - jpeg_component_info * comp_info; - /* comp_info[i] describes component that appears i'th in SOF */ - - boolean progressive_mode; /* TRUE if SOFn specifies progressive mode */ - boolean arith_code; /* TRUE=arithmetic coding, FALSE=Huffman */ - - UINT8 arith_dc_L[NUM_ARITH_TBLS]; /* L values for DC arith-coding tables */ - UINT8 arith_dc_U[NUM_ARITH_TBLS]; /* U values for DC arith-coding tables */ - UINT8 arith_ac_K[NUM_ARITH_TBLS]; /* Kx values for AC arith-coding tables */ - - unsigned int restart_interval; /* MCUs per restart interval, or 0 for no restart */ - - /* These fields record data obtained from optional markers recognized by - * the JPEG library. - */ - boolean saw_JFIF_marker; /* TRUE iff a JFIF APP0 marker was found */ - /* Data copied from JFIF marker: */ - UINT8 density_unit; /* JFIF code for pixel size units */ - UINT16 X_density; /* Horizontal pixel density */ - UINT16 Y_density; /* Vertical pixel density */ - boolean saw_Adobe_marker; /* TRUE iff an Adobe APP14 marker was found */ - UINT8 Adobe_transform; /* Color transform code from Adobe marker */ - - boolean CCIR601_sampling; /* TRUE=first samples are cosited */ - - /* Remaining fields are known throughout decompressor, but generally - * should not be touched by a surrounding application. - */ - - /* - * These fields are computed during decompression startup - */ - int max_h_samp_factor; /* largest h_samp_factor */ - int max_v_samp_factor; /* largest v_samp_factor */ - - int min_DCT_scaled_size; /* smallest DCT_scaled_size of any component */ - - JDIMENSION total_iMCU_rows; /* # of iMCU rows in image */ - /* The coefficient controller's input and output progress is measured in - * units of "iMCU" (interleaved MCU) rows. These are the same as MCU rows - * in fully interleaved JPEG scans, but are used whether the scan is - * interleaved or not. We define an iMCU row as v_samp_factor DCT block - * rows of each component. Therefore, the IDCT output contains - * v_samp_factor*DCT_scaled_size sample rows of a component per iMCU row. - */ - - JSAMPLE * sample_range_limit; /* table for fast range-limiting */ - - /* - * These fields are valid during any one scan. - * They describe the components and MCUs actually appearing in the scan. - * Note that the decompressor output side must not use these fields. - */ - int comps_in_scan; /* # of JPEG components in this scan */ - jpeg_component_info * cur_comp_info[MAX_COMPS_IN_SCAN]; - /* *cur_comp_info[i] describes component that appears i'th in SOS */ - - JDIMENSION MCUs_per_row; /* # of MCUs across the image */ - JDIMENSION MCU_rows_in_scan; /* # of MCU rows in the image */ - - int blocks_in_MCU; /* # of DCT blocks per MCU */ - int MCU_membership[D_MAX_BLOCKS_IN_MCU]; - /* MCU_membership[i] is index in cur_comp_info of component owning */ - /* i'th block in an MCU */ - - int Ss, Se, Ah, Al; /* progressive JPEG parameters for scan */ - - /* This field is shared between entropy decoder and marker parser. - * It is either zero or the code of a JPEG marker that has been - * read from the data source, but has not yet been processed. - */ - int unread_marker; - - /* - * Links to decompression subobjects (methods, private variables of modules) - */ - struct jpeg_decomp_master * master; - struct jpeg_d_main_controller * main; - struct jpeg_d_coef_controller * coef; - struct jpeg_d_post_controller * post; - struct jpeg_input_controller * inputctl; - struct jpeg_marker_reader * marker; - struct jpeg_entropy_decoder * entropy; - struct jpeg_inverse_dct * idct; - struct jpeg_upsampler * upsample; - struct jpeg_color_deconverter * cconvert; - struct jpeg_color_quantizer * cquantize; -}; - - -/* "Object" declarations for JPEG modules that may be supplied or called - * directly by the surrounding application. - * As with all objects in the JPEG library, these structs only define the - * publicly visible methods and state variables of a module. Additional - * private fields may exist after the public ones. - */ - - -/* Error handler object */ - -struct jpeg_error_mgr { - /* Error exit handler: does not return to caller */ - JMETHOD(void, error_exit, (j_common_ptr cinfo)); - /* Conditionally emit a trace or warning message */ - JMETHOD(void, emit_message, (j_common_ptr cinfo, int msg_level)); - /* Routine that actually outputs a trace or error message */ - JMETHOD(void, output_message, (j_common_ptr cinfo)); - /* Format a message string for the most recent JPEG error or message */ - JMETHOD(void, format_message, (j_common_ptr cinfo, char * buffer)); -#define JMSG_LENGTH_MAX 200 /* recommended size of format_message buffer */ - /* Reset error state variables at start of a new image */ - JMETHOD(void, reset_error_mgr, (j_common_ptr cinfo)); - - /* The message ID code and any parameters are saved here. - * A message can have one string parameter or up to 8 int parameters. - */ - int msg_code; -#define JMSG_STR_PARM_MAX 80 - union { - int i[8]; - char s[JMSG_STR_PARM_MAX]; - } msg_parm; - - /* Standard state variables for error facility */ - - int trace_level; /* max msg_level that will be displayed */ - - /* For recoverable corrupt-data errors, we emit a warning message, - * but keep going unless emit_message chooses to abort. emit_message - * should count warnings in num_warnings. The surrounding application - * can check for bad data by seeing if num_warnings is nonzero at the - * end of processing. - */ - long num_warnings; /* number of corrupt-data warnings */ - - /* These fields point to the table(s) of error message strings. - * An application can change the table pointer to switch to a different - * message list (typically, to change the language in which errors are - * reported). Some applications may wish to add additional error codes - * that will be handled by the JPEG library error mechanism; the second - * table pointer is used for this purpose. - * - * First table includes all errors generated by JPEG library itself. - * Error code 0 is reserved for a "no such error string" message. - */ - const char * const * jpeg_message_table; /* Library errors */ - int last_jpeg_message; /* Table contains strings 0..last_jpeg_message */ - /* Second table can be added by application (see cjpeg/djpeg for example). - * It contains strings numbered first_addon_message..last_addon_message. - */ - const char * const * addon_message_table; /* Non-library errors */ - int first_addon_message; /* code for first string in addon table */ - int last_addon_message; /* code for last string in addon table */ -}; - - -/* Progress monitor object */ - -struct jpeg_progress_mgr { - JMETHOD(void, progress_monitor, (j_common_ptr cinfo)); - - long pass_counter; /* work units completed in this pass */ - long pass_limit; /* total number of work units in this pass */ - int completed_passes; /* passes completed so far */ - int total_passes; /* total number of passes expected */ -}; - - -/* Data destination object for compression */ - -struct jpeg_destination_mgr { - JOCTET * next_output_byte; /* => next byte to write in buffer */ - size_t free_in_buffer; /* # of byte spaces remaining in buffer */ - - JMETHOD(void, init_destination, (j_compress_ptr cinfo)); - JMETHOD(boolean, empty_output_buffer, (j_compress_ptr cinfo)); - JMETHOD(void, term_destination, (j_compress_ptr cinfo)); -}; - - -/* Data source object for decompression */ - -struct jpeg_source_mgr { - const JOCTET * next_input_byte; /* => next byte to read from buffer */ - size_t bytes_in_buffer; /* # of bytes remaining in buffer */ - - JMETHOD(void, init_source, (j_decompress_ptr cinfo)); - JMETHOD(boolean, fill_input_buffer, (j_decompress_ptr cinfo)); - JMETHOD(void, skip_input_data, (j_decompress_ptr cinfo, long num_bytes)); - JMETHOD(boolean, resync_to_restart, (j_decompress_ptr cinfo, int desired)); - JMETHOD(void, term_source, (j_decompress_ptr cinfo)); -}; - - -/* Memory manager object. - * Allocates "small" objects (a few K total), "large" objects (tens of K), - * and "really big" objects (virtual arrays with backing store if needed). - * The memory manager does not allow individual objects to be freed; rather, - * each created object is assigned to a pool, and whole pools can be freed - * at once. This is faster and more convenient than remembering exactly what - * to free, especially where malloc()/free() are not too speedy. - * NB: alloc routines never return NULL. They exit to error_exit if not - * successful. - */ - -#define JPOOL_PERMANENT 0 /* lasts until master record is destroyed */ -#define JPOOL_IMAGE 1 /* lasts until done with image/datastream */ -#define JPOOL_NUMPOOLS 2 - -typedef struct jvirt_sarray_control * jvirt_sarray_ptr; -typedef struct jvirt_barray_control * jvirt_barray_ptr; - - -struct jpeg_memory_mgr { - /* Method pointers */ - JMETHOD(void *, alloc_small, (j_common_ptr cinfo, int pool_id, - size_t sizeofobject)); - JMETHOD(void FAR *, alloc_large, (j_common_ptr cinfo, int pool_id, - size_t sizeofobject)); - JMETHOD(JSAMPARRAY, alloc_sarray, (j_common_ptr cinfo, int pool_id, - JDIMENSION samplesperrow, - JDIMENSION numrows)); - JMETHOD(JBLOCKARRAY, alloc_barray, (j_common_ptr cinfo, int pool_id, - JDIMENSION blocksperrow, - JDIMENSION numrows)); - JMETHOD(jvirt_sarray_ptr, request_virt_sarray, (j_common_ptr cinfo, - int pool_id, - boolean pre_zero, - JDIMENSION samplesperrow, - JDIMENSION numrows, - JDIMENSION maxaccess)); - JMETHOD(jvirt_barray_ptr, request_virt_barray, (j_common_ptr cinfo, - int pool_id, - boolean pre_zero, - JDIMENSION blocksperrow, - JDIMENSION numrows, - JDIMENSION maxaccess)); - JMETHOD(void, realize_virt_arrays, (j_common_ptr cinfo)); - JMETHOD(JSAMPARRAY, access_virt_sarray, (j_common_ptr cinfo, - jvirt_sarray_ptr ptr, - JDIMENSION start_row, - JDIMENSION num_rows, - boolean writable)); - JMETHOD(JBLOCKARRAY, access_virt_barray, (j_common_ptr cinfo, - jvirt_barray_ptr ptr, - JDIMENSION start_row, - JDIMENSION num_rows, - boolean writable)); - JMETHOD(void, free_pool, (j_common_ptr cinfo, int pool_id)); - JMETHOD(void, self_destruct, (j_common_ptr cinfo)); - - /* Limit on memory allocation for this JPEG object. (Note that this is - * merely advisory, not a guaranteed maximum; it only affects the space - * used for virtual-array buffers.) May be changed by outer application - * after creating the JPEG object. - */ - long max_memory_to_use; -}; - - -/* Routine signature for application-supplied marker processing methods. - * Need not pass marker code since it is stored in cinfo->unread_marker. - */ -typedef JMETHOD(boolean, jpeg_marker_parser_method, (j_decompress_ptr cinfo)); - - -/* Declarations for routines called by application. - * The JPP macro hides prototype parameters from compilers that can't cope. - * Note JPP requires double parentheses. - */ - -#ifdef HAVE_PROTOTYPES -#define JPP(arglist) arglist -#else -#define JPP(arglist) () -#endif - - -/* Short forms of external names for systems with brain-damaged linkers. - * We shorten external names to be unique in the first six letters, which - * is good enough for all known systems. - * (If your compiler itself needs names to be unique in less than 15 - * characters, you are out of luck. Get a better compiler.) - */ - -#ifdef NEED_SHORT_EXTERNAL_NAMES -#define jpeg_std_error jStdError -#define jpeg_create_compress jCreaCompress -#define jpeg_create_decompress jCreaDecompress -#define jpeg_destroy_compress jDestCompress -#define jpeg_destroy_decompress jDestDecompress -#define jpeg_stdio_dest jStdDest -#define jpeg_stdio_src jStdSrc -#define jpeg_set_defaults jSetDefaults -#define jpeg_set_colorspace jSetColorspace -#define jpeg_default_colorspace jDefColorspace -#define jpeg_set_quality jSetQuality -#define jpeg_set_linear_quality jSetLQuality -#define jpeg_add_quant_table jAddQuantTable -#define jpeg_quality_scaling jQualityScaling -#define jpeg_simple_progression jSimProgress -#define jpeg_suppress_tables jSuppressTables -#define jpeg_alloc_quant_table jAlcQTable -#define jpeg_alloc_huff_table jAlcHTable -#define jpeg_start_compress jStrtCompress -#define jpeg_write_scanlines jWrtScanlines -#define jpeg_finish_compress jFinCompress -#define jpeg_write_raw_data jWrtRawData -#define jpeg_write_marker jWrtMarker -#define jpeg_write_tables jWrtTables -#define jpeg_read_header jReadHeader -#define jpeg_start_decompress jStrtDecompress -#define jpeg_read_scanlines jReadScanlines -#define jpeg_finish_decompress jFinDecompress -#define jpeg_read_raw_data jReadRawData -#define jpeg_has_multiple_scans jHasMultScn -#define jpeg_start_output jStrtOutput -#define jpeg_finish_output jFinOutput -#define jpeg_input_complete jInComplete -#define jpeg_new_colormap jNewCMap -#define jpeg_consume_input jConsumeInput -#define jpeg_calc_output_dimensions jCalcDimensions -#define jpeg_set_marker_processor jSetMarker -#define jpeg_read_coefficients jReadCoefs -#define jpeg_write_coefficients jWrtCoefs -#define jpeg_copy_critical_parameters jCopyCrit -#define jpeg_abort_compress jAbrtCompress -#define jpeg_abort_decompress jAbrtDecompress -#define jpeg_abort jAbort -#define jpeg_destroy jDestroy -#define jpeg_resync_to_restart jResyncRestart -#endif /* NEED_SHORT_EXTERNAL_NAMES */ - - -/* Default error-management setup */ -EXTERN struct jpeg_error_mgr *jpeg_std_error JPP((struct jpeg_error_mgr *err)); - -/* Initialization and destruction of JPEG compression objects */ -/* NB: you must set up the error-manager BEFORE calling jpeg_create_xxx */ -EXTERN void jpeg_create_compress JPP((j_compress_ptr cinfo)); -EXTERN void jpeg_create_decompress JPP((j_decompress_ptr cinfo)); -EXTERN void jpeg_destroy_compress JPP((j_compress_ptr cinfo)); -EXTERN void jpeg_destroy_decompress JPP((j_decompress_ptr cinfo)); - -/* Standard data source and destination managers: stdio streams. */ -/* Caller is responsible for opening the file before and closing after. */ -EXTERN void jpeg_stdio_dest JPP((j_compress_ptr cinfo, FILE * outfile)); -EXTERN void jpeg_stdio_src JPP((j_decompress_ptr cinfo, unsigned char *infile)); - -/* Default parameter setup for compression */ -EXTERN void jpeg_set_defaults JPP((j_compress_ptr cinfo)); -/* Compression parameter setup aids */ -EXTERN void jpeg_set_colorspace JPP((j_compress_ptr cinfo, - J_COLOR_SPACE colorspace)); -EXTERN void jpeg_default_colorspace JPP((j_compress_ptr cinfo)); -EXTERN void jpeg_set_quality JPP((j_compress_ptr cinfo, int quality, - boolean force_baseline)); -EXTERN void jpeg_set_linear_quality JPP((j_compress_ptr cinfo, - int scale_factor, - boolean force_baseline)); -EXTERN void jpeg_add_quant_table JPP((j_compress_ptr cinfo, int which_tbl, - const unsigned int *basic_table, - int scale_factor, - boolean force_baseline)); -EXTERN int jpeg_quality_scaling JPP((int quality)); -EXTERN void jpeg_simple_progression JPP((j_compress_ptr cinfo)); -EXTERN void jpeg_suppress_tables JPP((j_compress_ptr cinfo, - boolean suppress)); -EXTERN JQUANT_TBL * jpeg_alloc_quant_table JPP((j_common_ptr cinfo)); -EXTERN JHUFF_TBL * jpeg_alloc_huff_table JPP((j_common_ptr cinfo)); - -/* Main entry points for compression */ -EXTERN void jpeg_start_compress JPP((j_compress_ptr cinfo, - boolean write_all_tables)); -EXTERN JDIMENSION jpeg_write_scanlines JPP((j_compress_ptr cinfo, - JSAMPARRAY scanlines, - JDIMENSION num_lines)); -EXTERN void jpeg_finish_compress JPP((j_compress_ptr cinfo)); - -/* Replaces jpeg_write_scanlines when writing raw downsampled data. */ -EXTERN JDIMENSION jpeg_write_raw_data JPP((j_compress_ptr cinfo, - JSAMPIMAGE data, - JDIMENSION num_lines)); - -/* Write a special marker. See libjpeg.doc concerning safe usage. */ -EXTERN void jpeg_write_marker JPP((j_compress_ptr cinfo, int marker, - const JOCTET *dataptr, unsigned int datalen)); - -/* Alternate compression function: just write an abbreviated table file */ -EXTERN void jpeg_write_tables JPP((j_compress_ptr cinfo)); - -/* Decompression startup: read start of JPEG datastream to see what's there */ -EXTERN int jpeg_read_header JPP((j_decompress_ptr cinfo, - boolean require_image)); -/* Return value is one of: */ -#define JPEG_SUSPENDED 0 /* Suspended due to lack of input data */ -#define JPEG_HEADER_OK 1 /* Found valid image datastream */ -#define JPEG_HEADER_TABLES_ONLY 2 /* Found valid table-specs-only datastream */ -/* If you pass require_image = TRUE (normal case), you need not check for - * a TABLES_ONLY return code; an abbreviated file will cause an error exit. - * JPEG_SUSPENDED is only possible if you use a data source module that can - * give a suspension return (the stdio source module doesn't). - */ - -/* Main entry points for decompression */ -EXTERN boolean jpeg_start_decompress JPP((j_decompress_ptr cinfo)); -EXTERN JDIMENSION jpeg_read_scanlines JPP((j_decompress_ptr cinfo, - JSAMPARRAY scanlines, - JDIMENSION max_lines)); -EXTERN boolean jpeg_finish_decompress JPP((j_decompress_ptr cinfo)); - -/* Replaces jpeg_read_scanlines when reading raw downsampled data. */ -EXTERN JDIMENSION jpeg_read_raw_data JPP((j_decompress_ptr cinfo, - JSAMPIMAGE data, - JDIMENSION max_lines)); - -/* Additional entry points for buffered-image mode. */ -EXTERN boolean jpeg_has_multiple_scans JPP((j_decompress_ptr cinfo)); -EXTERN boolean jpeg_start_output JPP((j_decompress_ptr cinfo, - int scan_number)); -EXTERN boolean jpeg_finish_output JPP((j_decompress_ptr cinfo)); -EXTERN boolean jpeg_input_complete JPP((j_decompress_ptr cinfo)); -EXTERN void jpeg_new_colormap JPP((j_decompress_ptr cinfo)); -EXTERN int jpeg_consume_input JPP((j_decompress_ptr cinfo)); -/* Return value is one of: */ -/* #define JPEG_SUSPENDED 0 Suspended due to lack of input data */ -#define JPEG_REACHED_SOS 1 /* Reached start of new scan */ -#define JPEG_REACHED_EOI 2 /* Reached end of image */ -#define JPEG_ROW_COMPLETED 3 /* Completed one iMCU row */ -#define JPEG_SCAN_COMPLETED 4 /* Completed last iMCU row of a scan */ - -/* Precalculate output dimensions for current decompression parameters. */ -EXTERN void jpeg_calc_output_dimensions JPP((j_decompress_ptr cinfo)); - -/* Install a special processing method for COM or APPn markers. */ -EXTERN void jpeg_set_marker_processor JPP((j_decompress_ptr cinfo, - int marker_code, - jpeg_marker_parser_method routine)); - -/* Read or write raw DCT coefficients --- useful for lossless transcoding. */ -EXTERN jvirt_barray_ptr * jpeg_read_coefficients JPP((j_decompress_ptr cinfo)); -EXTERN void jpeg_write_coefficients JPP((j_compress_ptr cinfo, - jvirt_barray_ptr * coef_arrays)); -EXTERN void jpeg_copy_critical_parameters JPP((j_decompress_ptr srcinfo, - j_compress_ptr dstinfo)); - -/* If you choose to abort compression or decompression before completing - * jpeg_finish_(de)compress, then you need to clean up to release memory, - * temporary files, etc. You can just call jpeg_destroy_(de)compress - * if you're done with the JPEG object, but if you want to clean it up and - * reuse it, call this: - */ -EXTERN void jpeg_abort_compress JPP((j_compress_ptr cinfo)); -EXTERN void jpeg_abort_decompress JPP((j_decompress_ptr cinfo)); - -/* Generic versions of jpeg_abort and jpeg_destroy that work on either - * flavor of JPEG object. These may be more convenient in some places. - */ -EXTERN void jpeg_abort JPP((j_common_ptr cinfo)); -EXTERN void jpeg_destroy JPP((j_common_ptr cinfo)); - -/* Default restart-marker-resync procedure for use by data source modules */ -EXTERN boolean jpeg_resync_to_restart JPP((j_decompress_ptr cinfo, - int desired)); - - -/* These marker codes are exported since applications and data source modules - * are likely to want to use them. - */ - -#define JPEG_RST0 0xD0 /* RST0 marker code */ -#define JPEG_EOI 0xD9 /* EOI marker code */ -#define JPEG_APP0 0xE0 /* APP0 marker code */ -#define JPEG_COM 0xFE /* COM marker code */ - - -/* If we have a brain-damaged compiler that emits warnings (or worse, errors) - * for structure definitions that are never filled in, keep it quiet by - * supplying dummy definitions for the various substructures. - */ - -#ifdef INCOMPLETE_TYPES_BROKEN -#ifndef JPEG_INTERNALS /* will be defined in jpegint.h */ -struct jvirt_sarray_control { long dummy; }; -struct jvirt_barray_control { long dummy; }; -struct jpeg_comp_master { long dummy; }; -struct jpeg_c_main_controller { long dummy; }; -struct jpeg_c_prep_controller { long dummy; }; -struct jpeg_c_coef_controller { long dummy; }; -struct jpeg_marker_writer { long dummy; }; -struct jpeg_color_converter { long dummy; }; -struct jpeg_downsampler { long dummy; }; -struct jpeg_forward_dct { long dummy; }; -struct jpeg_entropy_encoder { long dummy; }; -struct jpeg_decomp_master { long dummy; }; -struct jpeg_d_main_controller { long dummy; }; -struct jpeg_d_coef_controller { long dummy; }; -struct jpeg_d_post_controller { long dummy; }; -struct jpeg_input_controller { long dummy; }; -struct jpeg_marker_reader { long dummy; }; -struct jpeg_entropy_decoder { long dummy; }; -struct jpeg_inverse_dct { long dummy; }; -struct jpeg_upsampler { long dummy; }; -struct jpeg_color_deconverter { long dummy; }; -struct jpeg_color_quantizer { long dummy; }; -#endif /* JPEG_INTERNALS */ -#endif /* INCOMPLETE_TYPES_BROKEN */ - - -/* - * The JPEG library modules define JPEG_INTERNALS before including this file. - * The internal structure declarations are read only when that is true. - * Applications using the library should not include jpegint.h, but may wish - * to include jerror.h. - */ - -#ifdef JPEG_INTERNALS -#include "../jpeg-6/jpegint.h" /* fetch private declarations */ -#include "../jpeg-6/jerror.h" /* fetch error codes too */ -#endif - -#endif /* JPEGLIB_H */ diff --git a/engine/jpeg-6/jpegtran.c b/engine/jpeg-6/jpegtran.c deleted file mode 100644 index f602c6b..0000000 --- a/engine/jpeg-6/jpegtran.c +++ /dev/null @@ -1,370 +0,0 @@ -/* - * jpegtran.c - * - * Copyright (C) 1995, Thomas G. Lane. - * This file is part of the Independent JPEG Group's software. - * For conditions of distribution and use, see the accompanying README file. - * - * This file contains a command-line user interface for JPEG transcoding. - * It is very similar to cjpeg.c, but provides lossless transcoding between - * different JPEG file formats. - */ - -#include "cdjpeg.h" /* Common decls for cjpeg/djpeg applications */ -#include "jversion.h" /* for version message */ - -#ifdef USE_CCOMMAND /* command-line reader for Macintosh */ -#ifdef __MWERKS__ -#include /* Metrowerks declares it here */ -#endif -#ifdef THINK_C -#include /* Think declares it here */ -#endif -#endif - - -/* - * Argument-parsing code. - * The switch parser is designed to be useful with DOS-style command line - * syntax, ie, intermixed switches and file names, where only the switches - * to the left of a given file name affect processing of that file. - * The main program in this file doesn't actually use this capability... - */ - - -static const char * progname; /* program name for error messages */ -static char * outfilename; /* for -outfile switch */ - - -LOCAL void -usage (void) -/* complain about bad command line */ -{ - fprintf(stderr, "usage: %s [switches] ", progname); -#ifdef TWO_FILE_COMMANDLINE - fprintf(stderr, "inputfile outputfile\n"); -#else - fprintf(stderr, "[inputfile]\n"); -#endif - - fprintf(stderr, "Switches (names may be abbreviated):\n"); -#ifdef ENTROPY_OPT_SUPPORTED - fprintf(stderr, " -optimize Optimize Huffman table (smaller file, but slow compression)\n"); -#endif -#ifdef C_PROGRESSIVE_SUPPORTED - fprintf(stderr, " -progressive Create progressive JPEG file\n"); -#endif - fprintf(stderr, "Switches for advanced users:\n"); - fprintf(stderr, " -restart N Set restart interval in rows, or in blocks with B\n"); - fprintf(stderr, " -maxmemory N Maximum memory to use (in kbytes)\n"); - fprintf(stderr, " -outfile name Specify name for output file\n"); - fprintf(stderr, " -verbose or -debug Emit debug output\n"); - fprintf(stderr, "Switches for wizards:\n"); -#ifdef C_ARITH_CODING_SUPPORTED - fprintf(stderr, " -arithmetic Use arithmetic coding\n"); -#endif -#ifdef C_MULTISCAN_FILES_SUPPORTED - fprintf(stderr, " -scans file Create multi-scan JPEG per script file\n"); -#endif - exit(EXIT_FAILURE); -} - - -LOCAL int -parse_switches (j_compress_ptr cinfo, int argc, char **argv, - int last_file_arg_seen, boolean for_real) -/* Parse optional switches. - * Returns argv[] index of first file-name argument (== argc if none). - * Any file names with indexes <= last_file_arg_seen are ignored; - * they have presumably been processed in a previous iteration. - * (Pass 0 for last_file_arg_seen on the first or only iteration.) - * for_real is FALSE on the first (dummy) pass; we may skip any expensive - * processing. - */ -{ - int argn; - char * arg; - boolean simple_progressive; - char * scansarg = NULL; /* saves -scans parm if any */ - - /* Set up default JPEG parameters. */ - simple_progressive = FALSE; - outfilename = NULL; - cinfo->err->trace_level = 0; - - /* Scan command line options, adjust parameters */ - - for (argn = 1; argn < argc; argn++) { - arg = argv[argn]; - if (*arg != '-') { - /* Not a switch, must be a file name argument */ - if (argn <= last_file_arg_seen) { - outfilename = NULL; /* -outfile applies to just one input file */ - continue; /* ignore this name if previously processed */ - } - break; /* else done parsing switches */ - } - arg++; /* advance past switch marker character */ - - if (keymatch(arg, "arithmetic", 1)) { - /* Use arithmetic coding. */ -#ifdef C_ARITH_CODING_SUPPORTED - cinfo->arith_code = TRUE; -#else - fprintf(stderr, "%s: sorry, arithmetic coding not supported\n", - progname); - exit(EXIT_FAILURE); -#endif - - } else if (keymatch(arg, "debug", 1) || keymatch(arg, "verbose", 1)) { - /* Enable debug printouts. */ - /* On first -d, print version identification */ - static boolean printed_version = FALSE; - - if (! printed_version) { - fprintf(stderr, "Independent JPEG Group's JPEGTRAN, version %s\n%s\n", - JVERSION, JCOPYRIGHT); - printed_version = TRUE; - } - cinfo->err->trace_level++; - - } else if (keymatch(arg, "maxmemory", 3)) { - /* Maximum memory in Kb (or Mb with 'm'). */ - long lval; - char ch = 'x'; - - if (++argn >= argc) /* advance to next argument */ - usage(); - if (sscanf(argv[argn], "%ld%c", &lval, &ch) < 1) - usage(); - if (ch == 'm' || ch == 'M') - lval *= 1000L; - cinfo->mem->max_memory_to_use = lval * 1000L; - - } else if (keymatch(arg, "optimize", 1) || keymatch(arg, "optimise", 1)) { - /* Enable entropy parm optimization. */ -#ifdef ENTROPY_OPT_SUPPORTED - cinfo->optimize_coding = TRUE; -#else - fprintf(stderr, "%s: sorry, entropy optimization was not compiled\n", - progname); - exit(EXIT_FAILURE); -#endif - - } else if (keymatch(arg, "outfile", 4)) { - /* Set output file name. */ - if (++argn >= argc) /* advance to next argument */ - usage(); - outfilename = argv[argn]; /* save it away for later use */ - - } else if (keymatch(arg, "progressive", 1)) { - /* Select simple progressive mode. */ -#ifdef C_PROGRESSIVE_SUPPORTED - simple_progressive = TRUE; - /* We must postpone execution until num_components is known. */ -#else - fprintf(stderr, "%s: sorry, progressive output was not compiled\n", - progname); - exit(EXIT_FAILURE); -#endif - - } else if (keymatch(arg, "restart", 1)) { - /* Restart interval in MCU rows (or in MCUs with 'b'). */ - long lval; - char ch = 'x'; - - if (++argn >= argc) /* advance to next argument */ - usage(); - if (sscanf(argv[argn], "%ld%c", &lval, &ch) < 1) - usage(); - if (lval < 0 || lval > 65535L) - usage(); - if (ch == 'b' || ch == 'B') { - cinfo->restart_interval = (unsigned int) lval; - cinfo->restart_in_rows = 0; /* else prior '-restart n' overrides me */ - } else { - cinfo->restart_in_rows = (int) lval; - /* restart_interval will be computed during startup */ - } - - } else if (keymatch(arg, "scans", 2)) { - /* Set scan script. */ -#ifdef C_MULTISCAN_FILES_SUPPORTED - if (++argn >= argc) /* advance to next argument */ - usage(); - scansarg = argv[argn]; - /* We must postpone reading the file in case -progressive appears. */ -#else - fprintf(stderr, "%s: sorry, multi-scan output was not compiled\n", - progname); - exit(EXIT_FAILURE); -#endif - - } else { - usage(); /* bogus switch */ - } - } - - /* Post-switch-scanning cleanup */ - - if (for_real) { - -#ifdef C_PROGRESSIVE_SUPPORTED - if (simple_progressive) /* process -progressive; -scans can override */ - jpeg_simple_progression(cinfo); -#endif - -#ifdef C_MULTISCAN_FILES_SUPPORTED - if (scansarg != NULL) /* process -scans if it was present */ - if (! read_scan_script(cinfo, scansarg)) - usage(); -#endif - } - - return argn; /* return index of next arg (file name) */ -} - - -/* - * The main program. - */ - -GLOBAL int -main (int argc, char **argv) -{ - struct jpeg_decompress_struct srcinfo; - struct jpeg_compress_struct dstinfo; - struct jpeg_error_mgr jsrcerr, jdsterr; -#ifdef PROGRESS_REPORT - struct cdjpeg_progress_mgr progress; -#endif - jvirt_barray_ptr * coef_arrays; - int file_index; - FILE * input_file; - FILE * output_file; - - /* On Mac, fetch a command line. */ -#ifdef USE_CCOMMAND - argc = ccommand(&argv); -#endif - - progname = argv[0]; - if (progname == NULL || progname[0] == 0) - progname = "jpegtran"; /* in case C library doesn't provide it */ - - /* Initialize the JPEG decompression object with default error handling. */ - srcinfo.err = jpeg_std_error(&jsrcerr); - jpeg_create_decompress(&srcinfo); - /* Initialize the JPEG compression object with default error handling. */ - dstinfo.err = jpeg_std_error(&jdsterr); - jpeg_create_compress(&dstinfo); - - /* Now safe to enable signal catcher. - * Note: we assume only the decompression object will have virtual arrays. - */ -#ifdef NEED_SIGNAL_CATCHER - enable_signal_catcher((j_common_ptr) &srcinfo); -#endif - - /* Scan command line to find file names. - * It is convenient to use just one switch-parsing routine, but the switch - * values read here are ignored; we will rescan the switches after opening - * the input file. - */ - - file_index = parse_switches(&dstinfo, argc, argv, 0, FALSE); - jsrcerr.trace_level = jdsterr.trace_level; - -#ifdef TWO_FILE_COMMANDLINE - /* Must have either -outfile switch or explicit output file name */ - if (outfilename == NULL) { - if (file_index != argc-2) { - fprintf(stderr, "%s: must name one input and one output file\n", - progname); - usage(); - } - outfilename = argv[file_index+1]; - } else { - if (file_index != argc-1) { - fprintf(stderr, "%s: must name one input and one output file\n", - progname); - usage(); - } - } -#else - /* Unix style: expect zero or one file name */ - if (file_index < argc-1) { - fprintf(stderr, "%s: only one input file\n", progname); - usage(); - } -#endif /* TWO_FILE_COMMANDLINE */ - - /* Open the input file. */ - if (file_index < argc) { - if ((input_file = fopen(argv[file_index], READ_BINARY)) == NULL) { - fprintf(stderr, "%s: can't open %s\n", progname, argv[file_index]); - exit(EXIT_FAILURE); - } - } else { - /* default input file is stdin */ - input_file = read_stdin(); - } - - /* Open the output file. */ - if (outfilename != NULL) { - if ((output_file = fopen(outfilename, WRITE_BINARY)) == NULL) { - fprintf(stderr, "%s: can't open %s\n", progname, outfilename); - exit(EXIT_FAILURE); - } - } else { - /* default output file is stdout */ - output_file = write_stdout(); - } - -#ifdef PROGRESS_REPORT - start_progress_monitor((j_common_ptr) &dstinfo, &progress); -#endif - - /* Specify data source for decompression */ - jpeg_stdio_src(&srcinfo, input_file); - - /* Read file header */ - (void) jpeg_read_header(&srcinfo, TRUE); - - /* Read source file as DCT coefficients */ - coef_arrays = jpeg_read_coefficients(&srcinfo); - - /* Initialize destination compression parameters from source values */ - jpeg_copy_critical_parameters(&srcinfo, &dstinfo); - - /* Adjust default compression parameters by re-parsing the options */ - file_index = parse_switches(&dstinfo, argc, argv, 0, TRUE); - - /* Specify data destination for compression */ - jpeg_stdio_dest(&dstinfo, output_file); - - /* Start compressor */ - jpeg_write_coefficients(&dstinfo, coef_arrays); - - /* ought to copy source comments here... */ - - /* Finish compression and release memory */ - jpeg_finish_compress(&dstinfo); - jpeg_destroy_compress(&dstinfo); - (void) jpeg_finish_decompress(&srcinfo); - jpeg_destroy_decompress(&srcinfo); - - /* Close files, if we opened them */ - if (input_file != stdin) - fclose(input_file); - if (output_file != stdout) - fclose(output_file); - -#ifdef PROGRESS_REPORT - end_progress_monitor((j_common_ptr) &dstinfo); -#endif - - /* All done. */ - exit(jsrcerr.num_warnings + jdsterr.num_warnings ?EXIT_WARNING:EXIT_SUCCESS); - return 0; /* suppress no-return-value warnings */ -} diff --git a/engine/jpeg-6/jquant1.c b/engine/jpeg-6/jquant1.c deleted file mode 100644 index 035e79a..0000000 --- a/engine/jpeg-6/jquant1.c +++ /dev/null @@ -1,856 +0,0 @@ -/* - * jquant1.c - * - * Copyright (C) 1991-1995, Thomas G. Lane. - * This file is part of the Independent JPEG Group's software. - * For conditions of distribution and use, see the accompanying README file. - * - * This file contains 1-pass color quantization (color mapping) routines. - * These routines provide mapping to a fixed color map using equally spaced - * color values. Optional Floyd-Steinberg or ordered dithering is available. - */ - -#define JPEG_INTERNALS -#include "jinclude.h" -#include "jpeglib.h" - -#ifdef QUANT_1PASS_SUPPORTED - - -/* - * The main purpose of 1-pass quantization is to provide a fast, if not very - * high quality, colormapped output capability. A 2-pass quantizer usually - * gives better visual quality; however, for quantized grayscale output this - * quantizer is perfectly adequate. Dithering is highly recommended with this - * quantizer, though you can turn it off if you really want to. - * - * In 1-pass quantization the colormap must be chosen in advance of seeing the - * image. We use a map consisting of all combinations of Ncolors[i] color - * values for the i'th component. The Ncolors[] values are chosen so that - * their product, the total number of colors, is no more than that requested. - * (In most cases, the product will be somewhat less.) - * - * Since the colormap is orthogonal, the representative value for each color - * component can be determined without considering the other components; - * then these indexes can be combined into a colormap index by a standard - * N-dimensional-array-subscript calculation. Most of the arithmetic involved - * can be precalculated and stored in the lookup table colorindex[]. - * colorindex[i][j] maps pixel value j in component i to the nearest - * representative value (grid plane) for that component; this index is - * multiplied by the array stride for component i, so that the - * index of the colormap entry closest to a given pixel value is just - * sum( colorindex[component-number][pixel-component-value] ) - * Aside from being fast, this scheme allows for variable spacing between - * representative values with no additional lookup cost. - * - * If gamma correction has been applied in color conversion, it might be wise - * to adjust the color grid spacing so that the representative colors are - * equidistant in linear space. At this writing, gamma correction is not - * implemented by jdcolor, so nothing is done here. - */ - - -/* Declarations for ordered dithering. - * - * We use a standard 16x16 ordered dither array. The basic concept of ordered - * dithering is described in many references, for instance Dale Schumacher's - * chapter II.2 of Graphics Gems II (James Arvo, ed. Academic Press, 1991). - * In place of Schumacher's comparisons against a "threshold" value, we add a - * "dither" value to the input pixel and then round the result to the nearest - * output value. The dither value is equivalent to (0.5 - threshold) times - * the distance between output values. For ordered dithering, we assume that - * the output colors are equally spaced; if not, results will probably be - * worse, since the dither may be too much or too little at a given point. - * - * The normal calculation would be to form pixel value + dither, range-limit - * this to 0..MAXJSAMPLE, and then index into the colorindex table as usual. - * We can skip the separate range-limiting step by extending the colorindex - * table in both directions. - */ - -#define ODITHER_SIZE 16 /* dimension of dither matrix */ -/* NB: if ODITHER_SIZE is not a power of 2, ODITHER_MASK uses will break */ -#define ODITHER_CELLS (ODITHER_SIZE*ODITHER_SIZE) /* # cells in matrix */ -#define ODITHER_MASK (ODITHER_SIZE-1) /* mask for wrapping around counters */ - -typedef int ODITHER_MATRIX[ODITHER_SIZE][ODITHER_SIZE]; -typedef int (*ODITHER_MATRIX_PTR)[ODITHER_SIZE]; - -static const UINT8 base_dither_matrix[ODITHER_SIZE][ODITHER_SIZE] = { - /* Bayer's order-4 dither array. Generated by the code given in - * Stephen Hawley's article "Ordered Dithering" in Graphics Gems I. - * The values in this array must range from 0 to ODITHER_CELLS-1. - */ - { 0,192, 48,240, 12,204, 60,252, 3,195, 51,243, 15,207, 63,255 }, - { 128, 64,176,112,140, 76,188,124,131, 67,179,115,143, 79,191,127 }, - { 32,224, 16,208, 44,236, 28,220, 35,227, 19,211, 47,239, 31,223 }, - { 160, 96,144, 80,172,108,156, 92,163, 99,147, 83,175,111,159, 95 }, - { 8,200, 56,248, 4,196, 52,244, 11,203, 59,251, 7,199, 55,247 }, - { 136, 72,184,120,132, 68,180,116,139, 75,187,123,135, 71,183,119 }, - { 40,232, 24,216, 36,228, 20,212, 43,235, 27,219, 39,231, 23,215 }, - { 168,104,152, 88,164,100,148, 84,171,107,155, 91,167,103,151, 87 }, - { 2,194, 50,242, 14,206, 62,254, 1,193, 49,241, 13,205, 61,253 }, - { 130, 66,178,114,142, 78,190,126,129, 65,177,113,141, 77,189,125 }, - { 34,226, 18,210, 46,238, 30,222, 33,225, 17,209, 45,237, 29,221 }, - { 162, 98,146, 82,174,110,158, 94,161, 97,145, 81,173,109,157, 93 }, - { 10,202, 58,250, 6,198, 54,246, 9,201, 57,249, 5,197, 53,245 }, - { 138, 74,186,122,134, 70,182,118,137, 73,185,121,133, 69,181,117 }, - { 42,234, 26,218, 38,230, 22,214, 41,233, 25,217, 37,229, 21,213 }, - { 170,106,154, 90,166,102,150, 86,169,105,153, 89,165,101,149, 85 } -}; - - -/* Declarations for Floyd-Steinberg dithering. - * - * Errors are accumulated into the array fserrors[], at a resolution of - * 1/16th of a pixel count. The error at a given pixel is propagated - * to its not-yet-processed neighbors using the standard F-S fractions, - * ... (here) 7/16 - * 3/16 5/16 1/16 - * We work left-to-right on even rows, right-to-left on odd rows. - * - * We can get away with a single array (holding one row's worth of errors) - * by using it to store the current row's errors at pixel columns not yet - * processed, but the next row's errors at columns already processed. We - * need only a few extra variables to hold the errors immediately around the - * current column. (If we are lucky, those variables are in registers, but - * even if not, they're probably cheaper to access than array elements are.) - * - * The fserrors[] array is indexed [component#][position]. - * We provide (#columns + 2) entries per component; the extra entry at each - * end saves us from special-casing the first and last pixels. - * - * Note: on a wide image, we might not have enough room in a PC's near data - * segment to hold the error array; so it is allocated with alloc_large. - */ - -#if BITS_IN_JSAMPLE == 8 -typedef INT16 FSERROR; /* 16 bits should be enough */ -typedef int LOCFSERROR; /* use 'int' for calculation temps */ -#else -typedef INT32 FSERROR; /* may need more than 16 bits */ -typedef INT32 LOCFSERROR; /* be sure calculation temps are big enough */ -#endif - -typedef FSERROR FAR *FSERRPTR; /* pointer to error array (in FAR storage!) */ - - -/* Private subobject */ - -#define MAX_Q_COMPS 4 /* max components I can handle */ - -typedef struct { - struct jpeg_color_quantizer pub; /* public fields */ - - /* Initially allocated colormap is saved here */ - JSAMPARRAY sv_colormap; /* The color map as a 2-D pixel array */ - int sv_actual; /* number of entries in use */ - - JSAMPARRAY colorindex; /* Precomputed mapping for speed */ - /* colorindex[i][j] = index of color closest to pixel value j in component i, - * premultiplied as described above. Since colormap indexes must fit into - * JSAMPLEs, the entries of this array will too. - */ - boolean is_padded; /* is the colorindex padded for odither? */ - - int Ncolors[MAX_Q_COMPS]; /* # of values alloced to each component */ - - /* Variables for ordered dithering */ - int row_index; /* cur row's vertical index in dither matrix */ - ODITHER_MATRIX_PTR odither[MAX_Q_COMPS]; /* one dither array per component */ - - /* Variables for Floyd-Steinberg dithering */ - FSERRPTR fserrors[MAX_Q_COMPS]; /* accumulated errors */ - boolean on_odd_row; /* flag to remember which row we are on */ -} my_cquantizer; - -typedef my_cquantizer * my_cquantize_ptr; - - -/* - * Policy-making subroutines for create_colormap and create_colorindex. - * These routines determine the colormap to be used. The rest of the module - * only assumes that the colormap is orthogonal. - * - * * select_ncolors decides how to divvy up the available colors - * among the components. - * * output_value defines the set of representative values for a component. - * * largest_input_value defines the mapping from input values to - * representative values for a component. - * Note that the latter two routines may impose different policies for - * different components, though this is not currently done. - */ - - -LOCAL int -select_ncolors (j_decompress_ptr cinfo, int Ncolors[]) -/* Determine allocation of desired colors to components, */ -/* and fill in Ncolors[] array to indicate choice. */ -/* Return value is total number of colors (product of Ncolors[] values). */ -{ - int nc = cinfo->out_color_components; /* number of color components */ - int max_colors = cinfo->desired_number_of_colors; - int total_colors, iroot, i, j; - boolean changed; - long temp; - static const int RGB_order[3] = { RGB_GREEN, RGB_RED, RGB_BLUE }; - - /* We can allocate at least the nc'th root of max_colors per component. */ - /* Compute floor(nc'th root of max_colors). */ - iroot = 1; - do { - iroot++; - temp = iroot; /* set temp = iroot ** nc */ - for (i = 1; i < nc; i++) - temp *= iroot; - } while (temp <= (long) max_colors); /* repeat till iroot exceeds root */ - iroot--; /* now iroot = floor(root) */ - - /* Must have at least 2 color values per component */ - if (iroot < 2) - ERREXIT1(cinfo, JERR_QUANT_FEW_COLORS, (int) temp); - - /* Initialize to iroot color values for each component */ - total_colors = 1; - for (i = 0; i < nc; i++) { - Ncolors[i] = iroot; - total_colors *= iroot; - } - /* We may be able to increment the count for one or more components without - * exceeding max_colors, though we know not all can be incremented. - * Sometimes, the first component can be incremented more than once! - * (Example: for 16 colors, we start at 2*2*2, go to 3*2*2, then 4*2*2.) - * In RGB colorspace, try to increment G first, then R, then B. - */ - do { - changed = FALSE; - for (i = 0; i < nc; i++) { - j = (cinfo->out_color_space == JCS_RGB ? RGB_order[i] : i); - /* calculate new total_colors if Ncolors[j] is incremented */ - temp = total_colors / Ncolors[j]; - temp *= Ncolors[j]+1; /* done in long arith to avoid oflo */ - if (temp > (long) max_colors) - break; /* won't fit, done with this pass */ - Ncolors[j]++; /* OK, apply the increment */ - total_colors = (int) temp; - changed = TRUE; - } - } while (changed); - - return total_colors; -} - - -LOCAL int -output_value (j_decompress_ptr cinfo, int ci, int j, int maxj) -/* Return j'th output value, where j will range from 0 to maxj */ -/* The output values must fall in 0..MAXJSAMPLE in increasing order */ -{ - /* We always provide values 0 and MAXJSAMPLE for each component; - * any additional values are equally spaced between these limits. - * (Forcing the upper and lower values to the limits ensures that - * dithering can't produce a color outside the selected gamut.) - */ - return (int) (((INT32) j * MAXJSAMPLE + maxj/2) / maxj); -} - - -LOCAL int -largest_input_value (j_decompress_ptr cinfo, int ci, int j, int maxj) -/* Return largest input value that should map to j'th output value */ -/* Must have largest(j=0) >= 0, and largest(j=maxj) >= MAXJSAMPLE */ -{ - /* Breakpoints are halfway between values returned by output_value */ - return (int) (((INT32) (2*j + 1) * MAXJSAMPLE + maxj) / (2*maxj)); -} - - -/* - * Create the colormap. - */ - -LOCAL void -create_colormap (j_decompress_ptr cinfo) -{ - my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; - JSAMPARRAY colormap; /* Created colormap */ - int total_colors; /* Number of distinct output colors */ - int i,j,k, nci, blksize, blkdist, ptr, val; - - /* Select number of colors for each component */ - total_colors = select_ncolors(cinfo, cquantize->Ncolors); - - /* Report selected color counts */ - if (cinfo->out_color_components == 3) - TRACEMS4(cinfo, 1, JTRC_QUANT_3_NCOLORS, - total_colors, cquantize->Ncolors[0], - cquantize->Ncolors[1], cquantize->Ncolors[2]); - else - TRACEMS1(cinfo, 1, JTRC_QUANT_NCOLORS, total_colors); - - /* Allocate and fill in the colormap. */ - /* The colors are ordered in the map in standard row-major order, */ - /* i.e. rightmost (highest-indexed) color changes most rapidly. */ - - colormap = (*cinfo->mem->alloc_sarray) - ((j_common_ptr) cinfo, JPOOL_IMAGE, - (JDIMENSION) total_colors, (JDIMENSION) cinfo->out_color_components); - - /* blksize is number of adjacent repeated entries for a component */ - /* blkdist is distance between groups of identical entries for a component */ - blkdist = total_colors; - - for (i = 0; i < cinfo->out_color_components; i++) { - /* fill in colormap entries for i'th color component */ - nci = cquantize->Ncolors[i]; /* # of distinct values for this color */ - blksize = blkdist / nci; - for (j = 0; j < nci; j++) { - /* Compute j'th output value (out of nci) for component */ - val = output_value(cinfo, i, j, nci-1); - /* Fill in all colormap entries that have this value of this component */ - for (ptr = j * blksize; ptr < total_colors; ptr += blkdist) { - /* fill in blksize entries beginning at ptr */ - for (k = 0; k < blksize; k++) - colormap[i][ptr+k] = (JSAMPLE) val; - } - } - blkdist = blksize; /* blksize of this color is blkdist of next */ - } - - /* Save the colormap in private storage, - * where it will survive color quantization mode changes. - */ - cquantize->sv_colormap = colormap; - cquantize->sv_actual = total_colors; -} - - -/* - * Create the color index table. - */ - -LOCAL void -create_colorindex (j_decompress_ptr cinfo) -{ - my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; - JSAMPROW indexptr; - int i,j,k, nci, blksize, val, pad; - - /* For ordered dither, we pad the color index tables by MAXJSAMPLE in - * each direction (input index values can be -MAXJSAMPLE .. 2*MAXJSAMPLE). - * This is not necessary in the other dithering modes. However, we - * flag whether it was done in case user changes dithering mode. - */ - if (cinfo->dither_mode == JDITHER_ORDERED) { - pad = MAXJSAMPLE*2; - cquantize->is_padded = TRUE; - } else { - pad = 0; - cquantize->is_padded = FALSE; - } - - cquantize->colorindex = (*cinfo->mem->alloc_sarray) - ((j_common_ptr) cinfo, JPOOL_IMAGE, - (JDIMENSION) (MAXJSAMPLE+1 + pad), - (JDIMENSION) cinfo->out_color_components); - - /* blksize is number of adjacent repeated entries for a component */ - blksize = cquantize->sv_actual; - - for (i = 0; i < cinfo->out_color_components; i++) { - /* fill in colorindex entries for i'th color component */ - nci = cquantize->Ncolors[i]; /* # of distinct values for this color */ - blksize = blksize / nci; - - /* adjust colorindex pointers to provide padding at negative indexes. */ - if (pad) - cquantize->colorindex[i] += MAXJSAMPLE; - - /* in loop, val = index of current output value, */ - /* and k = largest j that maps to current val */ - indexptr = cquantize->colorindex[i]; - val = 0; - k = largest_input_value(cinfo, i, 0, nci-1); - for (j = 0; j <= MAXJSAMPLE; j++) { - while (j > k) /* advance val if past boundary */ - k = largest_input_value(cinfo, i, ++val, nci-1); - /* premultiply so that no multiplication needed in main processing */ - indexptr[j] = (JSAMPLE) (val * blksize); - } - /* Pad at both ends if necessary */ - if (pad) - for (j = 1; j <= MAXJSAMPLE; j++) { - indexptr[-j] = indexptr[0]; - indexptr[MAXJSAMPLE+j] = indexptr[MAXJSAMPLE]; - } - } -} - - -/* - * Create an ordered-dither array for a component having ncolors - * distinct output values. - */ - -LOCAL ODITHER_MATRIX_PTR -make_odither_array (j_decompress_ptr cinfo, int ncolors) -{ - ODITHER_MATRIX_PTR odither; - int j,k; - INT32 num,den; - - odither = (ODITHER_MATRIX_PTR) - (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, - SIZEOF(ODITHER_MATRIX)); - /* The inter-value distance for this color is MAXJSAMPLE/(ncolors-1). - * Hence the dither value for the matrix cell with fill order f - * (f=0..N-1) should be (N-1-2*f)/(2*N) * MAXJSAMPLE/(ncolors-1). - * On 16-bit-int machine, be careful to avoid overflow. - */ - den = 2 * ODITHER_CELLS * ((INT32) (ncolors - 1)); - for (j = 0; j < ODITHER_SIZE; j++) { - for (k = 0; k < ODITHER_SIZE; k++) { - num = ((INT32) (ODITHER_CELLS-1 - 2*((int)base_dither_matrix[j][k]))) - * MAXJSAMPLE; - /* Ensure round towards zero despite C's lack of consistency - * about rounding negative values in integer division... - */ - odither[j][k] = (int) (num<0 ? -((-num)/den) : num/den); - } - } - return odither; -} - - -/* - * Create the ordered-dither tables. - * Components having the same number of representative colors may - * share a dither table. - */ - -LOCAL void -create_odither_tables (j_decompress_ptr cinfo) -{ - my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; - ODITHER_MATRIX_PTR odither; - int i, j, nci; - - for (i = 0; i < cinfo->out_color_components; i++) { - nci = cquantize->Ncolors[i]; /* # of distinct values for this color */ - odither = NULL; /* search for matching prior component */ - for (j = 0; j < i; j++) { - if (nci == cquantize->Ncolors[j]) { - odither = cquantize->odither[j]; - break; - } - } - if (odither == NULL) /* need a new table? */ - odither = make_odither_array(cinfo, nci); - cquantize->odither[i] = odither; - } -} - - -/* - * Map some rows of pixels to the output colormapped representation. - */ - -METHODDEF void -color_quantize (j_decompress_ptr cinfo, JSAMPARRAY input_buf, - JSAMPARRAY output_buf, int num_rows) -/* General case, no dithering */ -{ - my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; - JSAMPARRAY colorindex = cquantize->colorindex; - register int pixcode, ci; - register JSAMPROW ptrin, ptrout; - int row; - JDIMENSION col; - JDIMENSION width = cinfo->output_width; - register int nc = cinfo->out_color_components; - - for (row = 0; row < num_rows; row++) { - ptrin = input_buf[row]; - ptrout = output_buf[row]; - for (col = width; col > 0; col--) { - pixcode = 0; - for (ci = 0; ci < nc; ci++) { - pixcode += GETJSAMPLE(colorindex[ci][GETJSAMPLE(*ptrin++)]); - } - *ptrout++ = (JSAMPLE) pixcode; - } - } -} - - -METHODDEF void -color_quantize3 (j_decompress_ptr cinfo, JSAMPARRAY input_buf, - JSAMPARRAY output_buf, int num_rows) -/* Fast path for out_color_components==3, no dithering */ -{ - my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; - register int pixcode; - register JSAMPROW ptrin, ptrout; - JSAMPROW colorindex0 = cquantize->colorindex[0]; - JSAMPROW colorindex1 = cquantize->colorindex[1]; - JSAMPROW colorindex2 = cquantize->colorindex[2]; - int row; - JDIMENSION col; - JDIMENSION width = cinfo->output_width; - - for (row = 0; row < num_rows; row++) { - ptrin = input_buf[row]; - ptrout = output_buf[row]; - for (col = width; col > 0; col--) { - pixcode = GETJSAMPLE(colorindex0[GETJSAMPLE(*ptrin++)]); - pixcode += GETJSAMPLE(colorindex1[GETJSAMPLE(*ptrin++)]); - pixcode += GETJSAMPLE(colorindex2[GETJSAMPLE(*ptrin++)]); - *ptrout++ = (JSAMPLE) pixcode; - } - } -} - - -METHODDEF void -quantize_ord_dither (j_decompress_ptr cinfo, JSAMPARRAY input_buf, - JSAMPARRAY output_buf, int num_rows) -/* General case, with ordered dithering */ -{ - my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; - register JSAMPROW input_ptr; - register JSAMPROW output_ptr; - JSAMPROW colorindex_ci; - int * dither; /* points to active row of dither matrix */ - int row_index, col_index; /* current indexes into dither matrix */ - int nc = cinfo->out_color_components; - int ci; - int row; - JDIMENSION col; - JDIMENSION width = cinfo->output_width; - - for (row = 0; row < num_rows; row++) { - /* Initialize output values to 0 so can process components separately */ - jzero_far((void FAR *) output_buf[row], - (size_t) (width * SIZEOF(JSAMPLE))); - row_index = cquantize->row_index; - for (ci = 0; ci < nc; ci++) { - input_ptr = input_buf[row] + ci; - output_ptr = output_buf[row]; - colorindex_ci = cquantize->colorindex[ci]; - dither = cquantize->odither[ci][row_index]; - col_index = 0; - - for (col = width; col > 0; col--) { - /* Form pixel value + dither, range-limit to 0..MAXJSAMPLE, - * select output value, accumulate into output code for this pixel. - * Range-limiting need not be done explicitly, as we have extended - * the colorindex table to produce the right answers for out-of-range - * inputs. The maximum dither is +- MAXJSAMPLE; this sets the - * required amount of padding. - */ - *output_ptr += colorindex_ci[GETJSAMPLE(*input_ptr)+dither[col_index]]; - input_ptr += nc; - output_ptr++; - col_index = (col_index + 1) & ODITHER_MASK; - } - } - /* Advance row index for next row */ - row_index = (row_index + 1) & ODITHER_MASK; - cquantize->row_index = row_index; - } -} - - -METHODDEF void -quantize3_ord_dither (j_decompress_ptr cinfo, JSAMPARRAY input_buf, - JSAMPARRAY output_buf, int num_rows) -/* Fast path for out_color_components==3, with ordered dithering */ -{ - my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; - register int pixcode; - register JSAMPROW input_ptr; - register JSAMPROW output_ptr; - JSAMPROW colorindex0 = cquantize->colorindex[0]; - JSAMPROW colorindex1 = cquantize->colorindex[1]; - JSAMPROW colorindex2 = cquantize->colorindex[2]; - int * dither0; /* points to active row of dither matrix */ - int * dither1; - int * dither2; - int row_index, col_index; /* current indexes into dither matrix */ - int row; - JDIMENSION col; - JDIMENSION width = cinfo->output_width; - - for (row = 0; row < num_rows; row++) { - row_index = cquantize->row_index; - input_ptr = input_buf[row]; - output_ptr = output_buf[row]; - dither0 = cquantize->odither[0][row_index]; - dither1 = cquantize->odither[1][row_index]; - dither2 = cquantize->odither[2][row_index]; - col_index = 0; - - for (col = width; col > 0; col--) { - pixcode = GETJSAMPLE(colorindex0[GETJSAMPLE(*input_ptr++) + - dither0[col_index]]); - pixcode += GETJSAMPLE(colorindex1[GETJSAMPLE(*input_ptr++) + - dither1[col_index]]); - pixcode += GETJSAMPLE(colorindex2[GETJSAMPLE(*input_ptr++) + - dither2[col_index]]); - *output_ptr++ = (JSAMPLE) pixcode; - col_index = (col_index + 1) & ODITHER_MASK; - } - row_index = (row_index + 1) & ODITHER_MASK; - cquantize->row_index = row_index; - } -} - - -METHODDEF void -quantize_fs_dither (j_decompress_ptr cinfo, JSAMPARRAY input_buf, - JSAMPARRAY output_buf, int num_rows) -/* General case, with Floyd-Steinberg dithering */ -{ - my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; - register LOCFSERROR cur; /* current error or pixel value */ - LOCFSERROR belowerr; /* error for pixel below cur */ - LOCFSERROR bpreverr; /* error for below/prev col */ - LOCFSERROR bnexterr; /* error for below/next col */ - LOCFSERROR delta; - register FSERRPTR errorptr; /* => fserrors[] at column before current */ - register JSAMPROW input_ptr; - register JSAMPROW output_ptr; - JSAMPROW colorindex_ci; - JSAMPROW colormap_ci; - int pixcode; - int nc = cinfo->out_color_components; - int dir; /* 1 for left-to-right, -1 for right-to-left */ - int dirnc; /* dir * nc */ - int ci; - int row; - JDIMENSION col; - JDIMENSION width = cinfo->output_width; - JSAMPLE *range_limit = cinfo->sample_range_limit; - SHIFT_TEMPS - - for (row = 0; row < num_rows; row++) { - /* Initialize output values to 0 so can process components separately */ - jzero_far((void FAR *) output_buf[row], - (size_t) (width * SIZEOF(JSAMPLE))); - for (ci = 0; ci < nc; ci++) { - input_ptr = input_buf[row] + ci; - output_ptr = output_buf[row]; - if (cquantize->on_odd_row) { - /* work right to left in this row */ - input_ptr += (width-1) * nc; /* so point to rightmost pixel */ - output_ptr += width-1; - dir = -1; - dirnc = -nc; - errorptr = cquantize->fserrors[ci] + (width+1); /* => entry after last column */ - } else { - /* work left to right in this row */ - dir = 1; - dirnc = nc; - errorptr = cquantize->fserrors[ci]; /* => entry before first column */ - } - colorindex_ci = cquantize->colorindex[ci]; - colormap_ci = cquantize->sv_colormap[ci]; - /* Preset error values: no error propagated to first pixel from left */ - cur = 0; - /* and no error propagated to row below yet */ - belowerr = bpreverr = 0; - - for (col = width; col > 0; col--) { - /* cur holds the error propagated from the previous pixel on the - * current line. Add the error propagated from the previous line - * to form the complete error correction term for this pixel, and - * round the error term (which is expressed * 16) to an integer. - * RIGHT_SHIFT rounds towards minus infinity, so adding 8 is correct - * for either sign of the error value. - * Note: errorptr points to *previous* column's array entry. - */ - cur = RIGHT_SHIFT(cur + errorptr[dir] + 8, 4); - /* Form pixel value + error, and range-limit to 0..MAXJSAMPLE. - * The maximum error is +- MAXJSAMPLE; this sets the required size - * of the range_limit array. - */ - cur += GETJSAMPLE(*input_ptr); - cur = GETJSAMPLE(range_limit[cur]); - /* Select output value, accumulate into output code for this pixel */ - pixcode = GETJSAMPLE(colorindex_ci[cur]); - *output_ptr += (JSAMPLE) pixcode; - /* Compute actual representation error at this pixel */ - /* Note: we can do this even though we don't have the final */ - /* pixel code, because the colormap is orthogonal. */ - cur -= GETJSAMPLE(colormap_ci[pixcode]); - /* Compute error fractions to be propagated to adjacent pixels. - * Add these into the running sums, and simultaneously shift the - * next-line error sums left by 1 column. - */ - bnexterr = cur; - delta = cur * 2; - cur += delta; /* form error * 3 */ - errorptr[0] = (FSERROR) (bpreverr + cur); - cur += delta; /* form error * 5 */ - bpreverr = belowerr + cur; - belowerr = bnexterr; - cur += delta; /* form error * 7 */ - /* At this point cur contains the 7/16 error value to be propagated - * to the next pixel on the current line, and all the errors for the - * next line have been shifted over. We are therefore ready to move on. - */ - input_ptr += dirnc; /* advance input ptr to next column */ - output_ptr += dir; /* advance output ptr to next column */ - errorptr += dir; /* advance errorptr to current column */ - } - /* Post-loop cleanup: we must unload the final error value into the - * final fserrors[] entry. Note we need not unload belowerr because - * it is for the dummy column before or after the actual array. - */ - errorptr[0] = (FSERROR) bpreverr; /* unload prev err into array */ - } - cquantize->on_odd_row = (cquantize->on_odd_row ? FALSE : TRUE); - } -} - - -/* - * Allocate workspace for Floyd-Steinberg errors. - */ - -LOCAL void -alloc_fs_workspace (j_decompress_ptr cinfo) -{ - my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; - size_t arraysize; - int i; - - arraysize = (size_t) ((cinfo->output_width + 2) * SIZEOF(FSERROR)); - for (i = 0; i < cinfo->out_color_components; i++) { - cquantize->fserrors[i] = (FSERRPTR) - (*cinfo->mem->alloc_large)((j_common_ptr) cinfo, JPOOL_IMAGE, arraysize); - } -} - - -/* - * Initialize for one-pass color quantization. - */ - -METHODDEF void -start_pass_1_quant (j_decompress_ptr cinfo, boolean is_pre_scan) -{ - my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; - size_t arraysize; - int i; - - /* Install my colormap. */ - cinfo->colormap = cquantize->sv_colormap; - cinfo->actual_number_of_colors = cquantize->sv_actual; - - /* Initialize for desired dithering mode. */ - switch (cinfo->dither_mode) { - case JDITHER_NONE: - if (cinfo->out_color_components == 3) - cquantize->pub.color_quantize = color_quantize3; - else - cquantize->pub.color_quantize = color_quantize; - break; - case JDITHER_ORDERED: - if (cinfo->out_color_components == 3) - cquantize->pub.color_quantize = quantize3_ord_dither; - else - cquantize->pub.color_quantize = quantize_ord_dither; - cquantize->row_index = 0; /* initialize state for ordered dither */ - /* If user changed to ordered dither from another mode, - * we must recreate the color index table with padding. - * This will cost extra space, but probably isn't very likely. - */ - if (! cquantize->is_padded) - create_colorindex(cinfo); - /* Create ordered-dither tables if we didn't already. */ - if (cquantize->odither[0] == NULL) - create_odither_tables(cinfo); - break; - case JDITHER_FS: - cquantize->pub.color_quantize = quantize_fs_dither; - cquantize->on_odd_row = FALSE; /* initialize state for F-S dither */ - /* Allocate Floyd-Steinberg workspace if didn't already. */ - if (cquantize->fserrors[0] == NULL) - alloc_fs_workspace(cinfo); - /* Initialize the propagated errors to zero. */ - arraysize = (size_t) ((cinfo->output_width + 2) * SIZEOF(FSERROR)); - for (i = 0; i < cinfo->out_color_components; i++) - jzero_far((void FAR *) cquantize->fserrors[i], arraysize); - break; - default: - ERREXIT(cinfo, JERR_NOT_COMPILED); - break; - } -} - - -/* - * Finish up at the end of the pass. - */ - -METHODDEF void -finish_pass_1_quant (j_decompress_ptr cinfo) -{ - /* no work in 1-pass case */ -} - - -/* - * Switch to a new external colormap between output passes. - * Shouldn't get to this module! - */ - -METHODDEF void -new_color_map_1_quant (j_decompress_ptr cinfo) -{ - ERREXIT(cinfo, JERR_MODE_CHANGE); -} - - -/* - * Module initialization routine for 1-pass color quantization. - */ - -GLOBAL void -jinit_1pass_quantizer (j_decompress_ptr cinfo) -{ - my_cquantize_ptr cquantize; - - cquantize = (my_cquantize_ptr) - (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, - SIZEOF(my_cquantizer)); - cinfo->cquantize = (struct jpeg_color_quantizer *) cquantize; - cquantize->pub.start_pass = start_pass_1_quant; - cquantize->pub.finish_pass = finish_pass_1_quant; - cquantize->pub.new_color_map = new_color_map_1_quant; - cquantize->fserrors[0] = NULL; /* Flag FS workspace not allocated */ - cquantize->odither[0] = NULL; /* Also flag odither arrays not allocated */ - - /* Make sure my internal arrays won't overflow */ - if (cinfo->out_color_components > MAX_Q_COMPS) - ERREXIT1(cinfo, JERR_QUANT_COMPONENTS, MAX_Q_COMPS); - /* Make sure colormap indexes can be represented by JSAMPLEs */ - if (cinfo->desired_number_of_colors > (MAXJSAMPLE+1)) - ERREXIT1(cinfo, JERR_QUANT_MANY_COLORS, MAXJSAMPLE+1); - - /* Create the colormap and color index table. */ - create_colormap(cinfo); - create_colorindex(cinfo); - - /* Allocate Floyd-Steinberg workspace now if requested. - * We do this now since it is FAR storage and may affect the memory - * manager's space calculations. If the user changes to FS dither - * mode in a later pass, we will allocate the space then, and will - * possibly overrun the max_memory_to_use setting. - */ - if (cinfo->dither_mode == JDITHER_FS) - alloc_fs_workspace(cinfo); -} - -#endif /* QUANT_1PASS_SUPPORTED */ diff --git a/engine/jpeg-6/jquant2.c b/engine/jpeg-6/jquant2.c deleted file mode 100644 index 2504398..0000000 --- a/engine/jpeg-6/jquant2.c +++ /dev/null @@ -1,1310 +0,0 @@ -/* - * jquant2.c - * - * Copyright (C) 1991-1995, Thomas G. Lane. - * This file is part of the Independent JPEG Group's software. - * For conditions of distribution and use, see the accompanying README file. - * - * This file contains 2-pass color quantization (color mapping) routines. - * These routines provide selection of a custom color map for an image, - * followed by mapping of the image to that color map, with optional - * Floyd-Steinberg dithering. - * It is also possible to use just the second pass to map to an arbitrary - * externally-given color map. - * - * Note: ordered dithering is not supported, since there isn't any fast - * way to compute intercolor distances; it's unclear that ordered dither's - * fundamental assumptions even hold with an irregularly spaced color map. - */ - -#define JPEG_INTERNALS -#include "jinclude.h" -#include "jpeglib.h" - -#ifdef QUANT_2PASS_SUPPORTED - - -/* - * This module implements the well-known Heckbert paradigm for color - * quantization. Most of the ideas used here can be traced back to - * Heckbert's seminal paper - * Heckbert, Paul. "Color Image Quantization for Frame Buffer Display", - * Proc. SIGGRAPH '82, Computer Graphics v.16 #3 (July 1982), pp 297-304. - * - * In the first pass over the image, we accumulate a histogram showing the - * usage count of each possible color. To keep the histogram to a reasonable - * size, we reduce the precision of the input; typical practice is to retain - * 5 or 6 bits per color, so that 8 or 4 different input values are counted - * in the same histogram cell. - * - * Next, the color-selection step begins with a box representing the whole - * color space, and repeatedly splits the "largest" remaining box until we - * have as many boxes as desired colors. Then the mean color in each - * remaining box becomes one of the possible output colors. - * - * The second pass over the image maps each input pixel to the closest output - * color (optionally after applying a Floyd-Steinberg dithering correction). - * This mapping is logically trivial, but making it go fast enough requires - * considerable care. - * - * Heckbert-style quantizers vary a good deal in their policies for choosing - * the "largest" box and deciding where to cut it. The particular policies - * used here have proved out well in experimental comparisons, but better ones - * may yet be found. - * - * In earlier versions of the IJG code, this module quantized in YCbCr color - * space, processing the raw upsampled data without a color conversion step. - * This allowed the color conversion math to be done only once per colormap - * entry, not once per pixel. However, that optimization precluded other - * useful optimizations (such as merging color conversion with upsampling) - * and it also interfered with desired capabilities such as quantizing to an - * externally-supplied colormap. We have therefore abandoned that approach. - * The present code works in the post-conversion color space, typically RGB. - * - * To improve the visual quality of the results, we actually work in scaled - * RGB space, giving G distances more weight than R, and R in turn more than - * B. To do everything in integer math, we must use integer scale factors. - * The 2/3/1 scale factors used here correspond loosely to the relative - * weights of the colors in the NTSC grayscale equation. - * If you want to use this code to quantize a non-RGB color space, you'll - * probably need to change these scale factors. - */ - -#define R_SCALE 2 /* scale R distances by this much */ -#define G_SCALE 3 /* scale G distances by this much */ -#define B_SCALE 1 /* and B by this much */ - -/* Relabel R/G/B as components 0/1/2, respecting the RGB ordering defined - * in jmorecfg.h. As the code stands, it will do the right thing for R,G,B - * and B,G,R orders. If you define some other weird order in jmorecfg.h, - * you'll get compile errors until you extend this logic. In that case - * you'll probably want to tweak the histogram sizes too. - */ - -#if RGB_RED == 0 -#define C0_SCALE R_SCALE -#endif -#if RGB_BLUE == 0 -#define C0_SCALE B_SCALE -#endif -#if RGB_GREEN == 1 -#define C1_SCALE G_SCALE -#endif -#if RGB_RED == 2 -#define C2_SCALE R_SCALE -#endif -#if RGB_BLUE == 2 -#define C2_SCALE B_SCALE -#endif - - -/* - * First we have the histogram data structure and routines for creating it. - * - * The number of bits of precision can be adjusted by changing these symbols. - * We recommend keeping 6 bits for G and 5 each for R and B. - * If you have plenty of memory and cycles, 6 bits all around gives marginally - * better results; if you are short of memory, 5 bits all around will save - * some space but degrade the results. - * To maintain a fully accurate histogram, we'd need to allocate a "long" - * (preferably unsigned long) for each cell. In practice this is overkill; - * we can get by with 16 bits per cell. Few of the cell counts will overflow, - * and clamping those that do overflow to the maximum value will give close- - * enough results. This reduces the recommended histogram size from 256Kb - * to 128Kb, which is a useful savings on PC-class machines. - * (In the second pass the histogram space is re-used for pixel mapping data; - * in that capacity, each cell must be able to store zero to the number of - * desired colors. 16 bits/cell is plenty for that too.) - * Since the JPEG code is intended to run in small memory model on 80x86 - * machines, we can't just allocate the histogram in one chunk. Instead - * of a true 3-D array, we use a row of pointers to 2-D arrays. Each - * pointer corresponds to a C0 value (typically 2^5 = 32 pointers) and - * each 2-D array has 2^6*2^5 = 2048 or 2^6*2^6 = 4096 entries. Note that - * on 80x86 machines, the pointer row is in near memory but the actual - * arrays are in far memory (same arrangement as we use for image arrays). - */ - -#define MAXNUMCOLORS (MAXJSAMPLE+1) /* maximum size of colormap */ - -/* These will do the right thing for either R,G,B or B,G,R color order, - * but you may not like the results for other color orders. - */ -#define HIST_C0_BITS 5 /* bits of precision in R/B histogram */ -#define HIST_C1_BITS 6 /* bits of precision in G histogram */ -#define HIST_C2_BITS 5 /* bits of precision in B/R histogram */ - -/* Number of elements along histogram axes. */ -#define HIST_C0_ELEMS (1<cquantize; - register JSAMPROW ptr; - register histptr histp; - register hist3d histogram = cquantize->histogram; - int row; - JDIMENSION col; - JDIMENSION width = cinfo->output_width; - - for (row = 0; row < num_rows; row++) { - ptr = input_buf[row]; - for (col = width; col > 0; col--) { - /* get pixel value and index into the histogram */ - histp = & histogram[GETJSAMPLE(ptr[0]) >> C0_SHIFT] - [GETJSAMPLE(ptr[1]) >> C1_SHIFT] - [GETJSAMPLE(ptr[2]) >> C2_SHIFT]; - /* increment, check for overflow and undo increment if so. */ - if (++(*histp) <= 0) - (*histp)--; - ptr += 3; - } - } -} - - -/* - * Next we have the really interesting routines: selection of a colormap - * given the completed histogram. - * These routines work with a list of "boxes", each representing a rectangular - * subset of the input color space (to histogram precision). - */ - -typedef struct { - /* The bounds of the box (inclusive); expressed as histogram indexes */ - int c0min, c0max; - int c1min, c1max; - int c2min, c2max; - /* The volume (actually 2-norm) of the box */ - INT32 volume; - /* The number of nonzero histogram cells within this box */ - long colorcount; -} box; - -typedef box * boxptr; - - -LOCAL boxptr -find_biggest_color_pop (boxptr boxlist, int numboxes) -/* Find the splittable box with the largest color population */ -/* Returns NULL if no splittable boxes remain */ -{ - register boxptr boxp; - register int i; - register long maxc = 0; - boxptr which = NULL; - - for (i = 0, boxp = boxlist; i < numboxes; i++, boxp++) { - if (boxp->colorcount > maxc && boxp->volume > 0) { - which = boxp; - maxc = boxp->colorcount; - } - } - return which; -} - - -LOCAL boxptr -find_biggest_volume (boxptr boxlist, int numboxes) -/* Find the splittable box with the largest (scaled) volume */ -/* Returns NULL if no splittable boxes remain */ -{ - register boxptr boxp; - register int i; - register INT32 maxv = 0; - boxptr which = NULL; - - for (i = 0, boxp = boxlist; i < numboxes; i++, boxp++) { - if (boxp->volume > maxv) { - which = boxp; - maxv = boxp->volume; - } - } - return which; -} - - -LOCAL void -update_box (j_decompress_ptr cinfo, boxptr boxp) -/* Shrink the min/max bounds of a box to enclose only nonzero elements, */ -/* and recompute its volume and population */ -{ - my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; - hist3d histogram = cquantize->histogram; - histptr histp; - int c0,c1,c2; - int c0min,c0max,c1min,c1max,c2min,c2max; - INT32 dist0,dist1,dist2; - long ccount; - - c0min = boxp->c0min; c0max = boxp->c0max; - c1min = boxp->c1min; c1max = boxp->c1max; - c2min = boxp->c2min; c2max = boxp->c2max; - - if (c0max > c0min) - for (c0 = c0min; c0 <= c0max; c0++) - for (c1 = c1min; c1 <= c1max; c1++) { - histp = & histogram[c0][c1][c2min]; - for (c2 = c2min; c2 <= c2max; c2++) - if (*histp++ != 0) { - boxp->c0min = c0min = c0; - goto have_c0min; - } - } - have_c0min: - if (c0max > c0min) - for (c0 = c0max; c0 >= c0min; c0--) - for (c1 = c1min; c1 <= c1max; c1++) { - histp = & histogram[c0][c1][c2min]; - for (c2 = c2min; c2 <= c2max; c2++) - if (*histp++ != 0) { - boxp->c0max = c0max = c0; - goto have_c0max; - } - } - have_c0max: - if (c1max > c1min) - for (c1 = c1min; c1 <= c1max; c1++) - for (c0 = c0min; c0 <= c0max; c0++) { - histp = & histogram[c0][c1][c2min]; - for (c2 = c2min; c2 <= c2max; c2++) - if (*histp++ != 0) { - boxp->c1min = c1min = c1; - goto have_c1min; - } - } - have_c1min: - if (c1max > c1min) - for (c1 = c1max; c1 >= c1min; c1--) - for (c0 = c0min; c0 <= c0max; c0++) { - histp = & histogram[c0][c1][c2min]; - for (c2 = c2min; c2 <= c2max; c2++) - if (*histp++ != 0) { - boxp->c1max = c1max = c1; - goto have_c1max; - } - } - have_c1max: - if (c2max > c2min) - for (c2 = c2min; c2 <= c2max; c2++) - for (c0 = c0min; c0 <= c0max; c0++) { - histp = & histogram[c0][c1min][c2]; - for (c1 = c1min; c1 <= c1max; c1++, histp += HIST_C2_ELEMS) - if (*histp != 0) { - boxp->c2min = c2min = c2; - goto have_c2min; - } - } - have_c2min: - if (c2max > c2min) - for (c2 = c2max; c2 >= c2min; c2--) - for (c0 = c0min; c0 <= c0max; c0++) { - histp = & histogram[c0][c1min][c2]; - for (c1 = c1min; c1 <= c1max; c1++, histp += HIST_C2_ELEMS) - if (*histp != 0) { - boxp->c2max = c2max = c2; - goto have_c2max; - } - } - have_c2max: - - /* Update box volume. - * We use 2-norm rather than real volume here; this biases the method - * against making long narrow boxes, and it has the side benefit that - * a box is splittable iff norm > 0. - * Since the differences are expressed in histogram-cell units, - * we have to shift back to JSAMPLE units to get consistent distances; - * after which, we scale according to the selected distance scale factors. - */ - dist0 = ((c0max - c0min) << C0_SHIFT) * C0_SCALE; - dist1 = ((c1max - c1min) << C1_SHIFT) * C1_SCALE; - dist2 = ((c2max - c2min) << C2_SHIFT) * C2_SCALE; - boxp->volume = dist0*dist0 + dist1*dist1 + dist2*dist2; - - /* Now scan remaining volume of box and compute population */ - ccount = 0; - for (c0 = c0min; c0 <= c0max; c0++) - for (c1 = c1min; c1 <= c1max; c1++) { - histp = & histogram[c0][c1][c2min]; - for (c2 = c2min; c2 <= c2max; c2++, histp++) - if (*histp != 0) { - ccount++; - } - } - boxp->colorcount = ccount; -} - - -LOCAL int -median_cut (j_decompress_ptr cinfo, boxptr boxlist, int numboxes, - int desired_colors) -/* Repeatedly select and split the largest box until we have enough boxes */ -{ - int n,lb; - int c0,c1,c2,cmax; - register boxptr b1,b2; - - while (numboxes < desired_colors) { - /* Select box to split. - * Current algorithm: by population for first half, then by volume. - */ - if (numboxes*2 <= desired_colors) { - b1 = find_biggest_color_pop(boxlist, numboxes); - } else { - b1 = find_biggest_volume(boxlist, numboxes); - } - if (b1 == NULL) /* no splittable boxes left! */ - break; - b2 = &boxlist[numboxes]; /* where new box will go */ - /* Copy the color bounds to the new box. */ - b2->c0max = b1->c0max; b2->c1max = b1->c1max; b2->c2max = b1->c2max; - b2->c0min = b1->c0min; b2->c1min = b1->c1min; b2->c2min = b1->c2min; - /* Choose which axis to split the box on. - * Current algorithm: longest scaled axis. - * See notes in update_box about scaling distances. - */ - c0 = ((b1->c0max - b1->c0min) << C0_SHIFT) * C0_SCALE; - c1 = ((b1->c1max - b1->c1min) << C1_SHIFT) * C1_SCALE; - c2 = ((b1->c2max - b1->c2min) << C2_SHIFT) * C2_SCALE; - /* We want to break any ties in favor of green, then red, blue last. - * This code does the right thing for R,G,B or B,G,R color orders only. - */ -#if RGB_RED == 0 - cmax = c1; n = 1; - if (c0 > cmax) { cmax = c0; n = 0; } - if (c2 > cmax) { n = 2; } -#else - cmax = c1; n = 1; - if (c2 > cmax) { cmax = c2; n = 2; } - if (c0 > cmax) { n = 0; } -#endif - /* Choose split point along selected axis, and update box bounds. - * Current algorithm: split at halfway point. - * (Since the box has been shrunk to minimum volume, - * any split will produce two nonempty subboxes.) - * Note that lb value is max for lower box, so must be < old max. - */ - switch (n) { - case 0: - lb = (b1->c0max + b1->c0min) / 2; - b1->c0max = lb; - b2->c0min = lb+1; - break; - case 1: - lb = (b1->c1max + b1->c1min) / 2; - b1->c1max = lb; - b2->c1min = lb+1; - break; - case 2: - lb = (b1->c2max + b1->c2min) / 2; - b1->c2max = lb; - b2->c2min = lb+1; - break; - } - /* Update stats for boxes */ - update_box(cinfo, b1); - update_box(cinfo, b2); - numboxes++; - } - return numboxes; -} - - -LOCAL void -compute_color (j_decompress_ptr cinfo, boxptr boxp, int icolor) -/* Compute representative color for a box, put it in colormap[icolor] */ -{ - /* Current algorithm: mean weighted by pixels (not colors) */ - /* Note it is important to get the rounding correct! */ - my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; - hist3d histogram = cquantize->histogram; - histptr histp; - int c0,c1,c2; - int c0min,c0max,c1min,c1max,c2min,c2max; - long count; - long total = 0; - long c0total = 0; - long c1total = 0; - long c2total = 0; - - c0min = boxp->c0min; c0max = boxp->c0max; - c1min = boxp->c1min; c1max = boxp->c1max; - c2min = boxp->c2min; c2max = boxp->c2max; - - for (c0 = c0min; c0 <= c0max; c0++) - for (c1 = c1min; c1 <= c1max; c1++) { - histp = & histogram[c0][c1][c2min]; - for (c2 = c2min; c2 <= c2max; c2++) { - if ((count = *histp++) != 0) { - total += count; - c0total += ((c0 << C0_SHIFT) + ((1<>1)) * count; - c1total += ((c1 << C1_SHIFT) + ((1<>1)) * count; - c2total += ((c2 << C2_SHIFT) + ((1<>1)) * count; - } - } - } - - cinfo->colormap[0][icolor] = (JSAMPLE) ((c0total + (total>>1)) / total); - cinfo->colormap[1][icolor] = (JSAMPLE) ((c1total + (total>>1)) / total); - cinfo->colormap[2][icolor] = (JSAMPLE) ((c2total + (total>>1)) / total); -} - - -LOCAL void -select_colors (j_decompress_ptr cinfo, int desired_colors) -/* Master routine for color selection */ -{ - boxptr boxlist; - int numboxes; - int i; - - /* Allocate workspace for box list */ - boxlist = (boxptr) (*cinfo->mem->alloc_small) - ((j_common_ptr) cinfo, JPOOL_IMAGE, desired_colors * SIZEOF(box)); - /* Initialize one box containing whole space */ - numboxes = 1; - boxlist[0].c0min = 0; - boxlist[0].c0max = MAXJSAMPLE >> C0_SHIFT; - boxlist[0].c1min = 0; - boxlist[0].c1max = MAXJSAMPLE >> C1_SHIFT; - boxlist[0].c2min = 0; - boxlist[0].c2max = MAXJSAMPLE >> C2_SHIFT; - /* Shrink it to actually-used volume and set its statistics */ - update_box(cinfo, & boxlist[0]); - /* Perform median-cut to produce final box list */ - numboxes = median_cut(cinfo, boxlist, numboxes, desired_colors); - /* Compute the representative color for each box, fill colormap */ - for (i = 0; i < numboxes; i++) - compute_color(cinfo, & boxlist[i], i); - cinfo->actual_number_of_colors = numboxes; - TRACEMS1(cinfo, 1, JTRC_QUANT_SELECTED, numboxes); -} - - -/* - * These routines are concerned with the time-critical task of mapping input - * colors to the nearest color in the selected colormap. - * - * We re-use the histogram space as an "inverse color map", essentially a - * cache for the results of nearest-color searches. All colors within a - * histogram cell will be mapped to the same colormap entry, namely the one - * closest to the cell's center. This may not be quite the closest entry to - * the actual input color, but it's almost as good. A zero in the cache - * indicates we haven't found the nearest color for that cell yet; the array - * is cleared to zeroes before starting the mapping pass. When we find the - * nearest color for a cell, its colormap index plus one is recorded in the - * cache for future use. The pass2 scanning routines call fill_inverse_cmap - * when they need to use an unfilled entry in the cache. - * - * Our method of efficiently finding nearest colors is based on the "locally - * sorted search" idea described by Heckbert and on the incremental distance - * calculation described by Spencer W. Thomas in chapter III.1 of Graphics - * Gems II (James Arvo, ed. Academic Press, 1991). Thomas points out that - * the distances from a given colormap entry to each cell of the histogram can - * be computed quickly using an incremental method: the differences between - * distances to adjacent cells themselves differ by a constant. This allows a - * fairly fast implementation of the "brute force" approach of computing the - * distance from every colormap entry to every histogram cell. Unfortunately, - * it needs a work array to hold the best-distance-so-far for each histogram - * cell (because the inner loop has to be over cells, not colormap entries). - * The work array elements have to be INT32s, so the work array would need - * 256Kb at our recommended precision. This is not feasible in DOS machines. - * - * To get around these problems, we apply Thomas' method to compute the - * nearest colors for only the cells within a small subbox of the histogram. - * The work array need be only as big as the subbox, so the memory usage - * problem is solved. Furthermore, we need not fill subboxes that are never - * referenced in pass2; many images use only part of the color gamut, so a - * fair amount of work is saved. An additional advantage of this - * approach is that we can apply Heckbert's locality criterion to quickly - * eliminate colormap entries that are far away from the subbox; typically - * three-fourths of the colormap entries are rejected by Heckbert's criterion, - * and we need not compute their distances to individual cells in the subbox. - * The speed of this approach is heavily influenced by the subbox size: too - * small means too much overhead, too big loses because Heckbert's criterion - * can't eliminate as many colormap entries. Empirically the best subbox - * size seems to be about 1/512th of the histogram (1/8th in each direction). - * - * Thomas' article also describes a refined method which is asymptotically - * faster than the brute-force method, but it is also far more complex and - * cannot efficiently be applied to small subboxes. It is therefore not - * useful for programs intended to be portable to DOS machines. On machines - * with plenty of memory, filling the whole histogram in one shot with Thomas' - * refined method might be faster than the present code --- but then again, - * it might not be any faster, and it's certainly more complicated. - */ - - -/* log2(histogram cells in update box) for each axis; this can be adjusted */ -#define BOX_C0_LOG (HIST_C0_BITS-3) -#define BOX_C1_LOG (HIST_C1_BITS-3) -#define BOX_C2_LOG (HIST_C2_BITS-3) - -#define BOX_C0_ELEMS (1<actual_number_of_colors; - int maxc0, maxc1, maxc2; - int centerc0, centerc1, centerc2; - int i, x, ncolors; - INT32 minmaxdist, min_dist, max_dist, tdist; - INT32 mindist[MAXNUMCOLORS]; /* min distance to colormap entry i */ - - /* Compute true coordinates of update box's upper corner and center. - * Actually we compute the coordinates of the center of the upper-corner - * histogram cell, which are the upper bounds of the volume we care about. - * Note that since ">>" rounds down, the "center" values may be closer to - * min than to max; hence comparisons to them must be "<=", not "<". - */ - maxc0 = minc0 + ((1 << BOX_C0_SHIFT) - (1 << C0_SHIFT)); - centerc0 = (minc0 + maxc0) >> 1; - maxc1 = minc1 + ((1 << BOX_C1_SHIFT) - (1 << C1_SHIFT)); - centerc1 = (minc1 + maxc1) >> 1; - maxc2 = minc2 + ((1 << BOX_C2_SHIFT) - (1 << C2_SHIFT)); - centerc2 = (minc2 + maxc2) >> 1; - - /* For each color in colormap, find: - * 1. its minimum squared-distance to any point in the update box - * (zero if color is within update box); - * 2. its maximum squared-distance to any point in the update box. - * Both of these can be found by considering only the corners of the box. - * We save the minimum distance for each color in mindist[]; - * only the smallest maximum distance is of interest. - */ - minmaxdist = 0x7FFFFFFFL; - - for (i = 0; i < numcolors; i++) { - /* We compute the squared-c0-distance term, then add in the other two. */ - x = GETJSAMPLE(cinfo->colormap[0][i]); - if (x < minc0) { - tdist = (x - minc0) * C0_SCALE; - min_dist = tdist*tdist; - tdist = (x - maxc0) * C0_SCALE; - max_dist = tdist*tdist; - } else if (x > maxc0) { - tdist = (x - maxc0) * C0_SCALE; - min_dist = tdist*tdist; - tdist = (x - minc0) * C0_SCALE; - max_dist = tdist*tdist; - } else { - /* within cell range so no contribution to min_dist */ - min_dist = 0; - if (x <= centerc0) { - tdist = (x - maxc0) * C0_SCALE; - max_dist = tdist*tdist; - } else { - tdist = (x - minc0) * C0_SCALE; - max_dist = tdist*tdist; - } - } - - x = GETJSAMPLE(cinfo->colormap[1][i]); - if (x < minc1) { - tdist = (x - minc1) * C1_SCALE; - min_dist += tdist*tdist; - tdist = (x - maxc1) * C1_SCALE; - max_dist += tdist*tdist; - } else if (x > maxc1) { - tdist = (x - maxc1) * C1_SCALE; - min_dist += tdist*tdist; - tdist = (x - minc1) * C1_SCALE; - max_dist += tdist*tdist; - } else { - /* within cell range so no contribution to min_dist */ - if (x <= centerc1) { - tdist = (x - maxc1) * C1_SCALE; - max_dist += tdist*tdist; - } else { - tdist = (x - minc1) * C1_SCALE; - max_dist += tdist*tdist; - } - } - - x = GETJSAMPLE(cinfo->colormap[2][i]); - if (x < minc2) { - tdist = (x - minc2) * C2_SCALE; - min_dist += tdist*tdist; - tdist = (x - maxc2) * C2_SCALE; - max_dist += tdist*tdist; - } else if (x > maxc2) { - tdist = (x - maxc2) * C2_SCALE; - min_dist += tdist*tdist; - tdist = (x - minc2) * C2_SCALE; - max_dist += tdist*tdist; - } else { - /* within cell range so no contribution to min_dist */ - if (x <= centerc2) { - tdist = (x - maxc2) * C2_SCALE; - max_dist += tdist*tdist; - } else { - tdist = (x - minc2) * C2_SCALE; - max_dist += tdist*tdist; - } - } - - mindist[i] = min_dist; /* save away the results */ - if (max_dist < minmaxdist) - minmaxdist = max_dist; - } - - /* Now we know that no cell in the update box is more than minmaxdist - * away from some colormap entry. Therefore, only colors that are - * within minmaxdist of some part of the box need be considered. - */ - ncolors = 0; - for (i = 0; i < numcolors; i++) { - if (mindist[i] <= minmaxdist) - colorlist[ncolors++] = (JSAMPLE) i; - } - return ncolors; -} - - -LOCAL void -find_best_colors (j_decompress_ptr cinfo, int minc0, int minc1, int minc2, - int numcolors, JSAMPLE colorlist[], JSAMPLE bestcolor[]) -/* Find the closest colormap entry for each cell in the update box, - * given the list of candidate colors prepared by find_nearby_colors. - * Return the indexes of the closest entries in the bestcolor[] array. - * This routine uses Thomas' incremental distance calculation method to - * find the distance from a colormap entry to successive cells in the box. - */ -{ - int ic0, ic1, ic2; - int i, icolor; - register INT32 * bptr; /* pointer into bestdist[] array */ - JSAMPLE * cptr; /* pointer into bestcolor[] array */ - INT32 dist0, dist1; /* initial distance values */ - register INT32 dist2; /* current distance in inner loop */ - INT32 xx0, xx1; /* distance increments */ - register INT32 xx2; - INT32 inc0, inc1, inc2; /* initial values for increments */ - /* This array holds the distance to the nearest-so-far color for each cell */ - INT32 bestdist[BOX_C0_ELEMS * BOX_C1_ELEMS * BOX_C2_ELEMS]; - - /* Initialize best-distance for each cell of the update box */ - bptr = bestdist; - for (i = BOX_C0_ELEMS*BOX_C1_ELEMS*BOX_C2_ELEMS-1; i >= 0; i--) - *bptr++ = 0x7FFFFFFFL; - - /* For each color selected by find_nearby_colors, - * compute its distance to the center of each cell in the box. - * If that's less than best-so-far, update best distance and color number. - */ - - /* Nominal steps between cell centers ("x" in Thomas article) */ -#define STEP_C0 ((1 << C0_SHIFT) * C0_SCALE) -#define STEP_C1 ((1 << C1_SHIFT) * C1_SCALE) -#define STEP_C2 ((1 << C2_SHIFT) * C2_SCALE) - - for (i = 0; i < numcolors; i++) { - icolor = GETJSAMPLE(colorlist[i]); - /* Compute (square of) distance from minc0/c1/c2 to this color */ - inc0 = (minc0 - GETJSAMPLE(cinfo->colormap[0][icolor])) * C0_SCALE; - dist0 = inc0*inc0; - inc1 = (minc1 - GETJSAMPLE(cinfo->colormap[1][icolor])) * C1_SCALE; - dist0 += inc1*inc1; - inc2 = (minc2 - GETJSAMPLE(cinfo->colormap[2][icolor])) * C2_SCALE; - dist0 += inc2*inc2; - /* Form the initial difference increments */ - inc0 = inc0 * (2 * STEP_C0) + STEP_C0 * STEP_C0; - inc1 = inc1 * (2 * STEP_C1) + STEP_C1 * STEP_C1; - inc2 = inc2 * (2 * STEP_C2) + STEP_C2 * STEP_C2; - /* Now loop over all cells in box, updating distance per Thomas method */ - bptr = bestdist; - cptr = bestcolor; - xx0 = inc0; - for (ic0 = BOX_C0_ELEMS-1; ic0 >= 0; ic0--) { - dist1 = dist0; - xx1 = inc1; - for (ic1 = BOX_C1_ELEMS-1; ic1 >= 0; ic1--) { - dist2 = dist1; - xx2 = inc2; - for (ic2 = BOX_C2_ELEMS-1; ic2 >= 0; ic2--) { - if (dist2 < *bptr) { - *bptr = dist2; - *cptr = (JSAMPLE) icolor; - } - dist2 += xx2; - xx2 += 2 * STEP_C2 * STEP_C2; - bptr++; - cptr++; - } - dist1 += xx1; - xx1 += 2 * STEP_C1 * STEP_C1; - } - dist0 += xx0; - xx0 += 2 * STEP_C0 * STEP_C0; - } - } -} - - -LOCAL void -fill_inverse_cmap (j_decompress_ptr cinfo, int c0, int c1, int c2) -/* Fill the inverse-colormap entries in the update box that contains */ -/* histogram cell c0/c1/c2. (Only that one cell MUST be filled, but */ -/* we can fill as many others as we wish.) */ -{ - my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; - hist3d histogram = cquantize->histogram; - int minc0, minc1, minc2; /* lower left corner of update box */ - int ic0, ic1, ic2; - register JSAMPLE * cptr; /* pointer into bestcolor[] array */ - register histptr cachep; /* pointer into main cache array */ - /* This array lists the candidate colormap indexes. */ - JSAMPLE colorlist[MAXNUMCOLORS]; - int numcolors; /* number of candidate colors */ - /* This array holds the actually closest colormap index for each cell. */ - JSAMPLE bestcolor[BOX_C0_ELEMS * BOX_C1_ELEMS * BOX_C2_ELEMS]; - - /* Convert cell coordinates to update box ID */ - c0 >>= BOX_C0_LOG; - c1 >>= BOX_C1_LOG; - c2 >>= BOX_C2_LOG; - - /* Compute true coordinates of update box's origin corner. - * Actually we compute the coordinates of the center of the corner - * histogram cell, which are the lower bounds of the volume we care about. - */ - minc0 = (c0 << BOX_C0_SHIFT) + ((1 << C0_SHIFT) >> 1); - minc1 = (c1 << BOX_C1_SHIFT) + ((1 << C1_SHIFT) >> 1); - minc2 = (c2 << BOX_C2_SHIFT) + ((1 << C2_SHIFT) >> 1); - - /* Determine which colormap entries are close enough to be candidates - * for the nearest entry to some cell in the update box. - */ - numcolors = find_nearby_colors(cinfo, minc0, minc1, minc2, colorlist); - - /* Determine the actually nearest colors. */ - find_best_colors(cinfo, minc0, minc1, minc2, numcolors, colorlist, - bestcolor); - - /* Save the best color numbers (plus 1) in the main cache array */ - c0 <<= BOX_C0_LOG; /* convert ID back to base cell indexes */ - c1 <<= BOX_C1_LOG; - c2 <<= BOX_C2_LOG; - cptr = bestcolor; - for (ic0 = 0; ic0 < BOX_C0_ELEMS; ic0++) { - for (ic1 = 0; ic1 < BOX_C1_ELEMS; ic1++) { - cachep = & histogram[c0+ic0][c1+ic1][c2]; - for (ic2 = 0; ic2 < BOX_C2_ELEMS; ic2++) { - *cachep++ = (histcell) (GETJSAMPLE(*cptr++) + 1); - } - } - } -} - - -/* - * Map some rows of pixels to the output colormapped representation. - */ - -METHODDEF void -pass2_no_dither (j_decompress_ptr cinfo, - JSAMPARRAY input_buf, JSAMPARRAY output_buf, int num_rows) -/* This version performs no dithering */ -{ - my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; - hist3d histogram = cquantize->histogram; - register JSAMPROW inptr, outptr; - register histptr cachep; - register int c0, c1, c2; - int row; - JDIMENSION col; - JDIMENSION width = cinfo->output_width; - - for (row = 0; row < num_rows; row++) { - inptr = input_buf[row]; - outptr = output_buf[row]; - for (col = width; col > 0; col--) { - /* get pixel value and index into the cache */ - c0 = GETJSAMPLE(*inptr++) >> C0_SHIFT; - c1 = GETJSAMPLE(*inptr++) >> C1_SHIFT; - c2 = GETJSAMPLE(*inptr++) >> C2_SHIFT; - cachep = & histogram[c0][c1][c2]; - /* If we have not seen this color before, find nearest colormap entry */ - /* and update the cache */ - if (*cachep == 0) - fill_inverse_cmap(cinfo, c0,c1,c2); - /* Now emit the colormap index for this cell */ - *outptr++ = (JSAMPLE) (*cachep - 1); - } - } -} - - -METHODDEF void -pass2_fs_dither (j_decompress_ptr cinfo, - JSAMPARRAY input_buf, JSAMPARRAY output_buf, int num_rows) -/* This version performs Floyd-Steinberg dithering */ -{ - my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; - hist3d histogram = cquantize->histogram; - register LOCFSERROR cur0, cur1, cur2; /* current error or pixel value */ - LOCFSERROR belowerr0, belowerr1, belowerr2; /* error for pixel below cur */ - LOCFSERROR bpreverr0, bpreverr1, bpreverr2; /* error for below/prev col */ - register FSERRPTR errorptr; /* => fserrors[] at column before current */ - JSAMPROW inptr; /* => current input pixel */ - JSAMPROW outptr; /* => current output pixel */ - histptr cachep; - int dir; /* +1 or -1 depending on direction */ - int dir3; /* 3*dir, for advancing inptr & errorptr */ - int row; - JDIMENSION col; - JDIMENSION width = cinfo->output_width; - JSAMPLE *range_limit = cinfo->sample_range_limit; - int *error_limit = cquantize->error_limiter; - JSAMPROW colormap0 = cinfo->colormap[0]; - JSAMPROW colormap1 = cinfo->colormap[1]; - JSAMPROW colormap2 = cinfo->colormap[2]; - SHIFT_TEMPS - - for (row = 0; row < num_rows; row++) { - inptr = input_buf[row]; - outptr = output_buf[row]; - if (cquantize->on_odd_row) { - /* work right to left in this row */ - inptr += (width-1) * 3; /* so point to rightmost pixel */ - outptr += width-1; - dir = -1; - dir3 = -3; - errorptr = cquantize->fserrors + (width+1)*3; /* => entry after last column */ - cquantize->on_odd_row = FALSE; /* flip for next time */ - } else { - /* work left to right in this row */ - dir = 1; - dir3 = 3; - errorptr = cquantize->fserrors; /* => entry before first real column */ - cquantize->on_odd_row = TRUE; /* flip for next time */ - } - /* Preset error values: no error propagated to first pixel from left */ - cur0 = cur1 = cur2 = 0; - /* and no error propagated to row below yet */ - belowerr0 = belowerr1 = belowerr2 = 0; - bpreverr0 = bpreverr1 = bpreverr2 = 0; - - for (col = width; col > 0; col--) { - /* curN holds the error propagated from the previous pixel on the - * current line. Add the error propagated from the previous line - * to form the complete error correction term for this pixel, and - * round the error term (which is expressed * 16) to an integer. - * RIGHT_SHIFT rounds towards minus infinity, so adding 8 is correct - * for either sign of the error value. - * Note: errorptr points to *previous* column's array entry. - */ - cur0 = RIGHT_SHIFT(cur0 + errorptr[dir3+0] + 8, 4); - cur1 = RIGHT_SHIFT(cur1 + errorptr[dir3+1] + 8, 4); - cur2 = RIGHT_SHIFT(cur2 + errorptr[dir3+2] + 8, 4); - /* Limit the error using transfer function set by init_error_limit. - * See comments with init_error_limit for rationale. - */ - cur0 = error_limit[cur0]; - cur1 = error_limit[cur1]; - cur2 = error_limit[cur2]; - /* Form pixel value + error, and range-limit to 0..MAXJSAMPLE. - * The maximum error is +- MAXJSAMPLE (or less with error limiting); - * this sets the required size of the range_limit array. - */ - cur0 += GETJSAMPLE(inptr[0]); - cur1 += GETJSAMPLE(inptr[1]); - cur2 += GETJSAMPLE(inptr[2]); - cur0 = GETJSAMPLE(range_limit[cur0]); - cur1 = GETJSAMPLE(range_limit[cur1]); - cur2 = GETJSAMPLE(range_limit[cur2]); - /* Index into the cache with adjusted pixel value */ - cachep = & histogram[cur0>>C0_SHIFT][cur1>>C1_SHIFT][cur2>>C2_SHIFT]; - /* If we have not seen this color before, find nearest colormap */ - /* entry and update the cache */ - if (*cachep == 0) - fill_inverse_cmap(cinfo, cur0>>C0_SHIFT,cur1>>C1_SHIFT,cur2>>C2_SHIFT); - /* Now emit the colormap index for this cell */ - { register int pixcode = *cachep - 1; - *outptr = (JSAMPLE) pixcode; - /* Compute representation error for this pixel */ - cur0 -= GETJSAMPLE(colormap0[pixcode]); - cur1 -= GETJSAMPLE(colormap1[pixcode]); - cur2 -= GETJSAMPLE(colormap2[pixcode]); - } - /* Compute error fractions to be propagated to adjacent pixels. - * Add these into the running sums, and simultaneously shift the - * next-line error sums left by 1 column. - */ - { register LOCFSERROR bnexterr, delta; - - bnexterr = cur0; /* Process component 0 */ - delta = cur0 * 2; - cur0 += delta; /* form error * 3 */ - errorptr[0] = (FSERROR) (bpreverr0 + cur0); - cur0 += delta; /* form error * 5 */ - bpreverr0 = belowerr0 + cur0; - belowerr0 = bnexterr; - cur0 += delta; /* form error * 7 */ - bnexterr = cur1; /* Process component 1 */ - delta = cur1 * 2; - cur1 += delta; /* form error * 3 */ - errorptr[1] = (FSERROR) (bpreverr1 + cur1); - cur1 += delta; /* form error * 5 */ - bpreverr1 = belowerr1 + cur1; - belowerr1 = bnexterr; - cur1 += delta; /* form error * 7 */ - bnexterr = cur2; /* Process component 2 */ - delta = cur2 * 2; - cur2 += delta; /* form error * 3 */ - errorptr[2] = (FSERROR) (bpreverr2 + cur2); - cur2 += delta; /* form error * 5 */ - bpreverr2 = belowerr2 + cur2; - belowerr2 = bnexterr; - cur2 += delta; /* form error * 7 */ - } - /* At this point curN contains the 7/16 error value to be propagated - * to the next pixel on the current line, and all the errors for the - * next line have been shifted over. We are therefore ready to move on. - */ - inptr += dir3; /* Advance pixel pointers to next column */ - outptr += dir; - errorptr += dir3; /* advance errorptr to current column */ - } - /* Post-loop cleanup: we must unload the final error values into the - * final fserrors[] entry. Note we need not unload belowerrN because - * it is for the dummy column before or after the actual array. - */ - errorptr[0] = (FSERROR) bpreverr0; /* unload prev errs into array */ - errorptr[1] = (FSERROR) bpreverr1; - errorptr[2] = (FSERROR) bpreverr2; - } -} - - -/* - * Initialize the error-limiting transfer function (lookup table). - * The raw F-S error computation can potentially compute error values of up to - * +- MAXJSAMPLE. But we want the maximum correction applied to a pixel to be - * much less, otherwise obviously wrong pixels will be created. (Typical - * effects include weird fringes at color-area boundaries, isolated bright - * pixels in a dark area, etc.) The standard advice for avoiding this problem - * is to ensure that the "corners" of the color cube are allocated as output - * colors; then repeated errors in the same direction cannot cause cascading - * error buildup. However, that only prevents the error from getting - * completely out of hand; Aaron Giles reports that error limiting improves - * the results even with corner colors allocated. - * A simple clamping of the error values to about +- MAXJSAMPLE/8 works pretty - * well, but the smoother transfer function used below is even better. Thanks - * to Aaron Giles for this idea. - */ - -LOCAL void -init_error_limit (j_decompress_ptr cinfo) -/* Allocate and fill in the error_limiter table */ -{ - my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; - int * table; - int in, out; - - table = (int *) (*cinfo->mem->alloc_small) - ((j_common_ptr) cinfo, JPOOL_IMAGE, (MAXJSAMPLE*2+1) * SIZEOF(int)); - table += MAXJSAMPLE; /* so can index -MAXJSAMPLE .. +MAXJSAMPLE */ - cquantize->error_limiter = table; - -#define STEPSIZE ((MAXJSAMPLE+1)/16) - /* Map errors 1:1 up to +- MAXJSAMPLE/16 */ - out = 0; - for (in = 0; in < STEPSIZE; in++, out++) { - table[in] = out; table[-in] = -out; - } - /* Map errors 1:2 up to +- 3*MAXJSAMPLE/16 */ - for (; in < STEPSIZE*3; in++, out += (in&1) ? 0 : 1) { - table[in] = out; table[-in] = -out; - } - /* Clamp the rest to final out value (which is (MAXJSAMPLE+1)/8) */ - for (; in <= MAXJSAMPLE; in++) { - table[in] = out; table[-in] = -out; - } -#undef STEPSIZE -} - - -/* - * Finish up at the end of each pass. - */ - -METHODDEF void -finish_pass1 (j_decompress_ptr cinfo) -{ - my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; - - /* Select the representative colors and fill in cinfo->colormap */ - cinfo->colormap = cquantize->sv_colormap; - select_colors(cinfo, cquantize->desired); - /* Force next pass to zero the color index table */ - cquantize->needs_zeroed = TRUE; -} - - -METHODDEF void -finish_pass2 (j_decompress_ptr cinfo) -{ - /* no work */ -} - - -/* - * Initialize for each processing pass. - */ - -METHODDEF void -start_pass_2_quant (j_decompress_ptr cinfo, boolean is_pre_scan) -{ - my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; - hist3d histogram = cquantize->histogram; - int i; - - /* Only F-S dithering or no dithering is supported. */ - /* If user asks for ordered dither, give him F-S. */ - if (cinfo->dither_mode != JDITHER_NONE) - cinfo->dither_mode = JDITHER_FS; - - if (is_pre_scan) { - /* Set up method pointers */ - cquantize->pub.color_quantize = prescan_quantize; - cquantize->pub.finish_pass = finish_pass1; - cquantize->needs_zeroed = TRUE; /* Always zero histogram */ - } else { - /* Set up method pointers */ - if (cinfo->dither_mode == JDITHER_FS) - cquantize->pub.color_quantize = pass2_fs_dither; - else - cquantize->pub.color_quantize = pass2_no_dither; - cquantize->pub.finish_pass = finish_pass2; - - /* Make sure color count is acceptable */ - i = cinfo->actual_number_of_colors; - if (i < 1) - ERREXIT1(cinfo, JERR_QUANT_FEW_COLORS, 1); - if (i > MAXNUMCOLORS) - ERREXIT1(cinfo, JERR_QUANT_MANY_COLORS, MAXNUMCOLORS); - - if (cinfo->dither_mode == JDITHER_FS) { - size_t arraysize = (size_t) ((cinfo->output_width + 2) * - (3 * SIZEOF(FSERROR))); - /* Allocate Floyd-Steinberg workspace if we didn't already. */ - if (cquantize->fserrors == NULL) - cquantize->fserrors = (FSERRPTR) (*cinfo->mem->alloc_large) - ((j_common_ptr) cinfo, JPOOL_IMAGE, arraysize); - /* Initialize the propagated errors to zero. */ - jzero_far((void FAR *) cquantize->fserrors, arraysize); - /* Make the error-limit table if we didn't already. */ - if (cquantize->error_limiter == NULL) - init_error_limit(cinfo); - cquantize->on_odd_row = FALSE; - } - - } - /* Zero the histogram or inverse color map, if necessary */ - if (cquantize->needs_zeroed) { - for (i = 0; i < HIST_C0_ELEMS; i++) { - jzero_far((void FAR *) histogram[i], - HIST_C1_ELEMS*HIST_C2_ELEMS * SIZEOF(histcell)); - } - cquantize->needs_zeroed = FALSE; - } -} - - -/* - * Switch to a new external colormap between output passes. - */ - -METHODDEF void -new_color_map_2_quant (j_decompress_ptr cinfo) -{ - my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; - - /* Reset the inverse color map */ - cquantize->needs_zeroed = TRUE; -} - - -/* - * Module initialization routine for 2-pass color quantization. - */ - -GLOBAL void -jinit_2pass_quantizer (j_decompress_ptr cinfo) -{ - my_cquantize_ptr cquantize; - int i; - - cquantize = (my_cquantize_ptr) - (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, - SIZEOF(my_cquantizer)); - cinfo->cquantize = (struct jpeg_color_quantizer *) cquantize; - cquantize->pub.start_pass = start_pass_2_quant; - cquantize->pub.new_color_map = new_color_map_2_quant; - cquantize->fserrors = NULL; /* flag optional arrays not allocated */ - cquantize->error_limiter = NULL; - - /* Make sure jdmaster didn't give me a case I can't handle */ - if (cinfo->out_color_components != 3) - ERREXIT(cinfo, JERR_NOTIMPL); - - /* Allocate the histogram/inverse colormap storage */ - cquantize->histogram = (hist3d) (*cinfo->mem->alloc_small) - ((j_common_ptr) cinfo, JPOOL_IMAGE, HIST_C0_ELEMS * SIZEOF(hist2d)); - for (i = 0; i < HIST_C0_ELEMS; i++) { - cquantize->histogram[i] = (hist2d) (*cinfo->mem->alloc_large) - ((j_common_ptr) cinfo, JPOOL_IMAGE, - HIST_C1_ELEMS*HIST_C2_ELEMS * SIZEOF(histcell)); - } - cquantize->needs_zeroed = TRUE; /* histogram is garbage now */ - - /* Allocate storage for the completed colormap, if required. - * We do this now since it is FAR storage and may affect - * the memory manager's space calculations. - */ - if (cinfo->enable_2pass_quant) { - /* Make sure color count is acceptable */ - int desired = cinfo->desired_number_of_colors; - /* Lower bound on # of colors ... somewhat arbitrary as long as > 0 */ - if (desired < 8) - ERREXIT1(cinfo, JERR_QUANT_FEW_COLORS, 8); - /* Make sure colormap indexes can be represented by JSAMPLEs */ - if (desired > MAXNUMCOLORS) - ERREXIT1(cinfo, JERR_QUANT_MANY_COLORS, MAXNUMCOLORS); - cquantize->sv_colormap = (*cinfo->mem->alloc_sarray) - ((j_common_ptr) cinfo,JPOOL_IMAGE, (JDIMENSION) desired, (JDIMENSION) 3); - cquantize->desired = desired; - } else - cquantize->sv_colormap = NULL; - - /* Only F-S dithering or no dithering is supported. */ - /* If user asks for ordered dither, give him F-S. */ - if (cinfo->dither_mode != JDITHER_NONE) - cinfo->dither_mode = JDITHER_FS; - - /* Allocate Floyd-Steinberg workspace if necessary. - * This isn't really needed until pass 2, but again it is FAR storage. - * Although we will cope with a later change in dither_mode, - * we do not promise to honor max_memory_to_use if dither_mode changes. - */ - if (cinfo->dither_mode == JDITHER_FS) { - cquantize->fserrors = (FSERRPTR) (*cinfo->mem->alloc_large) - ((j_common_ptr) cinfo, JPOOL_IMAGE, - (size_t) ((cinfo->output_width + 2) * (3 * SIZEOF(FSERROR)))); - /* Might as well create the error-limiting table too. */ - init_error_limit(cinfo); - } -} - -#endif /* QUANT_2PASS_SUPPORTED */ diff --git a/engine/jpeg-6/jutils.c b/engine/jpeg-6/jutils.c deleted file mode 100644 index 4ba2a54..0000000 --- a/engine/jpeg-6/jutils.c +++ /dev/null @@ -1,175 +0,0 @@ -/* - * jutils.c - * - * Copyright (C) 1991-1995, Thomas G. Lane. - * This file is part of the Independent JPEG Group's software. - * For conditions of distribution and use, see the accompanying README file. - * - * This file contains tables and miscellaneous utility routines needed - * for both compression and decompression. - * Note we prefix all global names with "j" to minimize conflicts with - * a surrounding application. - */ - -#define JPEG_INTERNALS -#include "jinclude.h" -#include "jpeglib.h" - - -/* - * jpeg_zigzag_order[i] is the zigzag-order position of the i'th element - * of a DCT block read in natural order (left to right, top to bottom). - */ - -const int jpeg_zigzag_order[DCTSIZE2] = { - 0, 1, 5, 6, 14, 15, 27, 28, - 2, 4, 7, 13, 16, 26, 29, 42, - 3, 8, 12, 17, 25, 30, 41, 43, - 9, 11, 18, 24, 31, 40, 44, 53, - 10, 19, 23, 32, 39, 45, 52, 54, - 20, 22, 33, 38, 46, 51, 55, 60, - 21, 34, 37, 47, 50, 56, 59, 61, - 35, 36, 48, 49, 57, 58, 62, 63 -}; - -/* - * jpeg_natural_order[i] is the natural-order position of the i'th element - * of zigzag order. - * - * When reading corrupted data, the Huffman decoders could attempt - * to reference an entry beyond the end of this array (if the decoded - * zero run length reaches past the end of the block). To prevent - * wild stores without adding an inner-loop test, we put some extra - * "63"s after the real entries. This will cause the extra coefficient - * to be stored in location 63 of the block, not somewhere random. - * The worst case would be a run-length of 15, which means we need 16 - * fake entries. - */ - -const int jpeg_natural_order[DCTSIZE2+16] = { - 0, 1, 8, 16, 9, 2, 3, 10, - 17, 24, 32, 25, 18, 11, 4, 5, - 12, 19, 26, 33, 40, 48, 41, 34, - 27, 20, 13, 6, 7, 14, 21, 28, - 35, 42, 49, 56, 57, 50, 43, 36, - 29, 22, 15, 23, 30, 37, 44, 51, - 58, 59, 52, 45, 38, 31, 39, 46, - 53, 60, 61, 54, 47, 55, 62, 63, - 63, 63, 63, 63, 63, 63, 63, 63, /* extra entries for safety in decoder */ - 63, 63, 63, 63, 63, 63, 63, 63 -}; - - -/* - * Arithmetic utilities - */ - -GLOBAL long -jdiv_round_up (long a, long b) -/* Compute a/b rounded up to next integer, ie, ceil(a/b) */ -/* Assumes a >= 0, b > 0 */ -{ - return (a + b - 1L) / b; -} - - -GLOBAL long -jround_up (long a, long b) -/* Compute a rounded up to next multiple of b, ie, ceil(a/b)*b */ -/* Assumes a >= 0, b > 0 */ -{ - a += b - 1L; - return a - (a % b); -} - - -/* On normal machines we can apply MEMCOPY() and MEMZERO() to sample arrays - * and coefficient-block arrays. This won't work on 80x86 because the arrays - * are FAR and we're assuming a small-pointer memory model. However, some - * DOS compilers provide far-pointer versions of memcpy() and memset() even - * in the small-model libraries. These will be used if USE_FMEM is defined. - * Otherwise, the routines below do it the hard way. (The performance cost - * is not all that great, because these routines aren't very heavily used.) - */ - -#ifndef NEED_FAR_POINTERS /* normal case, same as regular macros */ -#define FMEMCOPY(dest,src,size) MEMCOPY(dest,src,size) -#define FMEMZERO(target,size) MEMZERO(target,size) -#else /* 80x86 case, define if we can */ -#ifdef USE_FMEM -#define FMEMCOPY(dest,src,size) _fmemcpy((void FAR *)(dest), (const void FAR *)(src), (size_t)(size)) -#define FMEMZERO(target,size) _fmemset((void FAR *)(target), 0, (size_t)(size)) -#endif -#endif - - -GLOBAL void -jcopy_sample_rows (JSAMPARRAY input_array, int source_row, - JSAMPARRAY output_array, int dest_row, - int num_rows, JDIMENSION num_cols) -/* Copy some rows of samples from one place to another. - * num_rows rows are copied from input_array[source_row++] - * to output_array[dest_row++]; these areas may overlap for duplication. - * The source and destination arrays must be at least as wide as num_cols. - */ -{ - register JSAMPROW inptr, outptr; -#ifdef FMEMCOPY - register size_t count = (size_t) (num_cols * SIZEOF(JSAMPLE)); -#else - register JDIMENSION count; -#endif - register int row; - - input_array += source_row; - output_array += dest_row; - - for (row = num_rows; row > 0; row--) { - inptr = *input_array++; - outptr = *output_array++; -#ifdef FMEMCOPY - FMEMCOPY(outptr, inptr, count); -#else - for (count = num_cols; count > 0; count--) - *outptr++ = *inptr++; /* needn't bother with GETJSAMPLE() here */ -#endif - } -} - - -GLOBAL void -jcopy_block_row (JBLOCKROW input_row, JBLOCKROW output_row, - JDIMENSION num_blocks) -/* Copy a row of coefficient blocks from one place to another. */ -{ -#ifdef FMEMCOPY - FMEMCOPY(output_row, input_row, num_blocks * (DCTSIZE2 * SIZEOF(JCOEF))); -#else - register JCOEFPTR inptr, outptr; - register long count; - - inptr = (JCOEFPTR) input_row; - outptr = (JCOEFPTR) output_row; - for (count = (long) num_blocks * DCTSIZE2; count > 0; count--) { - *outptr++ = *inptr++; - } -#endif -} - - -GLOBAL void -jzero_far (void FAR * target, size_t bytestozero) -/* Zero out a chunk of FAR memory. */ -/* This might be sample-array data, block-array data, or alloc_large data. */ -{ -#ifdef FMEMZERO - FMEMZERO(target, bytestozero); -#else - register char FAR * ptr = (char FAR *) target; - register size_t count; - - for (count = bytestozero; count > 0; count--) { - *ptr++ = 0; - } -#endif -} diff --git a/engine/jpeg-6/jversion.h b/engine/jpeg-6/jversion.h deleted file mode 100644 index f2f1b8d..0000000 --- a/engine/jpeg-6/jversion.h +++ /dev/null @@ -1,14 +0,0 @@ -/* - * jversion.h - * - * Copyright (C) 1991-1995, Thomas G. Lane. - * This file is part of the Independent JPEG Group's software. - * For conditions of distribution and use, see the accompanying README file. - * - * This file contains software version identification. - */ - - -#define JVERSION "6 2-Aug-95" - -#define JCOPYRIGHT "Copyright (C) 1995, Thomas G. Lane" diff --git a/engine/projects/uniquake/cpp.hint b/engine/projects/uniquake/cpp.hint deleted file mode 100644 index 22f5d0a..0000000 --- a/engine/projects/uniquake/cpp.hint +++ /dev/null @@ -1,2 +0,0 @@ -#define UNIQUAKE_API __declspec(dllexport) -#define UNIQUAKE_API __declspec(dllimport) diff --git a/engine/projects/uniquake/sys_uniquake.c b/engine/projects/uniquake/sys_uniquake.c deleted file mode 100644 index a124759..0000000 --- a/engine/projects/uniquake/sys_uniquake.c +++ /dev/null @@ -1,124 +0,0 @@ -#include "uniquake.h" - -#include "../../code/quakedef.h" - -typedef struct unity_syscalls_s -{ - void *target; - - void(*SysPrint)(void *target, const char *msg); - void(*SysError)(void *target, const char *msg); - void(*SysQuit)(void *target); - double(*SysFloatTime)(void *target); - - int(*SysFileOpenRead)(void *target, char *path, int *hndl); - int(*SysFileOpenWrite)(void *target, char *path); - void(*SysFileClose)(void *target, int handle); - void(*SysFileSeek)(void *target, int handle, int position); - int(*SysFileRead)(void *target, int handle, void *dest, int count); - int(*SysFileWrite)(void *target, int handle, void *data, int count); - int(*SysFileTime)(void *target, char *path); - void(*SysMkDir)(void *target, char *path); -} unity_syscalls_t; - -const unity_syscalls_t *unity_syscalls; - -void Sys_Error(char *error, ...) -{ - va_list argptr; - char text[1024]; - - va_start(argptr, error); - vsprintf(text, error, argptr); - va_end(argptr); - - unity_syscalls->SysError(unity_syscalls->target, text); -} - -void Sys_Printf(char *fmt, ...) -{ - va_list argptr; - char text[1024]; - - va_start(argptr, fmt); - vsprintf(text, fmt, argptr); - va_end(argptr); - - unity_syscalls->SysPrint(unity_syscalls->target, text); -} - -void Sys_Quit(void) -{ - unity_syscalls->SysQuit(unity_syscalls->target); -} - -double Sys_FloatTime(void) -{ - return unity_syscalls->SysFloatTime(unity_syscalls->target); -} - -int Sys_FileOpenRead(char *path, int *hndl) -{ - int t, retval; - t = VID_ForceUnlockedAndReturnState(); - retval = unity_syscalls->SysFileOpenRead(unity_syscalls->target, path, hndl); - VID_ForceLockState(t); - return retval; -} - -int Sys_FileOpenWrite(char *path) -{ - int t, retval; - t = VID_ForceUnlockedAndReturnState(); - retval = unity_syscalls->SysFileOpenWrite(unity_syscalls->target, path); - VID_ForceLockState(t); - return retval; -} - -void Sys_FileClose(int handle) -{ - int t; - t = VID_ForceUnlockedAndReturnState(); - unity_syscalls->SysFileClose(unity_syscalls->target, handle); - VID_ForceLockState(t); -} - -void Sys_FileSeek(int handle, int position) -{ - int t; - t = VID_ForceUnlockedAndReturnState(); - unity_syscalls->SysFileSeek(unity_syscalls->target, handle, position); - VID_ForceLockState(t); -} - -int Sys_FileRead(int handle, void *dest, int count) -{ - int t, retval; - t = VID_ForceUnlockedAndReturnState(); - retval = unity_syscalls->SysFileRead(unity_syscalls->target, handle, dest, count); - VID_ForceLockState(t); - return retval; -} - -int Sys_FileWrite(int handle, void *data, int count) -{ - int t, retval; - t = VID_ForceUnlockedAndReturnState(); - retval = unity_syscalls->SysFileWrite(unity_syscalls->target, handle, data, count); - VID_ForceLockState(t); - return retval; -} - -int Sys_FileTime(char *path) -{ - int t, retval; - t = VID_ForceUnlockedAndReturnState(); - retval = unity_syscalls->SysFileTime(unity_syscalls->target, path); - VID_ForceLockState(t); - return retval; -} - -void Sys_mkdir(char *path) -{ - unity_syscalls->SysMkDir(unity_syscalls->target, path); -} diff --git a/engine/projects/uniquake/uniquake.vcxproj b/engine/projects/uniquake/uniquake.vcxproj deleted file mode 100644 index 6908535..0000000 --- a/engine/projects/uniquake/uniquake.vcxproj +++ /dev/null @@ -1,447 +0,0 @@ - - - - - Debug - Win32 - - - Portable - Win32 - - - Portable - x64 - - - Release - Win32 - - - Debug - x64 - - - Release - x64 - - - - 15.0 - {6BF61A30-D954-4A67-9A68-CE981083D4DC} - Win32Proj - uniquake - 10.0.17763.0 - - - - DynamicLibrary - true - v141 - NotSet - - - DynamicLibrary - true - v141 - NotSet - - - DynamicLibrary - false - v141 - true - Unicode - - - DynamicLibrary - true - v141 - NotSet - - - DynamicLibrary - true - v141 - NotSet - - - DynamicLibrary - false - v141 - true - Unicode - - - - - - - - - - - - - - - - - - - - - - - - - - - uniquake - true - - - uniquake - true - - - uniquake - true - - - uniquake - true - - - UNIQUAKE - false - - - UNIQUAKE - false - - - - NotUsing - Level1 - Disabled - false - UQ_WINDEBUG;UQ_GLDEBUG;_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;UNIQUAKE_EXPORTS;_WINDOWS;_USRDLL;GLQUAKE;UQE_FMOD;%(PreprocessorDefinitions) - false - pch.h - - - MultiThreadedDebugDLL - - - Windows - true - false - kernel32.lib;user32.lib;gdi32.lib;opengl32.lib;winmm.lib;wsock32.lib;glu32.lib;fmodL_vc.lib - ..\..\fmodcore\lib\x86;%(AdditionalLibraryDirectories) - - - copy $(TargetDir)$(TargetName).dll $(SolutionDir)..\..\..\Assets\Plugins\windows\x86\uniquake.dll - - - - - NotUsing - Level1 - Disabled - false - UQ_GLDEBUG;_CRT_SECURE_NO_WARNINGS;_DEBUG;UNIQUAKE_EXPORTS;GLQUAKE;UQE_FMOD;%(PreprocessorDefinitions) - false - pch.h - - - MultiThreadedDebugDLL - - - Windows - true - false - opengl32.lib;glu32.lib;fmodL_vc.lib - ..\..\fmodcore\lib\x86;%(AdditionalLibraryDirectories) - - - copy $(TargetDir)$(TargetName).dll $(SolutionDir)..\..\..\Assets\Plugins\windows\x86\uniquake.dll - - - - - NotUsing - Level1 - Disabled - false - UQ_WINDEBUG;UQ_GLDEBUG;_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;UNIQUAKE_EXPORTS;_WINDOWS;_USRDLL;GLQUAKE;UQE_FMOD;%(PreprocessorDefinitions) - false - pch.h - - - - - Windows - true - false - kernel32.lib;user32.lib;gdi32.lib;opengl32.lib;winmm.lib;wsock32.lib;glu32.lib;fmodL_vc.lib - ..\..\fmodcore\lib\x64;%(AdditionalLibraryDirectories) - - - copy $(TargetDir)$(TargetName).dll $(SolutionDir)..\..\..\Assets\Plugins\windows\x86_64\uniquake.dll - - - - - NotUsing - Level1 - Disabled - false - UQ_GLDEBUG;_CRT_SECURE_NO_WARNINGS;_DEBUG;UNIQUAKE_EXPORTS;GLQUAKE;UQE_FMOD - false - pch.h - - - - - Windows - true - false - opengl32.lib;glu32.lib;fmodL_vc.lib - ..\..\fmodcore\lib\x64;%(AdditionalLibraryDirectories) - - - copy $(TargetDir)$(TargetName).dll $(SolutionDir)..\..\..\Assets\Plugins\windows\x86_64\uniquake.dll - - - - - NotUsing - Level3 - MaxSpeed - true - true - true - WIN32;NDEBUG;UNIQUAKE_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) - true - pch.h - - - - - Windows - true - true - true - false - fmodex_vc.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) - ..\..\fmod-4\lib;%(AdditionalLibraryDirectories) - - - - - NotUsing - Level3 - MaxSpeed - true - true - true - NDEBUG;UNIQUAKE_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) - true - pch.h - - - - - Windows - true - true - true - false - fmodex_vc.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) - ..\..\fmod-4\lib;%(AdditionalLibraryDirectories) - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/engine/projects/uniquake/uniquake.vcxproj.filters b/engine/projects/uniquake/uniquake.vcxproj.filters deleted file mode 100644 index 2684716..0000000 --- a/engine/projects/uniquake/uniquake.vcxproj.filters +++ /dev/null @@ -1,545 +0,0 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hh;hpp;hxx;hm;inl;inc;ipp;xsd - - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms - - - {3f2f4b7e-be4b-4320-b2b3-2ae03d48656b} - - - {c3683c27-7e24-40b1-9b4b-79a0d059c9a4} - - - {89755f20-dffb-43a4-a16f-4aacd1e25440} - - - - - - - - Header Files - - - engine - - - engine - - - engine - - - engine - - - engine - - - engine - - - engine - - - engine - - - engine - - - engine - - - engine - - - engine - - - engine - - - engine - - - engine - - - engine - - - engine - - - engine - - - engine - - - engine - - - engine - - - engine - - - engine - - - engine - - - engine - - - engine - - - engine - - - engine - - - engine - - - engine - - - engine - - - engine - - - engine - - - engine - - - engine - - - engine - - - engine - - - engine - - - engine - - - engine - - - engine - - - engine - - - engine - - - engine - - - engine - - - engine - - - engine - - - engine - - - engine - - - engine - - - engine - - - jpeg - - - jpeg - - - jpeg - - - jpeg - - - jpeg - - - jpeg - - - jpeg - - - jpeg - - - jpeg - - - jpeg - - - jpeg - - - fmod - - - fmod - - - fmod - - - fmod - - - fmod - - - fmod - - - fmod - - - fmod - - - - - engine - - - engine - - - engine - - - engine - - - engine - - - engine - - - engine - - - engine - - - engine - - - engine - - - engine - - - engine - - - engine - - - engine - - - engine - - - engine - - - engine - - - engine - - - engine - - - engine - - - engine - - - engine - - - engine - - - engine - - - engine - - - engine - - - engine - - - engine - - - engine - - - engine - - - engine - - - engine - - - engine - - - engine - - - engine - - - engine - - - engine - - - engine - - - engine - - - engine - - - engine - - - engine - - - engine - - - engine - - - engine - - - engine - - - engine - - - engine - - - engine - - - engine - - - engine - - - engine - - - engine - - - engine - - - engine - - - engine - - - engine - - - engine - - - engine - - - jpeg - - - jpeg - - - jpeg - - - jpeg - - - jpeg - - - jpeg - - - jpeg - - - jpeg - - - jpeg - - - jpeg - - - jpeg - - - jpeg - - - jpeg - - - jpeg - - - jpeg - - - jpeg - - - jpeg - - - jpeg - - - jpeg - - - jpeg - - - jpeg - - - jpeg - - - jpeg - - - jpeg - - - jpeg - - - jpeg - - - jpeg - - - jpeg - - - jpeg - - - jpeg - - - jpeg - - - jpeg - - - jpeg - - - jpeg - - - jpeg - - - jpeg - - - Source Files - - - Source Files - - - Source Files - - - - - Resource Files - - - \ No newline at end of file